From e758bec8c6c35589e8ec7c901ba9b191d74d35b5 Mon Sep 17 00:00:00 2001 From: Dayhun Date: Wed, 25 May 2022 22:35:57 +0900 Subject: [PATCH 001/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/1.arry/README.md | 5 +++++ Challenge/DahyunLim/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/DahyunLim/1.arry/README.md create mode 100644 Challenge/DahyunLim/1.arry/solve.js diff --git a/Challenge/DahyunLim/1.arry/README.md b/Challenge/DahyunLim/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/DahyunLim/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/DahyunLim/1.arry/solve.js b/Challenge/DahyunLim/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/DahyunLim/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 245a95c037d2cdf62580ddfa479ecd5070511bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cnimoseel=E2=80=9D?= Date: Wed, 25 May 2022 22:35:57 +0900 Subject: [PATCH 002/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SominLee/1.arry/README.md | 5 +++++ Challenge/SominLee/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/SominLee/1.arry/README.md create mode 100644 Challenge/SominLee/1.arry/solve.js diff --git a/Challenge/SominLee/1.arry/README.md b/Challenge/SominLee/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/SominLee/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SominLee/1.arry/solve.js b/Challenge/SominLee/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/SominLee/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 05d009a3b6b6d49a374d4f011b7d6edc16a47829 Mon Sep 17 00:00:00 2001 From: seokahi Date: Wed, 25 May 2022 22:35:58 +0900 Subject: [PATCH 003/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/1.arry/README.md | 5 +++++ Challenge/seokahi/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/seokahi/1.arry/README.md create mode 100644 Challenge/seokahi/1.arry/solve.js diff --git a/Challenge/seokahi/1.arry/README.md b/Challenge/seokahi/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/seokahi/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/seokahi/1.arry/solve.js b/Challenge/seokahi/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/seokahi/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From fa3cc7ec4846c81db22b30b7e35b226807abe639 Mon Sep 17 00:00:00 2001 From: greenT-Hee Date: Wed, 25 May 2022 22:36:00 +0900 Subject: [PATCH 004/308] =?UTF-8?q?Solve=201=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/TaeheeKim/1.arry/README.md | 5 +++++ Challenge/TaeheeKim/1.arry/solve.js | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 Challenge/TaeheeKim/1.arry/README.md create mode 100644 Challenge/TaeheeKim/1.arry/solve.js diff --git a/Challenge/TaeheeKim/1.arry/README.md b/Challenge/TaeheeKim/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/TaeheeKim/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/TaeheeKim/1.arry/solve.js b/Challenge/TaeheeKim/1.arry/solve.js new file mode 100644 index 0000000..48534d1 --- /dev/null +++ b/Challenge/TaeheeKim/1.arry/solve.js @@ -0,0 +1,7 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +console.log(num); \ No newline at end of file From 00e38b63afa69db2a288ad7785aa5ff5de3c8b20 Mon Sep 17 00:00:00 2001 From: ryungom Date: Wed, 25 May 2022 22:36:08 +0900 Subject: [PATCH 005/308] =?UTF-8?q?solve=20:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JaejuneRyu/README.md | 5 +++++ Challenge/JaejuneRyu/solve.js | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 Challenge/JaejuneRyu/README.md create mode 100644 Challenge/JaejuneRyu/solve.js diff --git a/Challenge/JaejuneRyu/README.md b/Challenge/JaejuneRyu/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/JaejuneRyu/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/JaejuneRyu/solve.js b/Challenge/JaejuneRyu/solve.js new file mode 100644 index 0000000..0424c3c --- /dev/null +++ b/Challenge/JaejuneRyu/solve.js @@ -0,0 +1,7 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); \ No newline at end of file From 9a6dd7ddaf264da8151237dcc65269dcc2412bd2 Mon Sep 17 00:00:00 2001 From: ujin Date: Wed, 25 May 2022 22:36:11 +0900 Subject: [PATCH 006/308] =?UTF-8?q?Solve:=201=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/UjinJeon/1.arry/README.md | 5 +++++ Challenge/UjinJeon/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/UjinJeon/1.arry/README.md create mode 100644 Challenge/UjinJeon/1.arry/solve.js diff --git a/Challenge/UjinJeon/1.arry/README.md b/Challenge/UjinJeon/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/UjinJeon/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/UjinJeon/1.arry/solve.js b/Challenge/UjinJeon/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/UjinJeon/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 85c3e0b040e32b92fdbbb408b21c60f4be5d4ac2 Mon Sep 17 00:00:00 2001 From: plutoin Date: Wed, 25 May 2022 22:36:17 +0900 Subject: [PATCH 007/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/1.arry/README.md | 5 +++++ Challenge/SoyeonJang/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/SoyeonJang/1.arry/README.md create mode 100644 Challenge/SoyeonJang/1.arry/solve.js diff --git a/Challenge/SoyeonJang/1.arry/README.md b/Challenge/SoyeonJang/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/SoyeonJang/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SoyeonJang/1.arry/solve.js b/Challenge/SoyeonJang/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/SoyeonJang/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 5bf36847bc64a89a1d4c544e76d6603aeacedea8 Mon Sep 17 00:00:00 2001 From: chooing Date: Wed, 25 May 2022 22:37:04 +0900 Subject: [PATCH 008/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihyeChoo/1.arry/README.md | 5 +++++ Challenge/JihyeChoo/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/JihyeChoo/1.arry/README.md create mode 100644 Challenge/JihyeChoo/1.arry/solve.js diff --git a/Challenge/JihyeChoo/1.arry/README.md b/Challenge/JihyeChoo/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/JihyeChoo/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/JihyeChoo/1.arry/solve.js b/Challenge/JihyeChoo/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/JihyeChoo/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From ac09c6750ceeaeb813cfe76717a6da48e1038df0 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Wed, 25 May 2022 22:39:03 +0900 Subject: [PATCH 009/308] =?UTF-8?q?Solve=20:=20001=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seyeongLee/1.arry/README.md | 5 +++++ Challenge/seyeongLee/1.arry/solve.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Challenge/seyeongLee/1.arry/README.md create mode 100644 Challenge/seyeongLee/1.arry/solve.js diff --git a/Challenge/seyeongLee/1.arry/README.md b/Challenge/seyeongLee/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/seyeongLee/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/seyeongLee/1.arry/solve.js b/Challenge/seyeongLee/1.arry/solve.js new file mode 100644 index 0000000..df08e42 --- /dev/null +++ b/Challenge/seyeongLee/1.arry/solve.js @@ -0,0 +1,15 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +// 첫번째 방법 +// nums.splice(3, 2); + +// 두번째 방법 +// nums.splice(-2, 2); + +// 세번째 방법 +nums.pop(); +nums.pop(); +console.log(nums); \ No newline at end of file From 7af8a059acaf6d6c659f42ae4b23a17ab5f14aba Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Wed, 25 May 2022 22:39:40 +0900 Subject: [PATCH 010/308] =?UTF-8?q?Solve:=20=EB=AC=B8=EC=A0=9C1=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/KimYeji/1.arry/README.md | 5 +++++ Challenge/KimYeji/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/KimYeji/1.arry/README.md create mode 100644 Challenge/KimYeji/1.arry/solve.js diff --git a/Challenge/KimYeji/1.arry/README.md b/Challenge/KimYeji/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/KimYeji/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/KimYeji/1.arry/solve.js b/Challenge/KimYeji/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/KimYeji/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 5c05fb0478fff2d97c1f5e42e83f409f030dcf86 Mon Sep 17 00:00:00 2001 From: unidagit Date: Wed, 25 May 2022 22:39:43 +0900 Subject: [PATCH 011/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/1.arry/README.md | 5 +++++ Challenge/YunheeJo/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/YunheeJo/1.arry/README.md create mode 100644 Challenge/YunheeJo/1.arry/solve.js diff --git a/Challenge/YunheeJo/1.arry/README.md b/Challenge/YunheeJo/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/YunheeJo/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/YunheeJo/1.arry/solve.js b/Challenge/YunheeJo/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/YunheeJo/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 7be6e4713a5a7ceeea0ee0ca9a2cad8b82a7b88d Mon Sep 17 00:00:00 2001 From: ryungom Date: Wed, 25 May 2022 22:39:56 +0900 Subject: [PATCH 012/308] =?UTF-8?q?Solbe=20:=201=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JaejuneRyu/{ => 1.arry}/README.md | 0 Challenge/JaejuneRyu/{ => 1.arry}/solve.js | 5 +---- 2 files changed, 1 insertion(+), 4 deletions(-) rename Challenge/JaejuneRyu/{ => 1.arry}/README.md (100%) rename Challenge/JaejuneRyu/{ => 1.arry}/solve.js (63%) diff --git a/Challenge/JaejuneRyu/README.md b/Challenge/JaejuneRyu/1.arry/README.md similarity index 100% rename from Challenge/JaejuneRyu/README.md rename to Challenge/JaejuneRyu/1.arry/README.md diff --git a/Challenge/JaejuneRyu/solve.js b/Challenge/JaejuneRyu/1.arry/solve.js similarity index 63% rename from Challenge/JaejuneRyu/solve.js rename to Challenge/JaejuneRyu/1.arry/solve.js index 0424c3c..7ffd8bd 100644 --- a/Challenge/JaejuneRyu/solve.js +++ b/Challenge/JaejuneRyu/1.arry/solve.js @@ -1,7 +1,4 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; - -nums.pop(); -nums.pop(); \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 25064da2c93cdeaa908804a4b2b8d5d9af19b239 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Wed, 25 May 2022 22:40:01 +0900 Subject: [PATCH 013/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/1.arry/solve.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Problems/1.arry/solve.js b/Problems/1.arry/solve.js index 7ffd8bd..14ef818 100644 --- a/Problems/1.arry/solve.js +++ b/Problems/1.arry/solve.js @@ -1,4 +1,6 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +nums.filter(x => x < 400); \ No newline at end of file From e87e4a5fe6f8da2994111e83420dbf2369fb8ac1 Mon Sep 17 00:00:00 2001 From: sooyyoung Date: Wed, 25 May 2022 22:40:38 +0900 Subject: [PATCH 014/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sooyoungCho/1.arry/README.md | 5 +++++ Challenge/sooyoungCho/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/sooyoungCho/1.arry/README.md create mode 100644 Challenge/sooyoungCho/1.arry/solve.js diff --git a/Challenge/sooyoungCho/1.arry/README.md b/Challenge/sooyoungCho/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/sooyoungCho/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/sooyoungCho/1.arry/solve.js b/Challenge/sooyoungCho/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/sooyoungCho/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 04f3e035fc93ed328cba1e90fcbf9671d67ee5a9 Mon Sep 17 00:00:00 2001 From: leeyeun Date: Wed, 25 May 2022 22:42:14 +0900 Subject: [PATCH 015/308] =?UTF-8?q?Feat=20=EC=9D=B4=EC=98=88=EC=9D=80=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YeeunLee/1.arry/README.md | 5 +++++ Challenge/YeeunLee/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/YeeunLee/1.arry/README.md create mode 100644 Challenge/YeeunLee/1.arry/solve.js diff --git a/Challenge/YeeunLee/1.arry/README.md b/Challenge/YeeunLee/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/YeeunLee/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/YeeunLee/1.arry/solve.js b/Challenge/YeeunLee/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/YeeunLee/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 2eee8f9e218b97ea6b1c5a652bc87995de3b93c4 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Wed, 25 May 2022 22:43:26 +0900 Subject: [PATCH 016/308] =?UTF-8?q?=EC=A1=B0=EB=AF=BC=EA=B2=BD=20=EC=B1=8C?= =?UTF-8?q?=EB=A6=B0=EC=A7=80=20=ED=8F=B4=EB=8D=94=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/1.arry/README.md | 5 +++++ Challenge/MinkyeongJo/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/MinkyeongJo/1.arry/README.md create mode 100644 Challenge/MinkyeongJo/1.arry/solve.js diff --git a/Challenge/MinkyeongJo/1.arry/README.md b/Challenge/MinkyeongJo/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/MinkyeongJo/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/MinkyeongJo/1.arry/solve.js b/Challenge/MinkyeongJo/1.arry/solve.js new file mode 100644 index 0000000..88d75d3 --- /dev/null +++ b/Challenge/MinkyeongJo/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500];`` \ No newline at end of file From c958691e8366bb574888d3ff442a6197e85a58b6 Mon Sep 17 00:00:00 2001 From: SeoHee3478 Date: Wed, 25 May 2022 22:56:57 +0900 Subject: [PATCH 017/308] =?UTF-8?q?Solve=20:=20001=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SeoheeJeon/README.md | 5 +++++ Challenge/SeoheeJeon/solve.js | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 Challenge/SeoheeJeon/README.md create mode 100644 Challenge/SeoheeJeon/solve.js diff --git a/Challenge/SeoheeJeon/README.md b/Challenge/SeoheeJeon/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/SeoheeJeon/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SeoheeJeon/solve.js b/Challenge/SeoheeJeon/solve.js new file mode 100644 index 0000000..7ab35db --- /dev/null +++ b/Challenge/SeoheeJeon/solve.js @@ -0,0 +1,6 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +// a \ No newline at end of file From 3b9df7dfd3e52e67624aa8a68e2c72cbc8770b51 Mon Sep 17 00:00:00 2001 From: heejin Date: Wed, 25 May 2022 22:58:16 +0900 Subject: [PATCH 018/308] =?UTF-8?q?Solve:1=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HeejinKim/1.arry/README.md | 5 +++++ Challenge/HeejinKim/1.arry/solve.js | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 Challenge/HeejinKim/1.arry/README.md create mode 100644 Challenge/HeejinKim/1.arry/solve.js diff --git a/Challenge/HeejinKim/1.arry/README.md b/Challenge/HeejinKim/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/HeejinKim/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/HeejinKim/1.arry/solve.js b/Challenge/HeejinKim/1.arry/solve.js new file mode 100644 index 0000000..0424c3c --- /dev/null +++ b/Challenge/HeejinKim/1.arry/solve.js @@ -0,0 +1,7 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); \ No newline at end of file From 31c1617c3d257d3430e2fc094b5fe2f2889028ce Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Wed, 25 May 2022 22:43:26 +0900 Subject: [PATCH 019/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/1.arry/README.md | 5 +++++ Challenge/MinkyeongJo/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/MinkyeongJo/1.arry/README.md create mode 100644 Challenge/MinkyeongJo/1.arry/solve.js diff --git a/Challenge/MinkyeongJo/1.arry/README.md b/Challenge/MinkyeongJo/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/MinkyeongJo/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/MinkyeongJo/1.arry/solve.js b/Challenge/MinkyeongJo/1.arry/solve.js new file mode 100644 index 0000000..88d75d3 --- /dev/null +++ b/Challenge/MinkyeongJo/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500];`` \ No newline at end of file From 3afde0d43d290ea4402af20595dc988b43bf361b Mon Sep 17 00:00:00 2001 From: skylar121 Date: Wed, 25 May 2022 23:05:21 +0900 Subject: [PATCH 020/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {GyeongRim => Challenge/GyeongRim}/1.arry/README.md | 0 {GyeongRim => Challenge/GyeongRim}/1.arry/solve.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {GyeongRim => Challenge/GyeongRim}/1.arry/README.md (100%) rename {GyeongRim => Challenge/GyeongRim}/1.arry/solve.js (100%) diff --git a/GyeongRim/1.arry/README.md b/Challenge/GyeongRim/1.arry/README.md similarity index 100% rename from GyeongRim/1.arry/README.md rename to Challenge/GyeongRim/1.arry/README.md diff --git a/GyeongRim/1.arry/solve.js b/Challenge/GyeongRim/1.arry/solve.js similarity index 100% rename from GyeongRim/1.arry/solve.js rename to Challenge/GyeongRim/1.arry/solve.js From 2334e78b2dbe0f06b8b7e0a1cd0ee3a0092bf987 Mon Sep 17 00:00:00 2001 From: hee1231 Date: Wed, 25 May 2022 23:08:34 +0900 Subject: [PATCH 021/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DoheeKim/1.arry/README.md | 5 +++++ Challenge/DoheeKim/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/DoheeKim/1.arry/README.md create mode 100644 Challenge/DoheeKim/1.arry/solve.js diff --git a/Challenge/DoheeKim/1.arry/README.md b/Challenge/DoheeKim/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/DoheeKim/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/DoheeKim/1.arry/solve.js b/Challenge/DoheeKim/1.arry/solve.js new file mode 100644 index 0000000..7ffd8bd --- /dev/null +++ b/Challenge/DoheeKim/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file From 1a0b3e6f0cb431e9a17a1b344c307fc45c19fe1c Mon Sep 17 00:00:00 2001 From: usablepaper Date: Wed, 25 May 2022 23:13:07 +0900 Subject: [PATCH 022/308] =?UTF-8?q?Solve=202=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Hyeonji/2.arryMethd/README.md | 11 +++++++++++ Challenge/Hyeonji/2.arryMethd/solve.js | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/Hyeonji/2.arryMethd/README.md create mode 100644 Challenge/Hyeonji/2.arryMethd/solve.js diff --git a/Challenge/Hyeonji/2.arryMethd/README.md b/Challenge/Hyeonji/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/Hyeonji/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/Hyeonji/2.arryMethd/solve.js b/Challenge/Hyeonji/2.arryMethd/solve.js new file mode 100644 index 0000000..4095544 --- /dev/null +++ b/Challenge/Hyeonji/2.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file From 96ff43b8bf6f451be791571acfd39ced7cee2e71 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Wed, 25 May 2022 23:19:24 +0900 Subject: [PATCH 023/308] git commit -m --- Challenge/Songmyeongseok/1.arry/README.md | 5 +++++ Challenge/Songmyeongseok/1.arry/solve.js | 6 ++++++ Challenge/Songmyeongseok/2.arryMethd/README.md | 11 +++++++++++ Challenge/Songmyeongseok/2.arryMethd/solve.js | 11 +++++++++++ Problems/1.arry/solve.js | 1 - 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 Challenge/Songmyeongseok/1.arry/README.md create mode 100644 Challenge/Songmyeongseok/1.arry/solve.js create mode 100644 Challenge/Songmyeongseok/2.arryMethd/README.md create mode 100644 Challenge/Songmyeongseok/2.arryMethd/solve.js diff --git a/Challenge/Songmyeongseok/1.arry/README.md b/Challenge/Songmyeongseok/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/Songmyeongseok/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/Songmyeongseok/1.arry/solve.js b/Challenge/Songmyeongseok/1.arry/solve.js new file mode 100644 index 0000000..14ef818 --- /dev/null +++ b/Challenge/Songmyeongseok/1.arry/solve.js @@ -0,0 +1,6 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.filter(x => x < 400); \ No newline at end of file diff --git a/Challenge/Songmyeongseok/2.arryMethd/README.md b/Challenge/Songmyeongseok/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/Songmyeongseok/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/Songmyeongseok/2.arryMethd/solve.js b/Challenge/Songmyeongseok/2.arryMethd/solve.js new file mode 100644 index 0000000..4095544 --- /dev/null +++ b/Challenge/Songmyeongseok/2.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/1.arry/solve.js b/Problems/1.arry/solve.js index 14ef818..7f6311f 100644 --- a/Problems/1.arry/solve.js +++ b/Problems/1.arry/solve.js @@ -3,4 +3,3 @@ var nums = [100, 200, 300, 400, 500]; -nums.filter(x => x < 400); \ No newline at end of file From 376a1a612406dd5c44dbc4b81fa451be27d83323 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Wed, 25 May 2022 23:37:43 +0900 Subject: [PATCH 024/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/2.arryMethd/README.md | 11 ----------- Challenge/Songmyeongseok/2.arryMethd/solve.js | 11 ----------- 2 files changed, 22 deletions(-) delete mode 100644 Challenge/Songmyeongseok/2.arryMethd/README.md delete mode 100644 Challenge/Songmyeongseok/2.arryMethd/solve.js diff --git a/Challenge/Songmyeongseok/2.arryMethd/README.md b/Challenge/Songmyeongseok/2.arryMethd/README.md deleted file mode 100644 index 01d8d19..0000000 --- a/Challenge/Songmyeongseok/2.arryMethd/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 문제2 : 배열의 내장함수 - -부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/Songmyeongseok/2.arryMethd/solve.js b/Challenge/Songmyeongseok/2.arryMethd/solve.js deleted file mode 100644 index 4095544..0000000 --- a/Challenge/Songmyeongseok/2.arryMethd/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제2 : 배열의 내장함수 - -// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file From 2b3966b77806c7e2a129af036fd352e2b2cdd7da Mon Sep 17 00:00:00 2001 From: Dayhun Date: Wed, 25 May 2022 23:49:34 +0900 Subject: [PATCH 025/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/1.arry/solve.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Challenge/DahyunLim/1.arry/solve.js b/Challenge/DahyunLim/1.arry/solve.js index 7ffd8bd..973f949 100644 --- a/Challenge/DahyunLim/1.arry/solve.js +++ b/Challenge/DahyunLim/1.arry/solve.js @@ -1,4 +1,7 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +nums.splice(3, 2); +nums; \ No newline at end of file From 30f11cdeef80a37b5237c4a0bba6aeee79793aef Mon Sep 17 00:00:00 2001 From: Subin Date: Thu, 26 May 2022 02:43:04 +0900 Subject: [PATCH 026/308] =?UTF-8?q?solve=20:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinLee/1.arry/README.md | 5 +++++ Challenge/SubinLee/1.arry/solve.js | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 Challenge/SubinLee/1.arry/README.md create mode 100644 Challenge/SubinLee/1.arry/solve.js diff --git a/Challenge/SubinLee/1.arry/README.md b/Challenge/SubinLee/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/SubinLee/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SubinLee/1.arry/solve.js b/Challenge/SubinLee/1.arry/solve.js new file mode 100644 index 0000000..b7ddb52 --- /dev/null +++ b/Challenge/SubinLee/1.arry/solve.js @@ -0,0 +1,4 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; From 0e55f8373452aa594618ec0420849dfb70e758ad Mon Sep 17 00:00:00 2001 From: unidagit Date: Thu, 26 May 2022 19:40:11 +0900 Subject: [PATCH 027/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/1.arry/solve.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Challenge/YunheeJo/1.arry/solve.js b/Challenge/YunheeJo/1.arry/solve.js index 7ffd8bd..f7d67ea 100644 --- a/Challenge/YunheeJo/1.arry/solve.js +++ b/Challenge/YunheeJo/1.arry/solve.js @@ -1,4 +1,8 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +nums.splice(3, 2); + +console.log(nums) \ No newline at end of file From 40767b428ed88fb8bbcf938d5b03a9b4c5c2bda9 Mon Sep 17 00:00:00 2001 From: unidagit Date: Thu, 26 May 2022 19:46:59 +0900 Subject: [PATCH 028/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/2.arryMethd/README.md | 11 +++++++++++ Challenge/YunheeJo/2.arryMethd/solve.js | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/YunheeJo/2.arryMethd/README.md create mode 100644 Challenge/YunheeJo/2.arryMethd/solve.js diff --git a/Challenge/YunheeJo/2.arryMethd/README.md b/Challenge/YunheeJo/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/YunheeJo/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/YunheeJo/2.arryMethd/solve.js b/Challenge/YunheeJo/2.arryMethd/solve.js new file mode 100644 index 0000000..fee7aa7 --- /dev/null +++ b/Challenge/YunheeJo/2.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +arr.splice(2, 0, 10000); +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file From 7d81b67f76e90a5eb442e3caceec8ee60f8e5616 Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Thu, 26 May 2022 20:38:46 +0900 Subject: [PATCH 029/308] =?UTF-8?q?Feat=20:6=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/6.false/README.md | 10 ++++++++++ Problems/6.false/solve.js | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Problems/6.false/README.md create mode 100644 Problems/6.false/solve.js diff --git a/Problems/6.false/README.md b/Problems/6.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Problems/6.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Problems/6.false/solve.js b/Problems/6.false/solve.js new file mode 100644 index 0000000..497a552 --- /dev/null +++ b/Problems/6.false/solve.js @@ -0,0 +1,10 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined \ No newline at end of file From 9e7e0a49e013a216c8230c79eef1a8e700aa9165 Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Thu, 26 May 2022 20:57:50 +0900 Subject: [PATCH 030/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sehunKim/1.arry/2.arryMethd/README.md | 11 +++++++++++ Challenge/sehunKim/1.arry/2.arryMethd/solve.js | 13 +++++++++++++ Challenge/sehunKim/1.arry/solve.js | 11 ++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Challenge/sehunKim/1.arry/2.arryMethd/README.md create mode 100644 Challenge/sehunKim/1.arry/2.arryMethd/solve.js diff --git a/Challenge/sehunKim/1.arry/2.arryMethd/README.md b/Challenge/sehunKim/1.arry/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/sehunKim/1.arry/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/sehunKim/1.arry/2.arryMethd/solve.js b/Challenge/sehunKim/1.arry/2.arryMethd/solve.js new file mode 100644 index 0000000..5c83183 --- /dev/null +++ b/Challenge/sehunKim/1.arry/2.arryMethd/solve.js @@ -0,0 +1,13 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +arr.splice(2,0,10000); +//arr.splice(index, 지정한 index 뒤로 제거할 개수, 넣을 값1, 넣을 값2...) +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/sehunKim/1.arry/solve.js b/Challenge/sehunKim/1.arry/solve.js index 7ffd8bd..70d275f 100644 --- a/Challenge/sehunKim/1.arry/solve.js +++ b/Challenge/sehunKim/1.arry/solve.js @@ -1,4 +1,13 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +//pop 사용 +// nums.pop(); +// nums.pop(); +// console.log(nums); + +//splice 사용 +nums.splice(3,2); +console.log(nums) \ No newline at end of file From ca92ab199038b430478928d5f634a8673fa6fbdf Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Thu, 26 May 2022 21:45:04 +0900 Subject: [PATCH 031/308] =?UTF-8?q?Feat=20:25=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/25.circle-area/README.md | 8 ++++++++ Problems/25.circle-area/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Problems/25.circle-area/README.md create mode 100644 Problems/25.circle-area/solve.js diff --git a/Problems/25.circle-area/README.md b/Problems/25.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Problems/25.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Problems/25.circle-area/solve.js b/Problems/25.circle-area/solve.js new file mode 100644 index 0000000..8328c2c --- /dev/null +++ b/Problems/25.circle-area/solve.js @@ -0,0 +1,12 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + + + + + \ No newline at end of file From ab9334bfd58a2b286e9030b3886ac5ba5f2719be Mon Sep 17 00:00:00 2001 From: plutoin Date: Thu, 26 May 2022 21:47:29 +0900 Subject: [PATCH 032/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/1.arry/solve.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Challenge/SoyeonJang/1.arry/solve.js b/Challenge/SoyeonJang/1.arry/solve.js index 7ffd8bd..1536a3e 100644 --- a/Challenge/SoyeonJang/1.arry/solve.js +++ b/Challenge/SoyeonJang/1.arry/solve.js @@ -1,4 +1,8 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); +console.log(nums); \ No newline at end of file From 9736e82284ea0db1e5ae601f44726f0fc0890fc0 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Thu, 26 May 2022 21:49:59 +0900 Subject: [PATCH 033/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/2.arryMethd/README.md | 11 +++++++++++ Challenge/MinkyeongJo/2.arryMethd/solve.js | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/MinkyeongJo/2.arryMethd/README.md create mode 100644 Challenge/MinkyeongJo/2.arryMethd/solve.js diff --git a/Challenge/MinkyeongJo/2.arryMethd/README.md b/Challenge/MinkyeongJo/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/MinkyeongJo/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/MinkyeongJo/2.arryMethd/solve.js b/Challenge/MinkyeongJo/2.arryMethd/solve.js new file mode 100644 index 0000000..7af4324 --- /dev/null +++ b/Challenge/MinkyeongJo/2.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +// 데이터 +var arr = [200, 100, 300]; +arr.splice(2, 0 ,1000); +console.log(arr); + +// 출력 +// [200, 100, 10000, 300] \ No newline at end of file From 458b74f4f28e01ad7ceb6b39b4c8ed1ff8be4456 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Thu, 26 May 2022 21:51:26 +0900 Subject: [PATCH 034/308] =?UTF-8?q?Solve:=202=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/2.arryMethd/README.md | 11 +++++++++++ Challenge/Songmyeongseok/2.arryMethd/solve.js | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 Challenge/Songmyeongseok/2.arryMethd/README.md create mode 100644 Challenge/Songmyeongseok/2.arryMethd/solve.js diff --git a/Challenge/Songmyeongseok/2.arryMethd/README.md b/Challenge/Songmyeongseok/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/Songmyeongseok/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/Songmyeongseok/2.arryMethd/solve.js b/Challenge/Songmyeongseok/2.arryMethd/solve.js new file mode 100644 index 0000000..e1fdd7c --- /dev/null +++ b/Challenge/Songmyeongseok/2.arryMethd/solve.js @@ -0,0 +1,14 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] + +//답 +//arr.splice(2,0,1000) \ No newline at end of file From 9a5df3d84747d917f3453ddebf5efe2ba6124c80 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:00:16 +0900 Subject: [PATCH 035/308] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1 ~ 6번 문제 추가 --- Problems/001.arry/README.md | 5 +++++ Problems/001.arry/solve.js | 5 +++++ Problems/002.arryMethd/README.md | 11 +++++++++++ Problems/002.arryMethd/solve.js | 11 +++++++++++ Problems/003.type/README.md | 13 +++++++++++++ Problems/003.type/solve.js | 11 +++++++++++ Problems/004.type(2)/README.md | 8 ++++++++ Problems/004.type(2)/solve.js | 8 ++++++++ Problems/005.for/README.md | 20 ++++++++++++++++++++ Problems/005.for/solve.js | 20 ++++++++++++++++++++ Problems/006.false/README.md | 10 ++++++++++ Problems/006.false/solve.js | 10 ++++++++++ 12 files changed, 132 insertions(+) create mode 100644 Problems/001.arry/README.md create mode 100644 Problems/001.arry/solve.js create mode 100644 Problems/002.arryMethd/README.md create mode 100644 Problems/002.arryMethd/solve.js create mode 100644 Problems/003.type/README.md create mode 100644 Problems/003.type/solve.js create mode 100644 Problems/004.type(2)/README.md create mode 100644 Problems/004.type(2)/solve.js create mode 100644 Problems/005.for/README.md create mode 100644 Problems/005.for/solve.js create mode 100644 Problems/006.false/README.md create mode 100644 Problems/006.false/solve.js diff --git a/Problems/001.arry/README.md b/Problems/001.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Problems/001.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/001.arry/solve.js b/Problems/001.arry/solve.js new file mode 100644 index 0000000..7f6311f --- /dev/null +++ b/Problems/001.arry/solve.js @@ -0,0 +1,5 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + diff --git a/Problems/002.arryMethd/README.md b/Problems/002.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Problems/002.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/002.arryMethd/solve.js b/Problems/002.arryMethd/solve.js new file mode 100644 index 0000000..4095544 --- /dev/null +++ b/Problems/002.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/003.type/README.md b/Problems/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Problems/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Problems/003.type/solve.js b/Problems/003.type/solve.js new file mode 100644 index 0000000..06ee628 --- /dev/null +++ b/Problems/003.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object \ No newline at end of file diff --git a/Problems/004.type(2)/README.md b/Problems/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Problems/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Problems/004.type(2)/solve.js b/Problems/004.type(2)/solve.js new file mode 100644 index 0000000..5980544 --- /dev/null +++ b/Problems/004.type(2)/solve.js @@ -0,0 +1,8 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file diff --git a/Problems/005.for/README.md b/Problems/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Problems/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Problems/005.for/solve.js b/Problems/005.for/solve.js new file mode 100644 index 0000000..9a9204a --- /dev/null +++ b/Problems/005.for/solve.js @@ -0,0 +1,20 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 \ No newline at end of file diff --git a/Problems/006.false/README.md b/Problems/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Problems/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Problems/006.false/solve.js b/Problems/006.false/solve.js new file mode 100644 index 0000000..497a552 --- /dev/null +++ b/Problems/006.false/solve.js @@ -0,0 +1,10 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined \ No newline at end of file From 9b1ecf9a41113df953a8b386d711f491f790ed7f Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:00:54 +0900 Subject: [PATCH 036/308] Delete Problems/001.arry directory --- Problems/001.arry/README.md | 5 ----- Problems/001.arry/solve.js | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 Problems/001.arry/README.md delete mode 100644 Problems/001.arry/solve.js diff --git a/Problems/001.arry/README.md b/Problems/001.arry/README.md deleted file mode 100644 index d5088f4..0000000 --- a/Problems/001.arry/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 문제1 : 배열의 삭제 - -다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/001.arry/solve.js b/Problems/001.arry/solve.js deleted file mode 100644 index 7f6311f..0000000 --- a/Problems/001.arry/solve.js +++ /dev/null @@ -1,5 +0,0 @@ -// # 문제1 : 배열의 삭제 -// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; - From 5fa04aa8fb3577c1ba6d8071e752177a31fa0f49 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:01:00 +0900 Subject: [PATCH 037/308] Delete Problems/002.arryMethd directory --- Problems/002.arryMethd/README.md | 11 ----------- Problems/002.arryMethd/solve.js | 11 ----------- 2 files changed, 22 deletions(-) delete mode 100644 Problems/002.arryMethd/README.md delete mode 100644 Problems/002.arryMethd/solve.js diff --git a/Problems/002.arryMethd/README.md b/Problems/002.arryMethd/README.md deleted file mode 100644 index 01d8d19..0000000 --- a/Problems/002.arryMethd/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 문제2 : 배열의 내장함수 - -부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/002.arryMethd/solve.js b/Problems/002.arryMethd/solve.js deleted file mode 100644 index 4095544..0000000 --- a/Problems/002.arryMethd/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제2 : 배열의 내장함수 - -// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file From 87df47363c2ab30630f146cf44b2857c72de2184 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:01:07 +0900 Subject: [PATCH 038/308] Delete Problems/003.type directory --- Problems/003.type/README.md | 13 ------------- Problems/003.type/solve.js | 11 ----------- 2 files changed, 24 deletions(-) delete mode 100644 Problems/003.type/README.md delete mode 100644 Problems/003.type/solve.js diff --git a/Problems/003.type/README.md b/Problems/003.type/README.md deleted file mode 100644 index 79ab0fb..0000000 --- a/Problems/003.type/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# 문제3 : 변수의 타입 - -다음 출력 값으로 올바른 것은? - -```jsx -var arr = [100, 200, 300]; -console.log(typeof(arr)); -``` - -1) undefined -2) string -3) number -4) object \ No newline at end of file diff --git a/Problems/003.type/solve.js b/Problems/003.type/solve.js deleted file mode 100644 index 06ee628..0000000 --- a/Problems/003.type/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제3 : 변수의 타입 - -// 다음 출력 값으로 올바른 것은? - -var arr = [100, 200, 300]; -console.log(typeof(arr)); - -// 1) undefined -// 2) string -// 3) number -// 4) object \ No newline at end of file From bedea49330ae807feccbcc4d888b77aedf1ee00e Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:01:13 +0900 Subject: [PATCH 039/308] Delete Problems/004.type(2) directory --- Problems/004.type(2)/README.md | 8 -------- Problems/004.type(2)/solve.js | 8 -------- 2 files changed, 16 deletions(-) delete mode 100644 Problems/004.type(2)/README.md delete mode 100644 Problems/004.type(2)/solve.js diff --git a/Problems/004.type(2)/README.md b/Problems/004.type(2)/README.md deleted file mode 100644 index 46ff4b1..0000000 --- a/Problems/004.type(2)/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# 문제4 : 변수의 타입2 - -다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -1. 입력 : a =1, 출력 : number -2. 입력 : a = 2.22, 출력 : boolean -3. 입력 : a = 'p', 출력 : string -4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Problems/004.type(2)/solve.js b/Problems/004.type(2)/solve.js deleted file mode 100644 index 5980544..0000000 --- a/Problems/004.type(2)/solve.js +++ /dev/null @@ -1,8 +0,0 @@ -// # 문제4 : 변수의 타입2 - -// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -// 1) 입력 : a =1, 출력 : number -// 2) 입력 : a = 2.22, 출력 : boolean -// 3) 입력 : a = 'p', 출력 : string -// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file From c987e95d7d729a0deacd7f67c9d4fb1db149c8fd Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:01:20 +0900 Subject: [PATCH 040/308] Delete Problems/005.for directory --- Problems/005.for/README.md | 20 -------------------- Problems/005.for/solve.js | 20 -------------------- 2 files changed, 40 deletions(-) delete mode 100644 Problems/005.for/README.md delete mode 100644 Problems/005.for/solve.js diff --git a/Problems/005.for/README.md b/Problems/005.for/README.md deleted file mode 100644 index e704b38..0000000 --- a/Problems/005.for/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -# 문제 5 for문 계산 - -다음 코드의 출력 값으로 알맞은 것은? - -```jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); -``` - -1) 10 -2) 12 -3) 14 -4) 16 \ No newline at end of file diff --git a/Problems/005.for/solve.js b/Problems/005.for/solve.js deleted file mode 100644 index 9a9204a..0000000 --- a/Problems/005.for/solve.js +++ /dev/null @@ -1,20 +0,0 @@ - -// # 문제 5 for문 계산 - -// 다음 코드의 출력 값으로 알맞은 것은? - -jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); - - -// 1) 10 -// 2) 12 -// 3) 14 -// 4) 16 \ No newline at end of file From 2ae29de4c4a88e00d9a49b85b31495e27f63497b Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:01:27 +0900 Subject: [PATCH 041/308] Delete Problems/006.false directory --- Problems/006.false/README.md | 10 ---------- Problems/006.false/solve.js | 10 ---------- 2 files changed, 20 deletions(-) delete mode 100644 Problems/006.false/README.md delete mode 100644 Problems/006.false/solve.js diff --git a/Problems/006.false/README.md b/Problems/006.false/README.md deleted file mode 100644 index 66f6e1d..0000000 --- a/Problems/006.false/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# 문제6 : False - -다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. -앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. - -1) NaN -2) 1 -3) "" -4) 0 -5) undefined \ No newline at end of file diff --git a/Problems/006.false/solve.js b/Problems/006.false/solve.js deleted file mode 100644 index 497a552..0000000 --- a/Problems/006.false/solve.js +++ /dev/null @@ -1,10 +0,0 @@ -//# 문제6 : False - -// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. -// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. - -// 1) NaN -// 2) 1 -// 3) "" -// 4) 0 -// 5) undefined \ No newline at end of file From 7fa6992d2d872dba0742bcc4745c148964c0bbd2 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:09 +0900 Subject: [PATCH 042/308] =?UTF-8?q?Feat=20:=201~6=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/001.arry/README.md | 5 +++++ Problems/001.arry/solve.js | 5 +++++ Problems/002.arryMethd/README.md | 11 +++++++++++ Problems/002.arryMethd/solve.js | 11 +++++++++++ Problems/003.type/README.md | 13 +++++++++++++ Problems/003.type/solve.js | 11 +++++++++++ Problems/004.type(2)/README.md | 8 ++++++++ Problems/004.type(2)/solve.js | 8 ++++++++ Problems/005.for/README.md | 20 ++++++++++++++++++++ Problems/005.for/solve.js | 20 ++++++++++++++++++++ Problems/006.false/README.md | 10 ++++++++++ Problems/006.false/solve.js | 10 ++++++++++ 12 files changed, 132 insertions(+) create mode 100644 Problems/001.arry/README.md create mode 100644 Problems/001.arry/solve.js create mode 100644 Problems/002.arryMethd/README.md create mode 100644 Problems/002.arryMethd/solve.js create mode 100644 Problems/003.type/README.md create mode 100644 Problems/003.type/solve.js create mode 100644 Problems/004.type(2)/README.md create mode 100644 Problems/004.type(2)/solve.js create mode 100644 Problems/005.for/README.md create mode 100644 Problems/005.for/solve.js create mode 100644 Problems/006.false/README.md create mode 100644 Problems/006.false/solve.js diff --git a/Problems/001.arry/README.md b/Problems/001.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Problems/001.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/001.arry/solve.js b/Problems/001.arry/solve.js new file mode 100644 index 0000000..7f6311f --- /dev/null +++ b/Problems/001.arry/solve.js @@ -0,0 +1,5 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + diff --git a/Problems/002.arryMethd/README.md b/Problems/002.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Problems/002.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/002.arryMethd/solve.js b/Problems/002.arryMethd/solve.js new file mode 100644 index 0000000..4095544 --- /dev/null +++ b/Problems/002.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/003.type/README.md b/Problems/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Problems/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Problems/003.type/solve.js b/Problems/003.type/solve.js new file mode 100644 index 0000000..06ee628 --- /dev/null +++ b/Problems/003.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object \ No newline at end of file diff --git a/Problems/004.type(2)/README.md b/Problems/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Problems/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Problems/004.type(2)/solve.js b/Problems/004.type(2)/solve.js new file mode 100644 index 0000000..5980544 --- /dev/null +++ b/Problems/004.type(2)/solve.js @@ -0,0 +1,8 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file diff --git a/Problems/005.for/README.md b/Problems/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Problems/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Problems/005.for/solve.js b/Problems/005.for/solve.js new file mode 100644 index 0000000..9a9204a --- /dev/null +++ b/Problems/005.for/solve.js @@ -0,0 +1,20 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 \ No newline at end of file diff --git a/Problems/006.false/README.md b/Problems/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Problems/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Problems/006.false/solve.js b/Problems/006.false/solve.js new file mode 100644 index 0000000..497a552 --- /dev/null +++ b/Problems/006.false/solve.js @@ -0,0 +1,10 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined \ No newline at end of file From 9bbed826d0dc86b610c4a7918c7e19d350ad9db0 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:25 +0900 Subject: [PATCH 043/308] Delete Problems/1.arry directory --- Problems/1.arry/README.md | 5 ----- Problems/1.arry/solve.js | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 Problems/1.arry/README.md delete mode 100644 Problems/1.arry/solve.js diff --git a/Problems/1.arry/README.md b/Problems/1.arry/README.md deleted file mode 100644 index d5088f4..0000000 --- a/Problems/1.arry/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 문제1 : 배열의 삭제 - -다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/1.arry/solve.js b/Problems/1.arry/solve.js deleted file mode 100644 index 7f6311f..0000000 --- a/Problems/1.arry/solve.js +++ /dev/null @@ -1,5 +0,0 @@ -// # 문제1 : 배열의 삭제 -// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; - From 3057e537abac1f9eb44499920e2b5c76cb2c2f78 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:37 +0900 Subject: [PATCH 044/308] Delete Problems/2.arryMethd directory --- Problems/2.arryMethd/README.md | 11 ----------- Problems/2.arryMethd/solve.js | 11 ----------- 2 files changed, 22 deletions(-) delete mode 100644 Problems/2.arryMethd/README.md delete mode 100644 Problems/2.arryMethd/solve.js diff --git a/Problems/2.arryMethd/README.md b/Problems/2.arryMethd/README.md deleted file mode 100644 index 01d8d19..0000000 --- a/Problems/2.arryMethd/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 문제2 : 배열의 내장함수 - -부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/2.arryMethd/solve.js b/Problems/2.arryMethd/solve.js deleted file mode 100644 index 4095544..0000000 --- a/Problems/2.arryMethd/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제2 : 배열의 내장함수 - -// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file From 0b6c35003ea04a3889cba9301d2652d4b5552c0e Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:45 +0900 Subject: [PATCH 045/308] Delete Problems/3.type directory --- Problems/3.type/README.md | 13 ------------- Problems/3.type/solve.js | 11 ----------- 2 files changed, 24 deletions(-) delete mode 100644 Problems/3.type/README.md delete mode 100644 Problems/3.type/solve.js diff --git a/Problems/3.type/README.md b/Problems/3.type/README.md deleted file mode 100644 index 79ab0fb..0000000 --- a/Problems/3.type/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# 문제3 : 변수의 타입 - -다음 출력 값으로 올바른 것은? - -```jsx -var arr = [100, 200, 300]; -console.log(typeof(arr)); -``` - -1) undefined -2) string -3) number -4) object \ No newline at end of file diff --git a/Problems/3.type/solve.js b/Problems/3.type/solve.js deleted file mode 100644 index 06ee628..0000000 --- a/Problems/3.type/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제3 : 변수의 타입 - -// 다음 출력 값으로 올바른 것은? - -var arr = [100, 200, 300]; -console.log(typeof(arr)); - -// 1) undefined -// 2) string -// 3) number -// 4) object \ No newline at end of file From 391e83d59bdb905369c479d40550a24e79359886 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:53 +0900 Subject: [PATCH 046/308] Delete Problems/4.type(2) directory --- Problems/4.type(2)/README.md | 8 -------- Problems/4.type(2)/solve.js | 8 -------- 2 files changed, 16 deletions(-) delete mode 100644 Problems/4.type(2)/README.md delete mode 100644 Problems/4.type(2)/solve.js diff --git a/Problems/4.type(2)/README.md b/Problems/4.type(2)/README.md deleted file mode 100644 index 46ff4b1..0000000 --- a/Problems/4.type(2)/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# 문제4 : 변수의 타입2 - -다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -1. 입력 : a =1, 출력 : number -2. 입력 : a = 2.22, 출력 : boolean -3. 입력 : a = 'p', 출력 : string -4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Problems/4.type(2)/solve.js b/Problems/4.type(2)/solve.js deleted file mode 100644 index 5980544..0000000 --- a/Problems/4.type(2)/solve.js +++ /dev/null @@ -1,8 +0,0 @@ -// # 문제4 : 변수의 타입2 - -// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -// 1) 입력 : a =1, 출력 : number -// 2) 입력 : a = 2.22, 출력 : boolean -// 3) 입력 : a = 'p', 출력 : string -// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file From ecc55eb01ac581ff183f3f00012bd037996216bb Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:03:00 +0900 Subject: [PATCH 047/308] Delete Problems/5.for directory --- Problems/5.for/README.md | 20 -------------------- Problems/5.for/solve.js | 20 -------------------- 2 files changed, 40 deletions(-) delete mode 100644 Problems/5.for/README.md delete mode 100644 Problems/5.for/solve.js diff --git a/Problems/5.for/README.md b/Problems/5.for/README.md deleted file mode 100644 index e704b38..0000000 --- a/Problems/5.for/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -# 문제 5 for문 계산 - -다음 코드의 출력 값으로 알맞은 것은? - -```jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); -``` - -1) 10 -2) 12 -3) 14 -4) 16 \ No newline at end of file diff --git a/Problems/5.for/solve.js b/Problems/5.for/solve.js deleted file mode 100644 index 9a9204a..0000000 --- a/Problems/5.for/solve.js +++ /dev/null @@ -1,20 +0,0 @@ - -// # 문제 5 for문 계산 - -// 다음 코드의 출력 값으로 알맞은 것은? - -jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); - - -// 1) 10 -// 2) 12 -// 3) 14 -// 4) 16 \ No newline at end of file From b82d8e61234cdd25aafa6ee4290fcc4bb380da62 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:03:06 +0900 Subject: [PATCH 048/308] Delete Problems/6.false directory --- Problems/6.false/README.md | 10 ---------- Problems/6.false/solve.js | 10 ---------- 2 files changed, 20 deletions(-) delete mode 100644 Problems/6.false/README.md delete mode 100644 Problems/6.false/solve.js diff --git a/Problems/6.false/README.md b/Problems/6.false/README.md deleted file mode 100644 index 66f6e1d..0000000 --- a/Problems/6.false/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# 문제6 : False - -다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. -앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. - -1) NaN -2) 1 -3) "" -4) 0 -5) undefined \ No newline at end of file diff --git a/Problems/6.false/solve.js b/Problems/6.false/solve.js deleted file mode 100644 index 497a552..0000000 --- a/Problems/6.false/solve.js +++ /dev/null @@ -1,10 +0,0 @@ -//# 문제6 : False - -// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. -// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. - -// 1) NaN -// 2) 1 -// 3) "" -// 4) 0 -// 5) undefined \ No newline at end of file From 28a066e5cf16538f59877e2d6db9cefdbc7eeddf Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:03:24 +0900 Subject: [PATCH 049/308] =?UTF-8?q?Feat=20:25=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/025.circle-area/README.md | 8 ++++++++ Problems/025.circle-area/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Problems/025.circle-area/README.md create mode 100644 Problems/025.circle-area/solve.js diff --git a/Problems/025.circle-area/README.md b/Problems/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Problems/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Problems/025.circle-area/solve.js b/Problems/025.circle-area/solve.js new file mode 100644 index 0000000..8328c2c --- /dev/null +++ b/Problems/025.circle-area/solve.js @@ -0,0 +1,12 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + + + + + \ No newline at end of file From 83159334802bb7e8a7882e5fbdc3b81ad19886b8 Mon Sep 17 00:00:00 2001 From: Jihoon Chae <93469760+jihoon-chae@users.noreply.github.com> Date: Thu, 26 May 2022 22:03:59 +0900 Subject: [PATCH 050/308] Delete Problems/25.circle-area directory --- Problems/25.circle-area/README.md | 8 -------- Problems/25.circle-area/solve.js | 12 ------------ 2 files changed, 20 deletions(-) delete mode 100644 Problems/25.circle-area/README.md delete mode 100644 Problems/25.circle-area/solve.js diff --git a/Problems/25.circle-area/README.md b/Problems/25.circle-area/README.md deleted file mode 100644 index 7e79bae..0000000 --- a/Problems/25.circle-area/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# 문제 25: 원의 넓이를 구하세요 - -원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. -함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. - -**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. - - diff --git a/Problems/25.circle-area/solve.js b/Problems/25.circle-area/solve.js deleted file mode 100644 index 8328c2c..0000000 --- a/Problems/25.circle-area/solve.js +++ /dev/null @@ -1,12 +0,0 @@ -// # 문제 25: 원의 넓이를 구하세요 - -// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. -// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. - -// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. - - - - - - \ No newline at end of file From 274585f58eca27ef9a5ff60f105ccaaaf808f58c Mon Sep 17 00:00:00 2001 From: sooyyoung Date: Thu, 26 May 2022 22:05:01 +0900 Subject: [PATCH 051/308] =?UTF-8?q?Solve=20:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sooyoungCho/2.arryMethd/README.md | 11 +++++++++++ Challenge/sooyoungCho/2.arryMethd/solve.js | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 Challenge/sooyoungCho/2.arryMethd/README.md create mode 100644 Challenge/sooyoungCho/2.arryMethd/solve.js diff --git a/Challenge/sooyoungCho/2.arryMethd/README.md b/Challenge/sooyoungCho/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/sooyoungCho/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/sooyoungCho/2.arryMethd/solve.js b/Challenge/sooyoungCho/2.arryMethd/solve.js new file mode 100644 index 0000000..2ce6440 --- /dev/null +++ b/Challenge/sooyoungCho/2.arryMethd/solve.js @@ -0,0 +1,14 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; + +arr.splice(2, 0, 10000); +// splice(start, deleteCount, item) + +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file From e39159ade7f79a9bf86f7afefa8a01a429bd4769 Mon Sep 17 00:00:00 2001 From: plutoin Date: Thu, 26 May 2022 22:42:40 +0900 Subject: [PATCH 052/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/002.arryMethd/README.md | 11 +++++++++++ Challenge/SoyeonJang/002.arryMethd/solve.js | 13 +++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Challenge/SoyeonJang/002.arryMethd/README.md create mode 100644 Challenge/SoyeonJang/002.arryMethd/solve.js diff --git a/Challenge/SoyeonJang/002.arryMethd/README.md b/Challenge/SoyeonJang/002.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/SoyeonJang/002.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/SoyeonJang/002.arryMethd/solve.js b/Challenge/SoyeonJang/002.arryMethd/solve.js new file mode 100644 index 0000000..3b4dc7d --- /dev/null +++ b/Challenge/SoyeonJang/002.arryMethd/solve.js @@ -0,0 +1,13 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +// 데이터 +var arr = [200, 100, 300]; + +arr.splice(2, 0, 10000) + +console.log(arr); + +// 출력 +// [200, 100, 10000, 300] \ No newline at end of file From 9a4f89f397a36cb083f10dc34296fc247ba4bf93 Mon Sep 17 00:00:00 2001 From: chooing Date: Thu, 26 May 2022 23:05:49 +0900 Subject: [PATCH 053/308] =?UTF-8?q?Solve=20:=20002,=20003,=20004=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihyeChoo/1.arry/solve.js | 4 +++- Challenge/JihyeChoo/2.arryMethd/README.md | 11 +++++++++++ Challenge/JihyeChoo/2.arryMethd/solve.js | 13 +++++++++++++ Challenge/JihyeChoo/3.type/README.md | 13 +++++++++++++ Challenge/JihyeChoo/3.type/solve.js | 11 +++++++++++ Challenge/JihyeChoo/4.type(2)/README.md | 8 ++++++++ Challenge/JihyeChoo/4.type(2)/solve.js | 10 ++++++++++ 7 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 Challenge/JihyeChoo/2.arryMethd/README.md create mode 100644 Challenge/JihyeChoo/2.arryMethd/solve.js create mode 100644 Challenge/JihyeChoo/3.type/README.md create mode 100644 Challenge/JihyeChoo/3.type/solve.js create mode 100644 Challenge/JihyeChoo/4.type(2)/README.md create mode 100644 Challenge/JihyeChoo/4.type(2)/solve.js diff --git a/Challenge/JihyeChoo/1.arry/solve.js b/Challenge/JihyeChoo/1.arry/solve.js index 7ffd8bd..34b5e79 100644 --- a/Challenge/JihyeChoo/1.arry/solve.js +++ b/Challenge/JihyeChoo/1.arry/solve.js @@ -1,4 +1,6 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; +nums.pop(); +nums.pop(); \ No newline at end of file diff --git a/Challenge/JihyeChoo/2.arryMethd/README.md b/Challenge/JihyeChoo/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/JihyeChoo/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/JihyeChoo/2.arryMethd/solve.js b/Challenge/JihyeChoo/2.arryMethd/solve.js new file mode 100644 index 0000000..dafdfd5 --- /dev/null +++ b/Challenge/JihyeChoo/2.arryMethd/solve.js @@ -0,0 +1,13 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +// 데이터 +var arr = [200, 100, 300]; +arr.splice(-1,0,10000); + +console.log(arr); + +// 출력 +// [200, 100, 10000, 300] + diff --git a/Challenge/JihyeChoo/3.type/README.md b/Challenge/JihyeChoo/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/JihyeChoo/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/JihyeChoo/3.type/solve.js b/Challenge/JihyeChoo/3.type/solve.js new file mode 100644 index 0000000..4a05ed3 --- /dev/null +++ b/Challenge/JihyeChoo/3.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object <----- Array는 Object의 하위 카테고리이다. \ No newline at end of file diff --git a/Challenge/JihyeChoo/4.type(2)/README.md b/Challenge/JihyeChoo/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/JihyeChoo/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/JihyeChoo/4.type(2)/solve.js b/Challenge/JihyeChoo/4.type(2)/solve.js new file mode 100644 index 0000000..3a64775 --- /dev/null +++ b/Challenge/JihyeChoo/4.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean <----- number로 출력되야한다. +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// true, false가 boolean이다 \ No newline at end of file From 650540cbd8c73124c2b6e6bc7dd4fe0dc791a611 Mon Sep 17 00:00:00 2001 From: seokahi Date: Fri, 27 May 2022 00:56:56 +0900 Subject: [PATCH 054/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/1.arry/solve.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Challenge/seokahi/1.arry/solve.js b/Challenge/seokahi/1.arry/solve.js index 7ffd8bd..fe6045b 100644 --- a/Challenge/seokahi/1.arry/solve.js +++ b/Challenge/seokahi/1.arry/solve.js @@ -1,4 +1,6 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; +nums.splice(3,2); +console.log(nums); \ No newline at end of file From 0d6601800e9b2c1aa1eaf75dbba75379bdd34e96 Mon Sep 17 00:00:00 2001 From: seokahi Date: Fri, 27 May 2022 01:00:31 +0900 Subject: [PATCH 055/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/2.arryMethd/README.md | 11 +++++++++++ Challenge/seokahi/2.arryMethd/solve.js | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/seokahi/2.arryMethd/README.md create mode 100644 Challenge/seokahi/2.arryMethd/solve.js diff --git a/Challenge/seokahi/2.arryMethd/README.md b/Challenge/seokahi/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/seokahi/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/seokahi/2.arryMethd/solve.js b/Challenge/seokahi/2.arryMethd/solve.js new file mode 100644 index 0000000..a32ffdf --- /dev/null +++ b/Challenge/seokahi/2.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +// 데이터 +var arr = [200, 100, 300]; +arr.splice(2,0,10000); +console.log(arr); + +// 출력 +// [200, 100, 10000, 300] \ No newline at end of file From f6f0138ff1d9c93ded410e9b851db7e2a27f4953 Mon Sep 17 00:00:00 2001 From: seokahi Date: Fri, 27 May 2022 01:01:52 +0900 Subject: [PATCH 056/308] =?UTF-8?q?Solve:=203=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/3.type/README.md | 13 +++++++++++++ Challenge/seokahi/3.type/solve.js | 11 +++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Challenge/seokahi/3.type/README.md create mode 100644 Challenge/seokahi/3.type/solve.js diff --git a/Challenge/seokahi/3.type/README.md b/Challenge/seokahi/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/seokahi/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/seokahi/3.type/solve.js b/Challenge/seokahi/3.type/solve.js new file mode 100644 index 0000000..9104753 --- /dev/null +++ b/Challenge/seokahi/3.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); +// 정답 : 4번 object +// 1) undefined +// 2) string +// 3) number +// 4) object \ No newline at end of file From 31a63d64d33619b2fce253683f25f120aecafe5c Mon Sep 17 00:00:00 2001 From: unidagit Date: Fri, 27 May 2022 11:44:28 +0900 Subject: [PATCH 057/308] =?UTF-8?q?Solve:=203=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/3.type/README.md | 13 +++++++++++++ Challenge/YunheeJo/3.type/solve.js | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Challenge/YunheeJo/3.type/README.md create mode 100644 Challenge/YunheeJo/3.type/solve.js diff --git a/Challenge/YunheeJo/3.type/README.md b/Challenge/YunheeJo/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/YunheeJo/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/YunheeJo/3.type/solve.js b/Challenge/YunheeJo/3.type/solve.js new file mode 100644 index 0000000..c4187d1 --- /dev/null +++ b/Challenge/YunheeJo/3.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +답: object \ No newline at end of file From e512c4b2907d873f1139e91851a66a52e2887512 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Fri, 27 May 2022 12:53:11 +0900 Subject: [PATCH 058/308] =?UTF-8?q?Solve=20:=20002,=20003,=20004,=20005,?= =?UTF-8?q?=20006=20=EB=AC=B8=EC=A0=9C=20=ED=92=80=EC=9D=B4\n=20Docs=20:?= =?UTF-8?q?=20001=20=ED=8F=B4=EB=8D=94=EB=AA=85=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{1.arry => 001.array}/README.md | 0 .../seyeongLee/{1.arry => 001.array}/solve.js | 0 .../seyeongLee/002.arrayMethod/README.md | 13 ++++++++++++ Challenge/seyeongLee/002.arrayMethod/solve.js | 18 +++++++++++++++++ Challenge/seyeongLee/003.type/README.md | 13 ++++++++++++ Challenge/seyeongLee/003.type/solve.js | 18 +++++++++++++++++ Challenge/seyeongLee/004.type(2)/README.md | 8 ++++++++ Challenge/seyeongLee/004.type(2)/solve.js | 18 +++++++++++++++++ Challenge/seyeongLee/005.for/README.md | 20 +++++++++++++++++++ Challenge/seyeongLee/005.for/solve.js | 19 ++++++++++++++++++ Challenge/seyeongLee/006.false/README.md | 10 ++++++++++ Challenge/seyeongLee/006.false/solve.js | 17 ++++++++++++++++ 12 files changed, 154 insertions(+) rename Challenge/seyeongLee/{1.arry => 001.array}/README.md (100%) rename Challenge/seyeongLee/{1.arry => 001.array}/solve.js (100%) create mode 100644 Challenge/seyeongLee/002.arrayMethod/README.md create mode 100644 Challenge/seyeongLee/002.arrayMethod/solve.js create mode 100644 Challenge/seyeongLee/003.type/README.md create mode 100644 Challenge/seyeongLee/003.type/solve.js create mode 100644 Challenge/seyeongLee/004.type(2)/README.md create mode 100644 Challenge/seyeongLee/004.type(2)/solve.js create mode 100644 Challenge/seyeongLee/005.for/README.md create mode 100644 Challenge/seyeongLee/005.for/solve.js create mode 100644 Challenge/seyeongLee/006.false/README.md create mode 100644 Challenge/seyeongLee/006.false/solve.js diff --git a/Challenge/seyeongLee/1.arry/README.md b/Challenge/seyeongLee/001.array/README.md similarity index 100% rename from Challenge/seyeongLee/1.arry/README.md rename to Challenge/seyeongLee/001.array/README.md diff --git a/Challenge/seyeongLee/1.arry/solve.js b/Challenge/seyeongLee/001.array/solve.js similarity index 100% rename from Challenge/seyeongLee/1.arry/solve.js rename to Challenge/seyeongLee/001.array/solve.js diff --git a/Challenge/seyeongLee/002.arrayMethod/README.md b/Challenge/seyeongLee/002.arrayMethod/README.md new file mode 100644 index 0000000..4a25f9f --- /dev/null +++ b/Challenge/seyeongLee/002.arrayMethod/README.md @@ -0,0 +1,13 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +```jsx +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/002.arrayMethod/solve.js b/Challenge/seyeongLee/002.arrayMethod/solve.js new file mode 100644 index 0000000..6068a91 --- /dev/null +++ b/Challenge/seyeongLee/002.arrayMethod/solve.js @@ -0,0 +1,18 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + + +// 첫번째 방법 +const arr1 = [200, 100, 300]; +arr1.splice(2, 0, 10000); +console.log(arr1); + + +// 두번째 방법 +const arr2 = [200, 100, 300]; +arr2.splice(-1, 0, 10000); +console.log(arr2); + + +// result : [200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/seyeongLee/003.type/README.md b/Challenge/seyeongLee/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/seyeongLee/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/seyeongLee/003.type/solve.js b/Challenge/seyeongLee/003.type/solve.js new file mode 100644 index 0000000..ee43b67 --- /dev/null +++ b/Challenge/seyeongLee/003.type/solve.js @@ -0,0 +1,18 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof (arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object -----> 정답!! +// why? 배열은 원사자료형이 아닌 객체자료형에 속하기 때문에 객체처럼 동작. 즉 배열은 'object'의 특수한 한 형태. +// 그러므로 typeof(배열)의 결과는 object + + +// 어떠한 데이터가 배열인지 아닌지 정확히 확인하기 위해서 'isArray()' 함수를 사용. +// 배열이면 true 아니면 false를 반환 +console.log(Array.isArray(arr)); // result : true \ No newline at end of file diff --git a/Challenge/seyeongLee/004.type(2)/README.md b/Challenge/seyeongLee/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/seyeongLee/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/seyeongLee/004.type(2)/solve.js b/Challenge/seyeongLee/004.type(2)/solve.js new file mode 100644 index 0000000..a9b8392 --- /dev/null +++ b/Challenge/seyeongLee/004.type(2)/solve.js @@ -0,0 +1,18 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean -----> 정답!! why? 실수도 number이기 때문 +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + + +const input1 = 1; +const input2 = 2.22; +const input3 = 'p'; +const input4 = [1, 2, 3]; +console.log(typeof (input1)); // result : number +console.log(typeof (input2)); // result : number +console.log(typeof (input3)); // result : string +console.log(typeof (input4)); // result : object \ No newline at end of file diff --git a/Challenge/seyeongLee/005.for/README.md b/Challenge/seyeongLee/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/seyeongLee/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/seyeongLee/005.for/solve.js b/Challenge/seyeongLee/005.for/solve.js new file mode 100644 index 0000000..4ad4a1e --- /dev/null +++ b/Challenge/seyeongLee/005.for/solve.js @@ -0,0 +1,19 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); // result : 16 + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 -----> 정답!! why? 10 + 1 + 3 + 2 = 16 \ No newline at end of file diff --git a/Challenge/seyeongLee/006.false/README.md b/Challenge/seyeongLee/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/seyeongLee/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/seyeongLee/006.false/solve.js b/Challenge/seyeongLee/006.false/solve.js new file mode 100644 index 0000000..dabf800 --- /dev/null +++ b/Challenge/seyeongLee/006.false/solve.js @@ -0,0 +1,17 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 -----> 정답!! why? 0외의 숫자는 전부 true +// 3) "" +// 4) 0 +// 5) undefined + + +console.log(!!NaN); // result : false +console.log(!!1); // result : true +console.log(!!""); // result : false +console.log(!!0); // result : false +console.log(!!undefined); // result : false \ No newline at end of file From 93723806232fbb91292b11c21a37dedaf4909ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=8B=A4=ED=98=84?= <82689971+Dayhun@users.noreply.github.com> Date: Fri, 27 May 2022 16:44:19 +0900 Subject: [PATCH 059/308] =?UTF-8?q?Solve:=201=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/1.arry/solve.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Challenge/DahyunLim/1.arry/solve.js b/Challenge/DahyunLim/1.arry/solve.js index 7b236c8..7923ba5 100644 --- a/Challenge/DahyunLim/1.arry/solve.js +++ b/Challenge/DahyunLim/1.arry/solve.js @@ -4,5 +4,4 @@ var nums = [100, 200, 300, 400, 500]; nums.splice(3, 2); -nums; -var nums = [100, 200, 300, 400, 500]; +console.log(nums); From 0356b202d7dee00552952e5c326a3412d74854fe Mon Sep 17 00:00:00 2001 From: plutoin Date: Fri, 27 May 2022 17:09:31 +0900 Subject: [PATCH 060/308] =?UTF-8?q?Solve:=203-6=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/003.type/README.md | 13 +++++++++++ Challenge/SoyeonJang/003.type/solve.js | 13 +++++++++++ Challenge/SoyeonJang/004.type(2)/README.md | 8 +++++++ Challenge/SoyeonJang/004.type(2)/solve.js | 11 +++++++++ Challenge/SoyeonJang/005.for/README.md | 19 ++++++++++++++++ Challenge/SoyeonJang/005.for/solve.js | 26 ++++++++++++++++++++++ Challenge/SoyeonJang/006.false/README.md | 10 +++++++++ Challenge/SoyeonJang/006.false/solve.js | 16 +++++++++++++ 8 files changed, 116 insertions(+) create mode 100644 Challenge/SoyeonJang/003.type/README.md create mode 100644 Challenge/SoyeonJang/003.type/solve.js create mode 100644 Challenge/SoyeonJang/004.type(2)/README.md create mode 100644 Challenge/SoyeonJang/004.type(2)/solve.js create mode 100644 Challenge/SoyeonJang/005.for/README.md create mode 100644 Challenge/SoyeonJang/005.for/solve.js create mode 100644 Challenge/SoyeonJang/006.false/README.md create mode 100644 Challenge/SoyeonJang/006.false/solve.js diff --git a/Challenge/SoyeonJang/003.type/README.md b/Challenge/SoyeonJang/003.type/README.md new file mode 100644 index 0000000..82fc123 --- /dev/null +++ b/Challenge/SoyeonJang/003.type/README.md @@ -0,0 +1,13 @@ +# 문제 3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/SoyeonJang/003.type/solve.js b/Challenge/SoyeonJang/003.type/solve.js new file mode 100644 index 0000000..d54ccfb --- /dev/null +++ b/Challenge/SoyeonJang/003.type/solve.js @@ -0,0 +1,13 @@ +// # 문제 3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined (원시타입) +// 2) string (원시타입) +// 3) number (원시타입) +// 4) object (참조타입) + +// 정답: 4번 \ No newline at end of file diff --git a/Challenge/SoyeonJang/004.type(2)/README.md b/Challenge/SoyeonJang/004.type(2)/README.md new file mode 100644 index 0000000..1a36d8c --- /dev/null +++ b/Challenge/SoyeonJang/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제 4 : 변수의 타입 2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/SoyeonJang/004.type(2)/solve.js b/Challenge/SoyeonJang/004.type(2)/solve.js new file mode 100644 index 0000000..badcbaf --- /dev/null +++ b/Challenge/SoyeonJang/004.type(2)/solve.js @@ -0,0 +1,11 @@ +// # 문제 4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a = 1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답: 2번 +// Boolean은 true, false 중 하나만 반환, 2.22는 number \ No newline at end of file diff --git a/Challenge/SoyeonJang/005.for/README.md b/Challenge/SoyeonJang/005.for/README.md new file mode 100644 index 0000000..f24648d --- /dev/null +++ b/Challenge/SoyeonJang/005.for/README.md @@ -0,0 +1,19 @@ +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/SoyeonJang/005.for/solve.js b/Challenge/SoyeonJang/005.for/solve.js new file mode 100644 index 0000000..6af6f76 --- /dev/null +++ b/Challenge/SoyeonJang/005.for/solve.js @@ -0,0 +1,26 @@ +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + +// 정답: 4번 + +/* 해설 +i = 1일 때, a = 11 계산 -> i += 2로 i = 3으로 증가 +i = 3일 때, a = 14 계산 -> i += 2로 i = 5로 증가 +i = 5 조건에 안 맞으므로 종료 +결과: a + b = 14 + 2 = 16 +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/006.false/README.md b/Challenge/SoyeonJang/006.false/README.md new file mode 100644 index 0000000..c6fef63 --- /dev/null +++ b/Challenge/SoyeonJang/006.false/README.md @@ -0,0 +1,10 @@ +# 문제 6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/SoyeonJang/006.false/solve.js b/Challenge/SoyeonJang/006.false/solve.js new file mode 100644 index 0000000..0d0cd1f --- /dev/null +++ b/Challenge/SoyeonJang/006.false/solve.js @@ -0,0 +1,16 @@ +// # 문제 6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + +// 정답: 2번 + +/* 해설 + falsy: 0, '', NaN, false, null, undefined +*/ \ No newline at end of file From 26bd0a5eb9b9696d472896f60659bd0b4d255cef Mon Sep 17 00:00:00 2001 From: Dayhun Date: Fri, 27 May 2022 17:11:55 +0900 Subject: [PATCH 061/308] =?UTF-8?q?Solve:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/2.arryMethd/README.md | 11 +++++++++++ Challenge/DahyunLim/2.arryMethd/solve.js | 12 ++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 Challenge/DahyunLim/2.arryMethd/README.md create mode 100644 Challenge/DahyunLim/2.arryMethd/solve.js diff --git a/Challenge/DahyunLim/2.arryMethd/README.md b/Challenge/DahyunLim/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/DahyunLim/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/DahyunLim/2.arryMethd/solve.js b/Challenge/DahyunLim/2.arryMethd/solve.js new file mode 100644 index 0000000..4ab4784 --- /dev/null +++ b/Challenge/DahyunLim/2.arryMethd/solve.js @@ -0,0 +1,12 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +//데이터 +var arr = [200, 100, 300]; +//pass +arr.splice(2, 0, 1000); +console.log(arr); + +//출력 +//[200, 100, 10000, 300] \ No newline at end of file From afea94cf80ca777cd1540e304a1832e645517b05 Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Fri, 27 May 2022 17:29:57 +0900 Subject: [PATCH 062/308] =?UTF-8?q?Feat=20:=2030=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/030.find-string/README.md | 15 +++++++++++++++ Problems/030.find-string/solve.js | 15 +++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Problems/030.find-string/README.md create mode 100644 Problems/030.find-string/solve.js diff --git a/Problems/030.find-string/README.md b/Problems/030.find-string/README.md new file mode 100644 index 0000000..b2f4ed6 --- /dev/null +++ b/Problems/030.find-string/README.md @@ -0,0 +1,15 @@ +# 문제30 : 문자열 속 문자 찾기 + +문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +**그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +```jsx +**입력** +pineapple is yummy +apple + +**출력** +4 +``` \ No newline at end of file diff --git a/Problems/030.find-string/solve.js b/Problems/030.find-string/solve.js new file mode 100644 index 0000000..1a69bf7 --- /dev/null +++ b/Problems/030.find-string/solve.js @@ -0,0 +1,15 @@ +// # 문제30 : 문자열 속 문자 찾기 + +// 문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +// 첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +// **그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +// ```jsx +// **입력** +// pineapple is yummy +// apple + +// **출력** +// 4 +// ``` \ No newline at end of file From 7e20f9cd60f8d4bee95348d36febcbb3adbc844b Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Fri, 27 May 2022 21:54:34 +0900 Subject: [PATCH 063/308] =?UTF-8?q?Feat=20:=207~15=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/007.variable/README.md | 9 +++++++++ Problems/007.variable/solve.js | 11 +++++++++++ Problems/008.object/README.md | 16 ++++++++++++++++ Problems/008.object/solve.js | 16 ++++++++++++++++ Problems/009.concat/README.md | 20 ++++++++++++++++++++ Problems/009.concat/solve.js | 20 ++++++++++++++++++++ Problems/010.star/README.md | 18 ++++++++++++++++++ Problems/010.star/solve.js | 18 ++++++++++++++++++ Problems/011.for/README.md | 11 +++++++++++ Problems/011.for/solve.js | 11 +++++++++++ Problems/012.class/README.md | 17 +++++++++++++++++ Problems/012.class/solve.js | 17 +++++++++++++++++ Problems/013.find-planet/README.md | 15 +++++++++++++++ Problems/013.find-planet/solve.js | 15 +++++++++++++++ Problems/014.if/README.md | 17 +++++++++++++++++ Problems/014.if/solve.js | 17 +++++++++++++++++ Problems/015.template _literals/README.md | 13 +++++++++++++ Problems/015.template _literals/solve.js | 13 +++++++++++++ 18 files changed, 274 insertions(+) create mode 100644 Problems/007.variable/README.md create mode 100644 Problems/007.variable/solve.js create mode 100644 Problems/008.object/README.md create mode 100644 Problems/008.object/solve.js create mode 100644 Problems/009.concat/README.md create mode 100644 Problems/009.concat/solve.js create mode 100644 Problems/010.star/README.md create mode 100644 Problems/010.star/solve.js create mode 100644 Problems/011.for/README.md create mode 100644 Problems/011.for/solve.js create mode 100644 Problems/012.class/README.md create mode 100644 Problems/012.class/solve.js create mode 100644 Problems/013.find-planet/README.md create mode 100644 Problems/013.find-planet/solve.js create mode 100644 Problems/014.if/README.md create mode 100644 Problems/014.if/solve.js create mode 100644 Problems/015.template _literals/README.md create mode 100644 Problems/015.template _literals/solve.js diff --git a/Problems/007.variable/README.md b/Problems/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Problems/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Problems/007.variable/solve.js b/Problems/007.variable/solve.js new file mode 100644 index 0000000..7f419f0 --- /dev/null +++ b/Problems/007.variable/solve.js @@ -0,0 +1,11 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ \ No newline at end of file diff --git a/Problems/008.object/README.md b/Problems/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Problems/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Problems/008.object/solve.js b/Problems/008.object/solve.js new file mode 100644 index 0000000..50aada1 --- /dev/null +++ b/Problems/008.object/solve.js @@ -0,0 +1,16 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ \ No newline at end of file diff --git a/Problems/009.concat/README.md b/Problems/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Problems/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Problems/009.concat/solve.js b/Problems/009.concat/solve.js new file mode 100644 index 0000000..da0c2d3 --- /dev/null +++ b/Problems/009.concat/solve.js @@ -0,0 +1,20 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ \ No newline at end of file diff --git a/Problems/010.star/README.md b/Problems/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Problems/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Problems/010.star/solve.js b/Problems/010.star/solve.js new file mode 100644 index 0000000..0ef4de0 --- /dev/null +++ b/Problems/010.star/solve.js @@ -0,0 +1,18 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ \ No newline at end of file diff --git a/Problems/011.for/README.md b/Problems/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Problems/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Problems/011.for/solve.js b/Problems/011.for/solve.js new file mode 100644 index 0000000..29d575c --- /dev/null +++ b/Problems/011.for/solve.js @@ -0,0 +1,11 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass + +console.log(s); +*/ \ No newline at end of file diff --git a/Problems/012.class/README.md b/Problems/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Problems/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Problems/012.class/solve.js b/Problems/012.class/solve.js new file mode 100644 index 0000000..31baa29 --- /dev/null +++ b/Problems/012.class/solve.js @@ -0,0 +1,17 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ \ No newline at end of file diff --git a/Problems/013.find-planet/README.md b/Problems/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Problems/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Problems/013.find-planet/solve.js b/Problems/013.find-planet/solve.js new file mode 100644 index 0000000..896ee8e --- /dev/null +++ b/Problems/013.find-planet/solve.js @@ -0,0 +1,15 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ \ No newline at end of file diff --git a/Problems/014.if/README.md b/Problems/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Problems/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Problems/014.if/solve.js b/Problems/014.if/solve.js new file mode 100644 index 0000000..6188404 --- /dev/null +++ b/Problems/014.if/solve.js @@ -0,0 +1,17 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +*/ \ No newline at end of file diff --git a/Problems/015.template _literals/README.md b/Problems/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Problems/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Problems/015.template _literals/solve.js b/Problems/015.template _literals/solve.js new file mode 100644 index 0000000..5c05ceb --- /dev/null +++ b/Problems/015.template _literals/solve.js @@ -0,0 +1,13 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ \ No newline at end of file From d84e9987d1886aaed0e238403865789fd50ddc8a Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Fri, 27 May 2022 22:18:32 +0900 Subject: [PATCH 064/308] =?UTF-8?q?Solve:=203-5=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sehunKim/003.type/README.md | 13 +++++++++++ Challenge/sehunKim/003.type/solve.js | 13 +++++++++++ Challenge/sehunKim/004.type(2)/README.md | 8 +++++++ Challenge/sehunKim/004.type(2)/solve.js | 10 ++++++++ Challenge/sehunKim/005.for/README.md | 20 ++++++++++++++++ Challenge/sehunKim/005.for/solve.js | 23 +++++++++++++++++++ .../{1.arry => }/2.arryMethd/README.md | 0 .../{1.arry => }/2.arryMethd/solve.js | 0 Problems/005.for/solve.js | 5 +++- 9 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 Challenge/sehunKim/003.type/README.md create mode 100644 Challenge/sehunKim/003.type/solve.js create mode 100644 Challenge/sehunKim/004.type(2)/README.md create mode 100644 Challenge/sehunKim/004.type(2)/solve.js create mode 100644 Challenge/sehunKim/005.for/README.md create mode 100644 Challenge/sehunKim/005.for/solve.js rename Challenge/sehunKim/{1.arry => }/2.arryMethd/README.md (100%) rename Challenge/sehunKim/{1.arry => }/2.arryMethd/solve.js (100%) diff --git a/Challenge/sehunKim/003.type/README.md b/Challenge/sehunKim/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/sehunKim/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/sehunKim/003.type/solve.js b/Challenge/sehunKim/003.type/solve.js new file mode 100644 index 0000000..780b2da --- /dev/null +++ b/Challenge/sehunKim/003.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +// 정답: 4번 object, JavaScript에서 typeof는 배열을 구분하지 못하여 object로 반환한다. \ No newline at end of file diff --git a/Challenge/sehunKim/004.type(2)/README.md b/Challenge/sehunKim/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/sehunKim/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/sehunKim/004.type(2)/solve.js b/Challenge/sehunKim/004.type(2)/solve.js new file mode 100644 index 0000000..45ccb46 --- /dev/null +++ b/Challenge/sehunKim/004.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 2) 입력 : a = 2.22, 출력 : number이다. \ No newline at end of file diff --git a/Challenge/sehunKim/005.for/README.md b/Challenge/sehunKim/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/sehunKim/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/sehunKim/005.for/solve.js b/Challenge/sehunKim/005.for/solve.js new file mode 100644 index 0000000..bfad872 --- /dev/null +++ b/Challenge/sehunKim/005.for/solve.js @@ -0,0 +1,23 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + +// 정답: 4번 +// i = 1 일때 a = 11, i = 3일때 a = 14, i < 5까지 순회임으로 a + b는 16이다. \ No newline at end of file diff --git a/Challenge/sehunKim/1.arry/2.arryMethd/README.md b/Challenge/sehunKim/2.arryMethd/README.md similarity index 100% rename from Challenge/sehunKim/1.arry/2.arryMethd/README.md rename to Challenge/sehunKim/2.arryMethd/README.md diff --git a/Challenge/sehunKim/1.arry/2.arryMethd/solve.js b/Challenge/sehunKim/2.arryMethd/solve.js similarity index 100% rename from Challenge/sehunKim/1.arry/2.arryMethd/solve.js rename to Challenge/sehunKim/2.arryMethd/solve.js diff --git a/Problems/005.for/solve.js b/Problems/005.for/solve.js index 9a9204a..bfad872 100644 --- a/Problems/005.for/solve.js +++ b/Problems/005.for/solve.js @@ -17,4 +17,7 @@ console.log(a+b); // 1) 10 // 2) 12 // 3) 14 -// 4) 16 \ No newline at end of file +// 4) 16 + +// 정답: 4번 +// i = 1 일때 a = 11, i = 3일때 a = 14, i < 5까지 순회임으로 a + b는 16이다. \ No newline at end of file From cb58711c5df13cf5564119d981cc3c53bdb608a2 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Fri, 27 May 2022 22:35:59 +0900 Subject: [PATCH 065/308] =?UTF-8?q?Solve:=203=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/3.type/README.md | 13 +++++++++++++ Challenge/MinkyeongJo/3.type/solve.js | 11 +++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Challenge/MinkyeongJo/3.type/README.md create mode 100644 Challenge/MinkyeongJo/3.type/solve.js diff --git a/Challenge/MinkyeongJo/3.type/README.md b/Challenge/MinkyeongJo/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/MinkyeongJo/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/MinkyeongJo/3.type/solve.js b/Challenge/MinkyeongJo/3.type/solve.js new file mode 100644 index 0000000..763f2b2 --- /dev/null +++ b/Challenge/MinkyeongJo/3.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object(정답!) \ No newline at end of file From d8c2ce8d92719a8cf01f6d12244aac40fd668c5e Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Fri, 27 May 2022 23:30:29 +0900 Subject: [PATCH 066/308] =?UTF-8?q?Solve:=2025=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihoonChae/025.circle-area/README.md | 8 ++++++++ Challenge/JihoonChae/025.circle-area/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Challenge/JihoonChae/025.circle-area/README.md create mode 100644 Challenge/JihoonChae/025.circle-area/solve.js diff --git a/Challenge/JihoonChae/025.circle-area/README.md b/Challenge/JihoonChae/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Challenge/JihoonChae/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Challenge/JihoonChae/025.circle-area/solve.js b/Challenge/JihoonChae/025.circle-area/solve.js new file mode 100644 index 0000000..f347219 --- /dev/null +++ b/Challenge/JihoonChae/025.circle-area/solve.js @@ -0,0 +1,12 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + +const n = prompt("원의 넓이는?"); +function getArea() { + return n ** 2 * 3.14; +} +console.log(getArea()); From 14310e78e6bfaa3956d90d7dd80a3fe2850403ce Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Fri, 27 May 2022 23:46:31 +0900 Subject: [PATCH 067/308] =?UTF-8?q?Solve:=2025=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/025.circle-area/README.md | 8 ++++++++ Challenge/Songmyeongseok/025.circle-area/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Challenge/Songmyeongseok/025.circle-area/README.md create mode 100644 Challenge/Songmyeongseok/025.circle-area/solve.js diff --git a/Challenge/Songmyeongseok/025.circle-area/README.md b/Challenge/Songmyeongseok/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Challenge/Songmyeongseok/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Challenge/Songmyeongseok/025.circle-area/solve.js b/Challenge/Songmyeongseok/025.circle-area/solve.js new file mode 100644 index 0000000..c3712f6 --- /dev/null +++ b/Challenge/Songmyeongseok/025.circle-area/solve.js @@ -0,0 +1,12 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + + +function 넓이(n) { + return n*n*3.14 +} \ No newline at end of file From dc15f48e8c38dc22f85677b13b33043466ad9d07 Mon Sep 17 00:00:00 2001 From: unidagit Date: Sat, 28 May 2022 09:43:24 +0900 Subject: [PATCH 068/308] =?UTF-8?q?Solve:=204=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/4.type(2)/README.md | 8 ++++++++ Challenge/YunheeJo/4.type(2)/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Challenge/YunheeJo/4.type(2)/README.md create mode 100644 Challenge/YunheeJo/4.type(2)/solve.js diff --git a/Challenge/YunheeJo/4.type(2)/README.md b/Challenge/YunheeJo/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/YunheeJo/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/YunheeJo/4.type(2)/solve.js b/Challenge/YunheeJo/4.type(2)/solve.js new file mode 100644 index 0000000..5832fe3 --- /dev/null +++ b/Challenge/YunheeJo/4.type(2)/solve.js @@ -0,0 +1,12 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + + +답은 2번입니다! +boolean은 참과 거짓을 의미합니다. a = 2.22 출력값은 number가 나와야합니다. \ No newline at end of file From 817619411b7eefb0229952ed7a4c2c0fd452eafe Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Sat, 28 May 2022 17:01:28 +0900 Subject: [PATCH 069/308] Solve 001 --- Challenge/HeelaeLim/001.arry/README.md | 5 +++++ Challenge/HeelaeLim/001.arry/solve.js | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 Challenge/HeelaeLim/001.arry/README.md create mode 100644 Challenge/HeelaeLim/001.arry/solve.js diff --git a/Challenge/HeelaeLim/001.arry/README.md b/Challenge/HeelaeLim/001.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/HeelaeLim/001.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/HeelaeLim/001.arry/solve.js b/Challenge/HeelaeLim/001.arry/solve.js new file mode 100644 index 0000000..e1f4bf9 --- /dev/null +++ b/Challenge/HeelaeLim/001.arry/solve.js @@ -0,0 +1,9 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); + +console.log(nums); \ No newline at end of file From ba7fb053186c4a811999dc09139f6b801990c945 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Sat, 28 May 2022 17:05:43 +0900 Subject: [PATCH 070/308] Solve: 002 --- Challenge/HeelaeLim/002.arryMethd/README.md | 11 +++++++++++ Challenge/HeelaeLim/002.arryMethd/solve.js | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/HeelaeLim/002.arryMethd/README.md create mode 100644 Challenge/HeelaeLim/002.arryMethd/solve.js diff --git a/Challenge/HeelaeLim/002.arryMethd/README.md b/Challenge/HeelaeLim/002.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/HeelaeLim/002.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/HeelaeLim/002.arryMethd/solve.js b/Challenge/HeelaeLim/002.arryMethd/solve.js new file mode 100644 index 0000000..4095544 --- /dev/null +++ b/Challenge/HeelaeLim/002.arryMethd/solve.js @@ -0,0 +1,11 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file From 2ef809088b18b0aa0a28f03422d1c6528e6a6f61 Mon Sep 17 00:00:00 2001 From: plutoin Date: Sat, 28 May 2022 20:29:29 +0900 Subject: [PATCH 071/308] =?UTF-8?q?Docs:=201=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=8F=B4=EB=8D=94=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/{1.arry => 001.arry}/README.md | 0 Challenge/SoyeonJang/{1.arry => 001.arry}/solve.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Challenge/SoyeonJang/{1.arry => 001.arry}/README.md (100%) rename Challenge/SoyeonJang/{1.arry => 001.arry}/solve.js (100%) diff --git a/Challenge/SoyeonJang/1.arry/README.md b/Challenge/SoyeonJang/001.arry/README.md similarity index 100% rename from Challenge/SoyeonJang/1.arry/README.md rename to Challenge/SoyeonJang/001.arry/README.md diff --git a/Challenge/SoyeonJang/1.arry/solve.js b/Challenge/SoyeonJang/001.arry/solve.js similarity index 100% rename from Challenge/SoyeonJang/1.arry/solve.js rename to Challenge/SoyeonJang/001.arry/solve.js From df7932531d3960e358e178ec046f0d8faf824870 Mon Sep 17 00:00:00 2001 From: plutoin Date: Sat, 28 May 2022 20:50:17 +0900 Subject: [PATCH 072/308] =?UTF-8?q?Solve:=207-9=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/007.variable/README.md | 9 +++++++++ Challenge/SoyeonJang/007.variable/solve.js | 19 +++++++++++++++++++ Challenge/SoyeonJang/008.object/README.md | 16 ++++++++++++++++ Challenge/SoyeonJang/008.object/solve.js | 19 +++++++++++++++++++ Challenge/SoyeonJang/009.concat/README.md | 20 ++++++++++++++++++++ Challenge/SoyeonJang/009.concat/solve.js | 20 ++++++++++++++++++++ 6 files changed, 103 insertions(+) create mode 100644 Challenge/SoyeonJang/007.variable/README.md create mode 100644 Challenge/SoyeonJang/007.variable/solve.js create mode 100644 Challenge/SoyeonJang/008.object/README.md create mode 100644 Challenge/SoyeonJang/008.object/solve.js create mode 100644 Challenge/SoyeonJang/009.concat/README.md create mode 100644 Challenge/SoyeonJang/009.concat/solve.js diff --git a/Challenge/SoyeonJang/007.variable/README.md b/Challenge/SoyeonJang/007.variable/README.md new file mode 100644 index 0000000..f872494 --- /dev/null +++ b/Challenge/SoyeonJang/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제 7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/SoyeonJang/007.variable/solve.js b/Challenge/SoyeonJang/007.variable/solve.js new file mode 100644 index 0000000..a92cee3 --- /dev/null +++ b/Challenge/SoyeonJang/007.variable/solve.js @@ -0,0 +1,19 @@ +/* +# 문제 7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let -> 예약어 +4) _age +5) 1age -> 첫 번째 글자 숫자 + +정답: 3번, 5번 + +변수명으로 사용할 수 있는 것 +1. 특수기호 +2. 문자열 (예약어 제외) +3. 숫자 (첫 번째로는 불가능) + +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/008.object/README.md b/Challenge/SoyeonJang/008.object/README.md new file mode 100644 index 0000000..73627d5 --- /dev/null +++ b/Challenge/SoyeonJang/008.object/README.md @@ -0,0 +1,16 @@ +# 문제 8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다.) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/008.object/solve.js b/Challenge/SoyeonJang/008.object/solve.js new file mode 100644 index 0000000..178db3f --- /dev/null +++ b/Challenge/SoyeonJang/008.object/solve.js @@ -0,0 +1,19 @@ +/* +# 문제 8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다.) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); + +정답: 84 + +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/009.concat/README.md b/Challenge/SoyeonJang/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/SoyeonJang/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/009.concat/solve.js b/Challenge/SoyeonJang/009.concat/solve.js new file mode 100644 index 0000000..1863e95 --- /dev/null +++ b/Challenge/SoyeonJang/009.concat/solve.js @@ -0,0 +1,20 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = year.concat('/', month, '/', day, ' ', hour, ':', minute, ':', second) + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ \ No newline at end of file From bac801a690c2cb52dead63c7541f29157b6fd4fe Mon Sep 17 00:00:00 2001 From: plutoin Date: Sat, 28 May 2022 21:15:18 +0900 Subject: [PATCH 073/308] =?UTF-8?q?Solve:=2010=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/010.star/README.md | 18 ++++++++++++ Challenge/SoyeonJang/010.star/solve.js | 39 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 Challenge/SoyeonJang/010.star/README.md create mode 100644 Challenge/SoyeonJang/010.star/solve.js diff --git a/Challenge/SoyeonJang/010.star/README.md b/Challenge/SoyeonJang/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/SoyeonJang/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/010.star/solve.js b/Challenge/SoyeonJang/010.star/solve.js new file mode 100644 index 0000000..28115ba --- /dev/null +++ b/Challenge/SoyeonJang/010.star/solve.js @@ -0,0 +1,39 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* + +방법 1 + +let level = 5; +for (let i = 1; i <= level ; i++) { + console.log(' '.repeat(level - i) + '*'.repeat(i * 2 - 1)) +} + +방법 2 + +let level = 5; +for (let i = 1; i <= level; i++) { + let tree = "" + for (let k = 1; k <= level - i; k++) { + tree += ' ' + } + for (let j = 1; j <= i * 2 - 1; j++) { + tree += '*' + } + console.log (tree) +} +*/ \ No newline at end of file From b46e3335e55826837e18bd4041b05584c04f7a4b Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Sat, 28 May 2022 21:57:55 +0900 Subject: [PATCH 074/308] =?UTF-8?q?Solve=20:=2011=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/011.for/README.md | 11 +++++++++++ Challenge/Songmyeongseok/011.for/solve.js | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 Challenge/Songmyeongseok/011.for/README.md create mode 100644 Challenge/Songmyeongseok/011.for/solve.js diff --git a/Challenge/Songmyeongseok/011.for/README.md b/Challenge/Songmyeongseok/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/Songmyeongseok/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/Songmyeongseok/011.for/solve.js b/Challenge/Songmyeongseok/011.for/solve.js new file mode 100644 index 0000000..6b0bcd3 --- /dev/null +++ b/Challenge/Songmyeongseok/011.for/solve.js @@ -0,0 +1,17 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass + +console.log(s); +*/ + +let s = 0; +for (let i = 1; i<=100; i++){ + s += i; +} + From 536e3e51e0152c9b4ae05c3f798fda77a352873e Mon Sep 17 00:00:00 2001 From: skylar121 Date: Sat, 28 May 2022 22:13:21 +0900 Subject: [PATCH 075/308] =?UTF-8?q?Solve:=2014=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/GyeongRim/14/README.md | 7 +++++++ Challenge/GyeongRim/14/solve.js | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 Challenge/GyeongRim/14/README.md create mode 100644 Challenge/GyeongRim/14/solve.js diff --git a/Challenge/GyeongRim/14/README.md b/Challenge/GyeongRim/14/README.md new file mode 100644 index 0000000..54c8aab --- /dev/null +++ b/Challenge/GyeongRim/14/README.md @@ -0,0 +1,7 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. \ No newline at end of file diff --git a/Challenge/GyeongRim/14/solve.js b/Challenge/GyeongRim/14/solve.js new file mode 100644 index 0000000..bb3531c --- /dev/null +++ b/Challenge/GyeongRim/14/solve.js @@ -0,0 +1,22 @@ +// 나의 답 +function 삼육구 (num) { + let number = num.toString().split(''); + let clap = []; + for (let i of number) { + if (i % 3 === 0) { + clap.push('짝'); + } else { + clap.push(i); + } + } + return clap; +}; + +// 답안 +const n = prompt('숫자를 입력하세요.'); + +if (n%3 == 0) { // 나머지 연산 %는 n을 3으로 나누었을때 몫이 아닌 나머지 값을 반환합니다. + console.log('짝'); +} else { + console.log(n); +} \ No newline at end of file From df290d2dffac51fa803ad12f9e6e60456f2a3998 Mon Sep 17 00:00:00 2001 From: sooyyoung Date: Sat, 28 May 2022 22:15:32 +0900 Subject: [PATCH 076/308] =?UTF-8?q?Solve=20:=203-4=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sooyoungCho/3.type/README.md | 13 +++++++++++++ Challenge/sooyoungCho/3.type/solve.js | 13 +++++++++++++ Challenge/sooyoungCho/4.type(2)/README.md | 8 ++++++++ Challenge/sooyoungCho/4.type(2)/solve.js | 10 ++++++++++ 4 files changed, 44 insertions(+) create mode 100644 Challenge/sooyoungCho/3.type/README.md create mode 100644 Challenge/sooyoungCho/3.type/solve.js create mode 100644 Challenge/sooyoungCho/4.type(2)/README.md create mode 100644 Challenge/sooyoungCho/4.type(2)/solve.js diff --git a/Challenge/sooyoungCho/3.type/README.md b/Challenge/sooyoungCho/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/sooyoungCho/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/sooyoungCho/3.type/solve.js b/Challenge/sooyoungCho/3.type/solve.js new file mode 100644 index 0000000..fa5635b --- /dev/null +++ b/Challenge/sooyoungCho/3.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +// 정답 4번! \ No newline at end of file diff --git a/Challenge/sooyoungCho/4.type(2)/README.md b/Challenge/sooyoungCho/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/sooyoungCho/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/sooyoungCho/4.type(2)/solve.js b/Challenge/sooyoungCho/4.type(2)/solve.js new file mode 100644 index 0000000..9cc8189 --- /dev/null +++ b/Challenge/sooyoungCho/4.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답 2번! number 출력 \ No newline at end of file From e1c8284291b4fa4ec15550c346882eb5618913cc Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Sat, 28 May 2022 22:17:07 +0900 Subject: [PATCH 077/308] =?UTF-8?q?Solve=20:=202=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JisuKim/2.arryMethd/solve.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Challenge/JisuKim/2.arryMethd/solve.js b/Challenge/JisuKim/2.arryMethd/solve.js index 4095544..9c3a582 100644 --- a/Challenge/JisuKim/2.arryMethd/solve.js +++ b/Challenge/JisuKim/2.arryMethd/solve.js @@ -8,4 +8,6 @@ var arr = [200, 100, 300]; console.log(arr); 출력 -[200, 100, 10000, 300] \ No newline at end of file +[200, 100, 10000, 300] + +arr.splice(2, 0, 10000); \ No newline at end of file From 1d59751b5d3dfd382f3b3ccac49e880aa8ebe72f Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Sat, 28 May 2022 22:17:59 +0900 Subject: [PATCH 078/308] =?UTF-8?q?Solve:=206-9=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sehunKim/006.false/README.md | 10 ++++++++++ Challenge/sehunKim/006.false/solve.js | 12 ++++++++++++ Challenge/sehunKim/007.variable/README.md | 9 +++++++++ Challenge/sehunKim/007.variable/solve.js | 13 +++++++++++++ Challenge/sehunKim/008.object/README.md | 16 ++++++++++++++++ Challenge/sehunKim/008.object/solve.js | 18 ++++++++++++++++++ Challenge/sehunKim/009.concat/README.md | 20 ++++++++++++++++++++ Challenge/sehunKim/009.concat/solve.js | 20 ++++++++++++++++++++ 8 files changed, 118 insertions(+) create mode 100644 Challenge/sehunKim/006.false/README.md create mode 100644 Challenge/sehunKim/006.false/solve.js create mode 100644 Challenge/sehunKim/007.variable/README.md create mode 100644 Challenge/sehunKim/007.variable/solve.js create mode 100644 Challenge/sehunKim/008.object/README.md create mode 100644 Challenge/sehunKim/008.object/solve.js create mode 100644 Challenge/sehunKim/009.concat/README.md create mode 100644 Challenge/sehunKim/009.concat/solve.js diff --git a/Challenge/sehunKim/006.false/README.md b/Challenge/sehunKim/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/sehunKim/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/sehunKim/006.false/solve.js b/Challenge/sehunKim/006.false/solve.js new file mode 100644 index 0000000..cf4097d --- /dev/null +++ b/Challenge/sehunKim/006.false/solve.js @@ -0,0 +1,12 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + +// 정답: 2번 1, 1은 null,undefined,0,"",NaN,false는 false로 취급한다. \ No newline at end of file diff --git a/Challenge/sehunKim/007.variable/README.md b/Challenge/sehunKim/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/sehunKim/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/sehunKim/007.variable/solve.js b/Challenge/sehunKim/007.variable/solve.js new file mode 100644 index 0000000..7c9a85d --- /dev/null +++ b/Challenge/sehunKim/007.variable/solve.js @@ -0,0 +1,13 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +// 정답: 3번 let, 5번 1age, JavaScript 식별자는 예약어를 사용할 수 없고 숫자가 가장 앞에 올 수 없다. \ No newline at end of file diff --git a/Challenge/sehunKim/008.object/README.md b/Challenge/sehunKim/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/sehunKim/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/sehunKim/008.object/solve.js b/Challenge/sehunKim/008.object/solve.js new file mode 100644 index 0000000..a177306 --- /dev/null +++ b/Challenge/sehunKim/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +// 정답:84, 객체의 키가 중복되었을 경우, 마지막 키의 값을 가져온다. \ No newline at end of file diff --git a/Challenge/sehunKim/009.concat/README.md b/Challenge/sehunKim/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/sehunKim/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/sehunKim/009.concat/solve.js b/Challenge/sehunKim/009.concat/solve.js new file mode 100644 index 0000000..5c0a185 --- /dev/null +++ b/Challenge/sehunKim/009.concat/solve.js @@ -0,0 +1,20 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; +// concat은 인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새 배열로 반환한다. 배열이 아니면 인수 를 붙여서 반환한다. +var result = year.concat('/',month,'/',day,' ',hour,':',minute,':',second); + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ \ No newline at end of file From e79cdeb9f1a4fce6ab1afa739ef73a6c57b6c06a Mon Sep 17 00:00:00 2001 From: leehyeonseop Date: Sat, 28 May 2022 22:20:13 +0900 Subject: [PATCH 079/308] =?UTF-8?q?Solve:=202=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HyeonseopLee/1.arry/solve.js | 6 +++++- Challenge/HyeonseopLee/2.arryMethd/README.md | 11 +++++++++++ Challenge/HyeonseopLee/2.arryMethd/solve.js | 12 ++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Challenge/HyeonseopLee/2.arryMethd/README.md create mode 100644 Challenge/HyeonseopLee/2.arryMethd/solve.js diff --git a/Challenge/HyeonseopLee/1.arry/solve.js b/Challenge/HyeonseopLee/1.arry/solve.js index 7ffd8bd..8a57a41 100644 --- a/Challenge/HyeonseopLee/1.arry/solve.js +++ b/Challenge/HyeonseopLee/1.arry/solve.js @@ -1,4 +1,8 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +let result = nums.filter((e) => e != 400 && e != 500); + +console.log(result); \ No newline at end of file diff --git a/Challenge/HyeonseopLee/2.arryMethd/README.md b/Challenge/HyeonseopLee/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/HyeonseopLee/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/HyeonseopLee/2.arryMethd/solve.js b/Challenge/HyeonseopLee/2.arryMethd/solve.js new file mode 100644 index 0000000..747f8cb --- /dev/null +++ b/Challenge/HyeonseopLee/2.arryMethd/solve.js @@ -0,0 +1,12 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +// 데이터 +var arr = [200, 100, 300]; +//pass +arr.splice(2, 0, 10000); +console.log(arr); + +// 출력 +// [200, 100, 10000, 300] \ No newline at end of file From d0cba3282b2453079264e424ad1d290014dce898 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Sat, 28 May 2022 22:38:47 +0900 Subject: [PATCH 080/308] =?UTF-8?q?Solve:=20=EB=AC=B8=EC=A0=9C4=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=EC=9D=98=20=ED=83=80=EC=9E=852=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/004.type(2)/README.md | 8 ++++++++ Challenge/MinkyeongJo/004.type(2)/solve.js | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 Challenge/MinkyeongJo/004.type(2)/README.md create mode 100644 Challenge/MinkyeongJo/004.type(2)/solve.js diff --git a/Challenge/MinkyeongJo/004.type(2)/README.md b/Challenge/MinkyeongJo/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/MinkyeongJo/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/MinkyeongJo/004.type(2)/solve.js b/Challenge/MinkyeongJo/004.type(2)/solve.js new file mode 100644 index 0000000..20c64a2 --- /dev/null +++ b/Challenge/MinkyeongJo/004.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답 2번: 2.22의 타입은 number가 나와야한다! \ No newline at end of file From 781d1fc49a50092c0f55caf84fef13ab9a4cee24 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Sun, 29 May 2022 13:43:47 +0900 Subject: [PATCH 081/308] Solve: 003 --- Challenge/HeelaeLim/003.type/README.md | 13 +++++++++++++ Challenge/HeelaeLim/003.type/solve.js | 8 ++++++++ 2 files changed, 21 insertions(+) create mode 100644 Challenge/HeelaeLim/003.type/README.md create mode 100644 Challenge/HeelaeLim/003.type/solve.js diff --git a/Challenge/HeelaeLim/003.type/README.md b/Challenge/HeelaeLim/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/HeelaeLim/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/HeelaeLim/003.type/solve.js b/Challenge/HeelaeLim/003.type/solve.js new file mode 100644 index 0000000..cc736cc --- /dev/null +++ b/Challenge/HeelaeLim/003.type/solve.js @@ -0,0 +1,8 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +//object \ No newline at end of file From 470d72b5099a2de3cb93adbbd6c93093cd17bc2e Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Sun, 29 May 2022 14:06:57 +0900 Subject: [PATCH 082/308] =?UTF-8?q?Solve:=203=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes Challenge/{KimYeji => YejiKim}/1.arry/README.md | 0 Challenge/{KimYeji => YejiKim}/1.arry/solve.js | 0 .../{KimYeji => YejiKim}/2.arryMethd/README.md | 0 .../{KimYeji => YejiKim}/2.arryMethd/solve.js | 0 Challenge/YejiKim/3.type/README.md | 13 +++++++++++++ Challenge/YejiKim/3.type/solve.js | 13 +++++++++++++ 7 files changed, 26 insertions(+) create mode 100644 .DS_Store rename Challenge/{KimYeji => YejiKim}/1.arry/README.md (100%) rename Challenge/{KimYeji => YejiKim}/1.arry/solve.js (100%) rename Challenge/{KimYeji => YejiKim}/2.arryMethd/README.md (100%) rename Challenge/{KimYeji => YejiKim}/2.arryMethd/solve.js (100%) create mode 100644 Challenge/YejiKim/3.type/README.md create mode 100644 Challenge/YejiKim/3.type/solve.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..88799d643674e109c559fbc034af888502d13dfd GIT binary patch literal 6148 zcmeH~L2uJA6vv;p01nfn9zcQvQY5ZZ$p}D-)+pF!@#X-+q42seh8=n25w+nr#yGh)ANadUsL%!FZg@lC4+| z4+@^+b*Vn5rApD~37t6tj=;Z7fcLIPeLAFqn(qD;UoqDIrA;s5JT9HpCw8CzNKeY5 zZo=@VSXuRM-M%BGT$3N;BQ=Ygq?y)(Wb&SSZcW*~kO;S|(L?;wk zj*t%rMU|=9KuxQx*1546kiPGadJpIG%`gl%g6;76Vk4Npc#8Jcv#rI#m-in(dAUD2 zF2|MPKMxalF=<=3dM4k{IA740cv6+BI)snoecGWTN~pvyrwVZLE*g4;sNc~@dP5UZ zl!K2mE}%l!*_9BmTSKm0$?R@YN5B#I zp9%2$AwXe`thPq=s{@t30zf^uwV|y){hQlTbQ*eiyxHwR(TF&^3Y z)~HD*p`VO-?30DPp$L2N5P=RS5gB#0Bj5;h39OoKkI( Date: Sun, 29 May 2022 14:07:07 +0900 Subject: [PATCH 083/308] =?UTF-8?q?Solve:=203=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/3.type/README.md | 13 +++++++++++++ Challenge/DahyunLim/3.type/solve.js | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Challenge/DahyunLim/3.type/README.md create mode 100644 Challenge/DahyunLim/3.type/solve.js diff --git a/Challenge/DahyunLim/3.type/README.md b/Challenge/DahyunLim/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/DahyunLim/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/DahyunLim/3.type/solve.js b/Challenge/DahyunLim/3.type/solve.js new file mode 100644 index 0000000..e975184 --- /dev/null +++ b/Challenge/DahyunLim/3.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof (arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +// 정답 4번 \ No newline at end of file From 4517de23039ca277cd6c55622aaaaa819df102af Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Sun, 29 May 2022 20:59:54 +0900 Subject: [PATCH 084/308] =?UTF-8?q?Feat=20:=2016~18=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/011.for/solve.js | 1 + .../README.md" | 10 ++++++++++ .../solve.js" | 9 +++++++++ Problems/017.limit/README.md | 7 +++++++ Problems/017.limit/solve.js | 9 +++++++++ Problems/018.average/README.md | 13 +++++++++++++ Problems/018.average/solve.js | 14 ++++++++++++++ 7 files changed, 63 insertions(+) create mode 100644 "Problems/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Problems/016.\353\241\234\352\276\270\352\272\274/solve.js" create mode 100644 Problems/017.limit/README.md create mode 100644 Problems/017.limit/solve.js create mode 100644 Problems/018.average/README.md create mode 100644 Problems/018.average/solve.js diff --git a/Challenge/Songmyeongseok/011.for/solve.js b/Challenge/Songmyeongseok/011.for/solve.js index 6b0bcd3..d9e29d3 100644 --- a/Challenge/Songmyeongseok/011.for/solve.js +++ b/Challenge/Songmyeongseok/011.for/solve.js @@ -15,3 +15,4 @@ for (let i = 1; i<=100; i++){ s += i; } + diff --git "a/Problems/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Problems/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Problems/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Problems/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Problems/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..0859045 --- /dev/null +++ "b/Problems/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,9 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +*/ \ No newline at end of file diff --git a/Problems/017.limit/README.md b/Problems/017.limit/README.md new file mode 100644 index 0000000..b364fc6 --- /dev/null +++ b/Problems/017.limit/README.md @@ -0,0 +1,7 @@ +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. diff --git a/Problems/017.limit/solve.js b/Problems/017.limit/solve.js new file mode 100644 index 0000000..1b30886 --- /dev/null +++ b/Problems/017.limit/solve.js @@ -0,0 +1,9 @@ +/* +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. +*/ \ No newline at end of file diff --git a/Problems/018.average/README.md b/Problems/018.average/README.md new file mode 100644 index 0000000..ca04b62 --- /dev/null +++ b/Problems/018.average/README.md @@ -0,0 +1,13 @@ +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` diff --git a/Problems/018.average/solve.js b/Problems/018.average/solve.js new file mode 100644 index 0000000..6a21475 --- /dev/null +++ b/Problems/018.average/solve.js @@ -0,0 +1,14 @@ +/* +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +**입출력** + +입력 : 20 30 40 +출력 : 30 + +*/ \ No newline at end of file From f748905be12f2cc70a9cf05065680da767dc805a Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Sun, 29 May 2022 21:11:31 +0900 Subject: [PATCH 085/308] =?UTF-8?q?Solve:=2016~17=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 10 ++++++++++ .../solve.js" | 13 +++++++++++++ Challenge/Songmyeongseok/017.limit/README.md | 7 +++++++ Challenge/Songmyeongseok/017.limit/solve.js | 17 +++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 "Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/solve.js" create mode 100644 Challenge/Songmyeongseok/017.limit/README.md create mode 100644 Challenge/Songmyeongseok/017.limit/solve.js diff --git "a/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..41dd4f4 --- /dev/null +++ "b/Challenge/Songmyeongseok/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,13 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +*/ + +function 로꾸거(x){ + return x.split('').reverse().join('') +} diff --git a/Challenge/Songmyeongseok/017.limit/README.md b/Challenge/Songmyeongseok/017.limit/README.md new file mode 100644 index 0000000..b364fc6 --- /dev/null +++ b/Challenge/Songmyeongseok/017.limit/README.md @@ -0,0 +1,7 @@ +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. diff --git a/Challenge/Songmyeongseok/017.limit/solve.js b/Challenge/Songmyeongseok/017.limit/solve.js new file mode 100644 index 0000000..f3f1113 --- /dev/null +++ b/Challenge/Songmyeongseok/017.limit/solve.js @@ -0,0 +1,17 @@ +/* +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. +*/ + +function height(x) { + if(x >= 150){ + console.log("YES") + } else { + console.log("NO") + } +} \ No newline at end of file From 463ca5745c8e78e304de69132b9c0d7522e6d2fe Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Sun, 29 May 2022 21:20:42 +0900 Subject: [PATCH 086/308] =?UTF-8?q?Docs=20:=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EB=8B=B5=EC=95=88=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/005.for/solve.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/Problems/005.for/solve.js b/Problems/005.for/solve.js index bfad872..4ba2483 100644 --- a/Problems/005.for/solve.js +++ b/Problems/005.for/solve.js @@ -18,6 +18,3 @@ console.log(a+b); // 2) 12 // 3) 14 // 4) 16 - -// 정답: 4번 -// i = 1 일때 a = 11, i = 3일때 a = 14, i < 5까지 순회임으로 a + b는 16이다. \ No newline at end of file From 414f568fb4478a0e860c404119119aff1afa1e7c Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Sun, 29 May 2022 22:09:24 +0900 Subject: [PATCH 087/308] Solve: 004, 005 --- Challenge/HeelaeLim/004.type(2)/README.md | 8 ++++++++ Challenge/HeelaeLim/004.type(2)/solve.js | 6 ++++++ Challenge/HeelaeLim/005.for/README.md | 20 ++++++++++++++++++++ Challenge/HeelaeLim/005.for/solve.js | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 Challenge/HeelaeLim/004.type(2)/README.md create mode 100644 Challenge/HeelaeLim/004.type(2)/solve.js create mode 100644 Challenge/HeelaeLim/005.for/README.md create mode 100644 Challenge/HeelaeLim/005.for/solve.js diff --git a/Challenge/HeelaeLim/004.type(2)/README.md b/Challenge/HeelaeLim/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/HeelaeLim/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/HeelaeLim/004.type(2)/solve.js b/Challenge/HeelaeLim/004.type(2)/solve.js new file mode 100644 index 0000000..090710f --- /dev/null +++ b/Challenge/HeelaeLim/004.type(2)/solve.js @@ -0,0 +1,6 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 2) 입력 : a = 2.22, 출력 : boolean +// 출력 : number diff --git a/Challenge/HeelaeLim/005.for/README.md b/Challenge/HeelaeLim/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/HeelaeLim/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/HeelaeLim/005.for/solve.js b/Challenge/HeelaeLim/005.for/solve.js new file mode 100644 index 0000000..e748689 --- /dev/null +++ b/Challenge/HeelaeLim/005.for/solve.js @@ -0,0 +1,18 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + +// 4) 16 + +// a = 10+1+3 = 14; b = 2; 따라서 a+b = 16; \ No newline at end of file From 5f42230c172543f07f2af0c504d75d5ce877fd56 Mon Sep 17 00:00:00 2001 From: plutoin Date: Sun, 29 May 2022 22:47:08 +0900 Subject: [PATCH 088/308] =?UTF-8?q?Solve:=2011=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/011.for/README.md | 11 +++++++++++ Challenge/SoyeonJang/011.for/solve.js | 15 +++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Challenge/SoyeonJang/011.for/README.md create mode 100644 Challenge/SoyeonJang/011.for/solve.js diff --git a/Challenge/SoyeonJang/011.for/README.md b/Challenge/SoyeonJang/011.for/README.md new file mode 100644 index 0000000..0adcbcb --- /dev/null +++ b/Challenge/SoyeonJang/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +// pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/011.for/solve.js b/Challenge/SoyeonJang/011.for/solve.js new file mode 100644 index 0000000..d3ca22c --- /dev/null +++ b/Challenge/SoyeonJang/011.for/solve.js @@ -0,0 +1,15 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +// pass + +for (let i = 1; i <= 100; i++) { + s += i +} + +console.log(s); +*/ \ No newline at end of file From ad9f9a3936bf1218ec2f06e46dc65621cac75853 Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Sun, 29 May 2022 22:49:18 +0900 Subject: [PATCH 089/308] =?UTF-8?q?Solve=20:=20003~007=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JisuKim/003.type/README.md | 13 ++++++++++++ Challenge/JisuKim/003.type/solve.js | 13 ++++++++++++ Challenge/JisuKim/004.type(2)/README.md | 8 +++++++ Challenge/JisuKim/004.type(2)/solve.js | 10 +++++++++ Challenge/JisuKim/005.for/README.md | 20 ++++++++++++++++++ Challenge/JisuKim/005.for/solve.js | 27 ++++++++++++++++++++++++ Challenge/JisuKim/006.false/README.md | 10 +++++++++ Challenge/JisuKim/006.false/solve.js | 13 ++++++++++++ Challenge/JisuKim/007.variable/README.md | 9 ++++++++ Challenge/JisuKim/007.variable/solve.js | 13 ++++++++++++ 10 files changed, 136 insertions(+) create mode 100644 Challenge/JisuKim/003.type/README.md create mode 100644 Challenge/JisuKim/003.type/solve.js create mode 100644 Challenge/JisuKim/004.type(2)/README.md create mode 100644 Challenge/JisuKim/004.type(2)/solve.js create mode 100644 Challenge/JisuKim/005.for/README.md create mode 100644 Challenge/JisuKim/005.for/solve.js create mode 100644 Challenge/JisuKim/006.false/README.md create mode 100644 Challenge/JisuKim/006.false/solve.js create mode 100644 Challenge/JisuKim/007.variable/README.md create mode 100644 Challenge/JisuKim/007.variable/solve.js diff --git a/Challenge/JisuKim/003.type/README.md b/Challenge/JisuKim/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/JisuKim/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/JisuKim/003.type/solve.js b/Challenge/JisuKim/003.type/solve.js new file mode 100644 index 0000000..bb79b83 --- /dev/null +++ b/Challenge/JisuKim/003.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +//4) object \ No newline at end of file diff --git a/Challenge/JisuKim/004.type(2)/README.md b/Challenge/JisuKim/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/JisuKim/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/JisuKim/004.type(2)/solve.js b/Challenge/JisuKim/004.type(2)/solve.js new file mode 100644 index 0000000..db1736e --- /dev/null +++ b/Challenge/JisuKim/004.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +//2. 입력 : a = 2.22, 출력 : boolean x true, false 값이며 a는 num \ No newline at end of file diff --git a/Challenge/JisuKim/005.for/README.md b/Challenge/JisuKim/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/JisuKim/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/JisuKim/005.for/solve.js b/Challenge/JisuKim/005.for/solve.js new file mode 100644 index 0000000..9422992 --- /dev/null +++ b/Challenge/JisuKim/005.for/solve.js @@ -0,0 +1,27 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + +// 10 2 +// 10 10 + 1 +// 11 11 + 3 +// 14 + 2 + +// 4번 16 \ No newline at end of file diff --git a/Challenge/JisuKim/006.false/README.md b/Challenge/JisuKim/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/JisuKim/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/JisuKim/006.false/solve.js b/Challenge/JisuKim/006.false/solve.js new file mode 100644 index 0000000..2984665 --- /dev/null +++ b/Challenge/JisuKim/006.false/solve.js @@ -0,0 +1,13 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + + +//정답: 2번 1, 1은 null,undefined,0,"",NaN,false는 false로 취급한다. \ No newline at end of file diff --git a/Challenge/JisuKim/007.variable/README.md b/Challenge/JisuKim/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/JisuKim/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/JisuKim/007.variable/solve.js b/Challenge/JisuKim/007.variable/solve.js new file mode 100644 index 0000000..fdd7a7e --- /dev/null +++ b/Challenge/JisuKim/007.variable/solve.js @@ -0,0 +1,13 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +//정답 : 정답: 3번 let, 5번 1age, JavaScript 식별자는 예약어를 사용할 수 없고 숫자가 가장 앞에 올 수 없다. \ No newline at end of file From 15d2444bb215fac02eb63db6c1681fa2d2dc8426 Mon Sep 17 00:00:00 2001 From: leehyeonseop Date: Sun, 29 May 2022 23:14:10 +0900 Subject: [PATCH 090/308] =?UTF-8?q?Solve:=203-4=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HyeonseopLee/003.type/README.md | 13 +++++++++++++ Challenge/HyeonseopLee/003.type/solve.js | 13 +++++++++++++ Challenge/HyeonseopLee/004.type(2)/README.md | 8 ++++++++ Challenge/HyeonseopLee/004.type(2)/solve.js | 10 ++++++++++ 4 files changed, 44 insertions(+) create mode 100644 Challenge/HyeonseopLee/003.type/README.md create mode 100644 Challenge/HyeonseopLee/003.type/solve.js create mode 100644 Challenge/HyeonseopLee/004.type(2)/README.md create mode 100644 Challenge/HyeonseopLee/004.type(2)/solve.js diff --git a/Challenge/HyeonseopLee/003.type/README.md b/Challenge/HyeonseopLee/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/HyeonseopLee/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/HyeonseopLee/003.type/solve.js b/Challenge/HyeonseopLee/003.type/solve.js new file mode 100644 index 0000000..9989eef --- /dev/null +++ b/Challenge/HyeonseopLee/003.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof(arr)); + +// 정답 : 4번 + +// 1) undefined +// 2) string +// 3) number +// 4) object \ No newline at end of file diff --git a/Challenge/HyeonseopLee/004.type(2)/README.md b/Challenge/HyeonseopLee/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/HyeonseopLee/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/HyeonseopLee/004.type(2)/solve.js b/Challenge/HyeonseopLee/004.type(2)/solve.js new file mode 100644 index 0000000..c781db2 --- /dev/null +++ b/Challenge/HyeonseopLee/004.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 정답 2번 + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file From 9489b8a6597be6d3c98c02c92e4bfcd0dda62d1e Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Sun, 29 May 2022 23:22:06 +0900 Subject: [PATCH 091/308] =?UTF-8?q?Solve=20:=20007=20~=20013=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seyeongLee/007.variable/README.md | 9 +++ Challenge/seyeongLee/007.variable/solve.js | 17 +++++ Challenge/seyeongLee/008.object/README.md | 16 +++++ Challenge/seyeongLee/008.object/solve.js | 28 ++++++++ Challenge/seyeongLee/009.concat/README.md | 20 ++++++ Challenge/seyeongLee/009.concat/solve.js | 36 ++++++++++ Challenge/seyeongLee/010.star/README.md | 18 +++++ Challenge/seyeongLee/010.star/solve.js | 65 +++++++++++++++++++ Challenge/seyeongLee/011.for/README.md | 11 ++++ Challenge/seyeongLee/011.for/solve.js | 18 +++++ Challenge/seyeongLee/012.class/README.md | 17 +++++ Challenge/seyeongLee/012.class/solve.js | 33 ++++++++++ .../seyeongLee/013.find-planet/README.md | 15 +++++ Challenge/seyeongLee/013.find-planet/solve.js | 21 ++++++ 14 files changed, 324 insertions(+) create mode 100644 Challenge/seyeongLee/007.variable/README.md create mode 100644 Challenge/seyeongLee/007.variable/solve.js create mode 100644 Challenge/seyeongLee/008.object/README.md create mode 100644 Challenge/seyeongLee/008.object/solve.js create mode 100644 Challenge/seyeongLee/009.concat/README.md create mode 100644 Challenge/seyeongLee/009.concat/solve.js create mode 100644 Challenge/seyeongLee/010.star/README.md create mode 100644 Challenge/seyeongLee/010.star/solve.js create mode 100644 Challenge/seyeongLee/011.for/README.md create mode 100644 Challenge/seyeongLee/011.for/solve.js create mode 100644 Challenge/seyeongLee/012.class/README.md create mode 100644 Challenge/seyeongLee/012.class/solve.js create mode 100644 Challenge/seyeongLee/013.find-planet/README.md create mode 100644 Challenge/seyeongLee/013.find-planet/solve.js diff --git a/Challenge/seyeongLee/007.variable/README.md b/Challenge/seyeongLee/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/seyeongLee/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/seyeongLee/007.variable/solve.js b/Challenge/seyeongLee/007.variable/solve.js new file mode 100644 index 0000000..18e925b --- /dev/null +++ b/Challenge/seyeongLee/007.variable/solve.js @@ -0,0 +1,17 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let -----> 정답!! +4) _age +5) 1age -----> 정답!! +*/ + +const age = 20; +const Age = 20; +const let = 20; // error : 예약어는 변수명으로 쓸 수 없다. +const _age = 20; +const 1age = 20; // error : 숫자는 변수명의 맨 앞에 쓸 수 없다. \ No newline at end of file diff --git a/Challenge/seyeongLee/008.object/README.md b/Challenge/seyeongLee/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/seyeongLee/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/008.object/solve.js b/Challenge/seyeongLee/008.object/solve.js new file mode 100644 index 0000000..96ea7b8 --- /dev/null +++ b/Challenge/seyeongLee/008.object/solve.js @@ -0,0 +1,28 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); -----> 정답 : 84 +*/ + +var d = { + 'height': 180, + 'weight': 78, + 'weight': 84, + 'temperature': 36, + 'eyesight': 1 +}; + +console.log(d['weight']); // result : 84 +console.log(d.weight); // result : 84 +// 객체이름[key] or 객체이름.key는 해당 key에 대응하는 value를 반환한다. \ No newline at end of file diff --git a/Challenge/seyeongLee/009.concat/README.md b/Challenge/seyeongLee/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/seyeongLee/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/009.concat/solve.js b/Challenge/seyeongLee/009.concat/solve.js new file mode 100644 index 0000000..78062c2 --- /dev/null +++ b/Challenge/seyeongLee/009.concat/solve.js @@ -0,0 +1,36 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ + +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +// 첫번째 방법 +var result1 = year.concat('/', month, '/', day, ' ', hour, ':', minute, ':', second); + +// 두번째 방법 +var result2 = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second; + +console.log(result1); // 2019/04/26 11:34:27 +console.log(result2); // 2019/04/26 11:34:27 \ No newline at end of file diff --git a/Challenge/seyeongLee/010.star/README.md b/Challenge/seyeongLee/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/seyeongLee/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/010.star/solve.js b/Challenge/seyeongLee/010.star/solve.js new file mode 100644 index 0000000..77a0d79 --- /dev/null +++ b/Challenge/seyeongLee/010.star/solve.js @@ -0,0 +1,65 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ + +// 첫번째 방법 : 웹브라우저 +const input = prompt("줄(행)의 갯수를 입력하세요"); + +for (let i = 0; i < input; i++) { + let result = ''; + for (let j = 0; j < input - i - 1; j++) { + result += ' '; + } + for (let k = 0; k < (2 * i + 1); k++) { + result += '*'; + } + console.log(result); +} + + +// 두번째 방법 : node.js +const readline = require("readline"); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +rl.question("줄(행)의 갯수를 입력하세요 : ", (input) => { + + for (let i = 0; i < input; i++) { + let result = ''; + for (let j = 0; j < input - i - 1; j++) { + result += ' '; + } + for (let k = 0; k < (2 * i + 1); k++) { + result += '*'; + } + console.log(result); + } + + rl.close(); +}); + +rl.on('close', () => { + process.exit(); +}) + +// 위와 같이 대표적인 런타임 환경(웹브라우저, node.js)에 따라 2가지 방식으로 문제를 풀이할 수 있습니다. +// 웹브라우저와 node.js는 값을 입력받는 코드가 다르지만 +// 그 외 문제 풀이법은 동일하기 때문에 앞으로는 웹브라우저 방식으로만 올리겠습니다. \ No newline at end of file diff --git a/Challenge/seyeongLee/011.for/README.md b/Challenge/seyeongLee/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/seyeongLee/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/011.for/solve.js b/Challenge/seyeongLee/011.for/solve.js new file mode 100644 index 0000000..1e2f2e2 --- /dev/null +++ b/Challenge/seyeongLee/011.for/solve.js @@ -0,0 +1,18 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass + +console.log(s); +*/ + +let s = 0; + +for (let i = 1; i <= 100; i++) { + s += i; +} +console.log(s); // result : 5050 \ No newline at end of file diff --git a/Challenge/seyeongLee/012.class/README.md b/Challenge/seyeongLee/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/seyeongLee/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/012.class/solve.js b/Challenge/seyeongLee/012.class/solve.js new file mode 100644 index 0000000..92b32d6 --- /dev/null +++ b/Challenge/seyeongLee/012.class/solve.js @@ -0,0 +1,33 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ + +class Wizard { + constructor(health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + + attack() { + console.log("파이어볼"); + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); // result : 545 210 10 +x.attack(); // result : 파이어볼 \ No newline at end of file diff --git a/Challenge/seyeongLee/013.find-planet/README.md b/Challenge/seyeongLee/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/seyeongLee/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/013.find-planet/solve.js b/Challenge/seyeongLee/013.find-planet/solve.js new file mode 100644 index 0000000..739942e --- /dev/null +++ b/Challenge/seyeongLee/013.find-planet/solve.js @@ -0,0 +1,21 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +let planet_arr = ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']; + +let input = prompt("몇번 째 행성이 궁금하신가요?", "1이상 8이하의 숫자를 입력하세요."); + +document.write(`행성 이름 : ${planet_arr[input - 1]}`); From 51f520c12b2b6d816c7dcf7b37f600a542058bef Mon Sep 17 00:00:00 2001 From: usablepaper Date: Mon, 30 May 2022 00:44:29 +0900 Subject: [PATCH 092/308] =?UTF-8?q?Solve=201=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Hyeonji/1.arry/solve.js | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Challenge/Hyeonji/1.arry/solve.js b/Challenge/Hyeonji/1.arry/solve.js index 7ffd8bd..d6efbd7 100644 --- a/Challenge/Hyeonji/1.arry/solve.js +++ b/Challenge/Hyeonji/1.arry/solve.js @@ -1,4 +1,43 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +// 첫번째 방법 + +nums.splice(3); + +// 두번째 방법 + +let newNums = nums.reduce((newNums, num) => { + if (num !== 400 && num !== 500) { + newNums.push(num); + } + return newNums; +}, []); + +// 세번째 방법 + +nums.filter((num) => { + if (num !== 400 && num !== 500) { + return num; + } +}); + +// 네번째 방법 + +let newNums2 = []; + +for (num of nums) { + if (num !== 400 && num !== 500) { + newNums2.push(num); + } +} + +// 다섯번째 방법 + +for (let i = nums.length - 1; i > 0; i--) { + if (nums[i] === 400 || nums[i] === 500) { + nums.splice(i, 1); + } +} From 24198a991daaa6d9ce913b3d213b5fda1526dac6 Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Mon, 30 May 2022 08:57:12 +0900 Subject: [PATCH 093/308] =?UTF-8?q?Feat=20:=2019=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/019.square/README.md | 3 +++ Problems/019.square/solve.js | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 Problems/019.square/README.md create mode 100644 Problems/019.square/solve.js diff --git a/Problems/019.square/README.md b/Problems/019.square/README.md new file mode 100644 index 0000000..e02a30a --- /dev/null +++ b/Problems/019.square/README.md @@ -0,0 +1,3 @@ +문제19 : 제곱을 구하자 + +공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. \ No newline at end of file diff --git a/Problems/019.square/solve.js b/Problems/019.square/solve.js new file mode 100644 index 0000000..32d251d --- /dev/null +++ b/Problems/019.square/solve.js @@ -0,0 +1,3 @@ +// 문제19 : 제곱을 구하자 + +// 공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. \ No newline at end of file From 92443a9f4026467c06e0cb1ade69a836c5338e75 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Mon, 30 May 2022 11:23:28 +0900 Subject: [PATCH 094/308] Solve: 006, 007 --- Challenge/HeelaeLim/006.false/README.md | 10 ++++++++++ Challenge/HeelaeLim/006.false/solve.js | 8 ++++++++ Challenge/HeelaeLim/007.variable/README.md | 9 +++++++++ Challenge/HeelaeLim/007.variable/solve.js | 9 +++++++++ 4 files changed, 36 insertions(+) create mode 100644 Challenge/HeelaeLim/006.false/README.md create mode 100644 Challenge/HeelaeLim/006.false/solve.js create mode 100644 Challenge/HeelaeLim/007.variable/README.md create mode 100644 Challenge/HeelaeLim/007.variable/solve.js diff --git a/Challenge/HeelaeLim/006.false/README.md b/Challenge/HeelaeLim/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/HeelaeLim/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/HeelaeLim/006.false/solve.js b/Challenge/HeelaeLim/006.false/solve.js new file mode 100644 index 0000000..f7c82a3 --- /dev/null +++ b/Challenge/HeelaeLim/006.false/solve.js @@ -0,0 +1,8 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + + +// 2) 1 +// 1, [], {} 등등은 true이다. \ No newline at end of file diff --git a/Challenge/HeelaeLim/007.variable/README.md b/Challenge/HeelaeLim/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/HeelaeLim/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/HeelaeLim/007.variable/solve.js b/Challenge/HeelaeLim/007.variable/solve.js new file mode 100644 index 0000000..9058cf9 --- /dev/null +++ b/Challenge/HeelaeLim/007.variable/solve.js @@ -0,0 +1,9 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +3) let +5) 1age + +이미 존재하는 let은 변수로 사용할 수 없다. 숫자가 앞으로 오도록 변수명을 지을 수 없다.*/ \ No newline at end of file From 18cf4bbc0ed5e4e0e12047d7beb93af43c19afda Mon Sep 17 00:00:00 2001 From: subincdev Date: Mon, 30 May 2022 12:01:32 +0900 Subject: [PATCH 095/308] =?UTF-8?q?=20Solve:=2010=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinChoi/010.star/README.md | 18 +++++++++++++++ Challenge/SubinChoi/010.star/solve.js | 31 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 Challenge/SubinChoi/010.star/README.md create mode 100644 Challenge/SubinChoi/010.star/solve.js diff --git a/Challenge/SubinChoi/010.star/README.md b/Challenge/SubinChoi/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/SubinChoi/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/010.star/solve.js b/Challenge/SubinChoi/010.star/solve.js new file mode 100644 index 0000000..0dcbe82 --- /dev/null +++ b/Challenge/SubinChoi/010.star/solve.js @@ -0,0 +1,31 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ + +let tree = ""; +for (let i = 1; i <= 5; i++) { + let star = ""; + for (let j = 1; j <= 5 - i; j++) { + star += " "; + } + for (let k = 1; k <= 2 * i - 1; k++) { + star += "*"; + } + tree += star + "\n"; +} +console.log(tree); From 3483d7a107c0b09d8e29cc2534417700a527f8ea Mon Sep 17 00:00:00 2001 From: unidagit Date: Mon, 30 May 2022 13:34:40 +0900 Subject: [PATCH 096/308] =?UTF-8?q?Solve:=205-7=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/006.false/README.md | 10 ++++++++++ Challenge/YunheeJo/006.false/solve.js | 12 ++++++++++++ Challenge/YunheeJo/007.variable/README.md | 11 +++++++++++ Challenge/YunheeJo/007.variable/solve.js | 13 +++++++++++++ Challenge/YunheeJo/5.for/README.md | 20 ++++++++++++++++++++ Challenge/YunheeJo/5.for/solve.js | 21 +++++++++++++++++++++ 6 files changed, 87 insertions(+) create mode 100644 Challenge/YunheeJo/006.false/README.md create mode 100644 Challenge/YunheeJo/006.false/solve.js create mode 100644 Challenge/YunheeJo/007.variable/README.md create mode 100644 Challenge/YunheeJo/007.variable/solve.js create mode 100644 Challenge/YunheeJo/5.for/README.md create mode 100644 Challenge/YunheeJo/5.for/solve.js diff --git a/Challenge/YunheeJo/006.false/README.md b/Challenge/YunheeJo/006.false/README.md new file mode 100644 index 0000000..c9a44ef --- /dev/null +++ b/Challenge/YunheeJo/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1. NaN +2. 1 +3. "" +4. 0 +5. undefined diff --git a/Challenge/YunheeJo/006.false/solve.js b/Challenge/YunheeJo/006.false/solve.js new file mode 100644 index 0000000..89be171 --- /dev/null +++ b/Challenge/YunheeJo/006.false/solve.js @@ -0,0 +1,12 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + +답은 2번입니다! \ No newline at end of file diff --git a/Challenge/YunheeJo/007.variable/README.md b/Challenge/YunheeJo/007.variable/README.md new file mode 100644 index 0000000..0f6f0c2 --- /dev/null +++ b/Challenge/YunheeJo/007.variable/README.md @@ -0,0 +1,11 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1. age +2. Age +3. let +4. \_age +5. 1age + +답은 3번하고 5번입니다 diff --git a/Challenge/YunheeJo/007.variable/solve.js b/Challenge/YunheeJo/007.variable/solve.js new file mode 100644 index 0000000..af6dd47 --- /dev/null +++ b/Challenge/YunheeJo/007.variable/solve.js @@ -0,0 +1,13 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +답은 3번하고 5번입니다 \ No newline at end of file diff --git a/Challenge/YunheeJo/5.for/README.md b/Challenge/YunheeJo/5.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/YunheeJo/5.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/YunheeJo/5.for/solve.js b/Challenge/YunheeJo/5.for/solve.js new file mode 100644 index 0000000..331d7a5 --- /dev/null +++ b/Challenge/YunheeJo/5.for/solve.js @@ -0,0 +1,21 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + +답은 16입니다! + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 \ No newline at end of file From 8b641735b8045ce8f15fc2e11fe21989bfb15138 Mon Sep 17 00:00:00 2001 From: plutoin Date: Mon, 30 May 2022 16:46:48 +0900 Subject: [PATCH 097/308] =?UTF-8?q?Solve:=2012-14=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/012.class/README.md | 17 +++++++++++ Challenge/SoyeonJang/012.class/solve.js | 28 +++++++++++++++++++ .../SoyeonJang/013.find-planet/README.md | 15 ++++++++++ Challenge/SoyeonJang/013.find-planet/solve.js | 19 +++++++++++++ Challenge/SoyeonJang/014.if/README.md | 17 +++++++++++ Challenge/SoyeonJang/014.if/solve.js | 25 +++++++++++++++++ 6 files changed, 121 insertions(+) create mode 100644 Challenge/SoyeonJang/012.class/README.md create mode 100644 Challenge/SoyeonJang/012.class/solve.js create mode 100644 Challenge/SoyeonJang/013.find-planet/README.md create mode 100644 Challenge/SoyeonJang/013.find-planet/solve.js create mode 100644 Challenge/SoyeonJang/014.if/README.md create mode 100644 Challenge/SoyeonJang/014.if/solve.js diff --git a/Challenge/SoyeonJang/012.class/README.md b/Challenge/SoyeonJang/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/SoyeonJang/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/012.class/solve.js b/Challenge/SoyeonJang/012.class/solve.js new file mode 100644 index 0000000..e156dcf --- /dev/null +++ b/Challenge/SoyeonJang/012.class/solve.js @@ -0,0 +1,28 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +class Wizard { + constructor (health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + attack() { + console.log('파이어볼') + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/013.find-planet/README.md b/Challenge/SoyeonJang/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/SoyeonJang/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/013.find-planet/solve.js b/Challenge/SoyeonJang/013.find-planet/solve.js new file mode 100644 index 0000000..370e4de --- /dev/null +++ b/Challenge/SoyeonJang/013.find-planet/solve.js @@ -0,0 +1,19 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +const planet = ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']; +const n = prompt('몇 번째 행성이 궁금하신가요?\n(1-8 사이의 숫자를 입력해 주세요.)'); +console.log(planet[n - 1]); \ No newline at end of file diff --git a/Challenge/SoyeonJang/014.if/README.md b/Challenge/SoyeonJang/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Challenge/SoyeonJang/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/014.if/solve.js b/Challenge/SoyeonJang/014.if/solve.js new file mode 100644 index 0000000..a54059c --- /dev/null +++ b/Challenge/SoyeonJang/014.if/solve.js @@ -0,0 +1,25 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +*/ + +const n = prompt('아무 정수나 입력해 주세요!') + +if (n % 3 == 0 && n != 0) { + console.log('짝') +} else { + console.log(n) +} \ No newline at end of file From 62f15f4c82bd9e7be846eec5793b21ff885652b8 Mon Sep 17 00:00:00 2001 From: sooyyoung Date: Mon, 30 May 2022 16:52:23 +0900 Subject: [PATCH 098/308] =?UTF-8?q?Solve=20:=205-9=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sooyoungCho/006.false/README.md | 10 ++++++++ Challenge/sooyoungCho/006.false/solve.js | 13 +++++++++++ Challenge/sooyoungCho/007.variable/README.md | 9 ++++++++ Challenge/sooyoungCho/007.variable/solve.js | 15 ++++++++++++ Challenge/sooyoungCho/008.object/README.md | 16 +++++++++++++ Challenge/sooyoungCho/008.object/solve.js | 19 ++++++++++++++++ Challenge/sooyoungCho/009.concat/README.md | 20 ++++++++++++++++ Challenge/sooyoungCho/009.concat/solve.js | 24 ++++++++++++++++++++ Challenge/sooyoungCho/5.for/README.md | 19 ++++++++++++++++ Challenge/sooyoungCho/5.for/solve.js | 23 +++++++++++++++++++ 10 files changed, 168 insertions(+) create mode 100644 Challenge/sooyoungCho/006.false/README.md create mode 100644 Challenge/sooyoungCho/006.false/solve.js create mode 100644 Challenge/sooyoungCho/007.variable/README.md create mode 100644 Challenge/sooyoungCho/007.variable/solve.js create mode 100644 Challenge/sooyoungCho/008.object/README.md create mode 100644 Challenge/sooyoungCho/008.object/solve.js create mode 100644 Challenge/sooyoungCho/009.concat/README.md create mode 100644 Challenge/sooyoungCho/009.concat/solve.js create mode 100644 Challenge/sooyoungCho/5.for/README.md create mode 100644 Challenge/sooyoungCho/5.for/solve.js diff --git a/Challenge/sooyoungCho/006.false/README.md b/Challenge/sooyoungCho/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/sooyoungCho/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/sooyoungCho/006.false/solve.js b/Challenge/sooyoungCho/006.false/solve.js new file mode 100644 index 0000000..dd1ce65 --- /dev/null +++ b/Challenge/sooyoungCho/006.false/solve.js @@ -0,0 +1,13 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + + +// 정답 : 2번 \ No newline at end of file diff --git a/Challenge/sooyoungCho/007.variable/README.md b/Challenge/sooyoungCho/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/sooyoungCho/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/sooyoungCho/007.variable/solve.js b/Challenge/sooyoungCho/007.variable/solve.js new file mode 100644 index 0000000..b01f167 --- /dev/null +++ b/Challenge/sooyoungCho/007.variable/solve.js @@ -0,0 +1,15 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + + +// 정답 : 3번, 5번 +// let은 예약어, 숫자 X \ No newline at end of file diff --git a/Challenge/sooyoungCho/008.object/README.md b/Challenge/sooyoungCho/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/sooyoungCho/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/008.object/solve.js b/Challenge/sooyoungCho/008.object/solve.js new file mode 100644 index 0000000..337ef09 --- /dev/null +++ b/Challenge/sooyoungCho/008.object/solve.js @@ -0,0 +1,19 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) +*/ + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); + + +// 정답 : 84 \ No newline at end of file diff --git a/Challenge/sooyoungCho/009.concat/README.md b/Challenge/sooyoungCho/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/sooyoungCho/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/009.concat/solve.js b/Challenge/sooyoungCho/009.concat/solve.js new file mode 100644 index 0000000..8ea261e --- /dev/null +++ b/Challenge/sooyoungCho/009.concat/solve.js @@ -0,0 +1,24 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. +*/ + +// 데이터 +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +//빈칸을 채워주세요 +var result = + +console.log(result); + +// 출력 +// 2019/04/26 11:34:27 + + +// 정답 : year.concat('/', month, '/', day, ' ', hour, ':', minute, ':', second); \ No newline at end of file diff --git a/Challenge/sooyoungCho/5.for/README.md b/Challenge/sooyoungCho/5.for/README.md new file mode 100644 index 0000000..6ae955d --- /dev/null +++ b/Challenge/sooyoungCho/5.for/README.md @@ -0,0 +1,19 @@ +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); +``` + +1. 10 +2. 12 +3. 14 +4. 16 diff --git a/Challenge/sooyoungCho/5.for/solve.js b/Challenge/sooyoungCho/5.for/solve.js new file mode 100644 index 0000000..54bcd27 --- /dev/null +++ b/Challenge/sooyoungCho/5.for/solve.js @@ -0,0 +1,23 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + + +// 정답 : 4번 +// for문을 2번 순환한다. i=1 -> a=11, i=3 -> a=14 \ No newline at end of file From 9d9f62a9c3c0f4f9ea37bd37f6da47eafdf06d18 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Mon, 30 May 2022 18:04:23 +0900 Subject: [PATCH 099/308] =?UTF-8?q?Solve=20:=2018~19=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/018.average/README.md | 13 +++++++++++++ Challenge/Songmyeongseok/018.average/solve.js | 18 ++++++++++++++++++ Challenge/Songmyeongseok/019.square/README.md | 3 +++ Challenge/Songmyeongseok/019.square/solve.js | 7 +++++++ 4 files changed, 41 insertions(+) create mode 100644 Challenge/Songmyeongseok/018.average/README.md create mode 100644 Challenge/Songmyeongseok/018.average/solve.js create mode 100644 Challenge/Songmyeongseok/019.square/README.md create mode 100644 Challenge/Songmyeongseok/019.square/solve.js diff --git a/Challenge/Songmyeongseok/018.average/README.md b/Challenge/Songmyeongseok/018.average/README.md new file mode 100644 index 0000000..ca04b62 --- /dev/null +++ b/Challenge/Songmyeongseok/018.average/README.md @@ -0,0 +1,13 @@ +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` diff --git a/Challenge/Songmyeongseok/018.average/solve.js b/Challenge/Songmyeongseok/018.average/solve.js new file mode 100644 index 0000000..34042b4 --- /dev/null +++ b/Challenge/Songmyeongseok/018.average/solve.js @@ -0,0 +1,18 @@ +/* +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +**입출력** + +입력 : 20 30 40 +출력 : 30 + +*/ + +function average(x,y,z){ + return Math.floor((x+y+z) / 3) +} \ No newline at end of file diff --git a/Challenge/Songmyeongseok/019.square/README.md b/Challenge/Songmyeongseok/019.square/README.md new file mode 100644 index 0000000..e02a30a --- /dev/null +++ b/Challenge/Songmyeongseok/019.square/README.md @@ -0,0 +1,3 @@ +문제19 : 제곱을 구하자 + +공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. \ No newline at end of file diff --git a/Challenge/Songmyeongseok/019.square/solve.js b/Challenge/Songmyeongseok/019.square/solve.js new file mode 100644 index 0000000..83a1e44 --- /dev/null +++ b/Challenge/Songmyeongseok/019.square/solve.js @@ -0,0 +1,7 @@ +// 문제19 : 제곱을 구하자 + +// 공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. + +function square(x,y){ + return x**y +} \ No newline at end of file From 08a6664a878cf9135bd83665862e58aa73283936 Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Mon, 30 May 2022 23:02:08 +0900 Subject: [PATCH 100/308] =?UTF-8?q?Solve=20:=2026=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihoonChae/026.planets_2/README.md | 4 ++++ Challenge/JihoonChae/026.planets_2/solve.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 Challenge/JihoonChae/026.planets_2/README.md create mode 100644 Challenge/JihoonChae/026.planets_2/solve.js diff --git a/Challenge/JihoonChae/026.planets_2/README.md b/Challenge/JihoonChae/026.planets_2/README.md new file mode 100644 index 0000000..47a5079 --- /dev/null +++ b/Challenge/JihoonChae/026.planets_2/README.md @@ -0,0 +1,4 @@ +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +**행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램**을 만들어 주세요. \ No newline at end of file diff --git a/Challenge/JihoonChae/026.planets_2/solve.js b/Challenge/JihoonChae/026.planets_2/solve.js new file mode 100644 index 0000000..16f03fb --- /dev/null +++ b/Challenge/JihoonChae/026.planets_2/solve.js @@ -0,0 +1,19 @@ +// 우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +// 이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +// **행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램**을 만들어 주세요. + +const planets = { + '수성' : 'Mercury', + '금성' : 'Venus', + '지구' : 'Earth', + '화성' : 'Mars', + '목성' : 'Jupiter', + '토성' : 'Saturn', + '천왕성' : 'Uranus', + '해왕성' : 'Neptune', +}; + +const name = prompt("행성의 이름은?"); + +console.log(planets[name]); \ No newline at end of file From 66b80d51e5c729813102030e43ef92f66b574a6c Mon Sep 17 00:00:00 2001 From: chooing Date: Mon, 30 May 2022 23:03:03 +0900 Subject: [PATCH 101/308] =?UTF-8?q?Solve=20:=20005=20-=20007=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihyeChoo/005.for/README.md | 20 ++++++++++++++++++++ Challenge/JihyeChoo/005.for/solve.js | 19 +++++++++++++++++++ Challenge/JihyeChoo/006.false/README.md | 10 ++++++++++ Challenge/JihyeChoo/006.false/solve.js | 20 ++++++++++++++++++++ Challenge/JihyeChoo/007.variable/README.md | 9 +++++++++ Challenge/JihyeChoo/007.variable/solve.js | 14 ++++++++++++++ 6 files changed, 92 insertions(+) create mode 100644 Challenge/JihyeChoo/005.for/README.md create mode 100644 Challenge/JihyeChoo/005.for/solve.js create mode 100644 Challenge/JihyeChoo/006.false/README.md create mode 100644 Challenge/JihyeChoo/006.false/solve.js create mode 100644 Challenge/JihyeChoo/007.variable/README.md create mode 100644 Challenge/JihyeChoo/007.variable/solve.js diff --git a/Challenge/JihyeChoo/005.for/README.md b/Challenge/JihyeChoo/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/JihyeChoo/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/JihyeChoo/005.for/solve.js b/Challenge/JihyeChoo/005.for/solve.js new file mode 100644 index 0000000..680df71 --- /dev/null +++ b/Challenge/JihyeChoo/005.for/solve.js @@ -0,0 +1,19 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 <---- a=14 b=2 14+2 =16 diff --git a/Challenge/JihyeChoo/006.false/README.md b/Challenge/JihyeChoo/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/JihyeChoo/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/JihyeChoo/006.false/solve.js b/Challenge/JihyeChoo/006.false/solve.js new file mode 100644 index 0000000..93e4901 --- /dev/null +++ b/Challenge/JihyeChoo/006.false/solve.js @@ -0,0 +1,20 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 <-------- true +// 3) "" +// 4) 0 +// 5) undefined + + +// false로 취급하는 것 +// NaN +// null +// false +// 0 +// "" '' : 빈 문자열 +// undifined + diff --git a/Challenge/JihyeChoo/007.variable/README.md b/Challenge/JihyeChoo/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/JihyeChoo/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/JihyeChoo/007.variable/solve.js b/Challenge/JihyeChoo/007.variable/solve.js new file mode 100644 index 0000000..faa0705 --- /dev/null +++ b/Challenge/JihyeChoo/007.variable/solve.js @@ -0,0 +1,14 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let <------ +4) _age +5) 1age <------ +*/ + +// 3) let은 js의 예약어로 변수명으로 사용할 수 없다. +// 5) 변수명은 숫자가 맨 처음으로 나올 수 없다. \ No newline at end of file From b0906f8f99f9ab8fbb751e6f357b0da648d793a0 Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Mon, 30 May 2022 23:21:16 +0900 Subject: [PATCH 102/308] =?UTF-8?q?Feat=20:=20026~029=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/026.planet_2/README.md | 6 +++++ Problems/026.planet_2/solve.js | 4 ++++ Problems/027.object/README.md | 14 +++++++++++ Problems/027.object/solve.js | 13 +++++++++++ Problems/028.2-gram/README.md | 23 +++++++++++++++++++ Problems/028.2-gram/solve.js | 23 +++++++++++++++++++ .../README.md" | 5 ++++ .../solve.js" | 5 ++++ 8 files changed, 93 insertions(+) create mode 100644 Problems/026.planet_2/README.md create mode 100644 Problems/026.planet_2/solve.js create mode 100644 Problems/027.object/README.md create mode 100644 Problems/027.object/solve.js create mode 100644 Problems/028.2-gram/README.md create mode 100644 Problems/028.2-gram/solve.js create mode 100644 "Problems/029.\353\214\200\353\254\270\354\236\220/README.md" create mode 100644 "Problems/029.\353\214\200\353\254\270\354\236\220/solve.js" diff --git a/Problems/026.planet_2/README.md b/Problems/026.planet_2/README.md new file mode 100644 index 0000000..678e82a --- /dev/null +++ b/Problems/026.planet_2/README.md @@ -0,0 +1,6 @@ +# 문제26 : 행성 문제2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git a/Problems/026.planet_2/solve.js b/Problems/026.planet_2/solve.js new file mode 100644 index 0000000..c13a28d --- /dev/null +++ b/Problems/026.planet_2/solve.js @@ -0,0 +1,4 @@ +// 문제26 : 행성 문제2 + +// 우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +// 이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. diff --git a/Problems/027.object/README.md b/Problems/027.object/README.md new file mode 100644 index 0000000..9b83945 --- /dev/null +++ b/Problems/027.object/README.md @@ -0,0 +1,14 @@ +# 문제27 : 객체 만들기 + +첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + +```jsx +**입력** +Yujin Hyewon +70 100 + +**출력** +{'Yujin': 70, 'Hyewon': 100} +``` \ No newline at end of file diff --git a/Problems/027.object/solve.js b/Problems/027.object/solve.js new file mode 100644 index 0000000..de057f9 --- /dev/null +++ b/Problems/027.object/solve.js @@ -0,0 +1,13 @@ +// # 문제27 : 객체 만들기 + +// 첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +// 두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + + +**입력** +Yujin Hyewon +70 100 + +**출력** +{'Yujin': 70, 'Hyewon': 100} diff --git a/Problems/028.2-gram/README.md b/Problems/028.2-gram/README.md new file mode 100644 index 0000000..3a0dfe1 --- /dev/null +++ b/Problems/028.2-gram/README.md @@ -0,0 +1,23 @@ +# 문제28 : 2-gram + +**2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +```jsx +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t +``` + +입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git a/Problems/028.2-gram/solve.js b/Problems/028.2-gram/solve.js new file mode 100644 index 0000000..da30893 --- /dev/null +++ b/Problems/028.2-gram/solve.js @@ -0,0 +1,23 @@ +// # 문제28 : 2-gram + +// **2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +// 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + + +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t + + +// 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git "a/Problems/029.\353\214\200\353\254\270\354\236\220/README.md" "b/Problems/029.\353\214\200\353\254\270\354\236\220/README.md" new file mode 100644 index 0000000..287a235 --- /dev/null +++ "b/Problems/029.\353\214\200\353\254\270\354\236\220/README.md" @@ -0,0 +1,5 @@ +# 문제29 : 대문자만 지나가세요 + +진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git "a/Problems/029.\353\214\200\353\254\270\354\236\220/solve.js" "b/Problems/029.\353\214\200\353\254\270\354\236\220/solve.js" new file mode 100644 index 0000000..865f652 --- /dev/null +++ "b/Problems/029.\353\214\200\353\254\270\354\236\220/solve.js" @@ -0,0 +1,5 @@ +// 문제29 : 대문자만 지나가세요 + +// 진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +// 알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. \ No newline at end of file From cbc13e291b7cba3170560ebe33ee02cab51ad04d Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Mon, 30 May 2022 23:36:43 +0900 Subject: [PATCH 103/308] =?UTF-8?q?Feat=20:=20026~029=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/027.object/solve.js | 10 +++++----- Problems/028.2-gram/solve.js | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Problems/027.object/solve.js b/Problems/027.object/solve.js index de057f9..aadfa27 100644 --- a/Problems/027.object/solve.js +++ b/Problems/027.object/solve.js @@ -5,9 +5,9 @@ // 두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. -**입력** -Yujin Hyewon -70 100 +// **입력** +// Yujin Hyewon +// 70 100 -**출력** -{'Yujin': 70, 'Hyewon': 100} +// **출력** +// {'Yujin': 70, 'Hyewon': 100} diff --git a/Problems/028.2-gram/solve.js b/Problems/028.2-gram/solve.js index da30893..31d0d5c 100644 --- a/Problems/028.2-gram/solve.js +++ b/Problems/028.2-gram/solve.js @@ -5,19 +5,19 @@ // 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. -**입력** -Javascript +// **입력** +// Javascript -**출력** -J a -a v -v a -a s -s c -c r -r i -i p -p t +// **출력** +// J a +// a v +// v a +// a s +// s c +// c r +// r i +// i p +// p t // 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file From 40d217a11f6ececb6aa15233d75d1ce15391d697 Mon Sep 17 00:00:00 2001 From: usablepaper Date: Tue, 31 May 2022 00:00:44 +0900 Subject: [PATCH 104/308] =?UTF-8?q?Solve=202=EB=B2=88=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Hyeonji/2.arryMethd/solve.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Challenge/Hyeonji/2.arryMethd/solve.js b/Challenge/Hyeonji/2.arryMethd/solve.js index 4095544..4d065c5 100644 --- a/Challenge/Hyeonji/2.arryMethd/solve.js +++ b/Challenge/Hyeonji/2.arryMethd/solve.js @@ -2,10 +2,10 @@ // 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. -데이터 +// 데이터 var arr = [200, 100, 300]; //pass +arr.splice(2, 0, 1000); console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file +// 출력 +// [200, 100, 10000, 300] From e3ef923f611ff20416b4800e8d59dff54b04e4ff Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Tue, 31 May 2022 01:34:04 +0900 Subject: [PATCH 105/308] Solve: 008, 009 --- Challenge/HeelaeLim/008.object/README.md | 16 +++++++++++++ Challenge/HeelaeLim/008.object/solve.js | 18 ++++++++++++++ Challenge/HeelaeLim/009.concat/README.md | 20 ++++++++++++++++ Challenge/HeelaeLim/009.concat/solve.js | 30 ++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 Challenge/HeelaeLim/008.object/README.md create mode 100644 Challenge/HeelaeLim/008.object/solve.js create mode 100644 Challenge/HeelaeLim/009.concat/README.md create mode 100644 Challenge/HeelaeLim/009.concat/solve.js diff --git a/Challenge/HeelaeLim/008.object/README.md b/Challenge/HeelaeLim/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/HeelaeLim/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/008.object/solve.js b/Challenge/HeelaeLim/008.object/solve.js new file mode 100644 index 0000000..3bc82ff --- /dev/null +++ b/Challenge/HeelaeLim/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); + +뒤에오는 weight 값인 84를 출력한다. +*/ \ No newline at end of file diff --git a/Challenge/HeelaeLim/009.concat/README.md b/Challenge/HeelaeLim/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/HeelaeLim/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/009.concat/solve.js b/Challenge/HeelaeLim/009.concat/solve.js new file mode 100644 index 0000000..f39e267 --- /dev/null +++ b/Challenge/HeelaeLim/009.concat/solve.js @@ -0,0 +1,30 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ + +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = `${year}/${month}/${day} ${hour}:${minute}:${second}` +console.log(result); \ No newline at end of file From 5f228eb63741587562f1229a3cc63754360590d7 Mon Sep 17 00:00:00 2001 From: subincdev Date: Tue, 31 May 2022 09:25:17 +0900 Subject: [PATCH 106/308] =?UTF-8?q?Solve:=2011=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/011.for/solve.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Problems/011.for/solve.js b/Problems/011.for/solve.js index 29d575c..fd4d891 100644 --- a/Problems/011.for/solve.js +++ b/Problems/011.for/solve.js @@ -8,4 +8,10 @@ let s = 0; //pass console.log(s); -*/ \ No newline at end of file +*/ + +let s = 0; +for (let i = 1; i <= 100; i++) { + s += i; +} +console.log(s); From 9ef45ebff894ec35da18ada0e3199d5dd329e3f9 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Tue, 31 May 2022 11:27:03 +0900 Subject: [PATCH 107/308] =?UTF-8?q?Solve:=204=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/004.type(2)/README.md | 8 ++++++++ Challenge/YejiKim/004.type(2)/solve.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Challenge/YejiKim/004.type(2)/README.md create mode 100644 Challenge/YejiKim/004.type(2)/solve.js diff --git a/Challenge/YejiKim/004.type(2)/README.md b/Challenge/YejiKim/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/YejiKim/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/YejiKim/004.type(2)/solve.js b/Challenge/YejiKim/004.type(2)/solve.js new file mode 100644 index 0000000..aa90a32 --- /dev/null +++ b/Challenge/YejiKim/004.type(2)/solve.js @@ -0,0 +1,12 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답. 2번입니다. +// 출력값으으로 number 이 출력됩니다. +// boolean값은 true, false 두가지 값을 가집니다. From 3628061e49f66748d87c68a20287e81f8186c888 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Tue, 31 May 2022 11:33:17 +0900 Subject: [PATCH 108/308] =?UTF-8?q?Solve:=205=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/005.for/README.md | 20 ++++++++++++++++++++ Challenge/YejiKim/005.for/solve.js | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 Challenge/YejiKim/005.for/README.md create mode 100644 Challenge/YejiKim/005.for/solve.js diff --git a/Challenge/YejiKim/005.for/README.md b/Challenge/YejiKim/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/YejiKim/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/YejiKim/005.for/solve.js b/Challenge/YejiKim/005.for/solve.js new file mode 100644 index 0000000..d946c0f --- /dev/null +++ b/Challenge/YejiKim/005.for/solve.js @@ -0,0 +1,24 @@ +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx; +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + +// 정답: 4번 +// i = 1 일때, a = 11 +// i = 3 일때, a = 14 +// i = 5 일때 i < 5 조건에 해당하지 않으므로 for문을 탈출한다. +// 14 + 2 = 16 From 8853c14933a3263995f17ee78508305704b2ff61 Mon Sep 17 00:00:00 2001 From: plutoin Date: Tue, 31 May 2022 11:45:19 +0900 Subject: [PATCH 109/308] =?UTF-8?q?Solve:=2015-17=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../015.template _literals/README.md | 13 +++++++++++ .../015.template _literals/solve.js | 17 ++++++++++++++ .../README.md" | 10 +++++++++ .../solve.js" | 22 +++++++++++++++++++ Challenge/SoyeonJang/017.limit/README.md | 7 ++++++ Challenge/SoyeonJang/017.limit/solve.js | 17 ++++++++++++++ 6 files changed, 86 insertions(+) create mode 100644 Challenge/SoyeonJang/015.template _literals/README.md create mode 100644 Challenge/SoyeonJang/015.template _literals/solve.js create mode 100644 "Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/solve.js" create mode 100644 Challenge/SoyeonJang/017.limit/README.md create mode 100644 Challenge/SoyeonJang/017.limit/solve.js diff --git a/Challenge/SoyeonJang/015.template _literals/README.md b/Challenge/SoyeonJang/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/SoyeonJang/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/015.template _literals/solve.js b/Challenge/SoyeonJang/015.template _literals/solve.js new file mode 100644 index 0000000..cc87bd0 --- /dev/null +++ b/Challenge/SoyeonJang/015.template _literals/solve.js @@ -0,0 +1,17 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ + +const name = prompt('이름을 입력해 자기소개를 해 보세요') + +console.log(`안녕하세요 저는 ${name}입니다.`) \ No newline at end of file diff --git "a/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..ba35dc4 --- /dev/null +++ "b/Challenge/SoyeonJang/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,22 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +*/ + +const sentence = prompt('문장을 입력해 주세요!\n거꾸로 바꾸어 드립니다') + +// 1. 메서드 체이닝 +console.log(sentence.split('').reverse().join('')) + +// 2. 함수 호출 +function reverse(str) { + let reverse = str.split('').reverse().join('') + return reverse +} + +console.log(reverse(`${sentence}`)) \ No newline at end of file diff --git a/Challenge/SoyeonJang/017.limit/README.md b/Challenge/SoyeonJang/017.limit/README.md new file mode 100644 index 0000000..b364fc6 --- /dev/null +++ b/Challenge/SoyeonJang/017.limit/README.md @@ -0,0 +1,7 @@ +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. diff --git a/Challenge/SoyeonJang/017.limit/solve.js b/Challenge/SoyeonJang/017.limit/solve.js new file mode 100644 index 0000000..3ef7d38 --- /dev/null +++ b/Challenge/SoyeonJang/017.limit/solve.js @@ -0,0 +1,17 @@ +/* +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. +*/ + +const height = prompt('입장 전 키 확인이 있겠습니다. 본인의 키를 입력해 주세요.') + +if (height >= 150) { + console.log('YES') +} else { + console.log('NO') +} \ No newline at end of file From ee46654e67f84d165a734a18a5c20e1bb250b50c Mon Sep 17 00:00:00 2001 From: Dayhun Date: Tue, 31 May 2022 11:45:54 +0900 Subject: [PATCH 110/308] =?UTF-8?q?Solve:=204=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/DahyunLim/4.type(2)/README.md | 8 ++++++++ Challenge/DahyunLim/4.type(2)/solve.js | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 Challenge/DahyunLim/4.type(2)/README.md create mode 100644 Challenge/DahyunLim/4.type(2)/solve.js diff --git a/Challenge/DahyunLim/4.type(2)/README.md b/Challenge/DahyunLim/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/DahyunLim/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/DahyunLim/4.type(2)/solve.js b/Challenge/DahyunLim/4.type(2)/solve.js new file mode 100644 index 0000000..46b173f --- /dev/null +++ b/Challenge/DahyunLim/4.type(2)/solve.js @@ -0,0 +1,11 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답 2번 +// a는 number From 905e2a5004eca55b09f136be916438ac4471856b Mon Sep 17 00:00:00 2001 From: subincdev Date: Tue, 31 May 2022 11:46:47 +0900 Subject: [PATCH 111/308] =?UTF-8?q?Solve:=2012=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/012.class/solve.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Problems/012.class/solve.js b/Problems/012.class/solve.js index 31baa29..ebf42bb 100644 --- a/Problems/012.class/solve.js +++ b/Problems/012.class/solve.js @@ -14,4 +14,19 @@ x.attack(); **출력** 545 210 10 파이어볼 -*/ \ No newline at end of file +*/ + +class Wizard { + constructor(health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + attack() { + console.log("파이어볼"); + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); From d488b41e92d666e14f3b49191ba6cfaa7914c293 Mon Sep 17 00:00:00 2001 From: subincdev Date: Tue, 31 May 2022 11:47:01 +0900 Subject: [PATCH 112/308] =?UTF-8?q?Solve:=2013=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/013.find-planet/solve.js | 102 +++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/Problems/013.find-planet/solve.js b/Problems/013.find-planet/solve.js index 896ee8e..937f862 100644 --- a/Problems/013.find-planet/solve.js +++ b/Problems/013.find-planet/solve.js @@ -12,4 +12,104 @@ 입력 : 1 출력 : 수성 -*/ \ No newline at end of file +*/ + +// const arr = [ +// "수성", +// "금성", +// "지구", +// "화성", +// "목성", +// "토성", +// "천왕성", +// "해왕성", +// ]; +// 1트 +// const answer = prompt("숫자를 입력해주세요"); +// if (answer > 8 || answer < 1) { +// alert("다시 입력해주세요"); +// prompt("숫자를 입력해주세요"); +// console.log(arr[answer - 1]); +// } else { +// console.log(arr[answer - 1]); +// } + +// 오류 +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if ((answer > 8 || answer < 1) && typeof answer !== "number") { +// console.log(typeof answer); +// // alert("1과 8사이 숫자로 다시 입력해주세요"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// function galaxy() { +// const answer = prompt("1부터 8사이의 숫자를 입력해주세요"); + +// if (Number(answer) > 8 || Number(answer) < 1) { +// alert("다시 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// prompt 는 사용자의 입력값을 모두 문자열로 처리해줌 +// 1. 숫자로 바꾸고 NaN인지 확인 +// NaN == NaN false라서 안됨 +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if (Number(answer) == NaN) { +// return galaxy(); +// } else if (Number(answer) > 8 || Number(answer) < 1) { +// alert("1-8 사이의 수를 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// 정답 +const arr = [ + "수성", + "금성", + "지구", + "화성", + "목성", + "토성", + "천왕성", + "해왕성", +]; + +//1. isNaN +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if (isNaN(Number(answer))) { +// alert("숫자만 입력이 가능합니다."); +// return galaxy(); +// } else if (Number(answer) > 8 || Number(answer) < 1) { +// alert("1-8 사이의 수를 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); +// 2. 정규식 사용 +function galaxy() { + const regExp = /[1-8]/g; + const answer = prompt("숫자를 입력해주세요"); + if (!regExp.test(Number(answer))) { + alert("1-8사이의 숫자만 입력이 가능합니다."); + return galaxy(); + } + console.log(arr[answer - 1]); +} + +galaxy(); From 87b894c29e0b385aee9e8916e883b35539778482 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Tue, 31 May 2022 14:40:12 +0900 Subject: [PATCH 113/308] Solve: 010, 011 --- Challenge/HeelaeLim/010.star/README.md | 18 +++++++++++++++++ Challenge/HeelaeLim/010.star/solve.js | 28 ++++++++++++++++++++++++++ Challenge/HeelaeLim/011.for/README.md | 11 ++++++++++ Challenge/HeelaeLim/011.for/solve.js | 19 +++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 Challenge/HeelaeLim/010.star/README.md create mode 100644 Challenge/HeelaeLim/010.star/solve.js create mode 100644 Challenge/HeelaeLim/011.for/README.md create mode 100644 Challenge/HeelaeLim/011.for/solve.js diff --git a/Challenge/HeelaeLim/010.star/README.md b/Challenge/HeelaeLim/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/HeelaeLim/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/010.star/solve.js b/Challenge/HeelaeLim/010.star/solve.js new file mode 100644 index 0000000..fc91bf0 --- /dev/null +++ b/Challenge/HeelaeLim/010.star/solve.js @@ -0,0 +1,28 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ + +function star(num){ + for(let i=0; i 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/011.for/solve.js b/Challenge/HeelaeLim/011.for/solve.js new file mode 100644 index 0000000..5e2ac09 --- /dev/null +++ b/Challenge/HeelaeLim/011.for/solve.js @@ -0,0 +1,19 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass + +console.log(s); +*/ + +let s = 0; + +for(let i = 1; i < 101; i++){ + s +=i; +} + +console.log(s); \ No newline at end of file From 33264b4699a54e7e151a4d6dfa89b237cb59d417 Mon Sep 17 00:00:00 2001 From: unidagit Date: Tue, 31 May 2022 20:36:47 +0900 Subject: [PATCH 114/308] =?UTF-8?q?Solve:=208=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/008.object/README.md | 18 ++++++++++++++++++ Challenge/YunheeJo/008.object/solve.js | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Challenge/YunheeJo/008.object/README.md create mode 100644 Challenge/YunheeJo/008.object/solve.js diff --git a/Challenge/YunheeJo/008.object/README.md b/Challenge/YunheeJo/008.object/README.md new file mode 100644 index 0000000..6a10def --- /dev/null +++ b/Challenge/YunheeJo/008.object/README.md @@ -0,0 +1,18 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + height: 180, + weight: 78, + weight: 84, + temperature: 36, + eyesight: 1, +}; + +console.log(d['weight']); +``` + +답은 84입니다 diff --git a/Challenge/YunheeJo/008.object/solve.js b/Challenge/YunheeJo/008.object/solve.js new file mode 100644 index 0000000..8b6701b --- /dev/null +++ b/Challenge/YunheeJo/008.object/solve.js @@ -0,0 +1,19 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + + +답은 84 \ No newline at end of file From b567efcd14c9d9d38439a7bb61f7acbf16bb69a6 Mon Sep 17 00:00:00 2001 From: leehyeonseop Date: Tue, 31 May 2022 21:07:23 +0900 Subject: [PATCH 115/308] =?UTF-8?q?Solve:=205-10=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HyeonseopLee/005.for/README.md | 20 +++++++++++++ Challenge/HyeonseopLee/005.for/solve.js | 21 ++++++++++++++ Challenge/HyeonseopLee/006.false/README.md | 10 +++++++ Challenge/HyeonseopLee/006.false/solve.js | 10 +++++++ Challenge/HyeonseopLee/007.variable/README.md | 9 ++++++ Challenge/HyeonseopLee/007.variable/solve.js | 11 +++++++ Challenge/HyeonseopLee/008.object/README.md | 16 ++++++++++ Challenge/HyeonseopLee/008.object/solve.js | 16 ++++++++++ Challenge/HyeonseopLee/009.concat/README.md | 20 +++++++++++++ Challenge/HyeonseopLee/009.concat/solve.js | 20 +++++++++++++ Challenge/HyeonseopLee/010.star/README.md | 18 ++++++++++++ Challenge/HyeonseopLee/010.star/solve.js | 29 +++++++++++++++++++ 12 files changed, 200 insertions(+) create mode 100644 Challenge/HyeonseopLee/005.for/README.md create mode 100644 Challenge/HyeonseopLee/005.for/solve.js create mode 100644 Challenge/HyeonseopLee/006.false/README.md create mode 100644 Challenge/HyeonseopLee/006.false/solve.js create mode 100644 Challenge/HyeonseopLee/007.variable/README.md create mode 100644 Challenge/HyeonseopLee/007.variable/solve.js create mode 100644 Challenge/HyeonseopLee/008.object/README.md create mode 100644 Challenge/HyeonseopLee/008.object/solve.js create mode 100644 Challenge/HyeonseopLee/009.concat/README.md create mode 100644 Challenge/HyeonseopLee/009.concat/solve.js create mode 100644 Challenge/HyeonseopLee/010.star/README.md create mode 100644 Challenge/HyeonseopLee/010.star/solve.js diff --git a/Challenge/HyeonseopLee/005.for/README.md b/Challenge/HyeonseopLee/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/HyeonseopLee/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/HyeonseopLee/005.for/solve.js b/Challenge/HyeonseopLee/005.for/solve.js new file mode 100644 index 0000000..8994db5 --- /dev/null +++ b/Challenge/HyeonseopLee/005.for/solve.js @@ -0,0 +1,21 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + +// 10 + 1 + 3 + 2 => 4번 + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 diff --git a/Challenge/HyeonseopLee/006.false/README.md b/Challenge/HyeonseopLee/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/HyeonseopLee/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/HyeonseopLee/006.false/solve.js b/Challenge/HyeonseopLee/006.false/solve.js new file mode 100644 index 0000000..ea6d7f0 --- /dev/null +++ b/Challenge/HyeonseopLee/006.false/solve.js @@ -0,0 +1,10 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. +// 2번 +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined \ No newline at end of file diff --git a/Challenge/HyeonseopLee/007.variable/README.md b/Challenge/HyeonseopLee/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/HyeonseopLee/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/HyeonseopLee/007.variable/solve.js b/Challenge/HyeonseopLee/007.variable/solve.js new file mode 100644 index 0000000..71be327 --- /dev/null +++ b/Challenge/HyeonseopLee/007.variable/solve.js @@ -0,0 +1,11 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. +// 3번 5번 +1) age +2) Age +3) let +4) _age +5) 1age +*/ \ No newline at end of file diff --git a/Challenge/HyeonseopLee/008.object/README.md b/Challenge/HyeonseopLee/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/HyeonseopLee/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/HyeonseopLee/008.object/solve.js b/Challenge/HyeonseopLee/008.object/solve.js new file mode 100644 index 0000000..dd2f59a --- /dev/null +++ b/Challenge/HyeonseopLee/008.object/solve.js @@ -0,0 +1,16 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. // 84 +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ \ No newline at end of file diff --git a/Challenge/HyeonseopLee/009.concat/README.md b/Challenge/HyeonseopLee/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/HyeonseopLee/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/HyeonseopLee/009.concat/solve.js b/Challenge/HyeonseopLee/009.concat/solve.js new file mode 100644 index 0000000..b85a19b --- /dev/null +++ b/Challenge/HyeonseopLee/009.concat/solve.js @@ -0,0 +1,20 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ \ No newline at end of file diff --git a/Challenge/HyeonseopLee/010.star/README.md b/Challenge/HyeonseopLee/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/HyeonseopLee/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/HyeonseopLee/010.star/solve.js b/Challenge/HyeonseopLee/010.star/solve.js new file mode 100644 index 0000000..471146f --- /dev/null +++ b/Challenge/HyeonseopLee/010.star/solve.js @@ -0,0 +1,29 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +let star = function(n) { + for(let i=1; i <= n; i++) { + console.log(' '.repeat(n-i) + '*'.repeat(2*i - 1)) + } +} + +2n - 1 => 1, 3, 5, 7 +만약 2층이면 1층에서 1칸 2층에서 0칸 +만약 3층이면 1층에서 2칸 2층에서 1칸 +star(5) + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ \ No newline at end of file From d4743bdd69ad8a8d2218ff68aa1a73d40c4b866e Mon Sep 17 00:00:00 2001 From: Hyebin-Woo Date: Tue, 31 May 2022 21:42:03 +0900 Subject: [PATCH 116/308] =?UTF-8?q?Solve=20:=201=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/hyebinWoo/1.arry/solve.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Challenge/hyebinWoo/1.arry/solve.js b/Challenge/hyebinWoo/1.arry/solve.js index 7ffd8bd..fa8b1dc 100644 --- a/Challenge/hyebinWoo/1.arry/solve.js +++ b/Challenge/hyebinWoo/1.arry/solve.js @@ -1,4 +1,9 @@ // # 문제1 : 배열의 삭제 // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); + +console.log(nums); From 04b9d9b1ffef39ba22da95c88f82140c7bdfcddf Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Tue, 31 May 2022 22:47:53 +0900 Subject: [PATCH 117/308] =?UTF-8?q?Solve=20:=2026~29=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Songmyeongseok/026.planet_2/README.md | 6 ++++ .../Songmyeongseok/026.planet_2/solve.js | 19 ++++++++++++ Challenge/Songmyeongseok/028.2-gram/README.md | 23 +++++++++++++++ Challenge/Songmyeongseok/028.2-gram/solve.js | 29 +++++++++++++++++++ .../README.md" | 5 ++++ .../solve.js" | 13 +++++++++ 6 files changed, 95 insertions(+) create mode 100644 Challenge/Songmyeongseok/026.planet_2/README.md create mode 100644 Challenge/Songmyeongseok/026.planet_2/solve.js create mode 100644 Challenge/Songmyeongseok/028.2-gram/README.md create mode 100644 Challenge/Songmyeongseok/028.2-gram/solve.js create mode 100644 "Challenge/Songmyeongseok/029.\353\214\200\353\254\270\354\236\220/README.md" create mode 100644 "Challenge/Songmyeongseok/029.\353\214\200\353\254\270\354\236\220/solve.js" diff --git a/Challenge/Songmyeongseok/026.planet_2/README.md b/Challenge/Songmyeongseok/026.planet_2/README.md new file mode 100644 index 0000000..678e82a --- /dev/null +++ b/Challenge/Songmyeongseok/026.planet_2/README.md @@ -0,0 +1,6 @@ +# 문제26 : 행성 문제2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git a/Challenge/Songmyeongseok/026.planet_2/solve.js b/Challenge/Songmyeongseok/026.planet_2/solve.js new file mode 100644 index 0000000..d93ec01 --- /dev/null +++ b/Challenge/Songmyeongseok/026.planet_2/solve.js @@ -0,0 +1,19 @@ +// 문제26 : 행성 문제2 + +// 우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +// 이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +const planets = { + '수성' : 'Mercury', + '금성' : 'Venus', + '지구' : 'Earth', + '화성' : 'Mars', + '목성' : 'Jupiter', + '토성' : 'Saturn', + '천왕성' : 'Uranus', + '해왕성' : 'Neptune', +}; + +function planet(x){ + return console.log(planets[x]) +} \ No newline at end of file diff --git a/Challenge/Songmyeongseok/028.2-gram/README.md b/Challenge/Songmyeongseok/028.2-gram/README.md new file mode 100644 index 0000000..3a0dfe1 --- /dev/null +++ b/Challenge/Songmyeongseok/028.2-gram/README.md @@ -0,0 +1,23 @@ +# 문제28 : 2-gram + +**2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +```jsx +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t +``` + +입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git a/Challenge/Songmyeongseok/028.2-gram/solve.js b/Challenge/Songmyeongseok/028.2-gram/solve.js new file mode 100644 index 0000000..1086992 --- /dev/null +++ b/Challenge/Songmyeongseok/028.2-gram/solve.js @@ -0,0 +1,29 @@ +// # 문제28 : 2-gram + +// **2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +// 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + + +// **입력** +// Javascript + +// **출력** +// J a +// a v +// v a +// a s +// s c +// c r +// r i +// i p +// p t + + +// 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. + +function gram(x){ + for(let i=0; i Date: Tue, 31 May 2022 23:30:07 +0900 Subject: [PATCH 118/308] =?UTF-8?q?Slove=20:=20014~018=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 0 bytes Challenge/seyeongLee/014.if/README.md | 17 ++++++++++++ Challenge/seyeongLee/014.if/solve.js | 25 ++++++++++++++++++ .../015.template _literals/README.md | 13 +++++++++ .../015.template _literals/solve.js | 16 +++++++++++ Challenge/seyeongLee/016.reverse/README.md | 10 +++++++ Challenge/seyeongLee/016.reverse/solve.js | 12 +++++++++ Challenge/seyeongLee/017.limit/README.md | 7 +++++ Challenge/seyeongLee/017.limit/solve.js | 16 +++++++++++ Challenge/seyeongLee/018.average/README.md | 13 +++++++++ Challenge/seyeongLee/018.average/solve.js | 23 ++++++++++++++++ 11 files changed, 152 insertions(+) delete mode 100644 .DS_Store create mode 100644 Challenge/seyeongLee/014.if/README.md create mode 100644 Challenge/seyeongLee/014.if/solve.js create mode 100644 Challenge/seyeongLee/015.template _literals/README.md create mode 100644 Challenge/seyeongLee/015.template _literals/solve.js create mode 100644 Challenge/seyeongLee/016.reverse/README.md create mode 100644 Challenge/seyeongLee/016.reverse/solve.js create mode 100644 Challenge/seyeongLee/017.limit/README.md create mode 100644 Challenge/seyeongLee/017.limit/solve.js create mode 100644 Challenge/seyeongLee/018.average/README.md create mode 100644 Challenge/seyeongLee/018.average/solve.js diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 88799d643674e109c559fbc034af888502d13dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~L2uJA6vv;p01nfn9zcQvQY5ZZ$p}D-)+pF!@#X-+q42seh8=n25w+nr#yGh)ANadUsL%!FZg@lC4+| z4+@^+b*Vn5rApD~37t6tj=;Z7fcLIPeLAFqn(qD;UoqDIrA;s5JT9HpCw8CzNKeY5 zZo=@VSXuRM-M%BGT$3N;BQ=Ygq?y)(Wb&SSZcW*~kO;S|(L?;wk zj*t%rMU|=9KuxQx*1546kiPGadJpIG%`gl%g6;76Vk4Npc#8Jcv#rI#m-in(dAUD2 zF2|MPKMxalF=<=3dM4k{IA740cv6+BI)snoecGWTN~pvyrwVZLE*g4;sNc~@dP5UZ zl!K2mE}%l!*_9BmTSKm0$?R@YN5B#I zp9%2$AwXe`thPq=s{@t30zf^uwV|y){hQlTbQ*eiyxHwR(TF&^3Y z)~HD*p`VO-?30DPp$L2N5P=RS5gB#0Bj5;h39OoKkI(= 150) { + document.write("YES"); +} else { + document.write("NO"); +} \ No newline at end of file diff --git a/Challenge/seyeongLee/018.average/README.md b/Challenge/seyeongLee/018.average/README.md new file mode 100644 index 0000000..ca04b62 --- /dev/null +++ b/Challenge/seyeongLee/018.average/README.md @@ -0,0 +1,13 @@ +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` diff --git a/Challenge/seyeongLee/018.average/solve.js b/Challenge/seyeongLee/018.average/solve.js new file mode 100644 index 0000000..4aa2d0b --- /dev/null +++ b/Challenge/seyeongLee/018.average/solve.js @@ -0,0 +1,23 @@ +/* +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +**입출력** + +입력 : 20 30 40 +출력 : 30 + +*/ +let input = prompt("국어,수학,영어 점수를 순서대로 입력해주세요").split(" "); + +let sum = 0; +let input_len = input.length; + +input.map(x => sum += +x); + +document.write(`국어,수학,영어 점수 : ${input.join(" ")}
`) +document.write(`평균 : ${Math.floor(sum / input_len)}점`); \ No newline at end of file From 13bd6b3d3b6bf73aff4e1e2611fa1a61a9e2c68a Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Tue, 31 May 2022 23:31:19 +0900 Subject: [PATCH 119/308] =?UTF-8?q?Feat=20:=2027=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihoonChae/027.object/README.md | 14 ++++++++++++++ Challenge/JihoonChae/027.object/solve.js | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Challenge/JihoonChae/027.object/README.md create mode 100644 Challenge/JihoonChae/027.object/solve.js diff --git a/Challenge/JihoonChae/027.object/README.md b/Challenge/JihoonChae/027.object/README.md new file mode 100644 index 0000000..9b83945 --- /dev/null +++ b/Challenge/JihoonChae/027.object/README.md @@ -0,0 +1,14 @@ +# 문제27 : 객체 만들기 + +첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + +```jsx +**입력** +Yujin Hyewon +70 100 + +**출력** +{'Yujin': 70, 'Hyewon': 100} +``` \ No newline at end of file diff --git a/Challenge/JihoonChae/027.object/solve.js b/Challenge/JihoonChae/027.object/solve.js new file mode 100644 index 0000000..1eb5e3f --- /dev/null +++ b/Challenge/JihoonChae/027.object/solve.js @@ -0,0 +1,22 @@ +// # 문제27 : 객체 만들기 + +// 첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +// 두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + + +// **입력** +// Yujin Hyewon +// 70 100 + +// **출력** +// {'Yujin': 70, 'Hyewon': 100} + +const name = prompt('당신의 이름은?').split(' ') // 키 값이 들어가는 변수 +const score = prompt('당신의 점수는?').split(' ') // 값들을 넣어주는 변수 +const obj = {} + +for(i=0; i Date: Wed, 1 Jun 2022 00:09:16 +0900 Subject: [PATCH 120/308] =?UTF-8?q?Solve=20:=2028=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihoonChae/028.2-gram/README.md | 23 +++++++++++++++++++ Challenge/JihoonChae/028.2-gram/solve.js | 28 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 Challenge/JihoonChae/028.2-gram/README.md create mode 100644 Challenge/JihoonChae/028.2-gram/solve.js diff --git a/Challenge/JihoonChae/028.2-gram/README.md b/Challenge/JihoonChae/028.2-gram/README.md new file mode 100644 index 0000000..3a0dfe1 --- /dev/null +++ b/Challenge/JihoonChae/028.2-gram/README.md @@ -0,0 +1,23 @@ +# 문제28 : 2-gram + +**2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +```jsx +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t +``` + +입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git a/Challenge/JihoonChae/028.2-gram/solve.js b/Challenge/JihoonChae/028.2-gram/solve.js new file mode 100644 index 0000000..c6d584e --- /dev/null +++ b/Challenge/JihoonChae/028.2-gram/solve.js @@ -0,0 +1,28 @@ +// # 문제28 : 2-gram + +// **2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +// 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + + +// **입력** +// Javascript + +// **출력** +// J a +// a v +// v a +// a s +// s c +// c r +// r i +// i p +// p t + + +// 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. + +const data = prompt('문자를 입력하세요') +for(i=0; i Date: Wed, 1 Jun 2022 08:58:34 +0900 Subject: [PATCH 121/308] Solve: 012,013,014 --- Challenge/HeelaeLim/012.class/README.md | 17 ++++++++++ Challenge/HeelaeLim/012.class/solve.js | 33 +++++++++++++++++++ Challenge/HeelaeLim/013.find-planet/README.md | 15 +++++++++ Challenge/HeelaeLim/013.find-planet/solve.js | 22 +++++++++++++ Challenge/HeelaeLim/014.if/README.md | 17 ++++++++++ Challenge/HeelaeLim/014.if/solve.js | 30 +++++++++++++++++ 6 files changed, 134 insertions(+) create mode 100644 Challenge/HeelaeLim/012.class/README.md create mode 100644 Challenge/HeelaeLim/012.class/solve.js create mode 100644 Challenge/HeelaeLim/013.find-planet/README.md create mode 100644 Challenge/HeelaeLim/013.find-planet/solve.js create mode 100644 Challenge/HeelaeLim/014.if/README.md create mode 100644 Challenge/HeelaeLim/014.if/solve.js diff --git a/Challenge/HeelaeLim/012.class/README.md b/Challenge/HeelaeLim/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/HeelaeLim/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/012.class/solve.js b/Challenge/HeelaeLim/012.class/solve.js new file mode 100644 index 0000000..f68cd53 --- /dev/null +++ b/Challenge/HeelaeLim/012.class/solve.js @@ -0,0 +1,33 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ + +class Wizard { + constructor(health, mana, armor){ + this.health = health; + this.mana = mana; + this.armor = armor; + } + + attack(){ + console.log("파이어볼") + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); \ No newline at end of file diff --git a/Challenge/HeelaeLim/013.find-planet/README.md b/Challenge/HeelaeLim/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/HeelaeLim/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/013.find-planet/solve.js b/Challenge/HeelaeLim/013.find-planet/solve.js new file mode 100644 index 0000000..97021ce --- /dev/null +++ b/Challenge/HeelaeLim/013.find-planet/solve.js @@ -0,0 +1,22 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +function planet_name(num){ + let planet = ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성'] + console.log(planet[num-1]); +} + +planet_name(1); \ No newline at end of file diff --git a/Challenge/HeelaeLim/014.if/README.md b/Challenge/HeelaeLim/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Challenge/HeelaeLim/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/014.if/solve.js b/Challenge/HeelaeLim/014.if/solve.js new file mode 100644 index 0000000..ff56bd2 --- /dev/null +++ b/Challenge/HeelaeLim/014.if/solve.js @@ -0,0 +1,30 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +*/ + +function three(num){ + if(num%3==0){ + console.log('짝'); + } + else{ + console.log(num); + } +} + +three(3); + +three(2); \ No newline at end of file From 01d0e375654da471980167d18ba83e037ff5fb6f Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Wed, 1 Jun 2022 22:59:07 +0900 Subject: [PATCH 122/308] =?UTF-8?q?Solve=20:=2030=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Songmyeongseok/030.find-string/README.md | 15 +++++++++++++++ .../Songmyeongseok/030.find-string/solve.js | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Challenge/Songmyeongseok/030.find-string/README.md create mode 100644 Challenge/Songmyeongseok/030.find-string/solve.js diff --git a/Challenge/Songmyeongseok/030.find-string/README.md b/Challenge/Songmyeongseok/030.find-string/README.md new file mode 100644 index 0000000..5e0fb3a --- /dev/null +++ b/Challenge/Songmyeongseok/030.find-string/README.md @@ -0,0 +1,15 @@ +# 문제30 : 문자열 속 문자 찾기 + +문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +**그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +```jsx +**입력** +pineapple is yummy +apple + +**출력** +4 +``` diff --git a/Challenge/Songmyeongseok/030.find-string/solve.js b/Challenge/Songmyeongseok/030.find-string/solve.js new file mode 100644 index 0000000..41714ca --- /dev/null +++ b/Challenge/Songmyeongseok/030.find-string/solve.js @@ -0,0 +1,19 @@ +// # 문제30 : 문자열 속 문자 찾기 + +// 문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +// 첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +// **그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +// ```jsx +// **입력** +// pineapple is yummy +// apple + +// **출력** +// 4 +// ``` + +function find_string(x,y) { + return x.indexOf(y) +} \ No newline at end of file From c0eb0869812d219bde0b891702de654353e38c01 Mon Sep 17 00:00:00 2001 From: JiSu Kim <85912592+jsk3342@users.noreply.github.com> Date: Thu, 2 Jun 2022 02:55:23 +0900 Subject: [PATCH 123/308] Docs: add readme cover --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a25f907..a65a077 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # JavaScript-Algorithm-Challenge +![알고리즘 첼린지 포스터](https://user-images.githubusercontent.com/85912592/171470808-dffbf327-ebbe-48a4-bc8c-2bce999cfd95.png) + ## 자바스크립트 알고리즘 첼린지! ### 문제 풀기 From 8d7555aff69093cedf178d0c889b362f916893e7 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Thu, 2 Jun 2022 08:39:52 +0900 Subject: [PATCH 124/308] =?UTF-8?q?Solve:=206=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/006.false/README.md | 10 ++++++++++ Challenge/YejiKim/006.false/solve.js | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/YejiKim/006.false/README.md create mode 100644 Challenge/YejiKim/006.false/solve.js diff --git a/Challenge/YejiKim/006.false/README.md b/Challenge/YejiKim/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/YejiKim/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/YejiKim/006.false/solve.js b/Challenge/YejiKim/006.false/solve.js new file mode 100644 index 0000000..0e8ef06 --- /dev/null +++ b/Challenge/YejiKim/006.false/solve.js @@ -0,0 +1,12 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + +//정답 2번 (true) From deb4625ba7608ece411fc0b953edde1b46c106a5 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Thu, 2 Jun 2022 08:41:04 +0900 Subject: [PATCH 125/308] =?UTF-8?q?Solve:=207=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/007.variable/README.md | 9 +++++++++ Challenge/YejiKim/007.variable/solve.js | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Challenge/YejiKim/007.variable/README.md create mode 100644 Challenge/YejiKim/007.variable/solve.js diff --git a/Challenge/YejiKim/007.variable/README.md b/Challenge/YejiKim/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/YejiKim/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/YejiKim/007.variable/solve.js b/Challenge/YejiKim/007.variable/solve.js new file mode 100644 index 0000000..e60470b --- /dev/null +++ b/Challenge/YejiKim/007.variable/solve.js @@ -0,0 +1,15 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +// 정답: 3, 5번 +// let은 예약어이므로 사용이 불가하다. +// 변수명에 숫자는 제일 처음으로 올 수 없다. From c3b4f8c1ce5c2e1843478aed22793bdfa829ce48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=9E=88=EC=A7=95?= Date: Thu, 2 Jun 2022 22:31:03 +0900 Subject: [PATCH 126/308] =?UTF-8?q?Solve:=2002=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HeejinKim/002.arryMethd/README.md | 11 +++++++++++ Challenge/HeejinKim/002.arryMethd/solve.js | 10 ++++++++++ 2 files changed, 21 insertions(+) create mode 100644 Challenge/HeejinKim/002.arryMethd/README.md create mode 100644 Challenge/HeejinKim/002.arryMethd/solve.js diff --git a/Challenge/HeejinKim/002.arryMethd/README.md b/Challenge/HeejinKim/002.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/HeejinKim/002.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/HeejinKim/002.arryMethd/solve.js b/Challenge/HeejinKim/002.arryMethd/solve.js new file mode 100644 index 0000000..1af1be9 --- /dev/null +++ b/Challenge/HeejinKim/002.arryMethd/solve.js @@ -0,0 +1,10 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터; +var arr = [200, 100, 300]; +arr.splice(2, 0, 10000); +console.log(arr); + +출력[(200, 100, 10000, 300)]; From 46afe862ede60e6b4690e8178ff0653ab74bacd2 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Thu, 2 Jun 2022 22:39:31 +0900 Subject: [PATCH 127/308] =?UTF-8?q?Solve=20:=20025~030=20=EB=AE=A8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seyeongLee/025.circle-area/README.md | 8 +++++ Challenge/seyeongLee/025.circle-area/solve.js | 14 +++++++++ Challenge/seyeongLee/026.planet_2/README.md | 6 ++++ Challenge/seyeongLee/026.planet_2/solve.js | 19 ++++++++++++ Challenge/seyeongLee/027.object/README.md | 14 +++++++++ Challenge/seyeongLee/027.object/solve.js | 26 +++++++++++++++++ Challenge/seyeongLee/028.2-gram/README.md | 23 +++++++++++++++ Challenge/seyeongLee/028.2-gram/solve.js | 29 +++++++++++++++++++ .../README.md" | 5 ++++ .../solve.js" | 13 +++++++++ .../seyeongLee/030.find-string/README.md | 15 ++++++++++ Challenge/seyeongLee/030.find-string/solve.js | 27 +++++++++++++++++ 12 files changed, 199 insertions(+) create mode 100644 Challenge/seyeongLee/025.circle-area/README.md create mode 100644 Challenge/seyeongLee/025.circle-area/solve.js create mode 100644 Challenge/seyeongLee/026.planet_2/README.md create mode 100644 Challenge/seyeongLee/026.planet_2/solve.js create mode 100644 Challenge/seyeongLee/027.object/README.md create mode 100644 Challenge/seyeongLee/027.object/solve.js create mode 100644 Challenge/seyeongLee/028.2-gram/README.md create mode 100644 Challenge/seyeongLee/028.2-gram/solve.js create mode 100644 "Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/README.md" create mode 100644 "Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/solve.js" create mode 100644 Challenge/seyeongLee/030.find-string/README.md create mode 100644 Challenge/seyeongLee/030.find-string/solve.js diff --git a/Challenge/seyeongLee/025.circle-area/README.md b/Challenge/seyeongLee/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Challenge/seyeongLee/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Challenge/seyeongLee/025.circle-area/solve.js b/Challenge/seyeongLee/025.circle-area/solve.js new file mode 100644 index 0000000..7a556da --- /dev/null +++ b/Challenge/seyeongLee/025.circle-area/solve.js @@ -0,0 +1,14 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + +function circle(r) { + return (r ** 2) * Math.PI; +} + +let radius = prompt("원 반지름의 길이을 입력하세요"); + +document.write(`원의 넓이 = ${circle(radius)}`); diff --git a/Challenge/seyeongLee/026.planet_2/README.md b/Challenge/seyeongLee/026.planet_2/README.md new file mode 100644 index 0000000..678e82a --- /dev/null +++ b/Challenge/seyeongLee/026.planet_2/README.md @@ -0,0 +1,6 @@ +# 문제26 : 행성 문제2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git a/Challenge/seyeongLee/026.planet_2/solve.js b/Challenge/seyeongLee/026.planet_2/solve.js new file mode 100644 index 0000000..b32d3d9 --- /dev/null +++ b/Challenge/seyeongLee/026.planet_2/solve.js @@ -0,0 +1,19 @@ +// 문제26 : 행성 문제2 + +// 우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +// 이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +let planetArr = { + "수성": "Mercury", + "금성": "Venus", + "지구": "Earth", + "화성": "Mars", + "목성": "Jupiter", + "토성": "Saturn", + "천왕성": "Uranus", + "해왕성": "Neptune" +} + +let koreanName = prompt("행성의 한글 이름을 입력하세요"); + +document.write(`행성의 영어 이름 : ${planetArr[koreanName]}`); diff --git a/Challenge/seyeongLee/027.object/README.md b/Challenge/seyeongLee/027.object/README.md new file mode 100644 index 0000000..9b83945 --- /dev/null +++ b/Challenge/seyeongLee/027.object/README.md @@ -0,0 +1,14 @@ +# 문제27 : 객체 만들기 + +첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + +```jsx +**입력** +Yujin Hyewon +70 100 + +**출력** +{'Yujin': 70, 'Hyewon': 100} +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/027.object/solve.js b/Challenge/seyeongLee/027.object/solve.js new file mode 100644 index 0000000..61236cc --- /dev/null +++ b/Challenge/seyeongLee/027.object/solve.js @@ -0,0 +1,26 @@ +// # 문제27 : 객체 만들기 + +// 첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +// 두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + + +// **입력** +// Yujin Hyewon +// 70 100 + +// **출력** +// {'Yujin': 70, 'Hyewon': 100} + +let studentName = prompt("학생의 이름을 입력하세요").split(" "); +let score = prompt("수학 점수를 입력하세요").split(" "); +let arr = {}; + + +for (let i=0; i`); +} \ No newline at end of file diff --git a/Challenge/seyeongLee/028.2-gram/README.md b/Challenge/seyeongLee/028.2-gram/README.md new file mode 100644 index 0000000..3a0dfe1 --- /dev/null +++ b/Challenge/seyeongLee/028.2-gram/README.md @@ -0,0 +1,23 @@ +# 문제28 : 2-gram + +**2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +```jsx +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t +``` + +입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git a/Challenge/seyeongLee/028.2-gram/solve.js b/Challenge/seyeongLee/028.2-gram/solve.js new file mode 100644 index 0000000..9abc1c6 --- /dev/null +++ b/Challenge/seyeongLee/028.2-gram/solve.js @@ -0,0 +1,29 @@ +// # 문제28 : 2-gram + +// **2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +// 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + + +// **입력** +// Javascript + +// **출력** +// J a +// a v +// v a +// a s +// s c +// c r +// r i +// i p +// p t + + +// 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. + +let input = prompt("문자열을 입력하세요"); + +for (let i=0; i`); +} \ No newline at end of file diff --git "a/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/README.md" "b/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/README.md" new file mode 100644 index 0000000..287a235 --- /dev/null +++ "b/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/README.md" @@ -0,0 +1,5 @@ +# 문제29 : 대문자만 지나가세요 + +진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git "a/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/solve.js" "b/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/solve.js" new file mode 100644 index 0000000..9cd25f1 --- /dev/null +++ "b/Challenge/seyeongLee/029.\353\214\200\353\254\270\354\236\220/solve.js" @@ -0,0 +1,13 @@ +// 문제29 : 대문자만 지나가세요 + +// 진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +// 알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. + +let input = prompt("알파벳 하나를 입력하세요"); + +if(input == input.toUpperCase()){ + document.write('YES'); +} else { + document.write('NO'); +} \ No newline at end of file diff --git a/Challenge/seyeongLee/030.find-string/README.md b/Challenge/seyeongLee/030.find-string/README.md new file mode 100644 index 0000000..b2f4ed6 --- /dev/null +++ b/Challenge/seyeongLee/030.find-string/README.md @@ -0,0 +1,15 @@ +# 문제30 : 문자열 속 문자 찾기 + +문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +**그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +```jsx +**입력** +pineapple is yummy +apple + +**출력** +4 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/030.find-string/solve.js b/Challenge/seyeongLee/030.find-string/solve.js new file mode 100644 index 0000000..dcf6839 --- /dev/null +++ b/Challenge/seyeongLee/030.find-string/solve.js @@ -0,0 +1,27 @@ +// # 문제30 : 문자열 속 문자 찾기 + +// 문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +// 첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +// **그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +// ```jsx +// **입력** +// pineapple is yummy +// apple + +// **출력** +// 4 +// ``` + +let input = prompt("문자열을 입력하세요"); +let word = prompt("찾고싶은 단어를 입력하세요"); + +document.write(`입력한 문자열 : ${input}
`); +document.write(`찾고싶은 단어 : ${word}
`); + +if (input.indexOf(word) == -1) { + document.write(`문자열에 포함되지 않은 단어입니다`); +} else { + document.write(`단어의 시작위치는 인덱스 ${input.indexOf(word)}입니다`); +} \ No newline at end of file From a98ffc392aef8a3254659d5491d94c545584321f Mon Sep 17 00:00:00 2001 From: plutoin Date: Thu, 2 Jun 2022 23:53:56 +0900 Subject: [PATCH 128/308] =?UTF-8?q?Solve:=2018=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/018.average/README.md | 13 ++++++++++++ Challenge/SoyeonJang/018.average/solve.js | 23 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Challenge/SoyeonJang/018.average/README.md create mode 100644 Challenge/SoyeonJang/018.average/solve.js diff --git a/Challenge/SoyeonJang/018.average/README.md b/Challenge/SoyeonJang/018.average/README.md new file mode 100644 index 0000000..ca04b62 --- /dev/null +++ b/Challenge/SoyeonJang/018.average/README.md @@ -0,0 +1,13 @@ +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` diff --git a/Challenge/SoyeonJang/018.average/solve.js b/Challenge/SoyeonJang/018.average/solve.js new file mode 100644 index 0000000..5262d3d --- /dev/null +++ b/Challenge/SoyeonJang/018.average/solve.js @@ -0,0 +1,23 @@ +/* +# 문제18 : 평균 점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구들의 평균 점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +**입출력** + +입력 : 20 30 40 +출력 : 30 +*/ + +const score = prompt('국어, 영어, 수학 점수를 입력해 주세요.').split(' ').map(Number) + +const result = score.reduce(function add(sum, currValue) { + return sum + currValue; +}, 0); + +const average = result / score.length; + +console.log(`평균: ${average} 점`) \ No newline at end of file From eb187718b06bcd04c1ef458d1654f046c54090ee Mon Sep 17 00:00:00 2001 From: plutoin Date: Fri, 3 Jun 2022 15:57:15 +0900 Subject: [PATCH 129/308] =?UTF-8?q?Solve:=2019=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/019.square/README.md | 3 +++ Challenge/SoyeonJang/019.square/solve.js | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 Challenge/SoyeonJang/019.square/README.md create mode 100644 Challenge/SoyeonJang/019.square/solve.js diff --git a/Challenge/SoyeonJang/019.square/README.md b/Challenge/SoyeonJang/019.square/README.md new file mode 100644 index 0000000..e02a30a --- /dev/null +++ b/Challenge/SoyeonJang/019.square/README.md @@ -0,0 +1,3 @@ +문제19 : 제곱을 구하자 + +공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. \ No newline at end of file diff --git a/Challenge/SoyeonJang/019.square/solve.js b/Challenge/SoyeonJang/019.square/solve.js new file mode 100644 index 0000000..dc93392 --- /dev/null +++ b/Challenge/SoyeonJang/019.square/solve.js @@ -0,0 +1,9 @@ +// 문제19 : 제곱을 구하자 + +// 공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. + +const number = prompt('두 개의 숫자를 입력해 주세요!').split(' ').map(Number) + +const result = Math.pow(number[0], number[1]) + +alert(`${number[0]}의 ${number[1]}승은 ${result}입니다.`) \ No newline at end of file From 1524c6dd6baacc9a59ce41ca12376537cbe55310 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Fri, 3 Jun 2022 20:38:59 +0900 Subject: [PATCH 130/308] Solve: 015, 016 --- .../015.template _literals/README.md | 13 ++++++++++++ .../HeelaeLim/015.template _literals/solve.js | 20 +++++++++++++++++++ Challenge/HeelaeLim/016.reverse/README.md | 10 ++++++++++ Challenge/HeelaeLim/016.reverse/solve.js | 19 ++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 Challenge/HeelaeLim/015.template _literals/README.md create mode 100644 Challenge/HeelaeLim/015.template _literals/solve.js create mode 100644 Challenge/HeelaeLim/016.reverse/README.md create mode 100644 Challenge/HeelaeLim/016.reverse/solve.js diff --git a/Challenge/HeelaeLim/015.template _literals/README.md b/Challenge/HeelaeLim/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/HeelaeLim/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/015.template _literals/solve.js b/Challenge/HeelaeLim/015.template _literals/solve.js new file mode 100644 index 0000000..4ec9675 --- /dev/null +++ b/Challenge/HeelaeLim/015.template _literals/solve.js @@ -0,0 +1,20 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ + +function introduce(){ + let Str = prompt(); + console.log(`안녕하세요. 저는 ${Str}입니다.`) +} + +introduce(); diff --git a/Challenge/HeelaeLim/016.reverse/README.md b/Challenge/HeelaeLim/016.reverse/README.md new file mode 100644 index 0000000..40b43f0 --- /dev/null +++ b/Challenge/HeelaeLim/016.reverse/README.md @@ -0,0 +1,10 @@ +# 문제16 : 로꾸꺼 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/016.reverse/solve.js b/Challenge/HeelaeLim/016.reverse/solve.js new file mode 100644 index 0000000..8ef6487 --- /dev/null +++ b/Challenge/HeelaeLim/016.reverse/solve.js @@ -0,0 +1,19 @@ +/* +# 문제16 : 로꾸꺼 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` +*/ + +function Upsidedown(){ + let Str = prompt(); + console.log(`${Str.split('').reverse().join('')}`) +} + +Upsidedown(); From a8d0302dca988b82f11219930ba14fa99e3e3439 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Fri, 3 Jun 2022 22:50:32 +0900 Subject: [PATCH 131/308] =?UTF-8?q?Feat=20:=2032,33=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 13 +++++++++++++ .../solve.js" | 13 +++++++++++++ Problems/033.Reverse/README.md | 13 +++++++++++++ Problems/033.Reverse/solve.js | 14 ++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 "Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" create mode 100644 "Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" create mode 100644 Problems/033.Reverse/README.md create mode 100644 Problems/033.Reverse/solve.js diff --git "a/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" "b/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" new file mode 100644 index 0000000..53459f4 --- /dev/null +++ "b/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" @@ -0,0 +1,13 @@ +# 문제32 : 문자열 만들기 + +취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +혜림이를 위해 **문자열을 입력받으면 단어의 갯수를 출력하는 프로그램**을 작성해 주세요. + +```jsx +**입력** +안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +**출력** +5 +``` diff --git "a/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" "b/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" new file mode 100644 index 0000000..83b4394 --- /dev/null +++ "b/Problems/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" @@ -0,0 +1,13 @@ +// # 문제32 : 문자열 만들기 + +// 취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +// 혜림이를 위해 문자열을 입력받으면 단어의 갯수를 출력하는 프로그램을 작성해 주세요. + +// ```jsx +// **입력** +// 안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +// **출력** +// 5 +// ``` diff --git a/Problems/033.Reverse/README.md b/Problems/033.Reverse/README.md new file mode 100644 index 0000000..7d450ce --- /dev/null +++ b/Problems/033.Reverse/README.md @@ -0,0 +1,13 @@ +# 문제33 : 거꾸로 출력하기 + +한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +```jsx +**입출력** +입력 : 1 2 3 4 5 +출력 : 5 4 3 2 1 + +**출력** +입력 : 2 4 6 7 8 +출력 : 8 7 6 4 2 +``` diff --git a/Problems/033.Reverse/solve.js b/Problems/033.Reverse/solve.js new file mode 100644 index 0000000..b1ff0c7 --- /dev/null +++ b/Problems/033.Reverse/solve.js @@ -0,0 +1,14 @@ +// # 문제33 : 거꾸로 출력하기 + +// 한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +// ```jsx +// **입출력** +// 입력 : 1 2 3 4 5 +// 출력 : 5 4 3 2 1 + +// **출력** +// 입력 : 2 4 6 7 8 +// 출력 : 8 7 6 4 2 +// ``` + From 44090c0d6095126f2e4fabbcd74db11fd308ea72 Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Sat, 4 Jun 2022 20:12:09 +0900 Subject: [PATCH 132/308] =?UTF-8?q?Solve=20:=208=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JisuKim/008.object/README.md | 16 ++++++++++++++++ Challenge/JisuKim/008.object/solve.js | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Challenge/JisuKim/008.object/README.md create mode 100644 Challenge/JisuKim/008.object/solve.js diff --git a/Challenge/JisuKim/008.object/README.md b/Challenge/JisuKim/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/JisuKim/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/JisuKim/008.object/solve.js b/Challenge/JisuKim/008.object/solve.js new file mode 100644 index 0000000..358e8cf --- /dev/null +++ b/Challenge/JisuKim/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +답 : 84 \ No newline at end of file From 102e4ffdae60150f57e21a822080a1126dfc57d4 Mon Sep 17 00:00:00 2001 From: heejin Date: Sat, 4 Jun 2022 23:43:07 +0900 Subject: [PATCH 133/308] =?UTF-8?q?Solve:=203,4,5=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HeejinKim/003.type/README.md | 13 +++++++++++++ Challenge/HeejinKim/003.type/solve.js | 8 ++++++++ Challenge/HeejinKim/004.type(2)/README.md | 8 ++++++++ Challenge/HeejinKim/004.type(2)/solve.js | 6 ++++++ Challenge/HeejinKim/005.for/README.md | 20 ++++++++++++++++++++ Challenge/HeejinKim/005.for/solve.js | 16 ++++++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 Challenge/HeejinKim/003.type/README.md create mode 100644 Challenge/HeejinKim/003.type/solve.js create mode 100644 Challenge/HeejinKim/004.type(2)/README.md create mode 100644 Challenge/HeejinKim/004.type(2)/solve.js create mode 100644 Challenge/HeejinKim/005.for/README.md create mode 100644 Challenge/HeejinKim/005.for/solve.js diff --git a/Challenge/HeejinKim/003.type/README.md b/Challenge/HeejinKim/003.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/HeejinKim/003.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/HeejinKim/003.type/solve.js b/Challenge/HeejinKim/003.type/solve.js new file mode 100644 index 0000000..7edb1e3 --- /dev/null +++ b/Challenge/HeejinKim/003.type/solve.js @@ -0,0 +1,8 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof (arr)); + +// 4) object \ No newline at end of file diff --git a/Challenge/HeejinKim/004.type(2)/README.md b/Challenge/HeejinKim/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/HeejinKim/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/HeejinKim/004.type(2)/solve.js b/Challenge/HeejinKim/004.type(2)/solve.js new file mode 100644 index 0000000..e95a14e --- /dev/null +++ b/Challenge/HeejinKim/004.type(2)/solve.js @@ -0,0 +1,6 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + + +// 2) 입력 : a = 2.22, 출력 : boolean diff --git a/Challenge/HeejinKim/005.for/README.md b/Challenge/HeejinKim/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/HeejinKim/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/HeejinKim/005.for/solve.js b/Challenge/HeejinKim/005.for/solve.js new file mode 100644 index 0000000..4185c4d --- /dev/null +++ b/Challenge/HeejinKim/005.for/solve.js @@ -0,0 +1,16 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); + +// 4) 16 From 6c55ce7def635193fd000135518046225087d09c Mon Sep 17 00:00:00 2001 From: seokahi Date: Sun, 5 Jun 2022 03:29:23 +0900 Subject: [PATCH 134/308] =?UTF-8?q?Solve:=204=EB=B2=88~6=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/004.type(2)/README.md | 8 ++++++++ Challenge/seokahi/004.type(2)/solve.js | 14 ++++++++++++++ Challenge/seokahi/005.for/README.md | 20 ++++++++++++++++++++ Challenge/seokahi/005.for/solve.js | 24 ++++++++++++++++++++++++ Challenge/seokahi/006.false/README.md | 10 ++++++++++ Challenge/seokahi/006.false/solve.js | 17 +++++++++++++++++ 6 files changed, 93 insertions(+) create mode 100644 Challenge/seokahi/004.type(2)/README.md create mode 100644 Challenge/seokahi/004.type(2)/solve.js create mode 100644 Challenge/seokahi/005.for/README.md create mode 100644 Challenge/seokahi/005.for/solve.js create mode 100644 Challenge/seokahi/006.false/README.md create mode 100644 Challenge/seokahi/006.false/solve.js diff --git a/Challenge/seokahi/004.type(2)/README.md b/Challenge/seokahi/004.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/seokahi/004.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/seokahi/004.type(2)/solve.js b/Challenge/seokahi/004.type(2)/solve.js new file mode 100644 index 0000000..4a1431c --- /dev/null +++ b/Challenge/seokahi/004.type(2)/solve.js @@ -0,0 +1,14 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// console.log(typeof 1) +// console.log(typeof 2.22) +// console.log(typeof 'p') +// console.log(typeof [1, 2, 3]) +// 정답 : 2번 (number로 출력.) + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file diff --git a/Challenge/seokahi/005.for/README.md b/Challenge/seokahi/005.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/seokahi/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/seokahi/005.for/solve.js b/Challenge/seokahi/005.for/solve.js new file mode 100644 index 0000000..2527c0a --- /dev/null +++ b/Challenge/seokahi/005.for/solve.js @@ -0,0 +1,24 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + +// a= 11 +// a= 14 +// a+b = 14 + 2 = 16 + +// 정답 : 4번 + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 \ No newline at end of file diff --git a/Challenge/seokahi/006.false/README.md b/Challenge/seokahi/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/seokahi/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/seokahi/006.false/solve.js b/Challenge/seokahi/006.false/solve.js new file mode 100644 index 0000000..3eacc7c --- /dev/null +++ b/Challenge/seokahi/006.false/solve.js @@ -0,0 +1,17 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + + +// 정답: 2번 (1은 True로 취급) +// console.log(!!NaN) +// console.log(!!1) +// console.log(!! "") +// console.log(!!0) +// console.log(!!undefined) +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined \ No newline at end of file From 71244c6598ce4aa25e83f99bcb6dc7e3fc66d501 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Sun, 5 Jun 2022 23:53:46 +0900 Subject: [PATCH 135/308] =?UTF-8?q?Feat=20:=2020~24=EB=B2=88,=2031?= =?UTF-8?q?=EB=B2=88=20=EB=AC=B8=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/020.share-remainder/README.md | 11 +++++++++++ Problems/020.share-remainder/solve.js | 11 +++++++++++ Problems/021.set/README.md | 9 +++++++++ Problems/021.set/solve.js | 11 +++++++++++ Problems/022.multiple/README.md | 9 +++++++++ Problems/022.multiple/solve.js | 11 +++++++++++ Problems/023.OX/README.md | 3 +++ Problems/023.OX/solve.js | 3 +++ Problems/024.toUpperCase/README.md | 12 ++++++++++++ Problems/024.toUpperCase/solve.js | 12 ++++++++++++ Problems/031.timeComplexity/README.md | 9 +++++++++ Problems/031.timeComplexity/solve.js | 11 +++++++++++ 12 files changed, 112 insertions(+) create mode 100644 Problems/020.share-remainder/README.md create mode 100644 Problems/020.share-remainder/solve.js create mode 100644 Problems/021.set/README.md create mode 100644 Problems/021.set/solve.js create mode 100644 Problems/022.multiple/README.md create mode 100644 Problems/022.multiple/solve.js create mode 100644 Problems/023.OX/README.md create mode 100644 Problems/023.OX/solve.js create mode 100644 Problems/024.toUpperCase/README.md create mode 100644 Problems/024.toUpperCase/solve.js create mode 100644 Problems/031.timeComplexity/README.md create mode 100644 Problems/031.timeComplexity/solve.js diff --git a/Problems/020.share-remainder/README.md b/Problems/020.share-remainder/README.md new file mode 100644 index 0000000..91c7d9c --- /dev/null +++ b/Problems/020.share-remainder/README.md @@ -0,0 +1,11 @@ +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +```jsx +**입출력** + +입력 : 10 2 +출력 : 5 0 +``` \ No newline at end of file diff --git a/Problems/020.share-remainder/solve.js b/Problems/020.share-remainder/solve.js new file mode 100644 index 0000000..a43ffad --- /dev/null +++ b/Problems/020.share-remainder/solve.js @@ -0,0 +1,11 @@ +/* +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +**입출력** + +입력 : 10 2 +출력 : 5 0 +*/ \ No newline at end of file diff --git a/Problems/021.set/README.md b/Problems/021.set/README.md new file mode 100644 index 0000000..255a239 --- /dev/null +++ b/Problems/021.set/README.md @@ -0,0 +1,9 @@ +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); \ No newline at end of file diff --git a/Problems/021.set/solve.js b/Problems/021.set/solve.js new file mode 100644 index 0000000..7e3b9cc --- /dev/null +++ b/Problems/021.set/solve.js @@ -0,0 +1,11 @@ +/* +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); +*/ \ No newline at end of file diff --git a/Problems/022.multiple/README.md b/Problems/022.multiple/README.md new file mode 100644 index 0000000..b4d74cc --- /dev/null +++ b/Problems/022.multiple/README.md @@ -0,0 +1,9 @@ +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 \ No newline at end of file diff --git a/Problems/022.multiple/solve.js b/Problems/022.multiple/solve.js new file mode 100644 index 0000000..0cfebbe --- /dev/null +++ b/Problems/022.multiple/solve.js @@ -0,0 +1,11 @@ +/* +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 +*/ \ No newline at end of file diff --git a/Problems/023.OX/README.md b/Problems/023.OX/README.md new file mode 100644 index 0000000..47e0046 --- /dev/null +++ b/Problems/023.OX/README.md @@ -0,0 +1,3 @@ +# 문제23 : OX문제 + +`console.log(10/3)`의 출력 결과는 **3**이다. \ No newline at end of file diff --git a/Problems/023.OX/solve.js b/Problems/023.OX/solve.js new file mode 100644 index 0000000..1d155a3 --- /dev/null +++ b/Problems/023.OX/solve.js @@ -0,0 +1,3 @@ +// # 문제23: OX문제 + +// `console.log(10/3)`의 출력 결과는 ** 3 ** 이다. \ No newline at end of file diff --git a/Problems/024.toUpperCase/README.md b/Problems/024.toUpperCase/README.md new file mode 100644 index 0000000..a5e5142 --- /dev/null +++ b/Problems/024.toUpperCase/README.md @@ -0,0 +1,12 @@ +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +```jsx +**입출력** + +입력 : mary +출력 : MARY +``` \ No newline at end of file diff --git a/Problems/024.toUpperCase/solve.js b/Problems/024.toUpperCase/solve.js new file mode 100644 index 0000000..989c7d6 --- /dev/null +++ b/Problems/024.toUpperCase/solve.js @@ -0,0 +1,12 @@ +/* +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +**입출력** + +입력 : mary +출력 : MARY +*/ \ No newline at end of file diff --git a/Problems/031.timeComplexity/README.md b/Problems/031.timeComplexity/README.md new file mode 100644 index 0000000..c10ae55 --- /dev/null +++ b/Problems/031.timeComplexity/README.md @@ -0,0 +1,9 @@ +# 문제31 : 자바스크립트 자료형의 복잡도 + +다음 배열 내장함수의 시간 복잡도가 O(1)이 아닌 것을 모두 고르시오. + +1) arr[i] +2) arr.push(5) +3) arr.slice() +4) arr.pop() +5) arr.includes(5) \ No newline at end of file diff --git a/Problems/031.timeComplexity/solve.js b/Problems/031.timeComplexity/solve.js new file mode 100644 index 0000000..eaab68a --- /dev/null +++ b/Problems/031.timeComplexity/solve.js @@ -0,0 +1,11 @@ +/* +# 문제31 : 자바스크립트 자료형의 복잡도 + +다음 배열 내장함수의 시간 복잡도가 O(1)이 아닌 것을 모두 고르시오. + +1) arr[i] +2) arr.push(5) +3) arr.slice() +4) arr.pop() +5) arr.includes(5) +*/ \ No newline at end of file From ef70e86fcda669a1ad55213bc9e93bbbdc04786a Mon Sep 17 00:00:00 2001 From: Jihoon Chae Date: Mon, 6 Jun 2022 16:41:04 +0900 Subject: [PATCH 136/308] =?UTF-8?q?Solve=20:=2029=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 5 +++++ .../solve.js" | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 "Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/README.md" create mode 100644 "Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/solve.js" diff --git "a/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/README.md" "b/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/README.md" new file mode 100644 index 0000000..287a235 --- /dev/null +++ "b/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/README.md" @@ -0,0 +1,5 @@ +# 문제29 : 대문자만 지나가세요 + +진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git "a/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/solve.js" "b/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/solve.js" new file mode 100644 index 0000000..195818e --- /dev/null +++ "b/Challenge/JihoonChae/029.\353\214\200\353\254\270\354\236\220/solve.js" @@ -0,0 +1,12 @@ +// 문제29 : 대문자만 지나가세요 + +// 진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +// 알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. + +const alphabet = prompt('알파벳을 입력하세요') +if (alphabet === alphabet.toUpperCase()) { + console.log("YES"); +} else { + console.log("NO"); +} \ No newline at end of file From 37ee7fd1712f80da571fa515b1ed7abc9276451f Mon Sep 17 00:00:00 2001 From: skylar121 Date: Mon, 6 Jun 2022 16:57:18 +0900 Subject: [PATCH 137/308] =?UTF-8?q?Solve:=2015=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4,=20Docs:=20001,=20014=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GyeongRim/{1.arry => 001.arry}/README.md | 0 .../GyeongRim/{1.arry => 001.arry}/solve.js | 0 Challenge/GyeongRim/{14 => 014.if}/README.md | 0 Challenge/GyeongRim/{14 => 014.if}/solve.js | 0 .../GyeongRim/015.template _literals/README.md | 13 +++++++++++++ .../GyeongRim/015.template _literals/solve.js | 16 ++++++++++++++++ 6 files changed, 29 insertions(+) rename Challenge/GyeongRim/{1.arry => 001.arry}/README.md (100%) rename Challenge/GyeongRim/{1.arry => 001.arry}/solve.js (100%) rename Challenge/GyeongRim/{14 => 014.if}/README.md (100%) rename Challenge/GyeongRim/{14 => 014.if}/solve.js (100%) create mode 100644 Challenge/GyeongRim/015.template _literals/README.md create mode 100644 Challenge/GyeongRim/015.template _literals/solve.js diff --git a/Challenge/GyeongRim/1.arry/README.md b/Challenge/GyeongRim/001.arry/README.md similarity index 100% rename from Challenge/GyeongRim/1.arry/README.md rename to Challenge/GyeongRim/001.arry/README.md diff --git a/Challenge/GyeongRim/1.arry/solve.js b/Challenge/GyeongRim/001.arry/solve.js similarity index 100% rename from Challenge/GyeongRim/1.arry/solve.js rename to Challenge/GyeongRim/001.arry/solve.js diff --git a/Challenge/GyeongRim/14/README.md b/Challenge/GyeongRim/014.if/README.md similarity index 100% rename from Challenge/GyeongRim/14/README.md rename to Challenge/GyeongRim/014.if/README.md diff --git a/Challenge/GyeongRim/14/solve.js b/Challenge/GyeongRim/014.if/solve.js similarity index 100% rename from Challenge/GyeongRim/14/solve.js rename to Challenge/GyeongRim/014.if/solve.js diff --git a/Challenge/GyeongRim/015.template _literals/README.md b/Challenge/GyeongRim/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/GyeongRim/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/GyeongRim/015.template _literals/solve.js b/Challenge/GyeongRim/015.template _literals/solve.js new file mode 100644 index 0000000..4e74350 --- /dev/null +++ b/Challenge/GyeongRim/015.template _literals/solve.js @@ -0,0 +1,16 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ + +const name = prompt('이름을 입력하세요.'); +console.log(`안녕하세요. 저는 ${name}입니다.`); \ No newline at end of file From ef14b7e625157efb3e653c8a86cb9c1773a42c53 Mon Sep 17 00:00:00 2001 From: skylar121 Date: Mon, 6 Jun 2022 17:16:32 +0900 Subject: [PATCH 138/308] =?UTF-8?q?Solve:=2016=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 10 ++++++++++ .../solve.js" | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 "Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/solve.js" diff --git "a/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..7f2d679 --- /dev/null +++ "b/Challenge/GyeongRim/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,16 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +*/ + +function reverseWord () { + const word = prompt('단어를 입력하세요.'); + console.log(word.split('').reverse().join('')); +} + +reverseWord(); \ No newline at end of file From 941fe2b2dab28e744756c29f495047f900c16d4a Mon Sep 17 00:00:00 2001 From: plutoin Date: Mon, 6 Jun 2022 17:45:14 +0900 Subject: [PATCH 139/308] =?UTF-8?q?Solve:=2020-24=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SoyeonJang/020.share-remainder/README.md | 11 +++++++++++ .../SoyeonJang/020.share-remainder/solve.js | 19 +++++++++++++++++++ Challenge/SoyeonJang/021.set/README.md | 9 +++++++++ Challenge/SoyeonJang/021.set/solve.js | 13 +++++++++++++ Challenge/SoyeonJang/022.multiple/README.md | 9 +++++++++ Challenge/SoyeonJang/022.multiple/solve.js | 14 ++++++++++++++ Challenge/SoyeonJang/023.OX/README.md | 3 +++ Challenge/SoyeonJang/023.OX/solve.js | 6 ++++++ .../SoyeonJang/024.toUpperCase/README.md | 12 ++++++++++++ Challenge/SoyeonJang/024.toUpperCase/solve.js | 15 +++++++++++++++ 10 files changed, 111 insertions(+) create mode 100644 Challenge/SoyeonJang/020.share-remainder/README.md create mode 100644 Challenge/SoyeonJang/020.share-remainder/solve.js create mode 100644 Challenge/SoyeonJang/021.set/README.md create mode 100644 Challenge/SoyeonJang/021.set/solve.js create mode 100644 Challenge/SoyeonJang/022.multiple/README.md create mode 100644 Challenge/SoyeonJang/022.multiple/solve.js create mode 100644 Challenge/SoyeonJang/023.OX/README.md create mode 100644 Challenge/SoyeonJang/023.OX/solve.js create mode 100644 Challenge/SoyeonJang/024.toUpperCase/README.md create mode 100644 Challenge/SoyeonJang/024.toUpperCase/solve.js diff --git a/Challenge/SoyeonJang/020.share-remainder/README.md b/Challenge/SoyeonJang/020.share-remainder/README.md new file mode 100644 index 0000000..91c7d9c --- /dev/null +++ b/Challenge/SoyeonJang/020.share-remainder/README.md @@ -0,0 +1,11 @@ +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +```jsx +**입출력** + +입력 : 10 2 +출력 : 5 0 +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/020.share-remainder/solve.js b/Challenge/SoyeonJang/020.share-remainder/solve.js new file mode 100644 index 0000000..0ec4dac --- /dev/null +++ b/Challenge/SoyeonJang/020.share-remainder/solve.js @@ -0,0 +1,19 @@ +/* +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +**입출력** + +입력 : 10 2 +출력 : 5 0 +*/ + +const number = prompt('두 개의 숫자를 입력해 주세요 나누어 드립니다').split(' ').map(Number) + +let divide = Math.floor(number[0] / number[1]) + +let remainder = Math.floor(number[0] % number[1]) + +console.log(divide, remainder) \ No newline at end of file diff --git a/Challenge/SoyeonJang/021.set/README.md b/Challenge/SoyeonJang/021.set/README.md new file mode 100644 index 0000000..255a239 --- /dev/null +++ b/Challenge/SoyeonJang/021.set/README.md @@ -0,0 +1,9 @@ +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); \ No newline at end of file diff --git a/Challenge/SoyeonJang/021.set/solve.js b/Challenge/SoyeonJang/021.set/solve.js new file mode 100644 index 0000000..4d71c05 --- /dev/null +++ b/Challenge/SoyeonJang/021.set/solve.js @@ -0,0 +1,13 @@ +/* +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); + +정답: 3번, 5번 +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/022.multiple/README.md b/Challenge/SoyeonJang/022.multiple/README.md new file mode 100644 index 0000000..b4d74cc --- /dev/null +++ b/Challenge/SoyeonJang/022.multiple/README.md @@ -0,0 +1,9 @@ +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 \ No newline at end of file diff --git a/Challenge/SoyeonJang/022.multiple/solve.js b/Challenge/SoyeonJang/022.multiple/solve.js new file mode 100644 index 0000000..6aff5e3 --- /dev/null +++ b/Challenge/SoyeonJang/022.multiple/solve.js @@ -0,0 +1,14 @@ +/* +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 + +정답: 3번 +나머지가 0인지 아닌지로 판별해 6의 배수인지 확인할 수 있음 +*/ \ No newline at end of file diff --git a/Challenge/SoyeonJang/023.OX/README.md b/Challenge/SoyeonJang/023.OX/README.md new file mode 100644 index 0000000..47e0046 --- /dev/null +++ b/Challenge/SoyeonJang/023.OX/README.md @@ -0,0 +1,3 @@ +# 문제23 : OX문제 + +`console.log(10/3)`의 출력 결과는 **3**이다. \ No newline at end of file diff --git a/Challenge/SoyeonJang/023.OX/solve.js b/Challenge/SoyeonJang/023.OX/solve.js new file mode 100644 index 0000000..3d0b923 --- /dev/null +++ b/Challenge/SoyeonJang/023.OX/solve.js @@ -0,0 +1,6 @@ +// # 문제23: OX문제 + +// `console.log(10/3)`의 출력 결과는 ** 3 ** 이다. + +// 정답: X +// Math.floor를 이용해 정수로 출력하면 3으로 나오지만 10/3으로만 출력했을 때 소숫점까지 출력됨 \ No newline at end of file diff --git a/Challenge/SoyeonJang/024.toUpperCase/README.md b/Challenge/SoyeonJang/024.toUpperCase/README.md new file mode 100644 index 0000000..a5e5142 --- /dev/null +++ b/Challenge/SoyeonJang/024.toUpperCase/README.md @@ -0,0 +1,12 @@ +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +```jsx +**입출력** + +입력 : mary +출력 : MARY +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/024.toUpperCase/solve.js b/Challenge/SoyeonJang/024.toUpperCase/solve.js new file mode 100644 index 0000000..cafa61d --- /dev/null +++ b/Challenge/SoyeonJang/024.toUpperCase/solve.js @@ -0,0 +1,15 @@ +/* +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +**입출력** + +입력 : mary +출력 : MARY +*/ + +const str = prompt('소문자 이름을 입력하면 대문자로 변경해 드립니다') +console.log(str.toUpperCase()) \ No newline at end of file From 8911891b798a0d2dbf1d5c69171b1eab95472076 Mon Sep 17 00:00:00 2001 From: unidagit Date: Mon, 6 Jun 2022 22:08:47 +0900 Subject: [PATCH 140/308] =?UTF-8?q?Solve:=20009=20~=20012=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/009.concat/README.md | 20 ++++++++++++++++++++ Challenge/YunheeJo/009.concat/solve.js | 19 +++++++++++++++++++ Challenge/YunheeJo/010.star/README.md | 18 ++++++++++++++++++ Challenge/YunheeJo/010.star/solve.js | 22 ++++++++++++++++++++++ Challenge/YunheeJo/011.for/README.md | 11 +++++++++++ Challenge/YunheeJo/011.for/solve.js | 12 ++++++++++++ Challenge/YunheeJo/012.class/README.md | 17 +++++++++++++++++ Challenge/YunheeJo/012.class/solve.js | 25 +++++++++++++++++++++++++ 8 files changed, 144 insertions(+) create mode 100644 Challenge/YunheeJo/009.concat/README.md create mode 100644 Challenge/YunheeJo/009.concat/solve.js create mode 100644 Challenge/YunheeJo/010.star/README.md create mode 100644 Challenge/YunheeJo/010.star/solve.js create mode 100644 Challenge/YunheeJo/011.for/README.md create mode 100644 Challenge/YunheeJo/011.for/solve.js create mode 100644 Challenge/YunheeJo/012.class/README.md create mode 100644 Challenge/YunheeJo/012.class/solve.js diff --git a/Challenge/YunheeJo/009.concat/README.md b/Challenge/YunheeJo/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/YunheeJo/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/YunheeJo/009.concat/solve.js b/Challenge/YunheeJo/009.concat/solve.js new file mode 100644 index 0000000..74e8e3a --- /dev/null +++ b/Challenge/YunheeJo/009.concat/solve.js @@ -0,0 +1,19 @@ + +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = year.concat('/',month,'/',day,' ',hour,':',minute,':',second); + +console.log(result); + +**출력** +2019/04/26 11:34:27 diff --git a/Challenge/YunheeJo/010.star/README.md b/Challenge/YunheeJo/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/YunheeJo/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/YunheeJo/010.star/solve.js b/Challenge/YunheeJo/010.star/solve.js new file mode 100644 index 0000000..98914c3 --- /dev/null +++ b/Challenge/YunheeJo/010.star/solve.js @@ -0,0 +1,22 @@ +// # 문제10 : 별 찍기 + +// 크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +// 하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +// **은비를 위해 프로그램을 작성해 주세요.** + +// **입력** +// 5 + +// **출력** +// * +// *** +// ***** +// ******* +// ********* + +const level = 5; + +for (let i = 1; i <= level; i++) { + console.log(' '.repeat(level - i) + '*'.repeat(i * 2 - 1)); +} diff --git a/Challenge/YunheeJo/011.for/README.md b/Challenge/YunheeJo/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/YunheeJo/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/YunheeJo/011.for/solve.js b/Challenge/YunheeJo/011.for/solve.js new file mode 100644 index 0000000..509d59f --- /dev/null +++ b/Challenge/YunheeJo/011.for/solve.js @@ -0,0 +1,12 @@ + +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +for (let i = 0; i <= 100; i++) { + s = s + i; +} + +console.log(s); diff --git a/Challenge/YunheeJo/012.class/README.md b/Challenge/YunheeJo/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/YunheeJo/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/YunheeJo/012.class/solve.js b/Challenge/YunheeJo/012.class/solve.js new file mode 100644 index 0000000..0a6cfc5 --- /dev/null +++ b/Challenge/YunheeJo/012.class/solve.js @@ -0,0 +1,25 @@ +// # 문제12 : 게임 캐릭터 클래스 만들기 + +// 다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +// **주어진 소스 코드를 수정해선 안됩니다.** + +// **데이터** +// <여기에 class를 작성하세요.> +const Wizard = class Wizard { + constructor(health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + attack() { + console.log('파이어볼'); + } +}; + +// const x = new Wizard(545, 210, 10); +// console.log(x.health, x.mana, x.armor); +// x.attack(); + +// **출력** +// 545 210 10 +// 파이어볼 From 9eafc16f1b6501c5a740f46005fa6b8e56073ed1 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Mon, 6 Jun 2022 22:49:49 +0900 Subject: [PATCH 141/308] =?UTF-8?q?Solve=20:=2032=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 13 +++++++++++++ .../solve.js" | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 "Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" create mode 100644 "Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" diff --git "a/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" "b/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" new file mode 100644 index 0000000..53459f4 --- /dev/null +++ "b/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" @@ -0,0 +1,13 @@ +# 문제32 : 문자열 만들기 + +취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +혜림이를 위해 **문자열을 입력받으면 단어의 갯수를 출력하는 프로그램**을 작성해 주세요. + +```jsx +**입력** +안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +**출력** +5 +``` diff --git "a/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" "b/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" new file mode 100644 index 0000000..da9c791 --- /dev/null +++ "b/Challenge/Songmyeongseok/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" @@ -0,0 +1,17 @@ +// # 문제32 : 문자열 만들기 + +// 취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +// 혜림이를 위해 문자열을 입력받으면 단어의 갯수를 출력하는 프로그램을 작성해 주세요. + +// ```jsx +// **입력** +// 안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +// **출력** +// 5 +// ``` + +function count(x){ + return x.split(' ').length +} From 76b707ad2590555ce6aeebe7c9a423e2eecb1838 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Mon, 6 Jun 2022 22:55:45 +0900 Subject: [PATCH 142/308] =?UTF-8?q?Solve:=20005=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/005.for/README.md | 20 ++++++++++++++++++++ Challenge/MinkyeongJo/005.for/solve.js | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 Challenge/MinkyeongJo/005.for/README.md create mode 100644 Challenge/MinkyeongJo/005.for/solve.js diff --git a/Challenge/MinkyeongJo/005.for/README.md b/Challenge/MinkyeongJo/005.for/README.md new file mode 100644 index 0000000..7ed44f2 --- /dev/null +++ b/Challenge/MinkyeongJo/005.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; //10+1+3=14 +} + +console.log(a+b); //14+2=16 +``` + +1) 10 +2) 12 +3) 14 +4) 16 //정답 \ No newline at end of file diff --git a/Challenge/MinkyeongJo/005.for/solve.js b/Challenge/MinkyeongJo/005.for/solve.js new file mode 100644 index 0000000..9a9204a --- /dev/null +++ b/Challenge/MinkyeongJo/005.for/solve.js @@ -0,0 +1,20 @@ + +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); + + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 \ No newline at end of file From 785dabc85784b9269299a489c5892efa8b2bc775 Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Mon, 6 Jun 2022 23:37:34 +0900 Subject: [PATCH 143/308] =?UTF-8?q?Solve:=2010-12=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sehunKim/010.star/README.md | 18 +++++++++++++++ Challenge/sehunKim/010.star/solve.js | 32 ++++++++++++++++++++++++++ Challenge/sehunKim/011.for/README.md | 11 +++++++++ Challenge/sehunKim/011.for/solve.js | 13 +++++++++++ Challenge/sehunKim/012.class/README.md | 17 ++++++++++++++ Challenge/sehunKim/012.class/solve.js | 27 ++++++++++++++++++++++ 6 files changed, 118 insertions(+) create mode 100644 Challenge/sehunKim/010.star/README.md create mode 100644 Challenge/sehunKim/010.star/solve.js create mode 100644 Challenge/sehunKim/011.for/README.md create mode 100644 Challenge/sehunKim/011.for/solve.js create mode 100644 Challenge/sehunKim/012.class/README.md create mode 100644 Challenge/sehunKim/012.class/solve.js diff --git a/Challenge/sehunKim/010.star/README.md b/Challenge/sehunKim/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/sehunKim/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/sehunKim/010.star/solve.js b/Challenge/sehunKim/010.star/solve.js new file mode 100644 index 0000000..7133d61 --- /dev/null +++ b/Challenge/sehunKim/010.star/solve.js @@ -0,0 +1,32 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ + +const n = prompt('숫자를 입력하세요.'); +let tree = ''; + +for (i = 0; i < n; i++) { + + for (j = 0; j < n-i; j++ ) { + tree += ' '; + } + for (k = 0; k < 2*i*1; k++) { + tree += '*' + } +} +console.log(tree); diff --git a/Challenge/sehunKim/011.for/README.md b/Challenge/sehunKim/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/sehunKim/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/sehunKim/011.for/solve.js b/Challenge/sehunKim/011.for/solve.js new file mode 100644 index 0000000..e17e792 --- /dev/null +++ b/Challenge/sehunKim/011.for/solve.js @@ -0,0 +1,13 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass +for (let i = 1; i < 101; i++) { + s += i +} +console.log(s); +*/ \ No newline at end of file diff --git a/Challenge/sehunKim/012.class/README.md b/Challenge/sehunKim/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/sehunKim/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/sehunKim/012.class/solve.js b/Challenge/sehunKim/012.class/solve.js new file mode 100644 index 0000000..97c8c90 --- /dev/null +++ b/Challenge/sehunKim/012.class/solve.js @@ -0,0 +1,27 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> +const Wizard = class Wizard { + constructor (health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + attack () { + console.log('파이어볼'); + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ \ No newline at end of file From 6ea2cbb0ea05f09d85109929a73118bb8e316b90 Mon Sep 17 00:00:00 2001 From: heejin Date: Mon, 6 Jun 2022 23:40:25 +0900 Subject: [PATCH 144/308] =?UTF-8?q?Solve:6,7,8=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HeejinKim/006.false/README.md | 10 ++++++++++ Challenge/HeejinKim/006.false/solve.js | 7 +++++++ Challenge/HeejinKim/007.variable/README.md | 9 +++++++++ Challenge/HeejinKim/007.variable/solve.js | 8 ++++++++ Challenge/HeejinKim/008.object/README.md | 16 ++++++++++++++++ Challenge/HeejinKim/008.object/solve.js | 18 ++++++++++++++++++ 6 files changed, 68 insertions(+) create mode 100644 Challenge/HeejinKim/006.false/README.md create mode 100644 Challenge/HeejinKim/006.false/solve.js create mode 100644 Challenge/HeejinKim/007.variable/README.md create mode 100644 Challenge/HeejinKim/007.variable/solve.js create mode 100644 Challenge/HeejinKim/008.object/README.md create mode 100644 Challenge/HeejinKim/008.object/solve.js diff --git a/Challenge/HeejinKim/006.false/README.md b/Challenge/HeejinKim/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/HeejinKim/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/HeejinKim/006.false/solve.js b/Challenge/HeejinKim/006.false/solve.js new file mode 100644 index 0000000..07a7b6f --- /dev/null +++ b/Challenge/HeejinKim/006.false/solve.js @@ -0,0 +1,7 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + + +// 2) 1 diff --git a/Challenge/HeejinKim/007.variable/README.md b/Challenge/HeejinKim/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/HeejinKim/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/HeejinKim/007.variable/solve.js b/Challenge/HeejinKim/007.variable/solve.js new file mode 100644 index 0000000..be35fe6 --- /dev/null +++ b/Challenge/HeejinKim/007.variable/solve.js @@ -0,0 +1,8 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +3) let +5) 1age +*/ \ No newline at end of file diff --git a/Challenge/HeejinKim/008.object/README.md b/Challenge/HeejinKim/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/HeejinKim/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/HeejinKim/008.object/solve.js b/Challenge/HeejinKim/008.object/solve.js new file mode 100644 index 0000000..5963ac6 --- /dev/null +++ b/Challenge/HeejinKim/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); + +84 +*/ \ No newline at end of file From 0f73c84c31a1f4f0a9913b0113a352c2ad9359bd Mon Sep 17 00:00:00 2001 From: usablepaper Date: Mon, 6 Jun 2022 23:56:34 +0900 Subject: [PATCH 145/308] =?UTF-8?q?Solve=203=EB=B2=88,4=EB=B2=88,5?= =?UTF-8?q?=EB=B2=88=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Hyeonji/3.type/README.md | 13 +++++++++++++ Challenge/Hyeonji/3.type/solve.js | 13 +++++++++++++ Challenge/Hyeonji/4.type_2/README.md | 8 ++++++++ Challenge/Hyeonji/4.type_2/solve.js | 10 ++++++++++ Challenge/Hyeonji/5.for/README.md | 20 ++++++++++++++++++++ Challenge/Hyeonji/5.for/solve.js | 20 ++++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 Challenge/Hyeonji/3.type/README.md create mode 100644 Challenge/Hyeonji/3.type/solve.js create mode 100644 Challenge/Hyeonji/4.type_2/README.md create mode 100644 Challenge/Hyeonji/4.type_2/solve.js create mode 100644 Challenge/Hyeonji/5.for/README.md create mode 100644 Challenge/Hyeonji/5.for/solve.js diff --git a/Challenge/Hyeonji/3.type/README.md b/Challenge/Hyeonji/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/Hyeonji/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/Hyeonji/3.type/solve.js b/Challenge/Hyeonji/3.type/solve.js new file mode 100644 index 0000000..06c7169 --- /dev/null +++ b/Challenge/Hyeonji/3.type/solve.js @@ -0,0 +1,13 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? + +var arr = [100, 200, 300]; +console.log(typeof arr); + +// 1) undefined +// 2) string +// 3) number +// 4) object + +// 답 = 4 diff --git a/Challenge/Hyeonji/4.type_2/README.md b/Challenge/Hyeonji/4.type_2/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/Hyeonji/4.type_2/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/Hyeonji/4.type_2/solve.js b/Challenge/Hyeonji/4.type_2/solve.js new file mode 100644 index 0000000..1276d8a --- /dev/null +++ b/Challenge/Hyeonji/4.type_2/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 답 2 diff --git a/Challenge/Hyeonji/5.for/README.md b/Challenge/Hyeonji/5.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/Hyeonji/5.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/Hyeonji/5.for/solve.js b/Challenge/Hyeonji/5.for/solve.js new file mode 100644 index 0000000..0613d93 --- /dev/null +++ b/Challenge/Hyeonji/5.for/solve.js @@ -0,0 +1,20 @@ +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +jsx; +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 + +// 답 = 4 From 9c7b831ea8349ac7b82675a3e0a3367b1ae5f458 Mon Sep 17 00:00:00 2001 From: chooing Date: Mon, 6 Jun 2022 23:56:48 +0900 Subject: [PATCH 146/308] =?UTF-8?q?Solve=20:=20008=20-=20010=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JihyeChoo/008.object/README.md | 16 +++++++++++ Challenge/JihyeChoo/008.object/solve.js | 18 +++++++++++++ Challenge/JihyeChoo/009.concat/README.md | 20 ++++++++++++++ Challenge/JihyeChoo/009.concat/solve.js | 23 ++++++++++++++++ Challenge/JihyeChoo/010.star/README.md | 18 +++++++++++++ Challenge/JihyeChoo/010.star/solve.js | 34 ++++++++++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 Challenge/JihyeChoo/008.object/README.md create mode 100644 Challenge/JihyeChoo/008.object/solve.js create mode 100644 Challenge/JihyeChoo/009.concat/README.md create mode 100644 Challenge/JihyeChoo/009.concat/solve.js create mode 100644 Challenge/JihyeChoo/010.star/README.md create mode 100644 Challenge/JihyeChoo/010.star/solve.js diff --git a/Challenge/JihyeChoo/008.object/README.md b/Challenge/JihyeChoo/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/JihyeChoo/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/JihyeChoo/008.object/solve.js b/Challenge/JihyeChoo/008.object/solve.js new file mode 100644 index 0000000..7354273 --- /dev/null +++ b/Challenge/JihyeChoo/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +// 출력값 ==> 78 \ No newline at end of file diff --git a/Challenge/JihyeChoo/009.concat/README.md b/Challenge/JihyeChoo/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/JihyeChoo/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/JihyeChoo/009.concat/solve.js b/Challenge/JihyeChoo/009.concat/solve.js new file mode 100644 index 0000000..2d9b7af --- /dev/null +++ b/Challenge/JihyeChoo/009.concat/solve.js @@ -0,0 +1,23 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ + +let result = year.concat('/', month, '/', day, ' ', hour, ':', minute, ':', second); +console.log(result); \ No newline at end of file diff --git a/Challenge/JihyeChoo/010.star/README.md b/Challenge/JihyeChoo/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/JihyeChoo/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/JihyeChoo/010.star/solve.js b/Challenge/JihyeChoo/010.star/solve.js new file mode 100644 index 0000000..32503f4 --- /dev/null +++ b/Challenge/JihyeChoo/010.star/solve.js @@ -0,0 +1,34 @@ +/* +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +*/ + +function treeMake(num) { + let tree=''; + for (let i = 1; i <= num; i++) { + for (let j = 1; j <= num-i; j++) { + tree+=' '; + } + for (let k = 1; k <= 2*i-1; k++) { + tree+='*'; + } + tree+='\n'; + } + console.log(tree); +} + +treeMake(prompt('트리의 단 수를 정해주세요.')); \ No newline at end of file From a08ed367c00a28806602154b2a97cbd44cff2254 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Mon, 6 Jun 2022 23:58:07 +0900 Subject: [PATCH 147/308] =?UTF-8?q?Solve=20:=20019=20~=20024=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seyeongLee/019.square/README.md | 3 +++ Challenge/seyeongLee/019.square/solve.js | 12 ++++++++++ .../seyeongLee/020.share-remainder/README.md | 11 ++++++++++ .../seyeongLee/020.share-remainder/solve.js | 19 ++++++++++++++++ Challenge/seyeongLee/021.set/README.md | 9 ++++++++ Challenge/seyeongLee/021.set/solve.js | 22 +++++++++++++++++++ Challenge/seyeongLee/022.multiple/README.md | 9 ++++++++ Challenge/seyeongLee/022.multiple/solve.js | 15 +++++++++++++ Challenge/seyeongLee/023.OX/README.md | 3 +++ Challenge/seyeongLee/023.OX/solve.js | 7 ++++++ .../seyeongLee/024.toUpperCase/README.md | 12 ++++++++++ Challenge/seyeongLee/024.toUpperCase/solve.js | 16 ++++++++++++++ 12 files changed, 138 insertions(+) create mode 100644 Challenge/seyeongLee/019.square/README.md create mode 100644 Challenge/seyeongLee/019.square/solve.js create mode 100644 Challenge/seyeongLee/020.share-remainder/README.md create mode 100644 Challenge/seyeongLee/020.share-remainder/solve.js create mode 100644 Challenge/seyeongLee/021.set/README.md create mode 100644 Challenge/seyeongLee/021.set/solve.js create mode 100644 Challenge/seyeongLee/022.multiple/README.md create mode 100644 Challenge/seyeongLee/022.multiple/solve.js create mode 100644 Challenge/seyeongLee/023.OX/README.md create mode 100644 Challenge/seyeongLee/023.OX/solve.js create mode 100644 Challenge/seyeongLee/024.toUpperCase/README.md create mode 100644 Challenge/seyeongLee/024.toUpperCase/solve.js diff --git a/Challenge/seyeongLee/019.square/README.md b/Challenge/seyeongLee/019.square/README.md new file mode 100644 index 0000000..e02a30a --- /dev/null +++ b/Challenge/seyeongLee/019.square/README.md @@ -0,0 +1,3 @@ +문제19 : 제곱을 구하자 + +공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. \ No newline at end of file diff --git a/Challenge/seyeongLee/019.square/solve.js b/Challenge/seyeongLee/019.square/solve.js new file mode 100644 index 0000000..29a20a7 --- /dev/null +++ b/Challenge/seyeongLee/019.square/solve.js @@ -0,0 +1,12 @@ +// 문제19 : 제곱을 구하자 + +// 공백으로 구분하여 두 숫자 a와 b가 주어지면, a의 b승을 구하는 프로그램을 작성하세요. + +let input = prompt("a의 b승 -> 원하는 a와 b 값을 입력하세요").split(" "); + +// +를 넣어줌으로서 문자열을 숫자형으로 변환 +// +없어도 계산에 문제는 없음 +let a = +input[0]; +let b = +input[1]; + +document.write(`${a}의 ${b}승 = ${a ** b}`); \ No newline at end of file diff --git a/Challenge/seyeongLee/020.share-remainder/README.md b/Challenge/seyeongLee/020.share-remainder/README.md new file mode 100644 index 0000000..91c7d9c --- /dev/null +++ b/Challenge/seyeongLee/020.share-remainder/README.md @@ -0,0 +1,11 @@ +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +```jsx +**입출력** + +입력 : 10 2 +출력 : 5 0 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/020.share-remainder/solve.js b/Challenge/seyeongLee/020.share-remainder/solve.js new file mode 100644 index 0000000..dc0d7e4 --- /dev/null +++ b/Challenge/seyeongLee/020.share-remainder/solve.js @@ -0,0 +1,19 @@ +/* +# 문제20 : 몫과 나머지 + +공백으로 구분하여 두 숫자가 주어집니다. +두번째 숫자로 첫번째 숫자를 나누었을 때 **그 몫과 나머지를 공백으로 구분하여 출력하세요.** + +**입출력** + +입력 : 10 2 +출력 : 5 0 +*/ + +let input = prompt("a 나누기 b -> 원하는 a와 b값을 입력하세요").split(" "); + +let a = input[0]; +let b = input[1]; + +document.write(`a = ${a}, b = ${b}
`); +document.write(`몫 = ${Math.floor(a / b)}, 나머지 = ${a % b}`); \ No newline at end of file diff --git a/Challenge/seyeongLee/021.set/README.md b/Challenge/seyeongLee/021.set/README.md new file mode 100644 index 0000000..255a239 --- /dev/null +++ b/Challenge/seyeongLee/021.set/README.md @@ -0,0 +1,9 @@ +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); \ No newline at end of file diff --git a/Challenge/seyeongLee/021.set/solve.js b/Challenge/seyeongLee/021.set/solve.js new file mode 100644 index 0000000..2477130 --- /dev/null +++ b/Challenge/seyeongLee/021.set/solve.js @@ -0,0 +1,22 @@ +/* +# 문제21 : set은 어떻게 만드나요? + +다음 중 set을 만드는 방법으로 올바른 것을 모두 고르시오. + +1) var x = {1, 2, 3, 5, 6, 7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); +*/ + +// 정답 : 3번, 5번 +var x1 = new Set('javascript'); +var x2 = new Set(); + +console.log(x1); +console.log(x2); + +// set은 객체 생성자를 이용하여 집합을 생성 +// 이 때 배열,맵,집합,문자열 등을 받는다. +// 인자를 넣지않으면 크기가 0인 빈 집합이 생성된다. diff --git a/Challenge/seyeongLee/022.multiple/README.md b/Challenge/seyeongLee/022.multiple/README.md new file mode 100644 index 0000000..b4d74cc --- /dev/null +++ b/Challenge/seyeongLee/022.multiple/README.md @@ -0,0 +1,9 @@ +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 \ No newline at end of file diff --git a/Challenge/seyeongLee/022.multiple/solve.js b/Challenge/seyeongLee/022.multiple/solve.js new file mode 100644 index 0000000..392eed8 --- /dev/null +++ b/Challenge/seyeongLee/022.multiple/solve.js @@ -0,0 +1,15 @@ +/* +# 문제22 : 배수인지 확인하기 + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i / 6 == 0 +2) i % 6 == 0 +3) i & 6 == 0 +4) i | 6 == 0 +5) i // 6 == 0 +*/ + +// 6의 배수인지 확인하기 위해서는 +// 6으로 나눴을 때 나머지가 0이면 된다. +// 그러므로 나머지 수식을 사용한 2번이 정답 \ No newline at end of file diff --git a/Challenge/seyeongLee/023.OX/README.md b/Challenge/seyeongLee/023.OX/README.md new file mode 100644 index 0000000..47e0046 --- /dev/null +++ b/Challenge/seyeongLee/023.OX/README.md @@ -0,0 +1,3 @@ +# 문제23 : OX문제 + +`console.log(10/3)`의 출력 결과는 **3**이다. \ No newline at end of file diff --git a/Challenge/seyeongLee/023.OX/solve.js b/Challenge/seyeongLee/023.OX/solve.js new file mode 100644 index 0000000..efb9929 --- /dev/null +++ b/Challenge/seyeongLee/023.OX/solve.js @@ -0,0 +1,7 @@ +// # 문제23: OX문제 + +// `console.log(10/3)`의 출력 결과는 ** 3 ** 이다. + +// 정답 : X +console.log(10/3); // result : 3.3333333333333335 +console.log(Math.floor(10/3)); // result : 3 \ No newline at end of file diff --git a/Challenge/seyeongLee/024.toUpperCase/README.md b/Challenge/seyeongLee/024.toUpperCase/README.md new file mode 100644 index 0000000..a5e5142 --- /dev/null +++ b/Challenge/seyeongLee/024.toUpperCase/README.md @@ -0,0 +1,12 @@ +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +```jsx +**입출력** + +입력 : mary +출력 : MARY +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/024.toUpperCase/solve.js b/Challenge/seyeongLee/024.toUpperCase/solve.js new file mode 100644 index 0000000..7721043 --- /dev/null +++ b/Challenge/seyeongLee/024.toUpperCase/solve.js @@ -0,0 +1,16 @@ +/* +# 문제24 : 대문자로 바꿔주세요! + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 전부 소문자, 어떤 이는 전부 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 **이름이 입력되면 전부 대문자로 출력되는 프로그램**을 만들어주세요. + +**입출력** + +입력 : mary +출력 : MARY +*/ + +let elnglishName = prompt("이름을 영어로 입력하세요"); + +document.write(elnglishName.toUpperCase()); \ No newline at end of file From 9f9e50d4625bd939727361cd0d6e9b7c1a592ac2 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Tue, 7 Jun 2022 00:35:59 +0900 Subject: [PATCH 148/308] =?UTF-8?q?Feat=20:=2034~39=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/034.sort/README.md | 16 +++++++++++++ Problems/034.sort/solve.js | 18 ++++++++++++++ Problems/035.function/README.md | 22 +++++++++++++++++ Problems/035.function/solve.js | 24 +++++++++++++++++++ Problems/036.Multiplication_Table/README.md | 10 ++++++++ Problems/036.Multiplication_Table/solve.js | 12 ++++++++++ .../README.md" | 11 +++++++++ .../solve.js" | 13 ++++++++++ .../README.md" | 13 ++++++++++ .../solve.js" | 15 ++++++++++++ .../README.md" | 18 ++++++++++++++ .../solve.js" | 20 ++++++++++++++++ 12 files changed, 192 insertions(+) create mode 100644 Problems/034.sort/README.md create mode 100644 Problems/034.sort/solve.js create mode 100644 Problems/035.function/README.md create mode 100644 Problems/035.function/solve.js create mode 100644 Problems/036.Multiplication_Table/README.md create mode 100644 Problems/036.Multiplication_Table/solve.js create mode 100644 "Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" create mode 100644 "Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" create mode 100644 "Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" create mode 100644 "Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" create mode 100644 "Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" create mode 100644 "Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" diff --git a/Problems/034.sort/README.md b/Problems/034.sort/README.md new file mode 100644 index 0000000..615626c --- /dev/null +++ b/Problems/034.sort/README.md @@ -0,0 +1,16 @@ +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** + +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` \ No newline at end of file diff --git a/Problems/034.sort/solve.js b/Problems/034.sort/solve.js new file mode 100644 index 0000000..ef2eef4 --- /dev/null +++ b/Problems/034.sort/solve.js @@ -0,0 +1,18 @@ +/* +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** + +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` +*/ diff --git a/Problems/035.function/README.md b/Problems/035.function/README.md new file mode 100644 index 0000000..5e4b62a --- /dev/null +++ b/Problems/035.function/README.md @@ -0,0 +1,22 @@ +# 문제35 : Factory 함수 사용하기 + +2제곱, 3제곱, 4제곱을 할 수 있는 Factory 함수를 만들려고 합니다. + +에 코드를 작성하여 two함수를 완성하세요. + +```jsx +function one(n){ + function two(){ + //pass + } + return two; +} + +const a = one(2); +const b = one(3); +const c = one(4); + +console.log(a(10)); +console.log(b(10)); +console.log(c(10)); +``` \ No newline at end of file diff --git a/Problems/035.function/solve.js b/Problems/035.function/solve.js new file mode 100644 index 0000000..5e30d7e --- /dev/null +++ b/Problems/035.function/solve.js @@ -0,0 +1,24 @@ +/* +# 문제35 : Factory 함수 사용하기 + +2제곱, 3제곱, 4제곱을 할 수 있는 Factory 함수를 만들려고 합니다. + +에 코드를 작성하여 two함수를 완성하세요. + +```jsx +function one(n){ + function two(){ + //pass + } + return two; +} + +const a = one(2); +const b = one(3); +const c = one(4); + +console.log(a(10)); +console.log(b(10)); +console.log(c(10)); +``` +*/ diff --git a/Problems/036.Multiplication_Table/README.md b/Problems/036.Multiplication_Table/README.md new file mode 100644 index 0000000..3691735 --- /dev/null +++ b/Problems/036.Multiplication_Table/README.md @@ -0,0 +1,10 @@ +# 문제36 : 구구단 출력하기 + +1~9까지의 숫자 중 하나를 입력하면 그 단의 구구단 결과를 한 줄에 출력하는 프로그램을 작성하세요. + +```jsx +**입출력** + +입력 : 2 +출력 : 2 4 6 8 10 12 14 16 18 +``` \ No newline at end of file diff --git a/Problems/036.Multiplication_Table/solve.js b/Problems/036.Multiplication_Table/solve.js new file mode 100644 index 0000000..9e2a29f --- /dev/null +++ b/Problems/036.Multiplication_Table/solve.js @@ -0,0 +1,12 @@ +/* +# 문제36 : 구구단 출력하기 + +1~9까지의 숫자 중 하나를 입력하면 그 단의 구구단 결과를 한 줄에 출력하는 프로그램을 작성하세요. + +```jsx +**입출력** + +입력 : 2 +출력 : 2 4 6 8 10 12 14 16 18 +``` +*/ diff --git "a/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" "b/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" new file mode 100644 index 0000000..18cac02 --- /dev/null +++ "b/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" @@ -0,0 +1,11 @@ +# 문제37 : 반장 선거 + +새 학기를 맞아 호준이네 반은 반장 선거를 하기로 했습니다. 그런데 표를 하나씩 개표하는 과정이 너무 번거롭게 느껴진 당신은 **학생들이 뽑은 후보들을 입력받으면 뽑힌 학생의 이름과 받은 표 수를 출력하는 프로그램**을 작성하기로 하였습니다. + +```jsx +**입력** +원범 원범 혜원 혜원 혜원 혜원 유진 유진 + +**출력** +혜원(이)가 총 4표로 반장이 되었습니다. +``` \ No newline at end of file diff --git "a/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" "b/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" new file mode 100644 index 0000000..9047acb --- /dev/null +++ "b/Problems/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" @@ -0,0 +1,13 @@ +/* +# 문제37 : 반장 선거 + +새 학기를 맞아 호준이네 반은 반장 선거를 하기로 했습니다. 그런데 표를 하나씩 개표하는 과정이 너무 번거롭게 느껴진 당신은 **학생들이 뽑은 후보들을 입력받으면 뽑힌 학생의 이름과 받은 표 수를 출력하는 프로그램**을 작성하기로 하였습니다. + +```jsx +**입력** +원범 원범 혜원 혜원 혜원 혜원 유진 유진 + +**출력** +혜원(이)가 총 4표로 반장이 되었습니다. +``` +*/ diff --git "a/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" "b/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" new file mode 100644 index 0000000..36a32d4 --- /dev/null +++ "b/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" @@ -0,0 +1,13 @@ +# 문제38 : 호준이의 아르바이트 + +호준이는 아르바이트로 영어 학원에서 단어 시험지를 채점하는 일을 하고 있다. 호준이가 일하는 학원은 매번 1위부터 3위까지의 학생에게 상으로 사탕을 준다. 그런데 오늘은 마침 사탕이 다 떨어져서 호준이가 채점을 하고 점수를 보내면, 당신이 아이들의 숫자만큼 사탕을 사러 가기로 했다. + +1위 ~ 3위 학생은 여러명일 수 있고 1~3위 학생 중 중복되는 학생까지 포함하여 사탕을 사기로 한다. +**학생들의 점수를 공백으로 구분하여 입력을 받고 사탕을 받을 학생의 수를 출력하세요.** + +```jsx +**입출력** + +입력 : 97 86 75 66 55 97 85 97 97 95 +출력 : 6 +``` \ No newline at end of file diff --git "a/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" "b/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" new file mode 100644 index 0000000..02ebce0 --- /dev/null +++ "b/Problems/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" @@ -0,0 +1,15 @@ +/* +# 문제38 : 호준이의 아르바이트 + +호준이는 아르바이트로 영어 학원에서 단어 시험지를 채점하는 일을 하고 있다. 호준이가 일하는 학원은 매번 1위부터 3위까지의 학생에게 상으로 사탕을 준다. 그런데 오늘은 마침 사탕이 다 떨어져서 호준이가 채점을 하고 점수를 보내면, 당신이 아이들의 숫자만큼 사탕을 사러 가기로 했다. + +1위 ~ 3위 학생은 여러명일 수 있고 1~3위 학생 중 중복되는 학생까지 포함하여 사탕을 사기로 한다. +**학생들의 점수를 공백으로 구분하여 입력을 받고 사탕을 받을 학생의 수를 출력하세요.** + +```jsx +**입출력** + +입력 : 97 86 75 66 55 97 85 97 97 95 +출력 : 6 +``` +*/ diff --git "a/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" "b/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" new file mode 100644 index 0000000..3b0af06 --- /dev/null +++ "b/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" @@ -0,0 +1,18 @@ +# 문제39 : 오타 수정하기 + +혜원이는 평소 영타가 빠르고 정확한 것을 친구들에게 자랑하고 다녔습니다. 반 친구들이 혜원이의 타자 속도가 빠르다는 것을 모두 알게 되자 혜원이는 모두의 앞에서 타자 실력을 보여주게 됩니다. + +그런데 막상 보여주려니 긴장이 되서 문장의 모든 e를 q로 잘못 친 것을 발견했습니다. +혜원이는 프로그램을 돌려 재빠르게 모든 q를 e로 바꾸는 프로그램을 작성하려고 합니다. + +**문장이 입력되면 모든 q를 e로 바꾸는 프로그램을 작성해 주세요.** + +```jsx +**입출력** + +입력 : querty +출력 : euerty + +입력 : hqllo my namq is hyqwon +출력 : hello my name is hyewon +``` \ No newline at end of file diff --git "a/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" "b/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" new file mode 100644 index 0000000..f593793 --- /dev/null +++ "b/Problems/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" @@ -0,0 +1,20 @@ +/* +# 문제39 : 오타 수정하기 + +혜원이는 평소 영타가 빠르고 정확한 것을 친구들에게 자랑하고 다녔습니다. 반 친구들이 혜원이의 타자 속도가 빠르다는 것을 모두 알게 되자 혜원이는 모두의 앞에서 타자 실력을 보여주게 됩니다. + +그런데 막상 보여주려니 긴장이 되서 문장의 모든 e를 q로 잘못 친 것을 발견했습니다. +혜원이는 프로그램을 돌려 재빠르게 모든 q를 e로 바꾸는 프로그램을 작성하려고 합니다. + +**문장이 입력되면 모든 q를 e로 바꾸는 프로그램을 작성해 주세요.** + +```jsx +**입출력** + +입력 : querty +출력 : euerty + +입력 : hqllo my namq is hyqwon +출력 : hello my name is hyewon +``` +*/ From 2479332f9370397ac699ecc47b2370cda890ebca Mon Sep 17 00:00:00 2001 From: plutoin Date: Tue, 7 Jun 2022 16:46:35 +0900 Subject: [PATCH 149/308] =?UTF-8?q?Solve:=2025=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/025.circle-area/README.md | 8 ++++++++ Challenge/SoyeonJang/025.circle-area/solve.js | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 Challenge/SoyeonJang/025.circle-area/README.md create mode 100644 Challenge/SoyeonJang/025.circle-area/solve.js diff --git a/Challenge/SoyeonJang/025.circle-area/README.md b/Challenge/SoyeonJang/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Challenge/SoyeonJang/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Challenge/SoyeonJang/025.circle-area/solve.js b/Challenge/SoyeonJang/025.circle-area/solve.js new file mode 100644 index 0000000..f97da0d --- /dev/null +++ b/Challenge/SoyeonJang/025.circle-area/solve.js @@ -0,0 +1,15 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + +const n = prompt('넓이를 구할 원의 반지름을 입력해 주세요.') + +function circleArea(radius) { + let area = radius * radius * 3.14 + console.log(`원의 넓이는 ${area}cm입니다.`) +} + +circleArea(n) \ No newline at end of file From 1230caa35063833ab7dffe8e1113eb1cac1b2750 Mon Sep 17 00:00:00 2001 From: unidagit Date: Tue, 7 Jun 2022 19:57:51 +0900 Subject: [PATCH 150/308] =?UTF-8?q?Solve:=2013=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YunheeJo/013.find-planet/README.md | 15 ++++++++++ Challenge/YunheeJo/013.find-planet/solve.js | 29 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 Challenge/YunheeJo/013.find-planet/README.md create mode 100644 Challenge/YunheeJo/013.find-planet/solve.js diff --git a/Challenge/YunheeJo/013.find-planet/README.md b/Challenge/YunheeJo/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/YunheeJo/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/YunheeJo/013.find-planet/solve.js b/Challenge/YunheeJo/013.find-planet/solve.js new file mode 100644 index 0000000..678dd4e --- /dev/null +++ b/Challenge/YunheeJo/013.find-planet/solve.js @@ -0,0 +1,29 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ +const arr = [ + '수성', + '금성', + '지구', + '화성', + '목성', + '토성', + '천왕성', + '해왕성', +]; + +const n = prompt('몇번째 행성을 원하시나요?'); + +console.log(arr[n - 1]); From aa4dc1df3c34cbbaa8b598c079834c81905b106d Mon Sep 17 00:00:00 2001 From: sooyyoung Date: Tue, 7 Jun 2022 22:17:31 +0900 Subject: [PATCH 151/308] =?UTF-8?q?Solve=20:=2011,=2013-15=EB=B2=88=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sooyoungCho/011.for/README.md | 11 ++++++++ Challenge/sooyoungCho/011.for/solve.js | 14 +++++++++++ .../sooyoungCho/013.find-planet/README.md | 15 +++++++++++ .../sooyoungCho/013.find-planet/solve.js | 21 ++++++++++++++++ Challenge/sooyoungCho/014.if/README.md | 17 +++++++++++++ Challenge/sooyoungCho/014.if/solve.js | 25 +++++++++++++++++++ .../015.template _literals/README.md | 13 ++++++++++ .../015.template _literals/solve.js | 17 +++++++++++++ 8 files changed, 133 insertions(+) create mode 100644 Challenge/sooyoungCho/011.for/README.md create mode 100644 Challenge/sooyoungCho/011.for/solve.js create mode 100644 Challenge/sooyoungCho/013.find-planet/README.md create mode 100644 Challenge/sooyoungCho/013.find-planet/solve.js create mode 100644 Challenge/sooyoungCho/014.if/README.md create mode 100644 Challenge/sooyoungCho/014.if/solve.js create mode 100644 Challenge/sooyoungCho/015.template _literals/README.md create mode 100644 Challenge/sooyoungCho/015.template _literals/solve.js diff --git a/Challenge/sooyoungCho/011.for/README.md b/Challenge/sooyoungCho/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/sooyoungCho/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/011.for/solve.js b/Challenge/sooyoungCho/011.for/solve.js new file mode 100644 index 0000000..572910c --- /dev/null +++ b/Challenge/sooyoungCho/011.for/solve.js @@ -0,0 +1,14 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. +*/ + +let s = 0; + +//pass +for(i = 1; i <= 100; i++){ + s += i; +} + +console.log(s); diff --git a/Challenge/sooyoungCho/013.find-planet/README.md b/Challenge/sooyoungCho/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/sooyoungCho/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/013.find-planet/solve.js b/Challenge/sooyoungCho/013.find-planet/solve.js new file mode 100644 index 0000000..b730889 --- /dev/null +++ b/Challenge/sooyoungCho/013.find-planet/solve.js @@ -0,0 +1,21 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +const planet = ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']; + +const n = prompt('몇 번째 행성인가요?'); + +console.log(planet[n-1]); \ No newline at end of file diff --git a/Challenge/sooyoungCho/014.if/README.md b/Challenge/sooyoungCho/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Challenge/sooyoungCho/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/014.if/solve.js b/Challenge/sooyoungCho/014.if/solve.js new file mode 100644 index 0000000..68cce6d --- /dev/null +++ b/Challenge/sooyoungCho/014.if/solve.js @@ -0,0 +1,25 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +*/ + +const n = prompt('숫자를 입력하시오!'); + +if(n % 3 == 0){ + console.log('짝'); +} else { + console.log(n); +} \ No newline at end of file diff --git a/Challenge/sooyoungCho/015.template _literals/README.md b/Challenge/sooyoungCho/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/sooyoungCho/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/sooyoungCho/015.template _literals/solve.js b/Challenge/sooyoungCho/015.template _literals/solve.js new file mode 100644 index 0000000..fbe0aa0 --- /dev/null +++ b/Challenge/sooyoungCho/015.template _literals/solve.js @@ -0,0 +1,17 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ + +const name = prompt('이름을 입력하시오!'); + +console.log(`안녕하세요. 저는 ${name}입니다.`); \ No newline at end of file From ea4e2106056421500d4d3f89db18a14b5c6c5f9d Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Tue, 7 Jun 2022 23:38:24 +0900 Subject: [PATCH 152/308] =?UTF-8?q?Solve=20:=2033=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/033.Reverse/README.md | 13 +++++++++++++ Challenge/Songmyeongseok/033.Reverse/solve.js | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Challenge/Songmyeongseok/033.Reverse/README.md create mode 100644 Challenge/Songmyeongseok/033.Reverse/solve.js diff --git a/Challenge/Songmyeongseok/033.Reverse/README.md b/Challenge/Songmyeongseok/033.Reverse/README.md new file mode 100644 index 0000000..7d450ce --- /dev/null +++ b/Challenge/Songmyeongseok/033.Reverse/README.md @@ -0,0 +1,13 @@ +# 문제33 : 거꾸로 출력하기 + +한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +```jsx +**입출력** +입력 : 1 2 3 4 5 +출력 : 5 4 3 2 1 + +**출력** +입력 : 2 4 6 7 8 +출력 : 8 7 6 4 2 +``` diff --git a/Challenge/Songmyeongseok/033.Reverse/solve.js b/Challenge/Songmyeongseok/033.Reverse/solve.js new file mode 100644 index 0000000..b1b1054 --- /dev/null +++ b/Challenge/Songmyeongseok/033.Reverse/solve.js @@ -0,0 +1,17 @@ +// # 문제33 : 거꾸로 출력하기 + +// 한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +// ```jsx +// **입출력** +// 입력 : 1 2 3 4 5 +// 출력 : 5 4 3 2 1 + +// **출력** +// 입력 : 2 4 6 7 8 +// 출력 : 8 7 6 4 2 +// ``` + +function reverse_string(x){ + return x.toString().split('').reverse().join() +} \ No newline at end of file From 7b4fdfee856665b32ae9db8621a656ed56c2aa6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=88=98=EC=98=81?= Date: Tue, 7 Jun 2022 23:49:39 +0900 Subject: [PATCH 153/308] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 88799d643674e109c559fbc034af888502d13dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~L2uJA6vv;p01nfn9zcQvQY5ZZ$p}D-)+pF!@#X-+q42seh8=n25w+nr#yGh)ANadUsL%!FZg@lC4+| z4+@^+b*Vn5rApD~37t6tj=;Z7fcLIPeLAFqn(qD;UoqDIrA;s5JT9HpCw8CzNKeY5 zZo=@VSXuRM-M%BGT$3N;BQ=Ygq?y)(Wb&SSZcW*~kO;S|(L?;wk zj*t%rMU|=9KuxQx*1546kiPGadJpIG%`gl%g6;76Vk4Npc#8Jcv#rI#m-in(dAUD2 zF2|MPKMxalF=<=3dM4k{IA740cv6+BI)snoecGWTN~pvyrwVZLE*g4;sNc~@dP5UZ zl!K2mE}%l!*_9BmTSKm0$?R@YN5B#I zp9%2$AwXe`thPq=s{@t30zf^uwV|y){hQlTbQ*eiyxHwR(TF&^3Y z)~HD*p`VO-?30DPp$L2N5P=RS5gB#0Bj5;h39OoKkI( Date: Wed, 8 Jun 2022 00:13:05 +0900 Subject: [PATCH 154/308] =?UTF-8?q?Solve=20:=2030=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JihoonChae/030.find-string/README.md | 15 ++++++++++++++ Challenge/JihoonChae/030.find-string/solve.js | 20 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Challenge/JihoonChae/030.find-string/README.md create mode 100644 Challenge/JihoonChae/030.find-string/solve.js diff --git a/Challenge/JihoonChae/030.find-string/README.md b/Challenge/JihoonChae/030.find-string/README.md new file mode 100644 index 0000000..b2f4ed6 --- /dev/null +++ b/Challenge/JihoonChae/030.find-string/README.md @@ -0,0 +1,15 @@ +# 문제30 : 문자열 속 문자 찾기 + +문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +**그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +```jsx +**입력** +pineapple is yummy +apple + +**출력** +4 +``` \ No newline at end of file diff --git a/Challenge/JihoonChae/030.find-string/solve.js b/Challenge/JihoonChae/030.find-string/solve.js new file mode 100644 index 0000000..02989d5 --- /dev/null +++ b/Challenge/JihoonChae/030.find-string/solve.js @@ -0,0 +1,20 @@ +// # 문제30 : 문자열 속 문자 찾기 + +// 문자 pineapple에는 apple이라는 문자가 숨어 있습니다. 원범이는 이렇듯 문자열 속에 숨어있는 문자를 찾아보려고 합니다. + +// 첫번째 입력에서는 문자열이 입력되고, 두번째에는 찾을 문자가 입력되어야 합니다. +// **그 문자가 시작하는 index를 반환하는 프로그램**을 만들어 주세요 + +// ```jsx +// **입력** +// pineapple is yummy +// apple + +// **출력** +// 4 +// ``` + +const data = prompt('문자열을 입력하세요'); +const word = prompt('찾을 단어를 입력하세요'); + +console.log(data.indexOf(word)); \ No newline at end of file From 041a22cc131f5d00213d0bf757aae34490619330 Mon Sep 17 00:00:00 2001 From: subincdev Date: Wed, 8 Jun 2022 23:11:45 +0900 Subject: [PATCH 155/308] =?UTF-8?q?Docs=20:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 11,12,13번 문제를 Problems js파일에서 풀어서 해당 부분을 삭제하였습니다 --- Problems/011.for/solve.js | 6 -- Problems/012.class/solve.js | 15 ----- Problems/013.find-planet/solve.js | 100 ------------------------------ 3 files changed, 121 deletions(-) diff --git a/Problems/011.for/solve.js b/Problems/011.for/solve.js index fd4d891..b4d4559 100644 --- a/Problems/011.for/solve.js +++ b/Problems/011.for/solve.js @@ -9,9 +9,3 @@ let s = 0; console.log(s); */ - -let s = 0; -for (let i = 1; i <= 100; i++) { - s += i; -} -console.log(s); diff --git a/Problems/012.class/solve.js b/Problems/012.class/solve.js index ebf42bb..eb9bab6 100644 --- a/Problems/012.class/solve.js +++ b/Problems/012.class/solve.js @@ -15,18 +15,3 @@ x.attack(); 545 210 10 파이어볼 */ - -class Wizard { - constructor(health, mana, armor) { - this.health = health; - this.mana = mana; - this.armor = armor; - } - attack() { - console.log("파이어볼"); - } -} - -const x = new Wizard(545, 210, 10); -console.log(x.health, x.mana, x.armor); -x.attack(); diff --git a/Problems/013.find-planet/solve.js b/Problems/013.find-planet/solve.js index 937f862..9394f23 100644 --- a/Problems/013.find-planet/solve.js +++ b/Problems/013.find-planet/solve.js @@ -13,103 +13,3 @@ 입력 : 1 출력 : 수성 */ - -// const arr = [ -// "수성", -// "금성", -// "지구", -// "화성", -// "목성", -// "토성", -// "천왕성", -// "해왕성", -// ]; -// 1트 -// const answer = prompt("숫자를 입력해주세요"); -// if (answer > 8 || answer < 1) { -// alert("다시 입력해주세요"); -// prompt("숫자를 입력해주세요"); -// console.log(arr[answer - 1]); -// } else { -// console.log(arr[answer - 1]); -// } - -// 오류 -// function galaxy() { -// const answer = prompt("숫자를 입력해주세요"); -// if ((answer > 8 || answer < 1) && typeof answer !== "number") { -// console.log(typeof answer); -// // alert("1과 8사이 숫자로 다시 입력해주세요"); -// return galaxy(); -// } -// console.log(arr[answer - 1]); -// } - -// galaxy(); - -// function galaxy() { -// const answer = prompt("1부터 8사이의 숫자를 입력해주세요"); - -// if (Number(answer) > 8 || Number(answer) < 1) { -// alert("다시 입력해주세요!"); -// return galaxy(); -// } -// console.log(arr[answer - 1]); -// } - -// galaxy(); - -// prompt 는 사용자의 입력값을 모두 문자열로 처리해줌 -// 1. 숫자로 바꾸고 NaN인지 확인 -// NaN == NaN false라서 안됨 -// function galaxy() { -// const answer = prompt("숫자를 입력해주세요"); -// if (Number(answer) == NaN) { -// return galaxy(); -// } else if (Number(answer) > 8 || Number(answer) < 1) { -// alert("1-8 사이의 수를 입력해주세요!"); -// return galaxy(); -// } -// console.log(arr[answer - 1]); -// } - -// galaxy(); - -// 정답 -const arr = [ - "수성", - "금성", - "지구", - "화성", - "목성", - "토성", - "천왕성", - "해왕성", -]; - -//1. isNaN -// function galaxy() { -// const answer = prompt("숫자를 입력해주세요"); -// if (isNaN(Number(answer))) { -// alert("숫자만 입력이 가능합니다."); -// return galaxy(); -// } else if (Number(answer) > 8 || Number(answer) < 1) { -// alert("1-8 사이의 수를 입력해주세요!"); -// return galaxy(); -// } -// console.log(arr[answer - 1]); -// } - -// galaxy(); -// 2. 정규식 사용 -function galaxy() { - const regExp = /[1-8]/g; - const answer = prompt("숫자를 입력해주세요"); - if (!regExp.test(Number(answer))) { - alert("1-8사이의 숫자만 입력이 가능합니다."); - return galaxy(); - } - console.log(arr[answer - 1]); -} - -galaxy(); From d2395e01a27d0a63a733c32240f54cd1ccffebdf Mon Sep 17 00:00:00 2001 From: subincdev Date: Wed, 8 Jun 2022 23:13:37 +0900 Subject: [PATCH 156/308] =?UTF-8?q?Docs=20:=20011~013=20solve=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 문제해결 파일이 잘못된 경로에 있어 올바른 경로로 수정하였습니다 --- Challenge/SubinChoi/011.for/README.md | 11 ++ Challenge/SubinChoi/011.for/solve.js | 17 +++ Challenge/SubinChoi/012.class/README.md | 17 +++ Challenge/SubinChoi/012.class/solve.js | 32 +++++ Challenge/SubinChoi/013.find-planet/README.md | 15 +++ Challenge/SubinChoi/013.find-planet/solve.js | 115 ++++++++++++++++++ 6 files changed, 207 insertions(+) create mode 100644 Challenge/SubinChoi/011.for/README.md create mode 100644 Challenge/SubinChoi/011.for/solve.js create mode 100644 Challenge/SubinChoi/012.class/README.md create mode 100644 Challenge/SubinChoi/012.class/solve.js create mode 100644 Challenge/SubinChoi/013.find-planet/README.md create mode 100644 Challenge/SubinChoi/013.find-planet/solve.js diff --git a/Challenge/SubinChoi/011.for/README.md b/Challenge/SubinChoi/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/SubinChoi/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/011.for/solve.js b/Challenge/SubinChoi/011.for/solve.js new file mode 100644 index 0000000..fd4d891 --- /dev/null +++ b/Challenge/SubinChoi/011.for/solve.js @@ -0,0 +1,17 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass + +console.log(s); +*/ + +let s = 0; +for (let i = 1; i <= 100; i++) { + s += i; +} +console.log(s); diff --git a/Challenge/SubinChoi/012.class/README.md b/Challenge/SubinChoi/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/SubinChoi/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/012.class/solve.js b/Challenge/SubinChoi/012.class/solve.js new file mode 100644 index 0000000..ebf42bb --- /dev/null +++ b/Challenge/SubinChoi/012.class/solve.js @@ -0,0 +1,32 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ + +class Wizard { + constructor(health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + attack() { + console.log("파이어볼"); + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); diff --git a/Challenge/SubinChoi/013.find-planet/README.md b/Challenge/SubinChoi/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/SubinChoi/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/013.find-planet/solve.js b/Challenge/SubinChoi/013.find-planet/solve.js new file mode 100644 index 0000000..937f862 --- /dev/null +++ b/Challenge/SubinChoi/013.find-planet/solve.js @@ -0,0 +1,115 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +// const arr = [ +// "수성", +// "금성", +// "지구", +// "화성", +// "목성", +// "토성", +// "천왕성", +// "해왕성", +// ]; +// 1트 +// const answer = prompt("숫자를 입력해주세요"); +// if (answer > 8 || answer < 1) { +// alert("다시 입력해주세요"); +// prompt("숫자를 입력해주세요"); +// console.log(arr[answer - 1]); +// } else { +// console.log(arr[answer - 1]); +// } + +// 오류 +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if ((answer > 8 || answer < 1) && typeof answer !== "number") { +// console.log(typeof answer); +// // alert("1과 8사이 숫자로 다시 입력해주세요"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// function galaxy() { +// const answer = prompt("1부터 8사이의 숫자를 입력해주세요"); + +// if (Number(answer) > 8 || Number(answer) < 1) { +// alert("다시 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// prompt 는 사용자의 입력값을 모두 문자열로 처리해줌 +// 1. 숫자로 바꾸고 NaN인지 확인 +// NaN == NaN false라서 안됨 +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if (Number(answer) == NaN) { +// return galaxy(); +// } else if (Number(answer) > 8 || Number(answer) < 1) { +// alert("1-8 사이의 수를 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); + +// 정답 +const arr = [ + "수성", + "금성", + "지구", + "화성", + "목성", + "토성", + "천왕성", + "해왕성", +]; + +//1. isNaN +// function galaxy() { +// const answer = prompt("숫자를 입력해주세요"); +// if (isNaN(Number(answer))) { +// alert("숫자만 입력이 가능합니다."); +// return galaxy(); +// } else if (Number(answer) > 8 || Number(answer) < 1) { +// alert("1-8 사이의 수를 입력해주세요!"); +// return galaxy(); +// } +// console.log(arr[answer - 1]); +// } + +// galaxy(); +// 2. 정규식 사용 +function galaxy() { + const regExp = /[1-8]/g; + const answer = prompt("숫자를 입력해주세요"); + if (!regExp.test(Number(answer))) { + alert("1-8사이의 숫자만 입력이 가능합니다."); + return galaxy(); + } + console.log(arr[answer - 1]); +} + +galaxy(); From 6637b71716c0edf3ff64c81222bdca0efd7d49e1 Mon Sep 17 00:00:00 2001 From: subincdev Date: Wed, 8 Jun 2022 23:48:58 +0900 Subject: [PATCH 157/308] =?UTF-8?q?Slove=20:=20014~016=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinChoi/014.if/README.md | 17 ++++++++++++ Challenge/SubinChoi/014.if/solve.js | 24 +++++++++++++++++ .../015.template _literals/README.md | 13 ++++++++++ .../SubinChoi/015.template _literals/solve.js | 16 ++++++++++++ .../README.md" | 10 +++++++ .../solve.js" | 26 +++++++++++++++++++ 6 files changed, 106 insertions(+) create mode 100644 Challenge/SubinChoi/014.if/README.md create mode 100644 Challenge/SubinChoi/014.if/solve.js create mode 100644 Challenge/SubinChoi/015.template _literals/README.md create mode 100644 Challenge/SubinChoi/015.template _literals/solve.js create mode 100644 "Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/solve.js" diff --git a/Challenge/SubinChoi/014.if/README.md b/Challenge/SubinChoi/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Challenge/SubinChoi/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/014.if/solve.js b/Challenge/SubinChoi/014.if/solve.js new file mode 100644 index 0000000..7f08572 --- /dev/null +++ b/Challenge/SubinChoi/014.if/solve.js @@ -0,0 +1,24 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +*/ + +const input = Number(prompt("숫자를 입력해주세요")); +if (input % 3 == 0 && input != 0) { + console.log("짝"); +} else { + console.log(input); +} diff --git a/Challenge/SubinChoi/015.template _literals/README.md b/Challenge/SubinChoi/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/SubinChoi/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/SubinChoi/015.template _literals/solve.js b/Challenge/SubinChoi/015.template _literals/solve.js new file mode 100644 index 0000000..8d2a089 --- /dev/null +++ b/Challenge/SubinChoi/015.template _literals/solve.js @@ -0,0 +1,16 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +*/ + +const input = prompt("당신의 이름은?"); +console.log(`안녕하세요. 저는 ${input}입니다.`); diff --git "a/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..ae3f4c8 --- /dev/null +++ "b/Challenge/SubinChoi/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,26 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +*/ + +//구차한 나의 답.. +const input = prompt("거꾸로 출력하고 싶은 단어를 입력하세요"); + +let upsideDown = ""; +for (let i = input.length - 1; i >= 0; i--) { + upsideDown += input[i]; +} +console.log(upsideDown); + +/*훨씬 깔끔하고 좋은 정답 +const reverseString = n.split('').reverse().join('');*/ +/* + * split() 메서드는 문자열을 배열로 만들어 반환하고, << 이 부분을 놓쳤음 + * reverse() 메서드는 배열의 순서를 반전하며, + * join() 메서드는 원소를 모두 붙여 문자열로 반환합니다. + */ From a35bb3792dc86c165a2fbb722a66d5530dcc39bc Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Thu, 9 Jun 2022 00:01:41 +0900 Subject: [PATCH 158/308] =?UTF-8?q?Solve:=2013-15=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/sehunKim/013.find-planet/README.md | 15 ++++++++++++ Challenge/sehunKim/013.find-planet/solve.js | 21 +++++++++++++++++ Challenge/sehunKim/014.if/README.md | 17 ++++++++++++++ Challenge/sehunKim/014.if/solve.js | 23 +++++++++++++++++++ .../sehunKim/015.template _literals/README.md | 13 +++++++++++ .../sehunKim/015.template _literals/solve.js | 18 +++++++++++++++ 6 files changed, 107 insertions(+) create mode 100644 Challenge/sehunKim/013.find-planet/README.md create mode 100644 Challenge/sehunKim/013.find-planet/solve.js create mode 100644 Challenge/sehunKim/014.if/README.md create mode 100644 Challenge/sehunKim/014.if/solve.js create mode 100644 Challenge/sehunKim/015.template _literals/README.md create mode 100644 Challenge/sehunKim/015.template _literals/solve.js diff --git a/Challenge/sehunKim/013.find-planet/README.md b/Challenge/sehunKim/013.find-planet/README.md new file mode 100644 index 0000000..8afacd3 --- /dev/null +++ b/Challenge/sehunKim/013.find-planet/README.md @@ -0,0 +1,15 @@ +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +```jsx +**입출력** + +입력 : 1 +출력 : 수성 +``` \ No newline at end of file diff --git a/Challenge/sehunKim/013.find-planet/solve.js b/Challenge/sehunKim/013.find-planet/solve.js new file mode 100644 index 0000000..df361e3 --- /dev/null +++ b/Challenge/sehunKim/013.find-planet/solve.js @@ -0,0 +1,21 @@ +/* +# 문제13 : 몇 번째 행성인가요? + +우리 태양계를 이루고 있는 행성은 **수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성**으로 총 8개 입니다. 저희는 우리 태양계의 n번째 행성이 무엇인지 알고 싶습니다. + +입력으로 행성의 순서를 나타내는 숫자 n이 입력됩니다. +출력으로 그 순서에 해당하는 행성의 이름을 출력해 주세요. + +예를들어 1이 입력되면, 첫번째 행성인 수성이 출력됩니다. + +**입출력** + +입력 : 1 +출력 : 수성 +*/ + +// 정답 : +const planet = ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']; +let n = prompt('숫자를 입력하세요.'); +console.log(planet[n-1]); + diff --git a/Challenge/sehunKim/014.if/README.md b/Challenge/sehunKim/014.if/README.md new file mode 100644 index 0000000..488df61 --- /dev/null +++ b/Challenge/sehunKim/014.if/README.md @@ -0,0 +1,17 @@ +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +```jsx +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 +``` \ No newline at end of file diff --git a/Challenge/sehunKim/014.if/solve.js b/Challenge/sehunKim/014.if/solve.js new file mode 100644 index 0000000..32bc412 --- /dev/null +++ b/Challenge/sehunKim/014.if/solve.js @@ -0,0 +1,23 @@ +/* +# 문제14 : 3의 배수 인가요? + +영희는 친구와 게임을 하고 있습니다. 서로 돌아가며 랜덤으로 숫자를 하나 말하고 그게 3의 배수이면 박수를 치고 아니면 그 숫자를 그대로 말하는 게임입니다. + +입력으로 랜덤한 숫자 n이 주어집니다. + +만약 그 수가 **3의 배수라면 '짝'이라는 글자를, 3의 배수가 아니라면 n을 그대로 출력**해 주세요. + +**입출력** + +입력 : 3 +출력 : 짝 + +입력 : 2 +출력 : 2 + +정답: if (n%3 == 0) { + console.log('짝'); +} else { + console.log(n); +} +*/ \ No newline at end of file diff --git a/Challenge/sehunKim/015.template _literals/README.md b/Challenge/sehunKim/015.template _literals/README.md new file mode 100644 index 0000000..2056ef3 --- /dev/null +++ b/Challenge/sehunKim/015.template _literals/README.md @@ -0,0 +1,13 @@ +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +```jsx +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. +``` \ No newline at end of file diff --git a/Challenge/sehunKim/015.template _literals/solve.js b/Challenge/sehunKim/015.template _literals/solve.js new file mode 100644 index 0000000..a43fc16 --- /dev/null +++ b/Challenge/sehunKim/015.template _literals/solve.js @@ -0,0 +1,18 @@ +/* +# 문제15 : 자기소개 + +신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다. + +만약 입력으로 `김다정`이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 +해주세요. + +**입출력** + +입력 : 김다정 +출력 : 안녕하세요. 저는 김다정입니다. + +정답 : +let 이름 = prompt('이름을 입력하세요'); +console.log(`안녕하세요. 저는 ${이름}입니다.`); + +*/ \ No newline at end of file From 32997f0efd457351a85f095f2fbeb2ae02fd12eb Mon Sep 17 00:00:00 2001 From: plutoin Date: Thu, 9 Jun 2022 00:16:36 +0900 Subject: [PATCH 159/308] =?UTF-8?q?Solve:=2026=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/026.planet_2/README.md | 6 ++++++ Challenge/SoyeonJang/026.planet_2/solve.js | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 Challenge/SoyeonJang/026.planet_2/README.md create mode 100644 Challenge/SoyeonJang/026.planet_2/solve.js diff --git a/Challenge/SoyeonJang/026.planet_2/README.md b/Challenge/SoyeonJang/026.planet_2/README.md new file mode 100644 index 0000000..678e82a --- /dev/null +++ b/Challenge/SoyeonJang/026.planet_2/README.md @@ -0,0 +1,6 @@ +# 문제26 : 행성 문제2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git a/Challenge/SoyeonJang/026.planet_2/solve.js b/Challenge/SoyeonJang/026.planet_2/solve.js new file mode 100644 index 0000000..0f37d3b --- /dev/null +++ b/Challenge/SoyeonJang/026.planet_2/solve.js @@ -0,0 +1,19 @@ +// 문제26 : 행성 문제2 + +// 우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +// 이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +// 행성의 한글 이름을 입력하면 영어 이름을 반환하는 프로그램을 만들어 주세요. + +let planet = { + 수성: "Mercury", + 금성: "Venus", + 지구: "Earth", + 화성: "Mars", + 목성: "Jupiter", + 토성: "Saturn", + 천왕성: "Uranus", + 해왕성: "Neptune" +} + +console.log(planet.수성) \ No newline at end of file From 263bad5b0b488cbbe754355a7a1933798785728a Mon Sep 17 00:00:00 2001 From: Subin Date: Thu, 9 Jun 2022 02:28:11 +0900 Subject: [PATCH 160/308] =?UTF-8?q?solve:1-5=EB=B2=88=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinLee/1.arry/README.md | 5 ----- Challenge/SubinLee/1.arry/solve.js | 4 ---- 2 files changed, 9 deletions(-) delete mode 100644 Challenge/SubinLee/1.arry/README.md delete mode 100644 Challenge/SubinLee/1.arry/solve.js diff --git a/Challenge/SubinLee/1.arry/README.md b/Challenge/SubinLee/1.arry/README.md deleted file mode 100644 index d5088f4..0000000 --- a/Challenge/SubinLee/1.arry/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 문제1 : 배열의 삭제 - -다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SubinLee/1.arry/solve.js b/Challenge/SubinLee/1.arry/solve.js deleted file mode 100644 index b7ddb52..0000000 --- a/Challenge/SubinLee/1.arry/solve.js +++ /dev/null @@ -1,4 +0,0 @@ -// # 문제1 : 배열의 삭제 -// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; From 64cdfc4b4b41b9e0277c61a3b99d11b4b7de3be2 Mon Sep 17 00:00:00 2001 From: Subin Date: Thu, 9 Jun 2022 02:33:40 +0900 Subject: [PATCH 161/308] =?UTF-8?q?solve:=201-5=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinLee/1.arry/README.md | 5 +++++ Challenge/SubinLee/1.arry/solve.js | 9 +++++++++ Challenge/SubinLee/2.arryMethd/README.md | 11 +++++++++++ Challenge/SubinLee/2.arryMethd/solve.js | 10 ++++++++++ Challenge/SubinLee/3.type/README.md | 13 +++++++++++++ Challenge/SubinLee/3.type/solve.js | 11 +++++++++++ Challenge/SubinLee/4.type(2)/README.md | 8 ++++++++ Challenge/SubinLee/4.type(2)/solve.js | 10 ++++++++++ Challenge/SubinLee/5.for/README.md | 20 ++++++++++++++++++++ Challenge/SubinLee/5.for/solve.js | 21 +++++++++++++++++++++ 10 files changed, 118 insertions(+) create mode 100644 Challenge/SubinLee/1.arry/README.md create mode 100644 Challenge/SubinLee/1.arry/solve.js create mode 100644 Challenge/SubinLee/2.arryMethd/README.md create mode 100644 Challenge/SubinLee/2.arryMethd/solve.js create mode 100644 Challenge/SubinLee/3.type/README.md create mode 100644 Challenge/SubinLee/3.type/solve.js create mode 100644 Challenge/SubinLee/4.type(2)/README.md create mode 100644 Challenge/SubinLee/4.type(2)/solve.js create mode 100644 Challenge/SubinLee/5.for/README.md create mode 100644 Challenge/SubinLee/5.for/solve.js diff --git a/Challenge/SubinLee/1.arry/README.md b/Challenge/SubinLee/1.arry/README.md new file mode 100644 index 0000000..d5088f4 --- /dev/null +++ b/Challenge/SubinLee/1.arry/README.md @@ -0,0 +1,5 @@ +# 문제1 : 배열의 삭제 + +다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Challenge/SubinLee/1.arry/solve.js b/Challenge/SubinLee/1.arry/solve.js new file mode 100644 index 0000000..fa8b1dc --- /dev/null +++ b/Challenge/SubinLee/1.arry/solve.js @@ -0,0 +1,9 @@ +// # 문제1 : 배열의 삭제 +// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. + +var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); + +console.log(nums); diff --git a/Challenge/SubinLee/2.arryMethd/README.md b/Challenge/SubinLee/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/SubinLee/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/SubinLee/2.arryMethd/solve.js b/Challenge/SubinLee/2.arryMethd/solve.js new file mode 100644 index 0000000..539cff9 --- /dev/null +++ b/Challenge/SubinLee/2.arryMethd/solve.js @@ -0,0 +1,10 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +var arr = [200, 100, 300]; +//pass +arr.splice(2, 0, 10000); +console.log(arr); + +// 출력[(200, 100, 10000, 300)]; diff --git a/Challenge/SubinLee/3.type/README.md b/Challenge/SubinLee/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/SubinLee/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/SubinLee/3.type/solve.js b/Challenge/SubinLee/3.type/solve.js new file mode 100644 index 0000000..33d3eec --- /dev/null +++ b/Challenge/SubinLee/3.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? 4번 + +var arr = [100, 200, 300]; +console.log(typeof arr); //object + +// 1) undefined +// 2) string +// 3) number +// 4) object diff --git a/Challenge/SubinLee/4.type(2)/README.md b/Challenge/SubinLee/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/SubinLee/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/SubinLee/4.type(2)/solve.js b/Challenge/SubinLee/4.type(2)/solve.js new file mode 100644 index 0000000..40c49d5 --- /dev/null +++ b/Challenge/SubinLee/4.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답 : 2번 diff --git a/Challenge/SubinLee/5.for/README.md b/Challenge/SubinLee/5.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/SubinLee/5.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/SubinLee/5.for/solve.js b/Challenge/SubinLee/5.for/solve.js new file mode 100644 index 0000000..15c47cf --- /dev/null +++ b/Challenge/SubinLee/5.for/solve.js @@ -0,0 +1,21 @@ +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); //3번 14 + +// i 한번 반복할때마다 +2 +// i = 1 10 +1 = 11 +// i = 3 11 +3 = 14 + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 From af991e61aa094d1db9dd6f639d1ef3ad75528a1f Mon Sep 17 00:00:00 2001 From: Subin Date: Thu, 9 Jun 2022 02:40:22 +0900 Subject: [PATCH 162/308] =?UTF-8?q?solve=20:=201-5=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SubinLee/1.arry/solve.js | 5 +++++ Challenge/SubinLee/2.arryMethd/README.md | 11 +++++++++++ Challenge/SubinLee/2.arryMethd/solve.js | 10 ++++++++++ Challenge/SubinLee/3.type/README.md | 13 +++++++++++++ Challenge/SubinLee/3.type/solve.js | 11 +++++++++++ Challenge/SubinLee/4.type(2)/README.md | 8 ++++++++ Challenge/SubinLee/4.type(2)/solve.js | 10 ++++++++++ Challenge/SubinLee/5.for/README.md | 20 ++++++++++++++++++++ Challenge/SubinLee/5.for/solve.js | 21 +++++++++++++++++++++ 9 files changed, 109 insertions(+) create mode 100644 Challenge/SubinLee/2.arryMethd/README.md create mode 100644 Challenge/SubinLee/2.arryMethd/solve.js create mode 100644 Challenge/SubinLee/3.type/README.md create mode 100644 Challenge/SubinLee/3.type/solve.js create mode 100644 Challenge/SubinLee/4.type(2)/README.md create mode 100644 Challenge/SubinLee/4.type(2)/solve.js create mode 100644 Challenge/SubinLee/5.for/README.md create mode 100644 Challenge/SubinLee/5.for/solve.js diff --git a/Challenge/SubinLee/1.arry/solve.js b/Challenge/SubinLee/1.arry/solve.js index b7ddb52..fa8b1dc 100644 --- a/Challenge/SubinLee/1.arry/solve.js +++ b/Challenge/SubinLee/1.arry/solve.js @@ -2,3 +2,8 @@ // 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. var nums = [100, 200, 300, 400, 500]; + +nums.pop(); +nums.pop(); + +console.log(nums); diff --git a/Challenge/SubinLee/2.arryMethd/README.md b/Challenge/SubinLee/2.arryMethd/README.md new file mode 100644 index 0000000..01d8d19 --- /dev/null +++ b/Challenge/SubinLee/2.arryMethd/README.md @@ -0,0 +1,11 @@ +# 문제2 : 배열의 내장함수 + +부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +데이터 +var arr = [200, 100, 300]; +//pass +console.log(arr); + +출력 +[200, 100, 10000, 300] \ No newline at end of file diff --git a/Challenge/SubinLee/2.arryMethd/solve.js b/Challenge/SubinLee/2.arryMethd/solve.js new file mode 100644 index 0000000..539cff9 --- /dev/null +++ b/Challenge/SubinLee/2.arryMethd/solve.js @@ -0,0 +1,10 @@ +// # 문제2 : 배열의 내장함수 + +// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. + +var arr = [200, 100, 300]; +//pass +arr.splice(2, 0, 10000); +console.log(arr); + +// 출력[(200, 100, 10000, 300)]; diff --git a/Challenge/SubinLee/3.type/README.md b/Challenge/SubinLee/3.type/README.md new file mode 100644 index 0000000..79ab0fb --- /dev/null +++ b/Challenge/SubinLee/3.type/README.md @@ -0,0 +1,13 @@ +# 문제3 : 변수의 타입 + +다음 출력 값으로 올바른 것은? + +```jsx +var arr = [100, 200, 300]; +console.log(typeof(arr)); +``` + +1) undefined +2) string +3) number +4) object \ No newline at end of file diff --git a/Challenge/SubinLee/3.type/solve.js b/Challenge/SubinLee/3.type/solve.js new file mode 100644 index 0000000..33d3eec --- /dev/null +++ b/Challenge/SubinLee/3.type/solve.js @@ -0,0 +1,11 @@ +// # 문제3 : 변수의 타입 + +// 다음 출력 값으로 올바른 것은? 4번 + +var arr = [100, 200, 300]; +console.log(typeof arr); //object + +// 1) undefined +// 2) string +// 3) number +// 4) object diff --git a/Challenge/SubinLee/4.type(2)/README.md b/Challenge/SubinLee/4.type(2)/README.md new file mode 100644 index 0000000..46ff4b1 --- /dev/null +++ b/Challenge/SubinLee/4.type(2)/README.md @@ -0,0 +1,8 @@ +# 문제4 : 변수의 타입2 + +다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +1. 입력 : a =1, 출력 : number +2. 입력 : a = 2.22, 출력 : boolean +3. 입력 : a = 'p', 출력 : string +4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Challenge/SubinLee/4.type(2)/solve.js b/Challenge/SubinLee/4.type(2)/solve.js new file mode 100644 index 0000000..40c49d5 --- /dev/null +++ b/Challenge/SubinLee/4.type(2)/solve.js @@ -0,0 +1,10 @@ +// # 문제4 : 변수의 타입2 + +// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? + +// 1) 입력 : a =1, 출력 : number +// 2) 입력 : a = 2.22, 출력 : boolean +// 3) 입력 : a = 'p', 출력 : string +// 4) 입력 : a = [1, 2, 3], 출력 : object + +// 정답 : 2번 diff --git a/Challenge/SubinLee/5.for/README.md b/Challenge/SubinLee/5.for/README.md new file mode 100644 index 0000000..e704b38 --- /dev/null +++ b/Challenge/SubinLee/5.for/README.md @@ -0,0 +1,20 @@ + +# 문제 5 for문 계산 + +다음 코드의 출력 값으로 알맞은 것은? + +```jsx +var a = 10; +var b = 2; + +for(var i=1; i<5; i+=2){ + a += i; +} + +console.log(a+b); +``` + +1) 10 +2) 12 +3) 14 +4) 16 \ No newline at end of file diff --git a/Challenge/SubinLee/5.for/solve.js b/Challenge/SubinLee/5.for/solve.js new file mode 100644 index 0000000..15c47cf --- /dev/null +++ b/Challenge/SubinLee/5.for/solve.js @@ -0,0 +1,21 @@ +// # 문제 5 for문 계산 + +// 다음 코드의 출력 값으로 알맞은 것은? + +var a = 10; +var b = 2; + +for (var i = 1; i < 5; i += 2) { + a += i; +} + +console.log(a + b); //3번 14 + +// i 한번 반복할때마다 +2 +// i = 1 10 +1 = 11 +// i = 3 11 +3 = 14 + +// 1) 10 +// 2) 12 +// 3) 14 +// 4) 16 From 7413c174a85cfb67b277230c357b75d27070f39a Mon Sep 17 00:00:00 2001 From: jsk3342 Date: Thu, 9 Jun 2022 08:52:18 +0900 Subject: [PATCH 163/308] =?UTF-8?q?Solve=20:=20009=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/JisuKim/009.concat/README.md | 20 +++++++++++++++++ Challenge/JisuKim/009.concat/solve.js | 30 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 Challenge/JisuKim/009.concat/README.md create mode 100644 Challenge/JisuKim/009.concat/solve.js diff --git a/Challenge/JisuKim/009.concat/README.md b/Challenge/JisuKim/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/JisuKim/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/JisuKim/009.concat/solve.js b/Challenge/JisuKim/009.concat/solve.js new file mode 100644 index 0000000..5339ec6 --- /dev/null +++ b/Challenge/JisuKim/009.concat/solve.js @@ -0,0 +1,30 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = year.concat(`/${month}/${day} ${hour}:${minute}:${second}`) + +console.log(result) \ No newline at end of file From 165647caaa28af144d2d0bf51daa0e8b83631107 Mon Sep 17 00:00:00 2001 From: plutoin Date: Thu, 9 Jun 2022 17:57:56 +0900 Subject: [PATCH 164/308] =?UTF-8?q?Solve:=2027=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/027.object/README.md | 14 ++++++++++++++ Challenge/SoyeonJang/027.object/solve.js | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Challenge/SoyeonJang/027.object/README.md create mode 100644 Challenge/SoyeonJang/027.object/solve.js diff --git a/Challenge/SoyeonJang/027.object/README.md b/Challenge/SoyeonJang/027.object/README.md new file mode 100644 index 0000000..9b83945 --- /dev/null +++ b/Challenge/SoyeonJang/027.object/README.md @@ -0,0 +1,14 @@ +# 문제27 : 객체 만들기 + +첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + +```jsx +**입력** +Yujin Hyewon +70 100 + +**출력** +{'Yujin': 70, 'Hyewon': 100} +``` \ No newline at end of file diff --git a/Challenge/SoyeonJang/027.object/solve.js b/Challenge/SoyeonJang/027.object/solve.js new file mode 100644 index 0000000..1cd501a --- /dev/null +++ b/Challenge/SoyeonJang/027.object/solve.js @@ -0,0 +1,21 @@ +// # 문제27 : 객체 만들기 + +// 첫번째 입력에서는 학생의 이름이 공백으로 구분되어 입력되고, 두번째에는 그 학생의 수학 점수가 공백으로 구분되어 주어집니다. + +// 두 개를 합쳐 **학생의 이름이 key**이고 **value가 수학 점수**인 객체를 출력해주세요. + +// **입력** +// Yujin Hyewon +// 70 100 + +// **출력** +// {'Yujin': 70, 'Hyewon': 100} + +const input = prompt("학생의 이름과 수학 점수를 차례대로 입력해 주세요").split( + " " +) + +input.reduce(function (object, value) { + object[input[0]] = parseInt(value) + return object +}, {}) From 5a22aaa2d3417c2fd25685035a43a10d481eba94 Mon Sep 17 00:00:00 2001 From: leehyeonseop Date: Thu, 9 Jun 2022 20:54:22 +0900 Subject: [PATCH 165/308] =?UTF-8?q?Solve:=2011-12=EB=B2=88=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/HyeonseopLee/011.for/README.md | 11 ++++++++ Challenge/HyeonseopLee/011.for/solve.js | 13 ++++++++++ Challenge/HyeonseopLee/012.class/README.md | 17 ++++++++++++ Challenge/HyeonseopLee/012.class/solve.js | 30 ++++++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 Challenge/HyeonseopLee/011.for/README.md create mode 100644 Challenge/HyeonseopLee/011.for/solve.js create mode 100644 Challenge/HyeonseopLee/012.class/README.md create mode 100644 Challenge/HyeonseopLee/012.class/solve.js diff --git a/Challenge/HyeonseopLee/011.for/README.md b/Challenge/HyeonseopLee/011.for/README.md new file mode 100644 index 0000000..a67da6e --- /dev/null +++ b/Challenge/HyeonseopLee/011.for/README.md @@ -0,0 +1,11 @@ +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +```jsx +let s = 0; + +//pass + +console.log(s); +``` \ No newline at end of file diff --git a/Challenge/HyeonseopLee/011.for/solve.js b/Challenge/HyeonseopLee/011.for/solve.js new file mode 100644 index 0000000..9767926 --- /dev/null +++ b/Challenge/HyeonseopLee/011.for/solve.js @@ -0,0 +1,13 @@ +/* +# 문제11 : for를 이용한 기본 활용 + +1부터 100까지 모두 더하는 Code를 부분에 완성하세요. `for`를 사용해야 합니다. + +let s = 0; + +//pass +for(let i=1; i<=100; i++) { + s += i; +} +console.log(s); +*/ \ No newline at end of file diff --git a/Challenge/HyeonseopLee/012.class/README.md b/Challenge/HyeonseopLee/012.class/README.md new file mode 100644 index 0000000..d3040ce --- /dev/null +++ b/Challenge/HyeonseopLee/012.class/README.md @@ -0,0 +1,17 @@ +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +```jsx +**데이터** +<여기에 class를 작성하세요.> + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +``` \ No newline at end of file diff --git a/Challenge/HyeonseopLee/012.class/solve.js b/Challenge/HyeonseopLee/012.class/solve.js new file mode 100644 index 0000000..6dbeb62 --- /dev/null +++ b/Challenge/HyeonseopLee/012.class/solve.js @@ -0,0 +1,30 @@ +/* +# 문제12 : 게임 캐릭터 클래스 만들기 + +다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. +**주어진 소스 코드를 수정해선 안됩니다.** + +**데이터** +<여기에 class를 작성하세요.> + +class Wizard { + constructor(health, mana, armor) { + this.health = health; + this.mana = mana; + this.armor = armor; + } + + attack() { + console.log("파이어볼"); + } +} + +const x = new Wizard(545, 210, 10); +console.log(x.health, x.mana, x.armor); +x.attack(); + +**출력** +545 210 10 +파이어볼 +*/ + From 3b8c285d6ca2ddd1f9a53b3b9a85ec8df58cb57f Mon Sep 17 00:00:00 2001 From: usablepaper Date: Thu, 9 Jun 2022 23:25:57 +0900 Subject: [PATCH 166/308] =?UTF-8?q?Solve=206=EB=B2=88,=207=EB=B2=88,=208?= =?UTF-8?q?=EB=B2=88=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Hyeonji/1.arry/README.md | 2 +- Challenge/Hyeonji/6.false/README.md | 10 ++++++++++ Challenge/Hyeonji/6.false/solve.js | 12 ++++++++++++ Challenge/Hyeonji/7.variable/README.md | 9 +++++++++ Challenge/Hyeonji/7.variable/solve.js | 13 +++++++++++++ Challenge/Hyeonji/8.object/README.md | 16 ++++++++++++++++ Challenge/Hyeonji/8.object/solve.js | 18 ++++++++++++++++++ Problems/1.arry/README.md | 5 ----- Problems/1.arry/solve.js | 4 ---- Problems/2.arryMethd/README.md | 11 ----------- Problems/2.arryMethd/solve.js | 11 ----------- Problems/3.type/README.md | 13 ------------- Problems/3.type/solve.js | 11 ----------- Problems/4.type(2)/README.md | 8 -------- Problems/4.type(2)/solve.js | 8 -------- Problems/5.for/README.md | 20 -------------------- Problems/5.for/solve.js | 20 -------------------- 17 files changed, 79 insertions(+), 112 deletions(-) create mode 100644 Challenge/Hyeonji/6.false/README.md create mode 100644 Challenge/Hyeonji/6.false/solve.js create mode 100644 Challenge/Hyeonji/7.variable/README.md create mode 100644 Challenge/Hyeonji/7.variable/solve.js create mode 100644 Challenge/Hyeonji/8.object/README.md create mode 100644 Challenge/Hyeonji/8.object/solve.js delete mode 100644 Problems/1.arry/README.md delete mode 100644 Problems/1.arry/solve.js delete mode 100644 Problems/2.arryMethd/README.md delete mode 100644 Problems/2.arryMethd/solve.js delete mode 100644 Problems/3.type/README.md delete mode 100644 Problems/3.type/solve.js delete mode 100644 Problems/4.type(2)/README.md delete mode 100644 Problems/4.type(2)/solve.js delete mode 100644 Problems/5.for/README.md delete mode 100644 Problems/5.for/solve.js diff --git a/Challenge/Hyeonji/1.arry/README.md b/Challenge/Hyeonji/1.arry/README.md index d5088f4..3dd029e 100644 --- a/Challenge/Hyeonji/1.arry/README.md +++ b/Challenge/Hyeonji/1.arry/README.md @@ -2,4 +2,4 @@ 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file +var nums = [100, 200, 300, 400, 500]; diff --git a/Challenge/Hyeonji/6.false/README.md b/Challenge/Hyeonji/6.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/Hyeonji/6.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/Hyeonji/6.false/solve.js b/Challenge/Hyeonji/6.false/solve.js new file mode 100644 index 0000000..fd39819 --- /dev/null +++ b/Challenge/Hyeonji/6.false/solve.js @@ -0,0 +1,12 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN +// 2) 1 +// 3) "" +// 4) 0 +// 5) undefined + +// 정답 2번!!!!!! diff --git a/Challenge/Hyeonji/7.variable/README.md b/Challenge/Hyeonji/7.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/Hyeonji/7.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/Hyeonji/7.variable/solve.js b/Challenge/Hyeonji/7.variable/solve.js new file mode 100644 index 0000000..359b9b1 --- /dev/null +++ b/Challenge/Hyeonji/7.variable/solve.js @@ -0,0 +1,13 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +// 답 3, 5 diff --git a/Challenge/Hyeonji/8.object/README.md b/Challenge/Hyeonji/8.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/Hyeonji/8.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/Hyeonji/8.object/solve.js b/Challenge/Hyeonji/8.object/solve.js new file mode 100644 index 0000000..983ab0a --- /dev/null +++ b/Challenge/Hyeonji/8.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +// 답 : 84 diff --git a/Problems/1.arry/README.md b/Problems/1.arry/README.md deleted file mode 100644 index d5088f4..0000000 --- a/Problems/1.arry/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 문제1 : 배열의 삭제 - -다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/1.arry/solve.js b/Problems/1.arry/solve.js deleted file mode 100644 index 7ffd8bd..0000000 --- a/Problems/1.arry/solve.js +++ /dev/null @@ -1,4 +0,0 @@ -// # 문제1 : 배열의 삭제 -// 다음 배열에서 400, 500를 삭제하는 code를 입력하세요. - -var nums = [100, 200, 300, 400, 500]; \ No newline at end of file diff --git a/Problems/2.arryMethd/README.md b/Problems/2.arryMethd/README.md deleted file mode 100644 index 01d8d19..0000000 --- a/Problems/2.arryMethd/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 문제2 : 배열의 내장함수 - -부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/2.arryMethd/solve.js b/Problems/2.arryMethd/solve.js deleted file mode 100644 index 4095544..0000000 --- a/Problems/2.arryMethd/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제2 : 배열의 내장함수 - -// 부분에 배열 내장함수를 이용하여 코드를 입력하고 다음과 같이 출력되게 하세요. - -데이터 -var arr = [200, 100, 300]; -//pass -console.log(arr); - -출력 -[200, 100, 10000, 300] \ No newline at end of file diff --git a/Problems/3.type/README.md b/Problems/3.type/README.md deleted file mode 100644 index 79ab0fb..0000000 --- a/Problems/3.type/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# 문제3 : 변수의 타입 - -다음 출력 값으로 올바른 것은? - -```jsx -var arr = [100, 200, 300]; -console.log(typeof(arr)); -``` - -1) undefined -2) string -3) number -4) object \ No newline at end of file diff --git a/Problems/3.type/solve.js b/Problems/3.type/solve.js deleted file mode 100644 index 06ee628..0000000 --- a/Problems/3.type/solve.js +++ /dev/null @@ -1,11 +0,0 @@ -// # 문제3 : 변수의 타입 - -// 다음 출력 값으로 올바른 것은? - -var arr = [100, 200, 300]; -console.log(typeof(arr)); - -// 1) undefined -// 2) string -// 3) number -// 4) object \ No newline at end of file diff --git a/Problems/4.type(2)/README.md b/Problems/4.type(2)/README.md deleted file mode 100644 index 46ff4b1..0000000 --- a/Problems/4.type(2)/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# 문제4 : 변수의 타입2 - -다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -1. 입력 : a =1, 출력 : number -2. 입력 : a = 2.22, 출력 : boolean -3. 입력 : a = 'p', 출력 : string -4. 입력 : a = [1, 2, 3], 출력 : object diff --git a/Problems/4.type(2)/solve.js b/Problems/4.type(2)/solve.js deleted file mode 100644 index 5980544..0000000 --- a/Problems/4.type(2)/solve.js +++ /dev/null @@ -1,8 +0,0 @@ -// # 문제4 : 변수의 타입2 - -// 다음 변수 a를 typeof(a)로 넣었을 때 출력될 값과의 연결이 알맞지 않은 것은? - -// 1) 입력 : a =1, 출력 : number -// 2) 입력 : a = 2.22, 출력 : boolean -// 3) 입력 : a = 'p', 출력 : string -// 4) 입력 : a = [1, 2, 3], 출력 : object \ No newline at end of file diff --git a/Problems/5.for/README.md b/Problems/5.for/README.md deleted file mode 100644 index e704b38..0000000 --- a/Problems/5.for/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -# 문제 5 for문 계산 - -다음 코드의 출력 값으로 알맞은 것은? - -```jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); -``` - -1) 10 -2) 12 -3) 14 -4) 16 \ No newline at end of file diff --git a/Problems/5.for/solve.js b/Problems/5.for/solve.js deleted file mode 100644 index 9a9204a..0000000 --- a/Problems/5.for/solve.js +++ /dev/null @@ -1,20 +0,0 @@ - -// # 문제 5 for문 계산 - -// 다음 코드의 출력 값으로 알맞은 것은? - -jsx -var a = 10; -var b = 2; - -for(var i=1; i<5; i+=2){ - a += i; -} - -console.log(a+b); - - -// 1) 10 -// 2) 12 -// 3) 14 -// 4) 16 \ No newline at end of file From 6863d2d6b9a19b9bbda5c9c8447fc3070c3e0197 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Thu, 9 Jun 2022 23:36:35 +0900 Subject: [PATCH 167/308] =?UTF-8?q?Feat=20:=2034=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Problems/034.Sort/README.md | 15 +++++++++++++++ Problems/034.Sort/solve.js | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Problems/034.Sort/README.md create mode 100644 Problems/034.Sort/solve.js diff --git a/Problems/034.Sort/README.md b/Problems/034.Sort/README.md new file mode 100644 index 0000000..2d7e610 --- /dev/null +++ b/Problems/034.Sort/README.md @@ -0,0 +1,15 @@ +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` diff --git a/Problems/034.Sort/solve.js b/Problems/034.Sort/solve.js new file mode 100644 index 0000000..e0501cd --- /dev/null +++ b/Problems/034.Sort/solve.js @@ -0,0 +1,16 @@ +// # 문제34 : sort 구현하기 + +// 민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +// 민주를 위해 키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램을 작성해보자. +// (키는 공백으로 구분하여 입력됩니다.) + +// ```jsx +// **입출력** +// 입력 : 176 156 155 165 166 169 +// 출력 : NO + +// 입력 : 155 156 165 166 169 176 +// 출력 : YES +// ``` + From a5eb06be55d87fa2ad72aacf99868b94c215c610 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Thu, 9 Jun 2022 23:37:41 +0900 Subject: [PATCH 168/308] =?UTF-8?q?Fix=20:=20=EC=9E=85=EB=A0=A5=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=200=EC=9D=B4=20=EB=93=A4=EC=96=B4=EC=99=94=EC=9D=84?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seyeongLee/014.if/solve.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Challenge/seyeongLee/014.if/solve.js b/Challenge/seyeongLee/014.if/solve.js index 3ee0dae..6aa5fdf 100644 --- a/Challenge/seyeongLee/014.if/solve.js +++ b/Challenge/seyeongLee/014.if/solve.js @@ -18,7 +18,7 @@ let input = prompt("숫자를 입력하세요."); -if (input % 3 == 0) { +if (input % 3 == 0 && input !== '0') { document.write("출력 : 짝"); } else { document.write(`출력 : ${input}`); From e2be68c45cb88bd21446b94be1f20b0691b0e1c1 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Thu, 9 Jun 2022 23:38:05 +0900 Subject: [PATCH 169/308] =?UTF-8?q?Solve=20:=20032=20~=20035=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 13 +++++++ .../solve.js" | 28 +++++++++++++ Challenge/seyeongLee/033.Reverse/README.md | 13 +++++++ Challenge/seyeongLee/033.Reverse/solve.js | 23 +++++++++++ Challenge/seyeongLee/034.sort/README.md | 16 ++++++++ Challenge/seyeongLee/034.sort/solve.js | 31 +++++++++++++++ Challenge/seyeongLee/035.function/README.md | 22 +++++++++++ Challenge/seyeongLee/035.function/solve.js | 39 +++++++++++++++++++ 8 files changed, 185 insertions(+) create mode 100644 "Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" create mode 100644 "Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" create mode 100644 Challenge/seyeongLee/033.Reverse/README.md create mode 100644 Challenge/seyeongLee/033.Reverse/solve.js create mode 100644 Challenge/seyeongLee/034.sort/README.md create mode 100644 Challenge/seyeongLee/034.sort/solve.js create mode 100644 Challenge/seyeongLee/035.function/README.md create mode 100644 Challenge/seyeongLee/035.function/solve.js diff --git "a/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" "b/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" new file mode 100644 index 0000000..53459f4 --- /dev/null +++ "b/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/README.md" @@ -0,0 +1,13 @@ +# 문제32 : 문자열 만들기 + +취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +혜림이를 위해 **문자열을 입력받으면 단어의 갯수를 출력하는 프로그램**을 작성해 주세요. + +```jsx +**입력** +안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +**출력** +5 +``` diff --git "a/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" "b/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" new file mode 100644 index 0000000..d0f8650 --- /dev/null +++ "b/Challenge/seyeongLee/032.\353\254\270\354\236\220\354\227\264\353\247\214\353\223\244\352\270\260/solve.js" @@ -0,0 +1,28 @@ +// # 문제32 : 문자열 만들기 + +// 취업 준비생인 혜림이는 자기소개서를 쓰고 있습니다. 열심히 자기소개서를 작성하던 도중 혜림이는 자기가 지금까지 단어를 얼마나 적었는지 궁금하게 됩니다. + +// 혜림이를 위해 문자열을 입력받으면 단어의 갯수를 출력하는 프로그램을 작성해 주세요. + +// ```jsx +// **입력** +// 안녕하세요. 저는 제주대학교 컴퓨터공학전공 혜림입니다. + +// **출력** +// 5 +// ``` + +let input = prompt("문자열을 입력하세요"); +let wordArr = input.split(" "); +let wordNum = 0; + +document.write(`입력한 문자열 : ${input}
`); + +// 공백 or 스페이스 바 여러 번 눌렀을 때 단어 개수 증가를 막기 위한 예외 처리 +for (const i of wordArr) { + if (i !== "") { + wordNum++; + } +} + +document.write(`단어의 갯수는 ${wordNum}입니다`); \ No newline at end of file diff --git a/Challenge/seyeongLee/033.Reverse/README.md b/Challenge/seyeongLee/033.Reverse/README.md new file mode 100644 index 0000000..7d450ce --- /dev/null +++ b/Challenge/seyeongLee/033.Reverse/README.md @@ -0,0 +1,13 @@ +# 문제33 : 거꾸로 출력하기 + +한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +```jsx +**입출력** +입력 : 1 2 3 4 5 +출력 : 5 4 3 2 1 + +**출력** +입력 : 2 4 6 7 8 +출력 : 8 7 6 4 2 +``` diff --git a/Challenge/seyeongLee/033.Reverse/solve.js b/Challenge/seyeongLee/033.Reverse/solve.js new file mode 100644 index 0000000..aa5d8a2 --- /dev/null +++ b/Challenge/seyeongLee/033.Reverse/solve.js @@ -0,0 +1,23 @@ +// # 문제33 : 거꾸로 출력하기 + +// 한 줄에 여러개의 숫자가 입력되면, 역순으로 그 숫자들을 하나씩 출력하는 프로그램을 작성하시오. + +// ```jsx +// **입출력** +// 입력 : 1 2 3 4 5 +// 출력 : 5 4 3 2 1 + +// **출력** +// 입력 : 2 4 6 7 8 +// 출력 : 8 7 6 4 2 +// ``` + +let input = prompt("숫자를 여러개 입력하세요").split(" "); +let output = []; + +for (i = input.length; i > 0; i--) { + output.push(input[i - 1]); +} + +document.write(`${input.join(" ")}
`); +document.write(`${output.join(" ")}`); \ No newline at end of file diff --git a/Challenge/seyeongLee/034.sort/README.md b/Challenge/seyeongLee/034.sort/README.md new file mode 100644 index 0000000..615626c --- /dev/null +++ b/Challenge/seyeongLee/034.sort/README.md @@ -0,0 +1,16 @@ +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** + +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/034.sort/solve.js b/Challenge/seyeongLee/034.sort/solve.js new file mode 100644 index 0000000..319a216 --- /dev/null +++ b/Challenge/seyeongLee/034.sort/solve.js @@ -0,0 +1,31 @@ +/* +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** + +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` +*/ + +let input = prompt("학생들의 키를 입력하세요"); +let inputSort = input.split(" ").sort((a, b) => a - b); +let result = ''; + +if (input == inputSort.join(" ")) { + result = 'YES' +} else { + result = 'NO'; +} + +document.write(`현재 순서 : ${input}
`); +document.write(`${result}`); \ No newline at end of file diff --git a/Challenge/seyeongLee/035.function/README.md b/Challenge/seyeongLee/035.function/README.md new file mode 100644 index 0000000..5e4b62a --- /dev/null +++ b/Challenge/seyeongLee/035.function/README.md @@ -0,0 +1,22 @@ +# 문제35 : Factory 함수 사용하기 + +2제곱, 3제곱, 4제곱을 할 수 있는 Factory 함수를 만들려고 합니다. + +에 코드를 작성하여 two함수를 완성하세요. + +```jsx +function one(n){ + function two(){ + //pass + } + return two; +} + +const a = one(2); +const b = one(3); +const c = one(4); + +console.log(a(10)); +console.log(b(10)); +console.log(c(10)); +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/035.function/solve.js b/Challenge/seyeongLee/035.function/solve.js new file mode 100644 index 0000000..9399d68 --- /dev/null +++ b/Challenge/seyeongLee/035.function/solve.js @@ -0,0 +1,39 @@ +/* +# 문제35 : Factory 함수 사용하기 + +2제곱, 3제곱, 4제곱을 할 수 있는 Factory 함수를 만들려고 합니다. + +에 코드를 작성하여 two함수를 완성하세요. + +```jsx +function one(n){ + function two(){ + //pass + } + return two; +} + +const a = one(2); +const b = one(3); +const c = one(4); + +console.log(a(10)); +console.log(b(10)); +console.log(c(10)); +``` +*/ + +function one(n) { + function two(num) { + return num ** n; + } + return two; +} + +const a = one(2); +const b = one(3); +const c = one(4); + +console.log(a(10)); +console.log(b(10)); +console.log(c(10)); \ No newline at end of file From 4657330827ced268e1726ea87a4b1fe9512fa549 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Fri, 10 Jun 2022 02:48:12 +0900 Subject: [PATCH 170/308] =?UTF-8?q?Solve:=208=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/008.object/README.md | 16 ++++++++++++++++ Challenge/YejiKim/008.object/solve.js | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Challenge/YejiKim/008.object/README.md create mode 100644 Challenge/YejiKim/008.object/solve.js diff --git a/Challenge/YejiKim/008.object/README.md b/Challenge/YejiKim/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/YejiKim/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/YejiKim/008.object/solve.js b/Challenge/YejiKim/008.object/solve.js new file mode 100644 index 0000000..50aa51f --- /dev/null +++ b/Challenge/YejiKim/008.object/solve.js @@ -0,0 +1,17 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ +// 정답 : 84 From 2e0feb00461f593de3cb95afb71e01bf37088410 Mon Sep 17 00:00:00 2001 From: Lim Heelae Date: Fri, 10 Jun 2022 08:41:22 +0900 Subject: [PATCH 171/308] Solve 017,018,019,020,021,022,023,024,025,026 --- Challenge/HeelaeLim/017.if2/README.md | 16 ++++++++ Challenge/HeelaeLim/017.if2/solve.js | 36 ++++++++++++++++++ Challenge/HeelaeLim/018.average/README.md | 13 +++++++ Challenge/HeelaeLim/018.average/solve.js | 23 ++++++++++++ Challenge/HeelaeLim/019.Multiple/README.md | 10 +++++ Challenge/HeelaeLim/019.Multiple/solve.js | 20 ++++++++++ Challenge/HeelaeLim/020.devide/README.md | 11 ++++++ Challenge/HeelaeLim/020.devide/solve.js | 21 +++++++++++ Challenge/HeelaeLim/021.Set/README.md | 9 +++++ Challenge/HeelaeLim/021.Set/solve.js | 15 ++++++++ Challenge/HeelaeLim/022.Multiple/README.md | 10 +++++ Challenge/HeelaeLim/022.Multiple/solve.js | 14 +++++++ Challenge/HeelaeLim/023.Calculate/README.md | 4 ++ Challenge/HeelaeLim/023.Calculate/solve.js | 7 ++++ Challenge/HeelaeLim/024.Uppercase/README.md | 12 ++++++ Challenge/HeelaeLim/024.Uppercase/solve.js | 21 +++++++++++ Challenge/HeelaeLim/025.circle-area/README.md | 8 ++++ Challenge/HeelaeLim/025.circle-area/solve.js | 16 ++++++++ .../HeelaeLim/026.find-planet2/README.md | 8 ++++ Challenge/HeelaeLim/026.find-planet2/solve.js | 37 +++++++++++++++++++ 20 files changed, 311 insertions(+) create mode 100644 Challenge/HeelaeLim/017.if2/README.md create mode 100644 Challenge/HeelaeLim/017.if2/solve.js create mode 100644 Challenge/HeelaeLim/018.average/README.md create mode 100644 Challenge/HeelaeLim/018.average/solve.js create mode 100644 Challenge/HeelaeLim/019.Multiple/README.md create mode 100644 Challenge/HeelaeLim/019.Multiple/solve.js create mode 100644 Challenge/HeelaeLim/020.devide/README.md create mode 100644 Challenge/HeelaeLim/020.devide/solve.js create mode 100644 Challenge/HeelaeLim/021.Set/README.md create mode 100644 Challenge/HeelaeLim/021.Set/solve.js create mode 100644 Challenge/HeelaeLim/022.Multiple/README.md create mode 100644 Challenge/HeelaeLim/022.Multiple/solve.js create mode 100644 Challenge/HeelaeLim/023.Calculate/README.md create mode 100644 Challenge/HeelaeLim/023.Calculate/solve.js create mode 100644 Challenge/HeelaeLim/024.Uppercase/README.md create mode 100644 Challenge/HeelaeLim/024.Uppercase/solve.js create mode 100644 Challenge/HeelaeLim/025.circle-area/README.md create mode 100644 Challenge/HeelaeLim/025.circle-area/solve.js create mode 100644 Challenge/HeelaeLim/026.find-planet2/README.md create mode 100644 Challenge/HeelaeLim/026.find-planet2/solve.js diff --git a/Challenge/HeelaeLim/017.if2/README.md b/Challenge/HeelaeLim/017.if2/README.md new file mode 100644 index 0000000..aa4559e --- /dev/null +++ b/Challenge/HeelaeLim/017.if2/README.md @@ -0,0 +1,16 @@ +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm이상만 탈 수 있습니다. + +입력으로 키가 주어지면 키가 150이 넘을 때 YES 아닐 때 NO를 출력하는 프로그램을 만드세요 + +```jsx +**입출력** + +입력 : 152 +출력 : YES + +입력 : 147 +출력 : NO +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/017.if2/solve.js b/Challenge/HeelaeLim/017.if2/solve.js new file mode 100644 index 0000000..7fe75ea --- /dev/null +++ b/Challenge/HeelaeLim/017.if2/solve.js @@ -0,0 +1,36 @@ +/* +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm이상만 탈 수 있습니다. + +입력으로 키가 주어지면 키가 150이 넘을 때 YES 아닐 때 NO를 출력하는 프로그램을 만드세요 + +```jsx +**입출력** + +입력 : 152 +출력 : YES + +입력 : 147 +출력 : NO +``` +*/ + +function Check(){ + let Num = prompt(); + if(!isNaN(Num)){ + if(Num >= 150){ + console.log("YES") + } + else{ + console.log("NO") + } + } + else{ + console.log("Please enter your key.(only Number!)") + } +} + +Check(); + diff --git a/Challenge/HeelaeLim/018.average/README.md b/Challenge/HeelaeLim/018.average/README.md new file mode 100644 index 0000000..26dbf3a --- /dev/null +++ b/Challenge/HeelaeLim/018.average/README.md @@ -0,0 +1,13 @@ +# 문제18 : 평균점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구둘의 평균점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/018.average/solve.js b/Challenge/HeelaeLim/018.average/solve.js new file mode 100644 index 0000000..b35e9f8 --- /dev/null +++ b/Challenge/HeelaeLim/018.average/solve.js @@ -0,0 +1,23 @@ +/* +# 문제18 : 평균점수 + +영하네 반은 국어, 수학, 영어 시험을 보았습니다. 영하는 친구둘의 평균점수를 구해주기로 했습니다. + +공백으로 구분하여 세 과목의 점수가 주어지면 전체 평균 점수를 구하는 프로그램을 작성하세요. +단, 소숫점 자리는 모두 버립니다. + +```jsx +**입출력** + +입력 : 20 30 40 +출력 : 30 +``` +*/ + +function Average(){ + let Str = prompt(); + let arr = Str.split(' '); + return Math.floor(arr.reduce((x,y)=>(+x)+(+y))/arr.length); +} + +Average(); diff --git a/Challenge/HeelaeLim/019.Multiple/README.md b/Challenge/HeelaeLim/019.Multiple/README.md new file mode 100644 index 0000000..d54028e --- /dev/null +++ b/Challenge/HeelaeLim/019.Multiple/README.md @@ -0,0 +1,10 @@ +# 문제19 : 제곱을 구하자. + +공백으로 구분하여 두 숫자 a, b가 주어지면 a의 b승을 구하는 프로그램을 작성하세요 + +```jsx +**입출력** + +입력 : 2 3 +출력 : 8 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/019.Multiple/solve.js b/Challenge/HeelaeLim/019.Multiple/solve.js new file mode 100644 index 0000000..ae84c49 --- /dev/null +++ b/Challenge/HeelaeLim/019.Multiple/solve.js @@ -0,0 +1,20 @@ +/* +# 문제19 : 제곱을 구하자. + +공백으로 구분하여 두 숫자 a, b가 주어지면 a의 b승을 구하는 프로그램을 작성하세요 + +```jsx +**입출력** + +입력 : 2 3 +출력 : 8 +``` +*/ + +function Involution(){ + let Str = prompt(); + let arr = Str.split(' '); + return Math.pow(arr[0], arr[1]); +} + +Involution(); diff --git a/Challenge/HeelaeLim/020.devide/README.md b/Challenge/HeelaeLim/020.devide/README.md new file mode 100644 index 0000000..cfb850a --- /dev/null +++ b/Challenge/HeelaeLim/020.devide/README.md @@ -0,0 +1,11 @@ +# 문제20 : 몫과 나머지. + +공백으로 구분하여 두 숫자가 주어집니다. +두 번째 숫자로 첫 번째 숫자를 나누었을 때 그 몫과 나머지를 공백으로 구분하여 출력하세요. + +```jsx +**입출력** + +입력 : 10 2 +출력 : 5 0 +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/020.devide/solve.js b/Challenge/HeelaeLim/020.devide/solve.js new file mode 100644 index 0000000..456481e --- /dev/null +++ b/Challenge/HeelaeLim/020.devide/solve.js @@ -0,0 +1,21 @@ +/* +# 문제20 : 몫과 나머지. + +공백으로 구분하여 두 숫자가 주어집니다. +두 번째 숫자로 첫 번째 숫자를 나누었을 때 그 몫과 나머지를 공백으로 구분하여 출력하세요. + +```jsx +**입출력** + +입력 : 10 2 +출력 : 5 0 +``` +*/ + +function Divide(){ + let Str = prompt(); + let arr = Str.split(' '); + console.log(`${arr[0]/arr[1]} ${arr[0]%arr[1]}`); +} + +Divide(); diff --git a/Challenge/HeelaeLim/021.Set/README.md b/Challenge/HeelaeLim/021.Set/README.md new file mode 100644 index 0000000..0e861c4 --- /dev/null +++ b/Challenge/HeelaeLim/021.Set/README.md @@ -0,0 +1,9 @@ +# 문제21 : Set + +다음 중 Set을 만드는 방법으로 올바른 것을 모두 고르시오 + +1) var x = {1,2,3,4,5,6,7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); \ No newline at end of file diff --git a/Challenge/HeelaeLim/021.Set/solve.js b/Challenge/HeelaeLim/021.Set/solve.js new file mode 100644 index 0000000..29bb7b5 --- /dev/null +++ b/Challenge/HeelaeLim/021.Set/solve.js @@ -0,0 +1,15 @@ +/* +# 문제21 : Set + +다음 중 Set을 만드는 방법으로 올바른 것을 모두 고르시오 + +1) var x = {1,2,3,4,5,6,7}; +2) var x = {}; +3) var x = new Set('javascript'); +4) var x = new Set(range(5)); +5) var x = new Set(); +*/ + +// 3) var x = new Set('javascript'); +// 5) var x = new Set(); +// 나머지는 답이 될 수 없다. diff --git a/Challenge/HeelaeLim/022.Multiple/README.md b/Challenge/HeelaeLim/022.Multiple/README.md new file mode 100644 index 0000000..b4dc05d --- /dev/null +++ b/Challenge/HeelaeLim/022.Multiple/README.md @@ -0,0 +1,10 @@ + +# 문제22 : Multiple + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i/6 == 0 +2) i%6 == 0 +3) i&6 == 0 +4) i|6 == 0 +5) i//6 == 0 \ No newline at end of file diff --git a/Challenge/HeelaeLim/022.Multiple/solve.js b/Challenge/HeelaeLim/022.Multiple/solve.js new file mode 100644 index 0000000..b3f91c0 --- /dev/null +++ b/Challenge/HeelaeLim/022.Multiple/solve.js @@ -0,0 +1,14 @@ +/* +# 문제22 : Multiple + +다음 중 변수 i가 6의 배수인지 확인하는 방법으로 올바른 것은? + +1) i/6 == 0 +2) i%6 == 0 +3) i&6 == 0 +4) i|6 == 0 +5) i//6 == 0 +*/ + +// 2) i%6 == 0 +// %를 통해 나머지를 구할 수 있다. diff --git a/Challenge/HeelaeLim/023.Calculate/README.md b/Challenge/HeelaeLim/023.Calculate/README.md new file mode 100644 index 0000000..a976653 --- /dev/null +++ b/Challenge/HeelaeLim/023.Calculate/README.md @@ -0,0 +1,4 @@ + +# 문제23 : Calculate + +console.log(10/3)의 출력 결과는 3이다. \ No newline at end of file diff --git a/Challenge/HeelaeLim/023.Calculate/solve.js b/Challenge/HeelaeLim/023.Calculate/solve.js new file mode 100644 index 0000000..c21f909 --- /dev/null +++ b/Challenge/HeelaeLim/023.Calculate/solve.js @@ -0,0 +1,7 @@ +/* +# 문제23 : Calculate + +console.log(10/3)의 출력 결과는 3이다. +*/ + +// 3.33333...이 나와야 한다. diff --git a/Challenge/HeelaeLim/024.Uppercase/README.md b/Challenge/HeelaeLim/024.Uppercase/README.md new file mode 100644 index 0000000..f649ced --- /dev/null +++ b/Challenge/HeelaeLim/024.Uppercase/README.md @@ -0,0 +1,12 @@ +# 문제24 : 대문자로 바꿔주세요 + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 소문자, 어떤 이는 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 이름이 입력되면 전부 대문자로 출력되는 프로그램을 만들어주세요. + +```jsx +**입출력** + +입력 : mary +출력 : MARY +``` \ No newline at end of file diff --git a/Challenge/HeelaeLim/024.Uppercase/solve.js b/Challenge/HeelaeLim/024.Uppercase/solve.js new file mode 100644 index 0000000..ac4c8b7 --- /dev/null +++ b/Challenge/HeelaeLim/024.Uppercase/solve.js @@ -0,0 +1,21 @@ +/* +# 문제24 : 대문자로 바꿔주세요 + +민지는 국제 포럼에서 아르바이트를 하게 되었습니다. 민지는 각 국에서 온 참가자들의 명단을 엑셀로 정리하고 있는데 참가자들 이름이 어떤 이는 소문자, 어떤 이는 대문자로 써져 있는 등 형식이 제각각이었습니다. + +민지를 위해 이름이 입력되면 전부 대문자로 출력되는 프로그램을 만들어주세요. + +```jsx +**입출력** + +입력 : mary +출력 : MARY +``` +*/ + +function Upper(){ + let Str = prompt(); + console.log(Str.toUpperCase()); +} + +Upper(); diff --git a/Challenge/HeelaeLim/025.circle-area/README.md b/Challenge/HeelaeLim/025.circle-area/README.md new file mode 100644 index 0000000..7e79bae --- /dev/null +++ b/Challenge/HeelaeLim/025.circle-area/README.md @@ -0,0 +1,8 @@ +# 문제 25: 원의 넓이를 구하세요 + +원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +**입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + + diff --git a/Challenge/HeelaeLim/025.circle-area/solve.js b/Challenge/HeelaeLim/025.circle-area/solve.js new file mode 100644 index 0000000..b8c1471 --- /dev/null +++ b/Challenge/HeelaeLim/025.circle-area/solve.js @@ -0,0 +1,16 @@ +// # 문제 25: 원의 넓이를 구하세요 + +// 원의 넓이는 `반지름의 길이 x 반지름의 길이 x 3.14`로 구할 수 있습니다. +// 함수를 사용하여 원의 넓이를 구하는 코드를 작성해봅시다. + +// **입력으로 반지름의 길이 정수 n이 주어지면 원의 넓이를 반환하는 함수**를 만들어 주세요. + +function circle_area(num){ + console.log(num**2*3.14); +} + +circle_area(5); + + + + \ No newline at end of file diff --git a/Challenge/HeelaeLim/026.find-planet2/README.md b/Challenge/HeelaeLim/026.find-planet2/README.md new file mode 100644 index 0000000..a5d41fe --- /dev/null +++ b/Challenge/HeelaeLim/026.find-planet2/README.md @@ -0,0 +1,8 @@ +# 문제 26: find-planet2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +**행성의 한글이름을 입력하면 영어 이름을 반환하는 프로그램**을 만들어 주세요. + + diff --git a/Challenge/HeelaeLim/026.find-planet2/solve.js b/Challenge/HeelaeLim/026.find-planet2/solve.js new file mode 100644 index 0000000..7ebdaf7 --- /dev/null +++ b/Challenge/HeelaeLim/026.find-planet2/solve.js @@ -0,0 +1,37 @@ +/* +# 문제 26: find-planet2 + +우리 태양계를 이루는 행성은 수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성이 있습니다. +이 행성들의 영어 이름은 Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune입니다. + +**행성의 한글이름을 입력하면 영어 이름을 반환하는 프로그램**을 만들어 주세요. +*/ + +function Translate(){ + let Str = prompt(); + if(Str === "수성"){ + console.log("Mercury"); + }else if(Str === "금성"){ + console.log("Venus"); + }else if(Str === "지구"){ + console.log("Earth"); + }else if(Str === "화성"){ + console.log("Mars"); + }else if(Str === "목성"){ + console.log("Jupiter"); + }else if(Str === "토성"){ + console.log("Saturn"); + }else if(Str === "천왕성"){ + console.log("Uranus"); + }else if(Str === "해왕성"){ + console.log("Neptune"); + }else { + console.log("It is not a solar system planet") + } +} + +Translate(); + + + + \ No newline at end of file From aec5c367099fdda62fbc87efc19c699c86b32983 Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Fri, 10 Jun 2022 09:57:44 +0900 Subject: [PATCH 172/308] =?UTF-8?q?Solve:=209=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/009.concat/README.md | 20 ++++++++++++++++++++ Challenge/YejiKim/009.concat/solve.js | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 Challenge/YejiKim/009.concat/README.md create mode 100644 Challenge/YejiKim/009.concat/solve.js diff --git a/Challenge/YejiKim/009.concat/README.md b/Challenge/YejiKim/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/YejiKim/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/YejiKim/009.concat/solve.js b/Challenge/YejiKim/009.concat/solve.js new file mode 100644 index 0000000..79877c8 --- /dev/null +++ b/Challenge/YejiKim/009.concat/solve.js @@ -0,0 +1,22 @@ +var year = "2019"; +var month = "04"; +var day = "26"; +var hour = "11"; +var minute = "34"; +var second = "27"; + +var result = year.concat( + "/", + month, + "/", + day, + " ", + hour, + ":", + minute, + ":", + second +); +console.log(result); + +// '2019/04/26 11:34:27' From e12bd21e1ac488388d68e747a98ed9fa7f05be7c Mon Sep 17 00:00:00 2001 From: yeeed711 Date: Fri, 10 Jun 2022 12:54:50 +0900 Subject: [PATCH 173/308] =?UTF-8?q?Solve:=2010=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/YejiKim/010.star/README.md | 18 ++++++++++++++++++ Challenge/YejiKim/010.star/solve.js | 4 ++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/YejiKim/010.star/README.md create mode 100644 Challenge/YejiKim/010.star/solve.js diff --git a/Challenge/YejiKim/010.star/README.md b/Challenge/YejiKim/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/YejiKim/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/YejiKim/010.star/solve.js b/Challenge/YejiKim/010.star/solve.js new file mode 100644 index 0000000..f578d24 --- /dev/null +++ b/Challenge/YejiKim/010.star/solve.js @@ -0,0 +1,4 @@ +let level = 5; +for (i = 1; i <= 5; i++) { + console.log(" ".repeat(level - i) + "*".repeat(2 * i - 1)); +} From 91ccb2d8675b77ef405c4b0e351fc92f3a7c915f Mon Sep 17 00:00:00 2001 From: Hun-Se Date: Fri, 10 Jun 2022 23:22:00 +0900 Subject: [PATCH 174/308] =?UTF-8?q?Solve:=2016-17=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 10 ++++++++++ .../solve.js" | 15 +++++++++++++++ Challenge/sehunKim/017.limit/README.md | 7 +++++++ Challenge/sehunKim/017.limit/solve.js | 17 +++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 "Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/README.md" create mode 100644 "Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/solve.js" create mode 100644 Challenge/sehunKim/017.limit/README.md create mode 100644 Challenge/sehunKim/017.limit/solve.js diff --git "a/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/README.md" "b/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/README.md" new file mode 100644 index 0000000..6528a39 --- /dev/null +++ "b/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/README.md" @@ -0,0 +1,10 @@ +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +```jsx +**입출력** + +입력 : 거꾸로 +출력 : 로꾸거 +``` diff --git "a/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/solve.js" "b/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/solve.js" new file mode 100644 index 0000000..5cbcb4a --- /dev/null +++ "b/Challenge/sehunKim/016.\353\241\234\352\276\270\352\272\274/solve.js" @@ -0,0 +1,15 @@ +/* +# 문제16 : 로꾸거 + +문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다. + +입력 : 거꾸로 +출력 : 로꾸거 + +const a = prompt('문장입력'); +const result = a.split('').reverse().join(''); +split() : 문장을 배열로 전환 +reverse() : 배열의 순서를 반대로 바꿈 +join(): 배열을 다시 문장으로 바꾸어 주는 역할을 한다. + +*/ \ No newline at end of file diff --git a/Challenge/sehunKim/017.limit/README.md b/Challenge/sehunKim/017.limit/README.md new file mode 100644 index 0000000..b364fc6 --- /dev/null +++ b/Challenge/sehunKim/017.limit/README.md @@ -0,0 +1,7 @@ +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. diff --git a/Challenge/sehunKim/017.limit/solve.js b/Challenge/sehunKim/017.limit/solve.js new file mode 100644 index 0000000..75e4583 --- /dev/null +++ b/Challenge/sehunKim/017.limit/solve.js @@ -0,0 +1,17 @@ +/* +# 문제17 : 놀이기구 키 제한 + +유주는 놀이공원 아르바이트 중입니다. 그런데 놀이기구마다 키 제한이 있습니다. +유주가 담당하는 놀이기구는 키가 150cm 이상만 탈 수 있습니다. + +입력으로 키가 주어지면 +키가 150이 넘으면 YES를 틀리면 NO를 출력하는 프로그램을 작성하세요. + +const height = prompt("키를 입력하세요."); + +if (height >= 150){ + console.log("YES"); +} else { + console.log("NO"); +} +*/ \ No newline at end of file From 5bd91a5eb9d5ea0b1555b7772ed0be35e91183f2 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Sat, 11 Jun 2022 13:16:42 +0900 Subject: [PATCH 175/308] =?UTF-8?q?Solve:=206=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/006.false/README.md | 10 ++++++++++ Challenge/MinkyeongJo/006.false/solve.js | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/MinkyeongJo/006.false/README.md create mode 100644 Challenge/MinkyeongJo/006.false/solve.js diff --git a/Challenge/MinkyeongJo/006.false/README.md b/Challenge/MinkyeongJo/006.false/README.md new file mode 100644 index 0000000..66f6e1d --- /dev/null +++ b/Challenge/MinkyeongJo/006.false/README.md @@ -0,0 +1,10 @@ +# 문제6 : False + +다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +1) NaN +2) 1 +3) "" +4) 0 +5) undefined \ No newline at end of file diff --git a/Challenge/MinkyeongJo/006.false/solve.js b/Challenge/MinkyeongJo/006.false/solve.js new file mode 100644 index 0000000..fc140c4 --- /dev/null +++ b/Challenge/MinkyeongJo/006.false/solve.js @@ -0,0 +1,12 @@ +//# 문제6 : False + +// 다음은 자바스크립트 문법 중에서 False로 취급하는 것들 입니다. +// 앗, False로 취급하지 않는 것이 하나 있네요! True를 찾아주세요. + +// 1) NaN -> false +// 2) 1 -> true +// 3) "" -> false +// 4) 0 -> false +// 5) undefined -> false + +// 정답은 2번! \ No newline at end of file From f1ec048386d8216ced55bcdd97932e29c40eabcb Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Sat, 11 Jun 2022 13:19:12 +0900 Subject: [PATCH 176/308] =?UTF-8?q?Solve:=207=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/007.variable/README.md | 9 +++++++++ Challenge/MinkyeongJo/007.variable/solve.js | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Challenge/MinkyeongJo/007.variable/README.md create mode 100644 Challenge/MinkyeongJo/007.variable/solve.js diff --git a/Challenge/MinkyeongJo/007.variable/README.md b/Challenge/MinkyeongJo/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/MinkyeongJo/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/MinkyeongJo/007.variable/solve.js b/Challenge/MinkyeongJo/007.variable/solve.js new file mode 100644 index 0000000..bdc16a1 --- /dev/null +++ b/Challenge/MinkyeongJo/007.variable/solve.js @@ -0,0 +1,13 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +//3번, 5번 : 변수명은 예약어 let을 사용할 수 없고 숫자로 시작할 수 없다. \ No newline at end of file From 92fc77a6db9388a22712b86c237a2e6f91213e29 Mon Sep 17 00:00:00 2001 From: minkyeongJ Date: Sat, 11 Jun 2022 13:22:01 +0900 Subject: [PATCH 177/308] =?UTF-8?q?Solve:=208=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/MinkyeongJo/008.object/README.md | 16 ++++++++++++++++ Challenge/MinkyeongJo/008.object/solve.js | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Challenge/MinkyeongJo/008.object/README.md create mode 100644 Challenge/MinkyeongJo/008.object/solve.js diff --git a/Challenge/MinkyeongJo/008.object/README.md b/Challenge/MinkyeongJo/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/MinkyeongJo/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/MinkyeongJo/008.object/solve.js b/Challenge/MinkyeongJo/008.object/solve.js new file mode 100644 index 0000000..737c243 --- /dev/null +++ b/Challenge/MinkyeongJo/008.object/solve.js @@ -0,0 +1,18 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +//출력값은 84. 객체의 키가 중복되었을 경우에는 제일 마지막 값을 불러온다. \ No newline at end of file From cd4f7d7dcb91954980679bba15df4015a548d5b7 Mon Sep 17 00:00:00 2001 From: plutoin Date: Sat, 11 Jun 2022 15:36:53 +0900 Subject: [PATCH 178/308] =?UTF-8?q?Solve:=2028-29=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/SoyeonJang/028.2-gram/README.md | 23 ++++++++++++++++ Challenge/SoyeonJang/028.2-gram/solve.js | 27 +++++++++++++++++++ .../README.md" | 5 ++++ .../solve.js" | 14 ++++++++++ 4 files changed, 69 insertions(+) create mode 100644 Challenge/SoyeonJang/028.2-gram/README.md create mode 100644 Challenge/SoyeonJang/028.2-gram/solve.js create mode 100644 "Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/README.md" create mode 100644 "Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/solve.js" diff --git a/Challenge/SoyeonJang/028.2-gram/README.md b/Challenge/SoyeonJang/028.2-gram/README.md new file mode 100644 index 0000000..3a0dfe1 --- /dev/null +++ b/Challenge/SoyeonJang/028.2-gram/README.md @@ -0,0 +1,23 @@ +# 문제28 : 2-gram + +**2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +```jsx +**입력** +Javascript + +**출력** +J a +a v +v a +a s +s c +c r +r i +i p +p t +``` + +입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. \ No newline at end of file diff --git a/Challenge/SoyeonJang/028.2-gram/solve.js b/Challenge/SoyeonJang/028.2-gram/solve.js new file mode 100644 index 0000000..8a7da50 --- /dev/null +++ b/Challenge/SoyeonJang/028.2-gram/solve.js @@ -0,0 +1,27 @@ +// # 문제28 : 2-gram + +// **2-gram**이란 문자열에서 2개의 연속된 요소를 출력하는 방법입니다. + +// 예를 들어 'Javascript'를 2-gram으로 반복해 본다면 다음과 같은 결과가 나옵니다. + +// **입력** +// Javascript + +// **출력** +// J a +// a v +// v a +// a s +// s c +// c r +// r i +// i p +// p t + +// 입력으로 문자열이 주어지면 **2-gram**으로 출력하는 프로그램을 작성해 주세요. + +let sentence = prompt("단어를 입력해 주세요").split("") + +for (let i = 0; i < sentence.length; i++) { + console.log(sentence[i], sentence[i + 1]) +} diff --git "a/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/README.md" "b/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/README.md" new file mode 100644 index 0000000..287a235 --- /dev/null +++ "b/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/README.md" @@ -0,0 +1,5 @@ +# 문제29 : 대문자만 지나가세요 + +진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. \ No newline at end of file diff --git "a/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/solve.js" "b/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/solve.js" new file mode 100644 index 0000000..0273fc4 --- /dev/null +++ "b/Challenge/SoyeonJang/029.\353\214\200\353\254\270\354\236\220/solve.js" @@ -0,0 +1,14 @@ +// 문제29 : 대문자만 지나가세요 + +// 진구는 영어 학원 아르바이트를 하고 있습니다. 반 아이들은 알파벳을 공부하는 학생들인데 오늘은 대문자 쓰기 시험을 봤습니다. + +// 알파벳 하나만을 입력하고 그 알파벳이 대문자이면 YES를 아니면 NO를 출력하는 프로그램을 만들어 주세요. + +const alphabet = prompt("한 개의 알파벳을 입력해 주세요") +const upperCaseStr = alphabet.toUpperCase() + +if (alphabet === upperCaseStr) { + console.log("YES") +} else { + console.log("No") +} From 5921b127b8caf46004c03b8b894e0eb60922e5d8 Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Sat, 11 Jun 2022 23:11:59 +0900 Subject: [PATCH 179/308] =?UTF-8?q?Solve=20:=20036=20~=20039=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../036.Multiplication_Table/README.md | 10 ++++++ .../036.Multiplication_Table/solve.js | 25 ++++++++++++++ .../README.md" | 11 ++++++ .../solve.js" | 34 +++++++++++++++++++ .../README.md" | 13 +++++++ .../solve.js" | 29 ++++++++++++++++ .../README.md" | 18 ++++++++++ .../solve.js" | 25 ++++++++++++++ 8 files changed, 165 insertions(+) create mode 100644 Challenge/seyeongLee/036.Multiplication_Table/README.md create mode 100644 Challenge/seyeongLee/036.Multiplication_Table/solve.js create mode 100644 "Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" create mode 100644 "Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" create mode 100644 "Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" create mode 100644 "Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" create mode 100644 "Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" create mode 100644 "Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" diff --git a/Challenge/seyeongLee/036.Multiplication_Table/README.md b/Challenge/seyeongLee/036.Multiplication_Table/README.md new file mode 100644 index 0000000..3691735 --- /dev/null +++ b/Challenge/seyeongLee/036.Multiplication_Table/README.md @@ -0,0 +1,10 @@ +# 문제36 : 구구단 출력하기 + +1~9까지의 숫자 중 하나를 입력하면 그 단의 구구단 결과를 한 줄에 출력하는 프로그램을 작성하세요. + +```jsx +**입출력** + +입력 : 2 +출력 : 2 4 6 8 10 12 14 16 18 +``` \ No newline at end of file diff --git a/Challenge/seyeongLee/036.Multiplication_Table/solve.js b/Challenge/seyeongLee/036.Multiplication_Table/solve.js new file mode 100644 index 0000000..8532784 --- /dev/null +++ b/Challenge/seyeongLee/036.Multiplication_Table/solve.js @@ -0,0 +1,25 @@ +/* +# 문제36 : 구구단 출력하기 + +1~9까지의 숫자 중 하나를 입력하면 그 단의 구구단 결과를 한 줄에 출력하는 프로그램을 작성하세요. + +```jsx +**입출력** + +입력 : 2 +출력 : 2 4 6 8 10 12 14 16 18 +``` +*/ + +let input = prompt("원하는 구구단의 단을 입력하세요"); + +function multiplicationTable(input) { + let result = ''; + + for (let i = 1; i < 10; i++) { + result += input * i + ' '; + } + return result; +} + +document.write(`${input}단 결과 : ${multiplicationTable(input)}`); \ No newline at end of file diff --git "a/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" "b/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" new file mode 100644 index 0000000..18cac02 --- /dev/null +++ "b/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/README.md" @@ -0,0 +1,11 @@ +# 문제37 : 반장 선거 + +새 학기를 맞아 호준이네 반은 반장 선거를 하기로 했습니다. 그런데 표를 하나씩 개표하는 과정이 너무 번거롭게 느껴진 당신은 **학생들이 뽑은 후보들을 입력받으면 뽑힌 학생의 이름과 받은 표 수를 출력하는 프로그램**을 작성하기로 하였습니다. + +```jsx +**입력** +원범 원범 혜원 혜원 혜원 혜원 유진 유진 + +**출력** +혜원(이)가 총 4표로 반장이 되었습니다. +``` \ No newline at end of file diff --git "a/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" "b/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" new file mode 100644 index 0000000..b1499de --- /dev/null +++ "b/Challenge/seyeongLee/037.\353\260\230\354\236\245_\354\204\240\352\261\260/solve.js" @@ -0,0 +1,34 @@ +/* +# 문제37 : 반장 선거 + +새 학기를 맞아 호준이네 반은 반장 선거를 하기로 했습니다. 그런데 표를 하나씩 개표하는 과정이 너무 번거롭게 느껴진 당신은 **학생들이 뽑은 후보들을 입력받으면 뽑힌 학생의 이름과 받은 표 수를 출력하는 프로그램**을 작성하기로 하였습니다. + +```jsx +**입력** +원범 원범 혜원 혜원 혜원 혜원 유진 유진 + +**출력** +혜원(이)가 총 4표로 반장이 되었습니다. +``` +*/ +let input = prompt("반장이 되길 원하는 학생의 이름을 입력하세요").split(' '); +let nameArr = []; + +for (const key in input) { + const name = input[key]; + if (nameArr[name] === undefined) { + nameArr[name] = 1; + } else { + nameArr[name]++; + } +} + +const winner = Object.keys(nameArr).reduce((a, b) => { + if (nameArr[a] > nameArr[b]) { + return a; + } else { + return b; + } +}) + +document.write(`${winner}(이)가 총 ${nameArr[winner]}표로 반장이 되었습니다.`); \ No newline at end of file diff --git "a/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" "b/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" new file mode 100644 index 0000000..36a32d4 --- /dev/null +++ "b/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/README.md" @@ -0,0 +1,13 @@ +# 문제38 : 호준이의 아르바이트 + +호준이는 아르바이트로 영어 학원에서 단어 시험지를 채점하는 일을 하고 있다. 호준이가 일하는 학원은 매번 1위부터 3위까지의 학생에게 상으로 사탕을 준다. 그런데 오늘은 마침 사탕이 다 떨어져서 호준이가 채점을 하고 점수를 보내면, 당신이 아이들의 숫자만큼 사탕을 사러 가기로 했다. + +1위 ~ 3위 학생은 여러명일 수 있고 1~3위 학생 중 중복되는 학생까지 포함하여 사탕을 사기로 한다. +**학생들의 점수를 공백으로 구분하여 입력을 받고 사탕을 받을 학생의 수를 출력하세요.** + +```jsx +**입출력** + +입력 : 97 86 75 66 55 97 85 97 97 95 +출력 : 6 +``` \ No newline at end of file diff --git "a/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" "b/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" new file mode 100644 index 0000000..a38003a --- /dev/null +++ "b/Challenge/seyeongLee/038.\355\230\270\354\244\200\354\235\264\354\235\230_\354\225\204\353\245\264\353\260\224\354\235\264\355\212\270/solve.js" @@ -0,0 +1,29 @@ +/* +# 문제38 : 호준이의 아르바이트 + +호준이는 아르바이트로 영어 학원에서 단어 시험지를 채점하는 일을 하고 있다. 호준이가 일하는 학원은 매번 1위부터 3위까지의 학생에게 상으로 사탕을 준다. 그런데 오늘은 마침 사탕이 다 떨어져서 호준이가 채점을 하고 점수를 보내면, 당신이 아이들의 숫자만큼 사탕을 사러 가기로 했다. + +1위 ~ 3위 학생은 여러명일 수 있고 1~3위 학생 중 중복되는 학생까지 포함하여 사탕을 사기로 한다. +**학생들의 점수를 공백으로 구분하여 입력을 받고 사탕을 받을 학생의 수를 출력하세요.** + +```jsx +**입출력** + +입력 : 97 86 75 66 55 97 85 97 97 95 +출력 : 6 +``` +*/ +let input = prompt("학생들의 영어 점수를 입력하세요").split(' ').sort((a, b) => b - a); +let count = 0; + +document.write(`학생들 영어 점수 : ${input}
`); + +for (let i = 0; i < input.length; i++) { + if (input[i] !== input[i + 1]) { + count++; + } + if (count == 3) { + document.write(`사탕받을 학생의 수 : ${input.indexOf(input[i]) + 1}명`); + break; + } +} diff --git "a/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" "b/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" new file mode 100644 index 0000000..3b0af06 --- /dev/null +++ "b/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/README.md" @@ -0,0 +1,18 @@ +# 문제39 : 오타 수정하기 + +혜원이는 평소 영타가 빠르고 정확한 것을 친구들에게 자랑하고 다녔습니다. 반 친구들이 혜원이의 타자 속도가 빠르다는 것을 모두 알게 되자 혜원이는 모두의 앞에서 타자 실력을 보여주게 됩니다. + +그런데 막상 보여주려니 긴장이 되서 문장의 모든 e를 q로 잘못 친 것을 발견했습니다. +혜원이는 프로그램을 돌려 재빠르게 모든 q를 e로 바꾸는 프로그램을 작성하려고 합니다. + +**문장이 입력되면 모든 q를 e로 바꾸는 프로그램을 작성해 주세요.** + +```jsx +**입출력** + +입력 : querty +출력 : euerty + +입력 : hqllo my namq is hyqwon +출력 : hello my name is hyewon +``` \ No newline at end of file diff --git "a/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" "b/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" new file mode 100644 index 0000000..dbd9131 --- /dev/null +++ "b/Challenge/seyeongLee/039.\354\230\244\355\203\200_\354\210\230\354\240\225\355\225\230\352\270\260/solve.js" @@ -0,0 +1,25 @@ +/* +# 문제39 : 오타 수정하기 + +혜원이는 평소 영타가 빠르고 정확한 것을 친구들에게 자랑하고 다녔습니다. 반 친구들이 혜원이의 타자 속도가 빠르다는 것을 모두 알게 되자 혜원이는 모두의 앞에서 타자 실력을 보여주게 됩니다. + +그런데 막상 보여주려니 긴장이 되서 문장의 모든 e를 q로 잘못 친 것을 발견했습니다. +혜원이는 프로그램을 돌려 재빠르게 모든 q를 e로 바꾸는 프로그램을 작성하려고 합니다. + +**문장이 입력되면 모든 q를 e로 바꾸는 프로그램을 작성해 주세요.** + +```jsx +**입출력** + +입력 : querty +출력 : euerty + +입력 : hqllo my namq is hyqwon +출력 : hello my name is hyewonq +``` +*/ +let input = prompt("문자열을 입력하세요"); + +document.write(`입력 : ${input}
`); +document.write(`출력(함수 사용) : ${input.replaceAll('q', 'e')}
`); +document.write(`출력(정규식 사용)) : ${input.replace(/q/g, 'e')}`); \ No newline at end of file From 0fa0d7d429d153e4eabb8a29ce15b99d5e719629 Mon Sep 17 00:00:00 2001 From: myeong-seok Date: Sat, 11 Jun 2022 23:49:32 +0900 Subject: [PATCH 180/308] =?UTF-8?q?Solve=20:=2034=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/Songmyeongseok/034.Sort/README.md | 16 +++++++++++ Challenge/Songmyeongseok/034.Sort/solve.js | 31 +++++++++++++++++++++ Problems/034.sort/README.md | 7 ++--- Problems/034.sort/solve.js | 24 ++++++++-------- 4 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 Challenge/Songmyeongseok/034.Sort/README.md create mode 100644 Challenge/Songmyeongseok/034.Sort/solve.js diff --git a/Challenge/Songmyeongseok/034.Sort/README.md b/Challenge/Songmyeongseok/034.Sort/README.md new file mode 100644 index 0000000..615626c --- /dev/null +++ b/Challenge/Songmyeongseok/034.Sort/README.md @@ -0,0 +1,16 @@ +# 문제34 : sort 구현하기 + +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +(키는 공백으로 구분하여 입력됩니다.) + +```jsx +**입출력** + +입력 : 176 156 155 165 166 169 +출력 : NO + +입력 : 155 156 165 166 169 176 +출력 : YES +``` \ No newline at end of file diff --git a/Challenge/Songmyeongseok/034.Sort/solve.js b/Challenge/Songmyeongseok/034.Sort/solve.js new file mode 100644 index 0000000..8a15938 --- /dev/null +++ b/Challenge/Songmyeongseok/034.Sort/solve.js @@ -0,0 +1,31 @@ +// # 문제34 : sort 구현하기 + +// 민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. + +// 민주를 위해 키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램을 작성해보자. +// (키는 공백으로 구분하여 입력됩니다.) + +// ```jsx +// **입출력** +// 입력 : 176 156 155 165 166 169 +// 출력 : NO + +// 입력 : 155 156 165 166 169 176 +// 출력 : YES +// ``` + +const unsorted = prompt('키를 입력하세요'); +let sorted = ""; + +sorted = unsorted + .split(" ") + .sort(function(a, b) { + return a - b; + }) + .join(" "); + +if (unsorted === sorted) { + console.log("Yes"); +} else { + console.log("No"); +} diff --git a/Problems/034.sort/README.md b/Problems/034.sort/README.md index 615626c..2d7e610 100644 --- a/Problems/034.sort/README.md +++ b/Problems/034.sort/README.md @@ -1,16 +1,15 @@ # 문제34 : sort 구현하기 -민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. +민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. -민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. +민주를 위해 키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램을 작성해보자. (키는 공백으로 구분하여 입력됩니다.) ```jsx **입출력** - 입력 : 176 156 155 165 166 169 출력 : NO 입력 : 155 156 165 166 169 176 출력 : YES -``` \ No newline at end of file +``` diff --git a/Problems/034.sort/solve.js b/Problems/034.sort/solve.js index ef2eef4..e0501cd 100644 --- a/Problems/034.sort/solve.js +++ b/Problems/034.sort/solve.js @@ -1,18 +1,16 @@ -/* -# 문제34 : sort 구현하기 +// # 문제34 : sort 구현하기 -민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. +// 민주는 체육부장으로 체육시간이 되면 반 친구들이 제대로 키 순서대로 모였는지를 확인해야 한다. 그런데 요즘 민주는 그것이 너무 번거롭게 느껴져 한 번에 확인하고 싶어한다. -민주를 위해 **키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램**을 작성해보자. -(키는 공백으로 구분하여 입력됩니다.) +// 민주를 위해 키가 주어지면 순서대로 제대로 섰는지 확인하는 프로그램을 작성해보자. +// (키는 공백으로 구분하여 입력됩니다.) -```jsx -**입출력** +// ```jsx +// **입출력** +// 입력 : 176 156 155 165 166 169 +// 출력 : NO -입력 : 176 156 155 165 166 169 -출력 : NO +// 입력 : 155 156 165 166 169 176 +// 출력 : YES +// ``` -입력 : 155 156 165 166 169 176 -출력 : YES -``` -*/ From 694f0790aa5ca13897302cad77f3d2371b20152b Mon Sep 17 00:00:00 2001 From: seokahi Date: Sun, 12 Jun 2022 03:12:33 +0900 Subject: [PATCH 181/308] =?UTF-8?q?Solve:=207~14=EB=B2=88=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Challenge/seokahi/007.variable/README.md | 9 + Challenge/seokahi/007.variable/solve.js | 20 + Challenge/seokahi/008.object/README.md | 16 + Challenge/seokahi/008.object/solve.js | 19 + Challenge/seokahi/009.concat/README.md | 20 + Challenge/seokahi/009.concat/solve.js | 31 + Challenge/seokahi/010.star/README.md | 18 + .../010.star/node_modules/.package-lock.json | 195 + .../node_modules/@colors/colors/LICENSE | 26 + .../node_modules/@colors/colors/README.md | 219 + .../@colors/colors/examples/normal-usage.js | 83 + .../@colors/colors/examples/safe-string.js | 80 + .../node_modules/@colors/colors/index.d.ts | 136 + .../node_modules/@colors/colors/lib/colors.js | 211 + .../@colors/colors/lib/custom/trap.js | 46 + .../@colors/colors/lib/custom/zalgo.js | 110 + .../colors/lib/extendStringPrototype.js | 110 + .../node_modules/@colors/colors/lib/index.js | 13 + .../@colors/colors/lib/maps/america.js | 10 + .../@colors/colors/lib/maps/rainbow.js | 12 + .../@colors/colors/lib/maps/random.js | 11 + .../@colors/colors/lib/maps/zebra.js | 5 + .../node_modules/@colors/colors/lib/styles.js | 95 + .../@colors/colors/lib/system/has-flag.js | 35 + .../colors/lib/system/supports-colors.js | 151 + .../node_modules/@colors/colors/package.json | 45 + .../node_modules/@colors/colors/safe.d.ts | 48 + .../node_modules/@colors/colors/safe.js | 10 + .../@colors/colors/themes/generic-logging.js | 12 + .../010.star/node_modules/async/CHANGELOG.md | 344 + .../010.star/node_modules/async/LICENSE | 19 + .../010.star/node_modules/async/README.md | 60 + .../010.star/node_modules/async/all.js | 119 + .../010.star/node_modules/async/allLimit.js | 46 + .../010.star/node_modules/async/allSeries.js | 45 + .../010.star/node_modules/async/any.js | 122 + .../010.star/node_modules/async/anyLimit.js | 47 + .../010.star/node_modules/async/anySeries.js | 46 + .../010.star/node_modules/async/apply.js | 55 + .../010.star/node_modules/async/applyEach.js | 57 + .../node_modules/async/applyEachSeries.js | 37 + .../010.star/node_modules/async/asyncify.js | 118 + .../010.star/node_modules/async/auto.js | 333 + .../010.star/node_modules/async/autoInject.js | 182 + .../010.star/node_modules/async/bower.json | 17 + .../010.star/node_modules/async/cargo.js | 63 + .../010.star/node_modules/async/cargoQueue.js | 71 + .../010.star/node_modules/async/compose.js | 55 + .../010.star/node_modules/async/concat.js | 115 + .../node_modules/async/concatLimit.js | 60 + .../node_modules/async/concatSeries.js | 41 + .../010.star/node_modules/async/constant.js | 55 + .../010.star/node_modules/async/detect.js | 96 + .../node_modules/async/detectLimit.js | 48 + .../node_modules/async/detectSeries.js | 47 + .../010.star/node_modules/async/dir.js | 43 + .../010.star/node_modules/async/dist/async.js | 6057 +++++++++++++++++ .../node_modules/async/dist/async.min.js | 1 + .../node_modules/async/dist/async.mjs | 5945 ++++++++++++++++ .../010.star/node_modules/async/doDuring.js | 68 + .../010.star/node_modules/async/doUntil.js | 46 + .../010.star/node_modules/async/doWhilst.js | 68 + .../010.star/node_modules/async/during.js | 78 + .../010.star/node_modules/async/each.js | 129 + .../010.star/node_modules/async/eachLimit.js | 50 + .../010.star/node_modules/async/eachOf.js | 185 + .../node_modules/async/eachOfLimit.js | 47 + .../node_modules/async/eachOfSeries.js | 39 + .../010.star/node_modules/async/eachSeries.js | 44 + .../node_modules/async/ensureAsync.js | 67 + .../010.star/node_modules/async/every.js | 119 + .../010.star/node_modules/async/everyLimit.js | 46 + .../node_modules/async/everySeries.js | 45 + .../010.star/node_modules/async/filter.js | 93 + .../node_modules/async/filterLimit.js | 45 + .../node_modules/async/filterSeries.js | 43 + .../010.star/node_modules/async/find.js | 96 + .../010.star/node_modules/async/findLimit.js | 48 + .../010.star/node_modules/async/findSeries.js | 47 + .../010.star/node_modules/async/flatMap.js | 115 + .../node_modules/async/flatMapLimit.js | 60 + .../node_modules/async/flatMapSeries.js | 41 + .../010.star/node_modules/async/foldl.js | 153 + .../010.star/node_modules/async/foldr.js | 41 + .../010.star/node_modules/async/forEach.js | 129 + .../node_modules/async/forEachLimit.js | 50 + .../010.star/node_modules/async/forEachOf.js | 185 + .../node_modules/async/forEachOfLimit.js | 47 + .../node_modules/async/forEachOfSeries.js | 39 + .../node_modules/async/forEachSeries.js | 44 + .../010.star/node_modules/async/forever.js | 68 + .../010.star/node_modules/async/groupBy.js | 108 + .../node_modules/async/groupByLimit.js | 71 + .../node_modules/async/groupBySeries.js | 36 + .../010.star/node_modules/async/index.js | 588 ++ .../010.star/node_modules/async/inject.js | 153 + .../async/internal/DoublyLinkedList.js | 92 + .../node_modules/async/internal/Heap.js | 120 + .../node_modules/async/internal/applyEach.js | 29 + .../async/internal/asyncEachOfLimit.js | 75 + .../node_modules/async/internal/awaitify.js | 27 + .../node_modules/async/internal/breakLoop.js | 10 + .../async/internal/consoleFunc.js | 31 + .../async/internal/createTester.js | 40 + .../async/internal/eachOfLimit.js | 90 + .../node_modules/async/internal/filter.js | 55 + .../async/internal/getIterator.js | 11 + .../async/internal/initialParams.js | 14 + .../async/internal/isArrayLike.js | 10 + .../node_modules/async/internal/iterator.js | 57 + .../node_modules/async/internal/map.js | 30 + .../node_modules/async/internal/once.js | 17 + .../node_modules/async/internal/onlyOnce.js | 15 + .../node_modules/async/internal/parallel.js | 34 + .../async/internal/promiseCallback.js | 23 + .../node_modules/async/internal/queue.js | 291 + .../node_modules/async/internal/range.js | 14 + .../node_modules/async/internal/reject.js | 26 + .../async/internal/setImmediate.js | 34 + .../async/internal/withoutIndex.js | 10 + .../node_modules/async/internal/wrapAsync.js | 34 + .../010.star/node_modules/async/log.js | 41 + .../010.star/node_modules/async/map.js | 142 + .../010.star/node_modules/async/mapLimit.js | 45 + .../010.star/node_modules/async/mapSeries.js | 44 + .../010.star/node_modules/async/mapValues.js | 152 + .../node_modules/async/mapValuesLimit.js | 61 + .../node_modules/async/mapValuesSeries.js | 37 + .../010.star/node_modules/async/memoize.js | 91 + .../010.star/node_modules/async/nextTick.js | 52 + .../010.star/node_modules/async/package.json | 80 + .../010.star/node_modules/async/parallel.js | 180 + .../node_modules/async/parallelLimit.js | 41 + .../node_modules/async/priorityQueue.js | 91 + .../010.star/node_modules/async/queue.js | 167 + .../010.star/node_modules/async/race.js | 67 + .../010.star/node_modules/async/reduce.js | 153 + .../node_modules/async/reduceRight.js | 41 + .../010.star/node_modules/async/reflect.js | 78 + .../010.star/node_modules/async/reflectAll.js | 93 + .../010.star/node_modules/async/reject.js | 87 + .../node_modules/async/rejectLimit.js | 45 + .../node_modules/async/rejectSeries.js | 43 + .../010.star/node_modules/async/retry.js | 159 + .../010.star/node_modules/async/retryable.js | 77 + .../010.star/node_modules/async/select.js | 93 + .../node_modules/async/selectLimit.js | 45 + .../node_modules/async/selectSeries.js | 43 + .../010.star/node_modules/async/seq.js | 79 + .../010.star/node_modules/async/series.js | 186 + .../node_modules/async/setImmediate.js | 45 + .../010.star/node_modules/async/some.js | 122 + .../010.star/node_modules/async/someLimit.js | 47 + .../010.star/node_modules/async/someSeries.js | 46 + .../010.star/node_modules/async/sortBy.js | 190 + .../010.star/node_modules/async/timeout.js | 89 + .../010.star/node_modules/async/times.js | 50 + .../010.star/node_modules/async/timesLimit.js | 43 + .../node_modules/async/timesSeries.js | 32 + .../010.star/node_modules/async/transform.js | 173 + .../010.star/node_modules/async/tryEach.js | 78 + .../010.star/node_modules/async/unmemoize.js | 25 + .../010.star/node_modules/async/until.js | 61 + .../010.star/node_modules/async/waterfall.js | 105 + .../010.star/node_modules/async/whilst.js | 78 + .../010.star/node_modules/async/wrapSync.js | 118 + .../010.star/node_modules/colors/.travis.yml | 6 + .../node_modules/colors/MIT-LICENSE.txt | 23 + .../010.star/node_modules/colors/ReadMe.md | 167 + .../colors/examples/normal-usage.js | 74 + .../colors/examples/safe-string.js | 76 + .../node_modules/colors/lib/colors.js | 176 + .../node_modules/colors/lib/custom/trap.js | 45 + .../node_modules/colors/lib/custom/zalgo.js | 104 + .../colors/lib/extendStringPrototype.js | 118 + .../010.star/node_modules/colors/lib/index.js | 12 + .../node_modules/colors/lib/maps/america.js | 12 + .../node_modules/colors/lib/maps/rainbow.js | 13 + .../node_modules/colors/lib/maps/random.js | 8 + .../node_modules/colors/lib/maps/zebra.js | 5 + .../node_modules/colors/lib/styles.js | 77 + .../colors/lib/system/supports-colors.js | 61 + .../010.star/node_modules/colors/package.json | 21 + .../010.star/node_modules/colors/safe.js | 9 + .../colors/screenshots/colors.png | Bin 0 -> 79787 bytes .../node_modules/colors/tests/basic-test.js | 50 + .../node_modules/colors/tests/safe-test.js | 45 + .../colors/themes/generic-logging.js | 12 + .../010.star/node_modules/cycle/README.md | 49 + .../010.star/node_modules/cycle/cycle.js | 170 + .../010.star/node_modules/cycle/package.json | 12 + .../node_modules/duplexer/.travis.yml | 6 + .../010.star/node_modules/duplexer/LICENCE | 19 + .../010.star/node_modules/duplexer/README.md | 49 + .../010.star/node_modules/duplexer/index.js | 87 + .../node_modules/duplexer/package.json | 42 + .../node_modules/duplexer/test/index.js | 31 + .../node_modules/event-stream/.travis.yml | 3 + .../node_modules/event-stream/LICENCE | 24 + .../node_modules/event-stream/examples/data | 3 + .../node_modules/event-stream/examples/map.js | 15 + .../event-stream/examples/pretty.js | 18 + .../event-stream/examples/split.js | 12 + .../node_modules/event-stream/index.js | 351 + .../node_modules/event-stream/package.json | 36 + .../node_modules/event-stream/readme.markdown | 345 + .../event-stream/test/connect.asynct.js | 86 + .../event-stream/test/filter.asynct.js | 17 + .../event-stream/test/flatmap.asynct.js | 17 + .../event-stream/test/helper/index.js | 12 + .../event-stream/test/merge.asynct.js | 29 + .../event-stream/test/parse.asynct.js | 32 + .../event-stream/test/pause.asynct.js | 39 + .../event-stream/test/pipeline.asynct.js | 52 + .../event-stream/test/readArray.asynct.js | 89 + .../event-stream/test/readable.asynct.js | 197 + .../event-stream/test/replace.asynct.js | 76 + .../event-stream/test/simple-map.asynct.js | 343 + .../event-stream/test/spec.asynct.js | 86 + .../event-stream/test/split.asynct.js | 47 + .../event-stream/test/stringify.js | 15 + .../event-stream/test/writeArray.asynct.js | 31 + .../010.star/node_modules/eyes/LICENSE | 20 + .../010.star/node_modules/eyes/Makefile | 4 + .../010.star/node_modules/eyes/README.md | 73 + .../010.star/node_modules/eyes/lib/eyes.js | 236 + .../010.star/node_modules/eyes/package.json | 14 + .../node_modules/eyes/test/eyes-test.js | 56 + .../010.star/node_modules/from/.npmignore | 1 + .../010.star/node_modules/from/.travis.yml | 6 + .../node_modules/from/LICENSE.APACHE2 | 15 + .../010.star/node_modules/from/LICENSE.MIT | 24 + .../010.star/node_modules/from/index.js | 68 + .../010.star/node_modules/from/package.json | 26 + .../node_modules/from/readme.markdown | 40 + .../010.star/node_modules/from/test/index.js | 210 + .../010.star/node_modules/isstream/.jshintrc | 59 + .../010.star/node_modules/isstream/.npmignore | 1 + .../node_modules/isstream/.travis.yml | 12 + .../010.star/node_modules/isstream/LICENSE.md | 11 + .../010.star/node_modules/isstream/README.md | 66 + .../node_modules/isstream/isstream.js | 27 + .../node_modules/isstream/package.json | 33 + .../010.star/node_modules/isstream/test.js | 168 + .../node_modules/lodash.assign/LICENSE | 47 + .../node_modules/lodash.assign/README.md | 18 + .../node_modules/lodash.assign/index.js | 637 ++ .../node_modules/lodash.assign/package.json | 17 + .../node_modules/map-stream/.npmignore | 3 + .../node_modules/map-stream/.travis.yml | 4 + .../010.star/node_modules/map-stream/LICENCE | 24 + .../map-stream/examples/pretty.js | 26 + .../010.star/node_modules/map-stream/index.js | 144 + .../node_modules/map-stream/package.json | 24 + .../node_modules/map-stream/readme.markdown | 37 + .../map-stream/test/simple-map.asynct.js | 318 + .../010.star/node_modules/mingo/CHANGELOG.md | 98 + .../node_modules/mingo/CONTRIBUTORS.md | 2 + .../010.star/node_modules/mingo/LICENSE | 20 + .../010.star/node_modules/mingo/README.md | 172 + .../010.star/node_modules/mingo/VERSION | 1 + .../node_modules/mingo/dist/mingo.es6.js | 3866 +++++++++++ .../010.star/node_modules/mingo/dist/mingo.js | 4212 ++++++++++++ .../node_modules/mingo/dist/mingo.map | 1 + .../node_modules/mingo/dist/mingo.min.js | 7 + .../node_modules/mingo/dist/mingo.min.js.gz | Bin 0 -> 11015 bytes .../node_modules/mingo/lib/aggregator.js | 54 + .../node_modules/mingo/lib/constants.js | 24 + .../010.star/node_modules/mingo/lib/cursor.js | 191 + .../010.star/node_modules/mingo/lib/index.js | 30 + .../node_modules/mingo/lib/internal.js | 496 ++ .../010.star/node_modules/mingo/lib/mixin.js | 27 + .../lib/operators/aggregation/arithmetic.js | 214 + .../mingo/lib/operators/aggregation/array.js | 322 + .../lib/operators/aggregation/boolean.js | 39 + .../lib/operators/aggregation/comparison.js | 26 + .../lib/operators/aggregation/conditional.js | 71 + .../mingo/lib/operators/aggregation/date.js | 182 + .../mingo/lib/operators/aggregation/index.js | 25 + .../lib/operators/aggregation/literal.js | 11 + .../mingo/lib/operators/aggregation/set.js | 78 + .../mingo/lib/operators/aggregation/string.js | 140 + .../lib/operators/aggregation/variable.js | 45 + .../node_modules/mingo/lib/operators/group.js | 158 + .../node_modules/mingo/lib/operators/index.js | 95 + .../mingo/lib/operators/pipeline.js | 650 ++ .../mingo/lib/operators/projection.js | 119 + .../node_modules/mingo/lib/operators/query.js | 419 ++ .../node_modules/mingo/lib/polyfill.js | 184 + .../010.star/node_modules/mingo/lib/query.js | 142 + .../010.star/node_modules/mingo/lib/util.js | 447 ++ .../010.star/node_modules/mingo/package.json | 55 + .../010.star/node_modules/mute-stream/LICENSE | 15 + .../node_modules/mute-stream/README.md | 68 + .../010.star/node_modules/mute-stream/mute.js | 145 + .../node_modules/mute-stream/package.json | 29 + .../node_modules/pause-stream/.npmignore | 3 + .../node_modules/pause-stream/LICENSE | 231 + .../node_modules/pause-stream/index.js | 3 + .../node_modules/pause-stream/package.json | 35 + .../node_modules/pause-stream/readme.markdown | 29 + .../node_modules/pause-stream/test/index.js | 17 + .../pause-stream/test/pause-end.js | 33 + .../010.star/node_modules/prompt/.eslintrc | 22 + .../010.star/node_modules/prompt/.jshintrc | 54 + .../010.star/node_modules/prompt/.travis.yml | 11 + .../node_modules/prompt/.vscode/settings.json | 3 + .../010.star/node_modules/prompt/CHANGELOG.md | 13 + .../010.star/node_modules/prompt/LICENSE | 19 + .../010.star/node_modules/prompt/README.md | 468 ++ .../node_modules/prompt/docs/docco.css | 194 + .../node_modules/prompt/docs/prompt.html | 296 + .../prompt/examples/add-properties.js | 35 + .../node_modules/prompt/examples/color.js | 19 + .../prompt/examples/dynamic-ask-prompt.js | 38 + .../prompt/examples/existing-properties.js | 35 + .../node_modules/prompt/examples/history.js | 44 + .../examples/nested-properties-prompt.js | 37 + .../prompt/examples/old-schema.js | 36 + .../prompt/examples/override-validation.js | 52 + .../node_modules/prompt/examples/password.js | 42 + .../prompt/examples/prompt-override.js | 36 + .../prompt/examples/prompt-streamline._js | 32 + .../prompt/examples/property-prompt.js | 45 + .../prompt/examples/simple-prompt.js | 25 + .../node_modules/prompt/examples/types.js | 20 + .../prompt/examples/yes-or-no-prompt.js | 32 + .../node_modules/prompt/lib/prompt.js | 822 +++ .../010.star/node_modules/prompt/package.json | 40 + .../node_modules/prompt/test/helpers.js | 177 + .../prompt/test/interactive-prompt-test.js | 49 + .../node_modules/prompt/test/macros.js | 82 + .../node_modules/prompt/test/prompt-test.js | 960 +++ .../010.star/node_modules/read/LICENSE | 15 + .../010.star/node_modules/read/README.md | 53 + .../010.star/node_modules/read/lib/read.js | 113 + .../010.star/node_modules/read/package.json | 27 + .../node_modules/revalidator/.npmignore | 2 + .../node_modules/revalidator/.travis.yml | 11 + .../node_modules/revalidator/CHANGELOG.md | 25 + .../010.star/node_modules/revalidator/LICENSE | 179 + .../node_modules/revalidator/README.md | 301 + .../revalidator/example/webservice.js | 204 + .../revalidator/lib/revalidator.js | 427 ++ .../node_modules/revalidator/package.json | 26 + .../revalidator/test/validator-test.js | 421 ++ .../010.star/node_modules/save/.eslintignore | 1 + .../010.star/node_modules/save/.eslintrc | 12 + .../node_modules/save/.prettierignore | 10 + .../010.star/node_modules/save/.prettierrc | 5 + .../010.star/node_modules/save/.travis.yml | 5 + .../010.star/node_modules/save/LICENSE | 13 + .../010.star/node_modules/save/README.md | 137 + .../node_modules/save/lib/memory-engine.js | 339 + .../010.star/node_modules/save/lib/save.js | 77 + .../010.star/node_modules/save/package.json | 52 + .../010.star/node_modules/save/test/count.js | 78 + .../save/test/create-or-update.js | 72 + .../010.star/node_modules/save/test/create.js | 181 + .../node_modules/save/test/delete-many.js | 71 + .../010.star/node_modules/save/test/delete.js | 41 + .../node_modules/save/test/engine.tests.js | 38 + .../node_modules/save/test/find-one.js | 75 + .../010.star/node_modules/save/test/find.js | 356 + .../node_modules/save/test/id-property.js | 17 + .../save/test/memory-engine.test.js | 10 + .../010.star/node_modules/save/test/read.js | 82 + .../node_modules/save/test/save.test.js | 11 + .../node_modules/save/test/streaming.js | 127 + .../node_modules/save/test/update-many.js | 28 + .../010.star/node_modules/save/test/update.js | 160 + .../010.star/node_modules/split/.npmignore | 3 + .../010.star/node_modules/split/.travis.yml | 3 + .../010.star/node_modules/split/LICENCE | 22 + .../node_modules/split/examples/pretty.js | 26 + .../010.star/node_modules/split/index.js | 63 + .../010.star/node_modules/split/package.json | 30 + .../node_modules/split/readme.markdown | 72 + .../node_modules/split/test/options.asynct.js | 46 + .../split/test/partitioned_unicode.js | 34 + .../node_modules/split/test/split.asynct.js | 137 + .../split/test/try_catch.asynct.js | 51 + .../node_modules/stack-trace/.npmignore | 1 + .../010.star/node_modules/stack-trace/License | 19 + .../node_modules/stack-trace/Makefile | 11 + .../node_modules/stack-trace/Readme.md | 98 + .../stack-trace/lib/stack-trace.js | 136 + .../node_modules/stack-trace/package.json | 21 + .../node_modules/stream-combiner/.npmignore | 3 + .../node_modules/stream-combiner/.travis.yml | 4 + .../node_modules/stream-combiner/LICENSE | 22 + .../node_modules/stream-combiner/README.md | 55 + .../node_modules/stream-combiner/index.js | 45 + .../node_modules/stream-combiner/package.json | 22 + .../stream-combiner/test/index.js | 65 + .../010.star/node_modules/through/.travis.yml | 5 + .../node_modules/through/LICENSE.APACHE2 | 15 + .../010.star/node_modules/through/LICENSE.MIT | 24 + .../010.star/node_modules/through/index.js | 108 + .../node_modules/through/package.json | 36 + .../node_modules/through/readme.markdown | 64 + .../node_modules/through/test/async.js | 28 + .../node_modules/through/test/auto-destroy.js | 30 + .../node_modules/through/test/buffering.js | 71 + .../010.star/node_modules/through/test/end.js | 45 + .../node_modules/through/test/index.js | 133 + .../010.star/node_modules/winston/LICENSE | 19 + .../010.star/node_modules/winston/README.md | 864 +++ .../010.star/node_modules/winston/index.d.ts | 501 ++ .../node_modules/winston/lib/winston.js | 165 + .../winston/lib/winston/common.js | 504 ++ .../winston/lib/winston/config.js | 68 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../lib/winston/config/syslog-config.js | 31 + .../winston/lib/winston/container.js | 128 + .../winston/lib/winston/exception.js | 56 + .../winston/lib/winston/logger.js | 729 ++ .../winston/lib/winston/transports.js | 36 + .../winston/lib/winston/transports/console.js | 130 + .../winston/lib/winston/transports/file.js | 685 ++ .../winston/lib/winston/transports/http.js | 242 + .../winston/lib/winston/transports/memory.js | 89 + .../lib/winston/transports/transport.js | 135 + .../node_modules/winston/package.json | 43 + .../node_modules/winston/test/helpers.js | 273 + .../winston/test/transports/console-test.js | 202 + .../test/transports/file-archive-test.js | 83 + .../test/transports/file-maxfiles-test.js | 102 + .../test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-open-test.js | 57 + .../test/transports/file-stress-test.js | 72 + .../test/transports/file-tailrolling-test.js | 92 + .../winston/test/transports/file-test.js | 134 + .../winston/test/transports/http-test.js | 70 + .../winston/test/transports/memory-test.js | 31 + .../winston/test/transports/transport.js | 212 + Challenge/seokahi/010.star/package-lock.json | 361 + Challenge/seokahi/010.star/package.json | 6 + Challenge/seokahi/010.star/solve.js | 44 + Challenge/seokahi/011.for/README.md | 11 + Challenge/seokahi/011.for/solve.js | 19 + Challenge/seokahi/012.class/README.md | 17 + Challenge/seokahi/012.class/solve.js | 32 + Challenge/seokahi/013.find-planet/README.md | 15 + Challenge/seokahi/013.find-planet/solve.js | 15 + Challenge/seokahi/014.if/README.md | 17 + Challenge/seokahi/014.if/solve.js | 25 + 448 files changed, 59276 insertions(+) create mode 100644 Challenge/seokahi/007.variable/README.md create mode 100644 Challenge/seokahi/007.variable/solve.js create mode 100644 Challenge/seokahi/008.object/README.md create mode 100644 Challenge/seokahi/008.object/solve.js create mode 100644 Challenge/seokahi/009.concat/README.md create mode 100644 Challenge/seokahi/009.concat/solve.js create mode 100644 Challenge/seokahi/010.star/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/.package-lock.json create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/examples/normal-usage.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/examples/safe-string.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/index.d.ts create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/colors.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/trap.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/zalgo.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/extendStringPrototype.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/america.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/rainbow.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/random.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/zebra.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/styles.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/has-flag.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/supports-colors.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/safe.d.ts create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/safe.js create mode 100644 Challenge/seokahi/010.star/node_modules/@colors/colors/themes/generic-logging.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/CHANGELOG.md create mode 100644 Challenge/seokahi/010.star/node_modules/async/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/async/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/async/all.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/allLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/allSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/any.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/anyLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/anySeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/apply.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/applyEach.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/applyEachSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/asyncify.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/auto.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/autoInject.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/bower.json create mode 100644 Challenge/seokahi/010.star/node_modules/async/cargo.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/cargoQueue.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/compose.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/concat.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/concatLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/concatSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/constant.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/detect.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/detectLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/detectSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/dir.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/dist/async.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/dist/async.min.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/dist/async.mjs create mode 100644 Challenge/seokahi/010.star/node_modules/async/doDuring.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/doUntil.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/doWhilst.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/during.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/each.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/eachLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/eachOf.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/eachOfLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/eachOfSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/eachSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/ensureAsync.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/every.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/everyLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/everySeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/filter.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/filterLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/filterSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/find.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/findLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/findSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/flatMap.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/flatMapLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/flatMapSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/foldl.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/foldr.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEach.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEachLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEachOf.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEachOfLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEachOfSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forEachSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/forever.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/groupBy.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/groupByLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/groupBySeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/inject.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/DoublyLinkedList.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/Heap.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/applyEach.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/asyncEachOfLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/awaitify.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/breakLoop.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/consoleFunc.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/createTester.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/eachOfLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/filter.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/getIterator.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/initialParams.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/isArrayLike.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/iterator.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/map.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/once.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/onlyOnce.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/parallel.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/promiseCallback.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/queue.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/range.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/reject.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/setImmediate.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/withoutIndex.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/internal/wrapAsync.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/log.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/map.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/mapLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/mapSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/mapValues.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/mapValuesLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/mapValuesSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/memoize.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/nextTick.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/async/parallel.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/parallelLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/priorityQueue.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/queue.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/race.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/reduce.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/reduceRight.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/reflect.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/reflectAll.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/reject.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/rejectLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/rejectSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/retry.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/retryable.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/select.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/selectLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/selectSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/seq.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/series.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/setImmediate.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/some.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/someLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/someSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/sortBy.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/timeout.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/times.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/timesLimit.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/timesSeries.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/transform.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/tryEach.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/unmemoize.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/until.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/waterfall.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/whilst.js create mode 100644 Challenge/seokahi/010.star/node_modules/async/wrapSync.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/colors/MIT-LICENSE.txt create mode 100644 Challenge/seokahi/010.star/node_modules/colors/ReadMe.md create mode 100644 Challenge/seokahi/010.star/node_modules/colors/examples/normal-usage.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/examples/safe-string.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/colors.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/custom/trap.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/custom/zalgo.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/extendStringPrototype.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/maps/america.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/maps/rainbow.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/maps/random.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/maps/zebra.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/styles.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/lib/system/supports-colors.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/colors/safe.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/screenshots/colors.png create mode 100644 Challenge/seokahi/010.star/node_modules/colors/tests/basic-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js create mode 100644 Challenge/seokahi/010.star/node_modules/cycle/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/cycle/cycle.js create mode 100644 Challenge/seokahi/010.star/node_modules/cycle/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/LICENCE create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/duplexer/test/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/LICENCE create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/examples/data create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js create mode 100644 Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/Makefile create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/from/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/from/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 create mode 100644 Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT create mode 100644 Challenge/seokahi/010.star/node_modules/from/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/from/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/from/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/from/test/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/.jshintrc create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/isstream.js create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/isstream/test.js create mode 100644 Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/lodash.assign/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/lodash.assign/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/lodash.assign/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/LICENCE create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/VERSION create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js.gz create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/aggregator.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/query.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/lib/util.js create mode 100644 Challenge/seokahi/010.star/node_modules/mingo/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/mute-stream/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/mute-stream/mute.js create mode 100644 Challenge/seokahi/010.star/node_modules/mute-stream/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/.eslintrc create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/.jshintrc create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/color.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/history.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/password.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/types.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/test/macros.js create mode 100644 Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/read/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/read/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/read/lib/read.js create mode 100644 Challenge/seokahi/010.star/node_modules/read/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/CHANGELOG.md create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/example/webservice.js create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/lib/revalidator.js create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/revalidator/test/validator-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/.eslintignore create mode 100644 Challenge/seokahi/010.star/node_modules/save/.eslintrc create mode 100644 Challenge/seokahi/010.star/node_modules/save/.prettierignore create mode 100644 Challenge/seokahi/010.star/node_modules/save/.prettierrc create mode 100644 Challenge/seokahi/010.star/node_modules/save/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/save/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/save/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/save/lib/memory-engine.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/lib/save.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/count.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/create-or-update.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/create.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/delete-many.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/delete.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/engine.tests.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/find-one.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/find.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/id-property.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/memory-engine.test.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/read.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/save.test.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/streaming.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/update-many.js create mode 100644 Challenge/seokahi/010.star/node_modules/save/test/update.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/split/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/split/LICENCE create mode 100644 Challenge/seokahi/010.star/node_modules/split/examples/pretty.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/split/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/split/test/options.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/test/partitioned_unicode.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/test/split.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/split/test/try_catch.asynct.js create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/License create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/Makefile create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/Readme.md create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/lib/stack-trace.js create mode 100644 Challenge/seokahi/010.star/node_modules/stack-trace/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/.npmignore create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/stream-combiner/test/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/.travis.yml create mode 100644 Challenge/seokahi/010.star/node_modules/through/LICENSE.APACHE2 create mode 100644 Challenge/seokahi/010.star/node_modules/through/LICENSE.MIT create mode 100644 Challenge/seokahi/010.star/node_modules/through/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/through/readme.markdown create mode 100644 Challenge/seokahi/010.star/node_modules/through/test/async.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/test/auto-destroy.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/test/buffering.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/test/end.js create mode 100644 Challenge/seokahi/010.star/node_modules/through/test/index.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/LICENSE create mode 100644 Challenge/seokahi/010.star/node_modules/winston/README.md create mode 100644 Challenge/seokahi/010.star/node_modules/winston/index.d.ts create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/common.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/config.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/container.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/exception.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/logger.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports/console.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports/file.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports/http.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports/memory.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/lib/winston/transports/transport.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/package.json create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/helpers.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/console-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-archive-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-open-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-stress-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-tailrolling-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/file-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/http-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/memory-test.js create mode 100644 Challenge/seokahi/010.star/node_modules/winston/test/transports/transport.js create mode 100644 Challenge/seokahi/010.star/package-lock.json create mode 100644 Challenge/seokahi/010.star/package.json create mode 100644 Challenge/seokahi/010.star/solve.js create mode 100644 Challenge/seokahi/011.for/README.md create mode 100644 Challenge/seokahi/011.for/solve.js create mode 100644 Challenge/seokahi/012.class/README.md create mode 100644 Challenge/seokahi/012.class/solve.js create mode 100644 Challenge/seokahi/013.find-planet/README.md create mode 100644 Challenge/seokahi/013.find-planet/solve.js create mode 100644 Challenge/seokahi/014.if/README.md create mode 100644 Challenge/seokahi/014.if/solve.js diff --git a/Challenge/seokahi/007.variable/README.md b/Challenge/seokahi/007.variable/README.md new file mode 100644 index 0000000..2002c44 --- /dev/null +++ b/Challenge/seokahi/007.variable/README.md @@ -0,0 +1,9 @@ +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + +1) age +2) Age +3) let +4) _age +5) 1age \ No newline at end of file diff --git a/Challenge/seokahi/007.variable/solve.js b/Challenge/seokahi/007.variable/solve.js new file mode 100644 index 0000000..32fbde9 --- /dev/null +++ b/Challenge/seokahi/007.variable/solve.js @@ -0,0 +1,20 @@ +/* +# 문제7 : 변수명 + +다음 중 변수명으로 사용할 수 없는 것 2개를 고르시오. + + +1) age +2) Age +3) let +4) _age +5) 1age +*/ + +// 답 3번, 5번 + +// let let = 10; +// console.log(let); + +// let 1age = 20; +// console.log(1age); diff --git a/Challenge/seokahi/008.object/README.md b/Challenge/seokahi/008.object/README.md new file mode 100644 index 0000000..0e23154 --- /dev/null +++ b/Challenge/seokahi/008.object/README.md @@ -0,0 +1,16 @@ +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +```jsx +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +``` \ No newline at end of file diff --git a/Challenge/seokahi/008.object/solve.js b/Challenge/seokahi/008.object/solve.js new file mode 100644 index 0000000..1a0e5ce --- /dev/null +++ b/Challenge/seokahi/008.object/solve.js @@ -0,0 +1,19 @@ +/* +# 문제8 : 객체의 키 이름 중복 + +자바스크립트 객체를 다음과 같이 만들었다. +출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. ) + +var d = { + 'height':180, + 'weight':78, + 'weight':84, + 'temperature':36, + 'eyesight':1 +}; + +console.log(d['weight']); +*/ + +// 출력값 => 84 + diff --git a/Challenge/seokahi/009.concat/README.md b/Challenge/seokahi/009.concat/README.md new file mode 100644 index 0000000..6087ee5 --- /dev/null +++ b/Challenge/seokahi/009.concat/README.md @@ -0,0 +1,20 @@ +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +```jsx +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +``` \ No newline at end of file diff --git a/Challenge/seokahi/009.concat/solve.js b/Challenge/seokahi/009.concat/solve.js new file mode 100644 index 0000000..f5270e8 --- /dev/null +++ b/Challenge/seokahi/009.concat/solve.js @@ -0,0 +1,31 @@ +/* +# 문제9 : concat을 활용한 출력 방법 + +다음 소스 코드를 완성하여 날짜와 시간을 출력하시오. + +**데이터** +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = //빈칸을 채워주세요 + +console.log(result); + +**출력** +2019/04/26 11:34:27 +*/ + +var year = '2019'; +var month = '04'; +var day = '26'; +var hour = '11'; +var minute = '34'; +var second = '27'; + +var result = year.concat('/',month,'/',day,' ',hour,':',minute,':',second); + +console.log(result); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/README.md b/Challenge/seokahi/010.star/README.md new file mode 100644 index 0000000..9b05132 --- /dev/null +++ b/Challenge/seokahi/010.star/README.md @@ -0,0 +1,18 @@ +# 문제10 : 별 찍기 + +크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. +하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다. + +**은비를 위해 프로그램을 작성해 주세요.** + +```jsx +**입력** +5 + +**출력** + * + *** + ***** + ******* +********* +``` \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/.package-lock.json b/Challenge/seokahi/010.star/node_modules/.package-lock.json new file mode 100644 index 0000000..1b42393 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/.package-lock.json @@ -0,0 +1,195 @@ +{ + "name": "010.star", + "lockfileVersion": 2, + "requires": true, + "packages": { + "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==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, + "node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" + }, + "node_modules/mingo": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-1.3.3.tgz", + "integrity": "sha512-Y4wGTD/M7AMqF8QxKaBGps+axq/Z48hdtRAeiKtInkEXMLzUWUwT0OPDzrB26xrav9GF1AOYJfwVWPcLwnkgTA==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/prompt": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.3.0.tgz", + "integrity": "sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==", + "dependencies": { + "@colors/colors": "1.5.0", + "async": "3.2.3", + "read": "1.0.x", + "revalidator": "0.1.x", + "winston": "2.x" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/revalidator": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", + "integrity": "sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/save": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/save/-/save-2.5.0.tgz", + "integrity": "sha512-xiVLpKVbx8EmW0HDkNRjYL271OnIRCo8VGWAEq6/K+E0dgNrwKV2xvKXdfPj6HGYA6l760800LyewSY3ooljCg==", + "dependencies": { + "async": "^3.2.2", + "event-stream": "^4.0.1", + "lodash.assign": "^4.2.0", + "mingo": "1" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/winston": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz", + "integrity": "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w==", + "dependencies": { + "async": "^3.2.3", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.10.0" + } + } + } +} diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/LICENSE b/Challenge/seokahi/010.star/node_modules/@colors/colors/LICENSE new file mode 100644 index 0000000..6b86056 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/LICENSE @@ -0,0 +1,26 @@ +MIT License + +Original Library + - Copyright (c) Marak Squires + +Additional Functionality + - Copyright (c) Sindre Sorhus (sindresorhus.com) + - Copyright (c) DABH (https://github.com/DABH) + +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/Challenge/seokahi/010.star/node_modules/@colors/colors/README.md b/Challenge/seokahi/010.star/node_modules/@colors/colors/README.md new file mode 100644 index 0000000..e2479ce --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/README.md @@ -0,0 +1,219 @@ +# @colors/colors ("colors.js") +[![Build Status](https://github.com/DABH/colors.js/actions/workflows/ci.yml/badge.svg)](https://github.com/DABH/colors.js/actions/workflows/ci.yml) +[![version](https://img.shields.io/npm/v/@colors/colors.svg)](https://www.npmjs.org/package/@colors/colors) + +Please check out the [roadmap](ROADMAP.md) for upcoming features and releases. Please open Issues to provide feedback. + +## get color and style in your node.js console + +![Demo](https://raw.githubusercontent.com/DABH/colors.js/master/screenshots/colors.png) + +## Installation + + npm install @colors/colors + +## colors and styles! + +### text colors + + - black + - red + - green + - yellow + - blue + - magenta + - cyan + - white + - gray + - grey + +### bright text colors + + - brightRed + - brightGreen + - brightYellow + - brightBlue + - brightMagenta + - brightCyan + - brightWhite + +### background colors + + - bgBlack + - bgRed + - bgGreen + - bgYellow + - bgBlue + - bgMagenta + - bgCyan + - bgWhite + - bgGray + - bgGrey + +### bright background colors + + - bgBrightRed + - bgBrightGreen + - bgBrightYellow + - bgBrightBlue + - bgBrightMagenta + - bgBrightCyan + - bgBrightWhite + +### styles + + - reset + - bold + - dim + - italic + - underline + - inverse + - hidden + - strikethrough + +### extras + + - rainbow + - zebra + - america + - trap + - random + + +## Usage + +By popular demand, `@colors/colors` now ships with two types of usages! + +The super nifty way + +```js +var colors = require('@colors/colors'); + +console.log('hello'.green); // outputs green text +console.log('i like cake and pies'.underline.red); // outputs red underlined text +console.log('inverse the color'.inverse); // inverses the color +console.log('OMG Rainbows!'.rainbow); // rainbow +console.log('Run the trap'.trap); // Drops the bass + +``` + +or a slightly less nifty way which doesn't extend `String.prototype` + +```js +var colors = require('@colors/colors/safe'); + +console.log(colors.green('hello')); // outputs green text +console.log(colors.red.underline('i like cake and pies')); // outputs red underlined text +console.log(colors.inverse('inverse the color')); // inverses the color +console.log(colors.rainbow('OMG Rainbows!')); // rainbow +console.log(colors.trap('Run the trap')); // Drops the bass + +``` + +I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. + +If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object. + +## Enabling/Disabling Colors + +The package will auto-detect whether your terminal can use colors and enable/disable accordingly. When colors are disabled, the color functions do nothing. You can override this with a command-line flag: + +```bash +node myapp.js --no-color +node myapp.js --color=false + +node myapp.js --color +node myapp.js --color=true +node myapp.js --color=always + +FORCE_COLOR=1 node myapp.js +``` + +Or in code: + +```javascript +var colors = require('@colors/colors'); +colors.enable(); +colors.disable(); +``` + +## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data) + +```js +var name = 'Beowulf'; +console.log(colors.green('Hello %s'), name); +// outputs -> 'Hello Beowulf' +``` + +## Custom themes + +### Using standard API + +```js + +var colors = require('@colors/colors'); + +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); +``` + +### Using string safe API + +```js +var colors = require('@colors/colors/safe'); + +// set single property +var error = colors.red; +error('this is red'); + +// set theme +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log(colors.error("this is an error")); + +// outputs yellow text +console.log(colors.warn("this is a warning")); + +``` + +### Combining Colors + +```javascript +var colors = require('@colors/colors'); + +colors.setTheme({ + custom: ['red', 'underline'] +}); + +console.log('test'.custom); +``` + +*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.* diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/normal-usage.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/normal-usage.js new file mode 100644 index 0000000..a4bfe7b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/normal-usage.js @@ -0,0 +1,83 @@ +var colors = require('../lib/index'); + +console.log('First some yellow text'.yellow); + +console.log('Underline that text'.yellow.underline); + +console.log('Make it bold and red'.red.bold); + +console.log(('Double Raindows All Day Long').rainbow); + +console.log('Drop the bass'.trap); + +console.log('DROP THE RAINBOW BASS'.trap.rainbow); + +// styles not widely supported +console.log('Chains are also cool.'.bold.italic.underline.red); + +// styles not widely supported +console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse + + ' styles! '.yellow.bold); +console.log('Zebras are so fun!'.zebra); + +// +// Remark: .strikethrough may not work with Mac OS Terminal App +// +console.log('This is ' + 'not'.strikethrough + ' fun.'); + +console.log('Background color attack!'.black.bgWhite); +console.log('Use random styles on everything!'.random); +console.log('America, Heck Yeah!'.america); + +// eslint-disable-next-line max-len +console.log('Blindingly '.brightCyan + 'bright? '.brightRed + 'Why '.brightYellow + 'not?!'.brightGreen); + +console.log('Setting themes is useful'); + +// +// Custom themes +// +console.log('Generic logging theme as JSON'.green.bold.underline); +// Load theme with JSON literal +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red', +}); + +// outputs red text +console.log('this is an error'.error); + +// outputs yellow text +console.log('this is a warning'.warn); + +// outputs grey text +console.log('this is an input'.input); + +console.log('Generic logging theme as file'.green.bold.underline); + +// Load a theme from file +try { + colors.setTheme(require(__dirname + '/../themes/generic-logging.js')); +} catch (err) { + console.log(err); +} + +// outputs red text +console.log('this is an error'.error); + +// outputs yellow text +console.log('this is a warning'.warn); + +// outputs grey text +console.log('this is an input'.input); + +// console.log("Don't summon".zalgo) + diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/safe-string.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/safe-string.js new file mode 100644 index 0000000..fc66474 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/examples/safe-string.js @@ -0,0 +1,80 @@ +var colors = require('../safe'); + +console.log(colors.yellow('First some yellow text')); + +console.log(colors.yellow.underline('Underline that text')); + +console.log(colors.red.bold('Make it bold and red')); + +console.log(colors.rainbow('Double Raindows All Day Long')); + +console.log(colors.trap('Drop the bass')); + +console.log(colors.rainbow(colors.trap('DROP THE RAINBOW BASS'))); + +// styles not widely supported +console.log(colors.bold.italic.underline.red('Chains are also cool.')); + +// styles not widely supported +console.log(colors.green('So ') + colors.underline('are') + ' ' + + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); + +console.log(colors.zebra('Zebras are so fun!')); + +console.log('This is ' + colors.strikethrough('not') + ' fun.'); + + +console.log(colors.black.bgWhite('Background color attack!')); +console.log(colors.random('Use random styles on everything!')); +console.log(colors.america('America, Heck Yeah!')); + +// eslint-disable-next-line max-len +console.log(colors.brightCyan('Blindingly ') + colors.brightRed('bright? ') + colors.brightYellow('Why ') + colors.brightGreen('not?!')); + +console.log('Setting themes is useful'); + +// +// Custom themes +// +// console.log('Generic logging theme as JSON'.green.bold.underline); +// Load theme with JSON literal +colors.setTheme({ + silly: 'rainbow', + input: 'blue', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red', +}); + +// outputs red text +console.log(colors.error('this is an error')); + +// outputs yellow text +console.log(colors.warn('this is a warning')); + +// outputs blue text +console.log(colors.input('this is an input')); + + +// console.log('Generic logging theme as file'.green.bold.underline); + +// Load a theme from file +colors.setTheme(require(__dirname + '/../themes/generic-logging.js')); + +// outputs red text +console.log(colors.error('this is an error')); + +// outputs yellow text +console.log(colors.warn('this is a warning')); + +// outputs grey text +console.log(colors.input('this is an input')); + +// console.log(colors.zalgo("Don't summon him")) + + diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/index.d.ts b/Challenge/seokahi/010.star/node_modules/@colors/colors/index.d.ts new file mode 100644 index 0000000..df3f2e6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/index.d.ts @@ -0,0 +1,136 @@ +// Type definitions for @colors/colors 1.4+ +// Project: https://github.com/Marak/colors.js +// Definitions by: Bart van der Schoor , Staffan Eketorp +// Definitions: https://github.com/DABH/colors.js + +export interface Color { + (text: string): string; + + strip: Color; + stripColors: Color; + + black: Color; + red: Color; + green: Color; + yellow: Color; + blue: Color; + magenta: Color; + cyan: Color; + white: Color; + gray: Color; + grey: Color; + + bgBlack: Color; + bgRed: Color; + bgGreen: Color; + bgYellow: Color; + bgBlue: Color; + bgMagenta: Color; + bgCyan: Color; + bgWhite: Color; + + reset: Color; + bold: Color; + dim: Color; + italic: Color; + underline: Color; + inverse: Color; + hidden: Color; + strikethrough: Color; + + rainbow: Color; + zebra: Color; + america: Color; + trap: Color; + random: Color; + zalgo: Color; +} + +export function enable(): void; +export function disable(): void; +export function setTheme(theme: any): void; + +export let enabled: boolean; + +export const strip: Color; +export const stripColors: Color; + +export const black: Color; +export const red: Color; +export const green: Color; +export const yellow: Color; +export const blue: Color; +export const magenta: Color; +export const cyan: Color; +export const white: Color; +export const gray: Color; +export const grey: Color; + +export const bgBlack: Color; +export const bgRed: Color; +export const bgGreen: Color; +export const bgYellow: Color; +export const bgBlue: Color; +export const bgMagenta: Color; +export const bgCyan: Color; +export const bgWhite: Color; + +export const reset: Color; +export const bold: Color; +export const dim: Color; +export const italic: Color; +export const underline: Color; +export const inverse: Color; +export const hidden: Color; +export const strikethrough: Color; + +export const rainbow: Color; +export const zebra: Color; +export const america: Color; +export const trap: Color; +export const random: Color; +export const zalgo: Color; + +declare global { + interface String { + strip: string; + stripColors: string; + + black: string; + red: string; + green: string; + yellow: string; + blue: string; + magenta: string; + cyan: string; + white: string; + gray: string; + grey: string; + + bgBlack: string; + bgRed: string; + bgGreen: string; + bgYellow: string; + bgBlue: string; + bgMagenta: string; + bgCyan: string; + bgWhite: string; + + reset: string; + // @ts-ignore + bold: string; + dim: string; + italic: string; + underline: string; + inverse: string; + hidden: string; + strikethrough: string; + + rainbow: string; + zebra: string; + america: string; + trap: string; + random: string; + zalgo: string; + } +} diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/colors.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/colors.js new file mode 100644 index 0000000..d9fb087 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/colors.js @@ -0,0 +1,211 @@ +/* + +The MIT License (MIT) + +Original Library + - Copyright (c) Marak Squires + +Additional functionality + - Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +var colors = {}; +module['exports'] = colors; + +colors.themes = {}; + +var util = require('util'); +var ansiStyles = colors.styles = require('./styles'); +var defineProps = Object.defineProperties; +var newLineRegex = new RegExp(/[\r\n]+/g); + +colors.supportsColor = require('./system/supports-colors').supportsColor; + +if (typeof colors.enabled === 'undefined') { + colors.enabled = colors.supportsColor() !== false; +} + +colors.enable = function() { + colors.enabled = true; +}; + +colors.disable = function() { + colors.enabled = false; +}; + +colors.stripColors = colors.strip = function(str) { + return ('' + str).replace(/\x1B\[\d+m/g, ''); +}; + +// eslint-disable-next-line no-unused-vars +var stylize = colors.stylize = function stylize(str, style) { + if (!colors.enabled) { + return str+''; + } + + var styleMap = ansiStyles[style]; + + // Stylize should work for non-ANSI styles, too + if (!styleMap && style in colors) { + // Style maps like trap operate as functions on strings; + // they don't have properties like open or close. + return colors[style](str); + } + + return styleMap.open + str + styleMap.close; +}; + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; +var escapeStringRegexp = function(str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + return str.replace(matchOperatorsRe, '\\$&'); +}; + +function build(_styles) { + var builder = function builder() { + return applyStyle.apply(builder, arguments); + }; + builder._styles = _styles; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + builder.__proto__ = proto; + return builder; +} + +var styles = (function() { + var ret = {}; + ansiStyles.grey = ansiStyles.gray; + Object.keys(ansiStyles).forEach(function(key) { + ansiStyles[key].closeRe = + new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + ret[key] = { + get: function() { + return build(this._styles.concat(key)); + }, + }; + }); + return ret; +})(); + +var proto = defineProps(function colors() {}, styles); + +function applyStyle() { + var args = Array.prototype.slice.call(arguments); + + var str = args.map(function(arg) { + // Use weak equality check so we can colorize null/undefined in safe mode + if (arg != null && arg.constructor === String) { + return arg; + } else { + return util.inspect(arg); + } + }).join(' '); + + if (!colors.enabled || !str) { + return str; + } + + var newLinesPresent = str.indexOf('\n') != -1; + + var nestedStyles = this._styles; + + var i = nestedStyles.length; + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + str = code.open + str.replace(code.closeRe, code.open) + code.close; + if (newLinesPresent) { + str = str.replace(newLineRegex, function(match) { + return code.close + match + code.open; + }); + } + } + + return str; +} + +colors.setTheme = function(theme) { + if (typeof theme === 'string') { + console.log('colors.setTheme now only accepts an object, not a string. ' + + 'If you are trying to set a theme from a file, it is now your (the ' + + 'caller\'s) responsibility to require the file. The old syntax ' + + 'looked like colors.setTheme(__dirname + ' + + '\'/../themes/generic-logging.js\'); The new syntax looks like '+ + 'colors.setTheme(require(__dirname + ' + + '\'/../themes/generic-logging.js\'));'); + return; + } + for (var style in theme) { + (function(style) { + colors[style] = function(str) { + if (typeof theme[style] === 'object') { + var out = str; + for (var i in theme[style]) { + out = colors[theme[style][i]](out); + } + return out; + } + return colors[theme[style]](str); + }; + })(style); + } +}; + +function init() { + var ret = {}; + Object.keys(styles).forEach(function(name) { + ret[name] = { + get: function() { + return build([name]); + }, + }; + }); + return ret; +} + +var sequencer = function sequencer(map, str) { + var exploded = str.split(''); + exploded = exploded.map(map); + return exploded.join(''); +}; + +// custom formatter methods +colors.trap = require('./custom/trap'); +colors.zalgo = require('./custom/zalgo'); + +// maps +colors.maps = {}; +colors.maps.america = require('./maps/america')(colors); +colors.maps.zebra = require('./maps/zebra')(colors); +colors.maps.rainbow = require('./maps/rainbow')(colors); +colors.maps.random = require('./maps/random')(colors); + +for (var map in colors.maps) { + (function(map) { + colors[map] = function(str) { + return sequencer(colors.maps[map], str); + }; + })(map); +} + +defineProps(colors, init()); diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/trap.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/trap.js new file mode 100644 index 0000000..fbccf88 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/trap.js @@ -0,0 +1,46 @@ +module['exports'] = function runTheTrap(text, options) { + var result = ''; + text = text || 'Run the trap, drop the bass'; + text = text.split(''); + var trap = { + a: ['\u0040', '\u0104', '\u023a', '\u0245', '\u0394', '\u039b', '\u0414'], + b: ['\u00df', '\u0181', '\u0243', '\u026e', '\u03b2', '\u0e3f'], + c: ['\u00a9', '\u023b', '\u03fe'], + d: ['\u00d0', '\u018a', '\u0500', '\u0501', '\u0502', '\u0503'], + e: ['\u00cb', '\u0115', '\u018e', '\u0258', '\u03a3', '\u03be', '\u04bc', + '\u0a6c'], + f: ['\u04fa'], + g: ['\u0262'], + h: ['\u0126', '\u0195', '\u04a2', '\u04ba', '\u04c7', '\u050a'], + i: ['\u0f0f'], + j: ['\u0134'], + k: ['\u0138', '\u04a0', '\u04c3', '\u051e'], + l: ['\u0139'], + m: ['\u028d', '\u04cd', '\u04ce', '\u0520', '\u0521', '\u0d69'], + n: ['\u00d1', '\u014b', '\u019d', '\u0376', '\u03a0', '\u048a'], + o: ['\u00d8', '\u00f5', '\u00f8', '\u01fe', '\u0298', '\u047a', '\u05dd', + '\u06dd', '\u0e4f'], + p: ['\u01f7', '\u048e'], + q: ['\u09cd'], + r: ['\u00ae', '\u01a6', '\u0210', '\u024c', '\u0280', '\u042f'], + s: ['\u00a7', '\u03de', '\u03df', '\u03e8'], + t: ['\u0141', '\u0166', '\u0373'], + u: ['\u01b1', '\u054d'], + v: ['\u05d8'], + w: ['\u0428', '\u0460', '\u047c', '\u0d70'], + x: ['\u04b2', '\u04fe', '\u04fc', '\u04fd'], + y: ['\u00a5', '\u04b0', '\u04cb'], + z: ['\u01b5', '\u0240'], + }; + text.forEach(function(c) { + c = c.toLowerCase(); + var chars = trap[c] || [' ']; + var rand = Math.floor(Math.random() * chars.length); + if (typeof trap[c] !== 'undefined') { + result += trap[c][rand]; + } else { + result += c; + } + }); + return result; +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/zalgo.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/zalgo.js new file mode 100644 index 0000000..0ef2b01 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/custom/zalgo.js @@ -0,0 +1,110 @@ +// please no +module['exports'] = function zalgo(text, options) { + text = text || ' he is here '; + var soul = { + 'up': [ + '̍', '̎', '̄', '̅', + '̿', '̑', '̆', '̐', + '͒', '͗', '͑', '̇', + '̈', '̊', '͂', '̓', + '̈', '͊', '͋', '͌', + '̃', '̂', '̌', '͐', + '̀', '́', '̋', '̏', + '̒', '̓', '̔', '̽', + '̉', 'ͣ', 'ͤ', 'ͥ', + 'ͦ', 'ͧ', 'ͨ', 'ͩ', + 'ͪ', 'ͫ', 'ͬ', 'ͭ', + 'ͮ', 'ͯ', '̾', '͛', + '͆', '̚', + ], + 'down': [ + '̖', '̗', '̘', '̙', + '̜', '̝', '̞', '̟', + '̠', '̤', '̥', '̦', + '̩', '̪', '̫', '̬', + '̭', '̮', '̯', '̰', + '̱', '̲', '̳', '̹', + '̺', '̻', '̼', 'ͅ', + '͇', '͈', '͉', '͍', + '͎', '͓', '͔', '͕', + '͖', '͙', '͚', '̣', + ], + 'mid': [ + '̕', '̛', '̀', '́', + '͘', '̡', '̢', '̧', + '̨', '̴', '̵', '̶', + '͜', '͝', '͞', + '͟', '͠', '͢', '̸', + '̷', '͡', ' ҉', + ], + }; + var all = [].concat(soul.up, soul.down, soul.mid); + + function randomNumber(range) { + var r = Math.floor(Math.random() * range); + return r; + } + + function isChar(character) { + var bool = false; + all.filter(function(i) { + bool = (i === character); + }); + return bool; + } + + + function heComes(text, options) { + var result = ''; + var counts; + var l; + options = options || {}; + options['up'] = + typeof options['up'] !== 'undefined' ? options['up'] : true; + options['mid'] = + typeof options['mid'] !== 'undefined' ? options['mid'] : true; + options['down'] = + typeof options['down'] !== 'undefined' ? options['down'] : true; + options['size'] = + typeof options['size'] !== 'undefined' ? options['size'] : 'maxi'; + text = text.split(''); + for (l in text) { + if (isChar(l)) { + continue; + } + result = result + text[l]; + counts = {'up': 0, 'down': 0, 'mid': 0}; + switch (options.size) { + case 'mini': + counts.up = randomNumber(8); + counts.mid = randomNumber(2); + counts.down = randomNumber(8); + break; + case 'maxi': + counts.up = randomNumber(16) + 3; + counts.mid = randomNumber(4) + 1; + counts.down = randomNumber(64) + 3; + break; + default: + counts.up = randomNumber(8) + 1; + counts.mid = randomNumber(6) / 2; + counts.down = randomNumber(8) + 1; + break; + } + + var arr = ['up', 'mid', 'down']; + for (var d in arr) { + var index = arr[d]; + for (var i = 0; i <= counts[index]; i++) { + if (options[index]) { + result = result + soul[index][randomNumber(soul[index].length)]; + } + } + } + } + return result; + } + // don't summon him + return heComes(text, options); +}; + diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/extendStringPrototype.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/extendStringPrototype.js new file mode 100644 index 0000000..46fd386 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/extendStringPrototype.js @@ -0,0 +1,110 @@ +var colors = require('./colors'); + +module['exports'] = function() { + // + // Extends prototype of native string object to allow for "foo".red syntax + // + var addProperty = function(color, func) { + String.prototype.__defineGetter__(color, func); + }; + + addProperty('strip', function() { + return colors.strip(this); + }); + + addProperty('stripColors', function() { + return colors.strip(this); + }); + + addProperty('trap', function() { + return colors.trap(this); + }); + + addProperty('zalgo', function() { + return colors.zalgo(this); + }); + + addProperty('zebra', function() { + return colors.zebra(this); + }); + + addProperty('rainbow', function() { + return colors.rainbow(this); + }); + + addProperty('random', function() { + return colors.random(this); + }); + + addProperty('america', function() { + return colors.america(this); + }); + + // + // Iterate through all default styles and colors + // + var x = Object.keys(colors.styles); + x.forEach(function(style) { + addProperty(style, function() { + return colors.stylize(this, style); + }); + }); + + function applyTheme(theme) { + // + // Remark: This is a list of methods that exist + // on String that you should not overwrite. + // + var stringPrototypeBlacklist = [ + '__defineGetter__', '__defineSetter__', '__lookupGetter__', + '__lookupSetter__', 'charAt', 'constructor', 'hasOwnProperty', + 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', + 'valueOf', 'charCodeAt', 'indexOf', 'lastIndexOf', 'length', + 'localeCompare', 'match', 'repeat', 'replace', 'search', 'slice', + 'split', 'substring', 'toLocaleLowerCase', 'toLocaleUpperCase', + 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', + ]; + + Object.keys(theme).forEach(function(prop) { + if (stringPrototypeBlacklist.indexOf(prop) !== -1) { + console.log('warn: '.red + ('String.prototype' + prop).magenta + + ' is probably something you don\'t want to override. ' + + 'Ignoring style name'); + } else { + if (typeof(theme[prop]) === 'string') { + colors[prop] = colors[theme[prop]]; + addProperty(prop, function() { + return colors[prop](this); + }); + } else { + var themePropApplicator = function(str) { + var ret = str || this; + for (var t = 0; t < theme[prop].length; t++) { + ret = colors[theme[prop][t]](ret); + } + return ret; + }; + addProperty(prop, themePropApplicator); + colors[prop] = function(str) { + return themePropApplicator(str); + }; + } + } + }); + } + + colors.setTheme = function(theme) { + if (typeof theme === 'string') { + console.log('colors.setTheme now only accepts an object, not a string. ' + + 'If you are trying to set a theme from a file, it is now your (the ' + + 'caller\'s) responsibility to require the file. The old syntax ' + + 'looked like colors.setTheme(__dirname + ' + + '\'/../themes/generic-logging.js\'); The new syntax looks like '+ + 'colors.setTheme(require(__dirname + ' + + '\'/../themes/generic-logging.js\'));'); + return; + } else { + applyTheme(theme); + } + }; +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/index.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/index.js new file mode 100644 index 0000000..9df5ab7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/index.js @@ -0,0 +1,13 @@ +var colors = require('./colors'); +module['exports'] = colors; + +// Remark: By default, colors will add style properties to String.prototype. +// +// If you don't wish to extend String.prototype, you can do this instead and +// native String will not be touched: +// +// var colors = require('colors/safe); +// colors.red("foo") +// +// +require('./extendStringPrototype')(); diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/america.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/america.js new file mode 100644 index 0000000..dc96903 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/america.js @@ -0,0 +1,10 @@ +module['exports'] = function(colors) { + return function(letter, i, exploded) { + if (letter === ' ') return letter; + switch (i%3) { + case 0: return colors.red(letter); + case 1: return colors.white(letter); + case 2: return colors.blue(letter); + } + }; +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/rainbow.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/rainbow.js new file mode 100644 index 0000000..2b00ac0 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/rainbow.js @@ -0,0 +1,12 @@ +module['exports'] = function(colors) { + // RoY G BiV + var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; + return function(letter, i, exploded) { + if (letter === ' ') { + return letter; + } else { + return colors[rainbowColors[i++ % rainbowColors.length]](letter); + } + }; +}; + diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/random.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/random.js new file mode 100644 index 0000000..3d82a39 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/random.js @@ -0,0 +1,11 @@ +module['exports'] = function(colors) { + var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green', + 'blue', 'white', 'cyan', 'magenta', 'brightYellow', 'brightRed', + 'brightGreen', 'brightBlue', 'brightWhite', 'brightCyan', 'brightMagenta']; + return function(letter, i, exploded) { + return letter === ' ' ? letter : + colors[ + available[Math.round(Math.random() * (available.length - 2))] + ](letter); + }; +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/zebra.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/zebra.js new file mode 100644 index 0000000..fa73623 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/maps/zebra.js @@ -0,0 +1,5 @@ +module['exports'] = function(colors) { + return function(letter, i, exploded) { + return i % 2 === 0 ? letter : colors.inverse(letter); + }; +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/styles.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/styles.js new file mode 100644 index 0000000..011dafd --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/styles.js @@ -0,0 +1,95 @@ +/* +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +var styles = {}; +module['exports'] = styles; + +var codes = { + reset: [0, 0], + + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], + grey: [90, 39], + + brightRed: [91, 39], + brightGreen: [92, 39], + brightYellow: [93, 39], + brightBlue: [94, 39], + brightMagenta: [95, 39], + brightCyan: [96, 39], + brightWhite: [97, 39], + + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + bgGray: [100, 49], + bgGrey: [100, 49], + + bgBrightRed: [101, 49], + bgBrightGreen: [102, 49], + bgBrightYellow: [103, 49], + bgBrightBlue: [104, 49], + bgBrightMagenta: [105, 49], + bgBrightCyan: [106, 49], + bgBrightWhite: [107, 49], + + // legacy styles for colors pre v1.0.0 + blackBG: [40, 49], + redBG: [41, 49], + greenBG: [42, 49], + yellowBG: [43, 49], + blueBG: [44, 49], + magentaBG: [45, 49], + cyanBG: [46, 49], + whiteBG: [47, 49], + +}; + +Object.keys(codes).forEach(function(key) { + var val = codes[key]; + var style = styles[key] = []; + style.open = '\u001b[' + val[0] + 'm'; + style.close = '\u001b[' + val[1] + 'm'; +}); diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/has-flag.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/has-flag.js new file mode 100644 index 0000000..a347dd4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/has-flag.js @@ -0,0 +1,35 @@ +/* +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. +*/ + +'use strict'; + +module.exports = function(flag, argv) { + argv = argv || process.argv; + + var terminatorPos = argv.indexOf('--'); + var prefix = /^-{1,2}/.test(flag) ? '' : '--'; + var pos = argv.indexOf(prefix + flag); + + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/supports-colors.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/supports-colors.js new file mode 100644 index 0000000..f1f9c8f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/lib/system/supports-colors.js @@ -0,0 +1,151 @@ +/* +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +'use strict'; + +var os = require('os'); +var hasFlag = require('./has-flag.js'); + +var env = process.env; + +var forceColor = void 0; +if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') + || hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 + || parseInt(env.FORCE_COLOR, 10) !== 0; +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level: level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, + }; +} + +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } + + if (hasFlag('color=16m') || hasFlag('color=full') + || hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } + + var min = forceColor ? 1 : 0; + + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first + // Windows release that supports 256 colors. Windows 10 build 14931 is the + // first release that supports 16m/TrueColor. + var osRelease = os.release().split('.'); + if (Number(process.versions.node.split('.')[0]) >= 8 + && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(function(sign) { + return sign in env; + }) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return (/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0 + ); + } + + if ('TERM_PROGRAM' in env) { + var version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Hyper': + return 3; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + if (env.TERM === 'dumb') { + return min; + } + + return min; +} + +function getSupportLevel(stream) { + var level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr), +}; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/package.json b/Challenge/seokahi/010.star/node_modules/@colors/colors/package.json new file mode 100644 index 0000000..cb87f20 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/package.json @@ -0,0 +1,45 @@ +{ + "name": "@colors/colors", + "description": "get colors in your node.js console", + "version": "1.5.0", + "author": "DABH", + "contributors": [ + { + "name": "DABH", + "url": "https://github.com/DABH" + } + ], + "homepage": "https://github.com/DABH/colors.js", + "bugs": "https://github.com/DABH/colors.js/issues", + "keywords": [ + "ansi", + "terminal", + "colors" + ], + "repository": { + "type": "git", + "url": "http://github.com/DABH/colors.js.git" + }, + "license": "MIT", + "scripts": { + "lint": "eslint . --fix", + "test": "export FORCE_COLOR=1 && node tests/basic-test.js && node tests/safe-test.js" + }, + "engines": { + "node": ">=0.1.90" + }, + "main": "lib/index.js", + "files": [ + "examples", + "lib", + "LICENSE", + "safe.js", + "themes", + "index.d.ts", + "safe.d.ts" + ], + "devDependencies": { + "eslint": "^5.2.0", + "eslint-config-google": "^0.11.0" + } +} diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.d.ts b/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.d.ts new file mode 100644 index 0000000..2bafc27 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.d.ts @@ -0,0 +1,48 @@ +// Type definitions for Colors.js 1.2 +// Project: https://github.com/Marak/colors.js +// Definitions by: Bart van der Schoor , Staffan Eketorp +// Definitions: https://github.com/Marak/colors.js + +export const enabled: boolean; +export function enable(): void; +export function disable(): void; +export function setTheme(theme: any): void; + +export function strip(str: string): string; +export function stripColors(str: string): string; + +export function black(str: string): string; +export function red(str: string): string; +export function green(str: string): string; +export function yellow(str: string): string; +export function blue(str: string): string; +export function magenta(str: string): string; +export function cyan(str: string): string; +export function white(str: string): string; +export function gray(str: string): string; +export function grey(str: string): string; + +export function bgBlack(str: string): string; +export function bgRed(str: string): string; +export function bgGreen(str: string): string; +export function bgYellow(str: string): string; +export function bgBlue(str: string): string; +export function bgMagenta(str: string): string; +export function bgCyan(str: string): string; +export function bgWhite(str: string): string; + +export function reset(str: string): string; +export function bold(str: string): string; +export function dim(str: string): string; +export function italic(str: string): string; +export function underline(str: string): string; +export function inverse(str: string): string; +export function hidden(str: string): string; +export function strikethrough(str: string): string; + +export function rainbow(str: string): string; +export function zebra(str: string): string; +export function america(str: string): string; +export function trap(str: string): string; +export function random(str: string): string; +export function zalgo(str: string): string; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.js new file mode 100644 index 0000000..a013d54 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/safe.js @@ -0,0 +1,10 @@ +// +// Remark: Requiring this file will use the "safe" colors API, +// which will not touch String.prototype. +// +// var colors = require('colors/safe'); +// colors.red("foo") +// +// +var colors = require('./lib/colors'); +module['exports'] = colors; diff --git a/Challenge/seokahi/010.star/node_modules/@colors/colors/themes/generic-logging.js b/Challenge/seokahi/010.star/node_modules/@colors/colors/themes/generic-logging.js new file mode 100644 index 0000000..63adfe4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/@colors/colors/themes/generic-logging.js @@ -0,0 +1,12 @@ +module['exports'] = { + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red', +}; diff --git a/Challenge/seokahi/010.star/node_modules/async/CHANGELOG.md b/Challenge/seokahi/010.star/node_modules/async/CHANGELOG.md new file mode 100644 index 0000000..133d05c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/CHANGELOG.md @@ -0,0 +1,344 @@ +# v3.2.3 +- Fix bugs in comment parsing in `autoInject`. (#1767, #1780) + +# v3.2.2 +- Fix potential prototype pollution exploit + +# v3.2.1 +- Use `queueMicrotask` if available to the environment (#1761) +- Minor perf improvement in `priorityQueue` (#1727) +- More examples in documentation (#1726) +- Various doc fixes (#1708, #1712, #1717, #1740, #1739, #1749, #1756) +- Improved test coverage (#1754) + +# v3.2.0 +- Fix a bug in Safari related to overwriting `func.name` +- Remove built-in browserify configuration (#1653) +- Varios doc fixes (#1688, #1703, #1704) + +# v3.1.1 +- Allow redefining `name` property on wrapped functions. + +# v3.1.0 + +- Added `q.pushAsync` and `q.unshiftAsync`, analagous to `q.push` and `q.unshift`, except they always do not accept a callback, and reject if processing the task errors. (#1659) +- Promises returned from `q.push` and `q.unshift` when a callback is not passed now resolve even if an error ocurred. (#1659) +- Fixed a parsing bug in `autoInject` with complicated function bodies (#1663) +- Added ES6+ configuration for Browserify bundlers (#1653) +- Various doc fixes (#1664, #1658, #1665, #1652) + +# v3.0.1 + +## Bug fixes +- Fixed a regression where arrays passed to `queue` and `cargo` would be completely flattened. (#1645) +- Clarified Async's browser support (#1643) + + +# v3.0.0 + +The `async`/`await` release! + +There are a lot of new features and subtle breaking changes in this major version, but the biggest feature is that most Async methods return a Promise if you omit the callback, meaning you can `await` them from within an `async` function. + +```js +const results = await async.mapLimit(urls, 5, async url => { + const resp = await fetch(url) + return resp.body +}) +``` + +## Breaking Changes +- Most Async methods return a Promise when the final callback is omitted, making them `await`-able! (#1572) +- We are now making heavy use of ES2015 features, this means we have dropped out-of-the-box support for Node 4 and earlier, and many old versions of browsers. (#1541, #1553) +- In `queue`, `priorityQueue`, `cargo` and `cargoQueue`, the "event"-style methods, like `q.drain` and `q.saturated` are now methods that register a callback, rather than properties you assign a callback to. They are now of the form `q.drain(callback)`. If you do not pass a callback a Promise will be returned for the next occurrence of the event, making them `await`-able, e.g. `await q.drain()`. (#1586, #1641) +- Calling `callback(false)` will cancel an async method, preventing further iteration and callback calls. This is useful for preventing memory leaks when you break out of an async flow by calling an outer callback. (#1064, #1542) +- `during` and `doDuring` have been removed, and instead `whilst`, `doWhilst`, `until` and `doUntil` now have asynchronous `test` functions. (#850, #1557) +- `limits` of less than 1 now cause an error to be thrown in queues and collection methods. (#1249, #1552) +- `memoize` no longer memoizes errors (#1465, #1466) +- `applyEach`/`applyEachSeries` have a simpler interface, to make them more easily type-able. It always returns a function that takes in a single callback argument. If that callback is omitted, a promise is returned, making it awaitable. (#1228, #1640) + +## New Features +- Async generators are now supported in all the Collection methods. (#1560) +- Added `cargoQueue`, a queue with both `concurrency` and `payload` size parameters. (#1567) +- Queue objects returned from `queue` now have a `Symbol.iterator` method, meaning they can be iterated over to inspect the current list of items in the queue. (#1459, #1556) +- A ESM-flavored `async.mjs` is included in the `async` package. This is described in the `package.json` `"module"` field, meaning it should be automatically used by Webpack and other compatible bundlers. + +## Bug fixes +- Better handle arbitrary error objects in `asyncify` (#1568, #1569) + +## Other +- Removed Lodash as a dependency (#1283, #1528) +- Miscellaneous docs fixes (#1393, #1501, #1540, #1543, #1558, #1563, #1564, #1579, #1581) +- Miscellaneous test fixes (#1538) + +------- + +# v2.6.1 +- Updated lodash to prevent `npm audit` warnings. (#1532, #1533) +- Made `async-es` more optimized for webpack users (#1517) +- Fixed a stack overflow with large collections and a synchronous iterator (#1514) +- Various small fixes/chores (#1505, #1511, #1527, #1530) + +# v2.6.0 +- Added missing aliases for many methods. Previously, you could not (e.g.) `require('async/find')` or use `async.anyLimit`. (#1483) +- Improved `queue` performance. (#1448, #1454) +- Add missing sourcemap (#1452, #1453) +- Various doc updates (#1448, #1471, #1483) + +# v2.5.0 +- Added `concatLimit`, the `Limit` equivalent of [`concat`](https://caolan.github.io/async/docs.html#concat) ([#1426](https://github.com/caolan/async/issues/1426), [#1430](https://github.com/caolan/async/pull/1430)) +- `concat` improvements: it now preserves order, handles falsy values and the `iteratee` callback takes a variable number of arguments ([#1437](https://github.com/caolan/async/issues/1437), [#1436](https://github.com/caolan/async/pull/1436)) +- Fixed an issue in `queue` where there was a size discrepancy between `workersList().length` and `running()` ([#1428](https://github.com/caolan/async/issues/1428), [#1429](https://github.com/caolan/async/pull/1429)) +- Various doc fixes ([#1422](https://github.com/caolan/async/issues/1422), [#1424](https://github.com/caolan/async/pull/1424)) + +# v2.4.1 +- Fixed a bug preventing functions wrapped with `timeout()` from being re-used. ([#1418](https://github.com/caolan/async/issues/1418), [#1419](https://github.com/caolan/async/issues/1419)) + +# v2.4.0 +- Added `tryEach`, for running async functions in parallel, where you only expect one to succeed. ([#1365](https://github.com/caolan/async/issues/1365), [#687](https://github.com/caolan/async/issues/687)) +- Improved performance, most notably in `parallel` and `waterfall` ([#1395](https://github.com/caolan/async/issues/1395)) +- Added `queue.remove()`, for removing items in a `queue` ([#1397](https://github.com/caolan/async/issues/1397), [#1391](https://github.com/caolan/async/issues/1391)) +- Fixed using `eval`, preventing Async from running in pages with Content Security Policy ([#1404](https://github.com/caolan/async/issues/1404), [#1403](https://github.com/caolan/async/issues/1403)) +- Fixed errors thrown in an `asyncify`ed function's callback being caught by the underlying Promise ([#1408](https://github.com/caolan/async/issues/1408)) +- Fixed timing of `queue.empty()` ([#1367](https://github.com/caolan/async/issues/1367)) +- Various doc fixes ([#1314](https://github.com/caolan/async/issues/1314), [#1394](https://github.com/caolan/async/issues/1394), [#1412](https://github.com/caolan/async/issues/1412)) + +# v2.3.0 +- Added support for ES2017 `async` functions. Wherever you can pass a Node-style/CPS function that uses a callback, you can also pass an `async` function. Previously, you had to wrap `async` functions with `asyncify`. The caveat is that it will only work if `async` functions are supported natively in your environment, transpiled implementations can't be detected. ([#1386](https://github.com/caolan/async/issues/1386), [#1390](https://github.com/caolan/async/issues/1390)) +- Small doc fix ([#1392](https://github.com/caolan/async/issues/1392)) + +# v2.2.0 +- Added `groupBy`, and the `Series`/`Limit` equivalents, analogous to [`_.groupBy`](http://lodash.com/docs#groupBy) ([#1364](https://github.com/caolan/async/issues/1364)) +- Fixed `transform` bug when `callback` was not passed ([#1381](https://github.com/caolan/async/issues/1381)) +- Added note about `reflect` to `parallel` docs ([#1385](https://github.com/caolan/async/issues/1385)) + +# v2.1.5 +- Fix `auto` bug when function names collided with Array.prototype ([#1358](https://github.com/caolan/async/issues/1358)) +- Improve some error messages ([#1349](https://github.com/caolan/async/issues/1349)) +- Avoid stack overflow case in queue +- Fixed an issue in `some`, `every` and `find` where processing would continue after the result was determined. +- Cleanup implementations of `some`, `every` and `find` + +# v2.1.3 +- Make bundle size smaller +- Create optimized hotpath for `filter` in array case. + +# v2.1.2 +- Fixed a stackoverflow bug with `detect`, `some`, `every` on large inputs ([#1293](https://github.com/caolan/async/issues/1293)). + +# v2.1.0 + +- `retry` and `retryable` now support an optional `errorFilter` function that determines if the `task` should retry on the error ([#1256](https://github.com/caolan/async/issues/1256), [#1261](https://github.com/caolan/async/issues/1261)) +- Optimized array iteration in `race`, `cargo`, `queue`, and `priorityQueue` ([#1253](https://github.com/caolan/async/issues/1253)) +- Added alias documentation to doc site ([#1251](https://github.com/caolan/async/issues/1251), [#1254](https://github.com/caolan/async/issues/1254)) +- Added [BootStrap scrollspy](http://getbootstrap.com/javascript/#scrollspy) to docs to highlight in the sidebar the current method being viewed ([#1289](https://github.com/caolan/async/issues/1289), [#1300](https://github.com/caolan/async/issues/1300)) +- Various minor doc fixes ([#1263](https://github.com/caolan/async/issues/1263), [#1264](https://github.com/caolan/async/issues/1264), [#1271](https://github.com/caolan/async/issues/1271), [#1278](https://github.com/caolan/async/issues/1278), [#1280](https://github.com/caolan/async/issues/1280), [#1282](https://github.com/caolan/async/issues/1282), [#1302](https://github.com/caolan/async/issues/1302)) + +# v2.0.1 + +- Significantly optimized all iteration based collection methods such as `each`, `map`, `filter`, etc ([#1245](https://github.com/caolan/async/issues/1245), [#1246](https://github.com/caolan/async/issues/1246), [#1247](https://github.com/caolan/async/issues/1247)). + +# v2.0.0 + +Lots of changes here! + +First and foremost, we have a slick new [site for docs](https://caolan.github.io/async/). Special thanks to [**@hargasinski**](https://github.com/hargasinski) for his work converting our old docs to `jsdoc` format and implementing the new website. Also huge ups to [**@ivanseidel**](https://github.com/ivanseidel) for designing our new logo. It was a long process for both of these tasks, but I think these changes turned out extraordinary well. + +The biggest feature is modularization. You can now `require("async/series")` to only require the `series` function. Every Async library function is available this way. You still can `require("async")` to require the entire library, like you could do before. + +We also provide Async as a collection of ES2015 modules. You can now `import {each} from 'async-es'` or `import waterfall from 'async-es/waterfall'`. If you are using only a few Async functions, and are using a ES bundler such as Rollup, this can significantly lower your build size. + +Major thanks to [**@Kikobeats**](github.com/Kikobeats), [**@aearly**](github.com/aearly) and [**@megawac**](github.com/megawac) for doing the majority of the modularization work, as well as [**@jdalton**](github.com/jdalton) and [**@Rich-Harris**](github.com/Rich-Harris) for advisory work on the general modularization strategy. + +Another one of the general themes of the 2.0 release is standardization of what an "async" function is. We are now more strictly following the node-style continuation passing style. That is, an async function is a function that: + +1. Takes a variable number of arguments +2. The last argument is always a callback +3. The callback can accept any number of arguments +4. The first argument passed to the callback will be treated as an error result, if the argument is truthy +5. Any number of result arguments can be passed after the "error" argument +6. The callback is called once and exactly once, either on the same tick or later tick of the JavaScript event loop. + +There were several cases where Async accepted some functions that did not strictly have these properties, most notably `auto`, `every`, `some`, `filter`, `reject` and `detect`. + +Another theme is performance. We have eliminated internal deferrals in all cases where they make sense. For example, in `waterfall` and `auto`, there was a `setImmediate` between each task -- these deferrals have been removed. A `setImmediate` call can add up to 1ms of delay. This might not seem like a lot, but it can add up if you are using many Async functions in the course of processing a HTTP request, for example. Nearly all asynchronous functions that do I/O already have some sort of deferral built in, so the extra deferral is unnecessary. The trade-off of this change is removing our built-in stack-overflow defense. Many synchronous callback calls in series can quickly overflow the JS call stack. If you do have a function that is sometimes synchronous (calling its callback on the same tick), and are running into stack overflows, wrap it with `async.ensureAsync()`. + +Another big performance win has been re-implementing `queue`, `cargo`, and `priorityQueue` with [doubly linked lists](https://en.wikipedia.org/wiki/Doubly_linked_list) instead of arrays. This has lead to queues being an order of [magnitude faster on large sets of tasks](https://github.com/caolan/async/pull/1205). + +## New Features + +- Async is now modularized. Individual functions can be `require()`d from the main package. (`require('async/auto')`) ([#984](https://github.com/caolan/async/issues/984), [#996](https://github.com/caolan/async/issues/996)) +- Async is also available as a collection of ES2015 modules in the new `async-es` package. (`import {forEachSeries} from 'async-es'`) ([#984](https://github.com/caolan/async/issues/984), [#996](https://github.com/caolan/async/issues/996)) +- Added `race`, analogous to `Promise.race()`. It will run an array of async tasks in parallel and will call its callback with the result of the first task to respond. ([#568](https://github.com/caolan/async/issues/568), [#1038](https://github.com/caolan/async/issues/1038)) +- Collection methods now accept ES2015 iterators. Maps, Sets, and anything that implements the iterator spec can now be passed directly to `each`, `map`, `parallel`, etc.. ([#579](https://github.com/caolan/async/issues/579), [#839](https://github.com/caolan/async/issues/839), [#1074](https://github.com/caolan/async/issues/1074)) +- Added `mapValues`, for mapping over the properties of an object and returning an object with the same keys. ([#1157](https://github.com/caolan/async/issues/1157), [#1177](https://github.com/caolan/async/issues/1177)) +- Added `timeout`, a wrapper for an async function that will make the task time-out after the specified time. ([#1007](https://github.com/caolan/async/issues/1007), [#1027](https://github.com/caolan/async/issues/1027)) +- Added `reflect` and `reflectAll`, analagous to [`Promise.reflect()`](http://bluebirdjs.com/docs/api/reflect.html), a wrapper for async tasks that always succeeds, by gathering results and errors into an object. ([#942](https://github.com/caolan/async/issues/942), [#1012](https://github.com/caolan/async/issues/1012), [#1095](https://github.com/caolan/async/issues/1095)) +- `constant` supports dynamic arguments -- it will now always use its last argument as the callback. ([#1016](https://github.com/caolan/async/issues/1016), [#1052](https://github.com/caolan/async/issues/1052)) +- `setImmediate` and `nextTick` now support arguments to partially apply to the deferred function, like the node-native versions do. ([#940](https://github.com/caolan/async/issues/940), [#1053](https://github.com/caolan/async/issues/1053)) +- `auto` now supports resolving cyclic dependencies using [Kahn's algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm) ([#1140](https://github.com/caolan/async/issues/1140)). +- Added `autoInject`, a relative of `auto` that automatically spreads a task's dependencies as arguments to the task function. ([#608](https://github.com/caolan/async/issues/608), [#1055](https://github.com/caolan/async/issues/1055), [#1099](https://github.com/caolan/async/issues/1099), [#1100](https://github.com/caolan/async/issues/1100)) +- You can now limit the concurrency of `auto` tasks. ([#635](https://github.com/caolan/async/issues/635), [#637](https://github.com/caolan/async/issues/637)) +- Added `retryable`, a relative of `retry` that wraps an async function, making it retry when called. ([#1058](https://github.com/caolan/async/issues/1058)) +- `retry` now supports specifying a function that determines the next time interval, useful for exponential backoff, logging and other retry strategies. ([#1161](https://github.com/caolan/async/issues/1161)) +- `retry` will now pass all of the arguments the task function was resolved with to the callback ([#1231](https://github.com/caolan/async/issues/1231)). +- Added `q.unsaturated` -- callback called when a `queue`'s number of running workers falls below a threshold. ([#868](https://github.com/caolan/async/issues/868), [#1030](https://github.com/caolan/async/issues/1030), [#1033](https://github.com/caolan/async/issues/1033), [#1034](https://github.com/caolan/async/issues/1034)) +- Added `q.error` -- a callback called whenever a `queue` task calls its callback with an error. ([#1170](https://github.com/caolan/async/issues/1170)) +- `applyEach` and `applyEachSeries` now pass results to the final callback. ([#1088](https://github.com/caolan/async/issues/1088)) + +## Breaking changes + +- Calling a callback more than once is considered an error, and an error will be thrown. This had an explicit breaking change in `waterfall`. If you were relying on this behavior, you should more accurately represent your control flow as an event emitter or stream. ([#814](https://github.com/caolan/async/issues/814), [#815](https://github.com/caolan/async/issues/815), [#1048](https://github.com/caolan/async/issues/1048), [#1050](https://github.com/caolan/async/issues/1050)) +- `auto` task functions now always take the callback as the last argument. If a task has dependencies, the `results` object will be passed as the first argument. To migrate old task functions, wrap them with [`_.flip`](https://lodash.com/docs#flip) ([#1036](https://github.com/caolan/async/issues/1036), [#1042](https://github.com/caolan/async/issues/1042)) +- Internal `setImmediate` calls have been refactored away. This may make existing flows vulnerable to stack overflows if you use many synchronous functions in series. Use `ensureAsync` to work around this. ([#696](https://github.com/caolan/async/issues/696), [#704](https://github.com/caolan/async/issues/704), [#1049](https://github.com/caolan/async/issues/1049), [#1050](https://github.com/caolan/async/issues/1050)) +- `map` used to return an object when iterating over an object. `map` now always returns an array, like in other libraries. The previous object behavior has been split out into `mapValues`. ([#1157](https://github.com/caolan/async/issues/1157), [#1177](https://github.com/caolan/async/issues/1177)) +- `filter`, `reject`, `some`, `every`, `detect` and their families like `{METHOD}Series` and `{METHOD}Limit` now expect an error as the first callback argument, rather than just a simple boolean. Pass `null` as the first argument, or use `fs.access` instead of `fs.exists`. ([#118](https://github.com/caolan/async/issues/118), [#774](https://github.com/caolan/async/issues/774), [#1028](https://github.com/caolan/async/issues/1028), [#1041](https://github.com/caolan/async/issues/1041)) +- `{METHOD}` and `{METHOD}Series` are now implemented in terms of `{METHOD}Limit`. This is a major internal simplification, and is not expected to cause many problems, but it does subtly affect how functions execute internally. ([#778](https://github.com/caolan/async/issues/778), [#847](https://github.com/caolan/async/issues/847)) +- `retry`'s callback is now optional. Previously, omitting the callback would partially apply the function, meaning it could be passed directly as a task to `series` or `auto`. The partially applied "control-flow" behavior has been separated out into `retryable`. ([#1054](https://github.com/caolan/async/issues/1054), [#1058](https://github.com/caolan/async/issues/1058)) +- The test function for `whilst`, `until`, and `during` used to be passed non-error args from the iteratee function's callback, but this led to weirdness where the first call of the test function would be passed no args. We have made it so the test function is never passed extra arguments, and only the `doWhilst`, `doUntil`, and `doDuring` functions pass iteratee callback arguments to the test function ([#1217](https://github.com/caolan/async/issues/1217), [#1224](https://github.com/caolan/async/issues/1224)) +- The `q.tasks` array has been renamed `q._tasks` and is now implemented as a doubly linked list (DLL). Any code that used to interact with this array will need to be updated to either use the provided helpers or support DLLs ([#1205](https://github.com/caolan/async/issues/1205)). +- The timing of the `q.saturated()` callback in a `queue` has been modified to better reflect when tasks pushed to the queue will start queueing. ([#724](https://github.com/caolan/async/issues/724), [#1078](https://github.com/caolan/async/issues/1078)) +- Removed `iterator` method in favour of [ES2015 iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators ) which natively supports arrays ([#1237](https://github.com/caolan/async/issues/1237)) +- Dropped support for Component, Jam, SPM, and Volo ([#1175](https://github.com/caolan/async/issues/1175), #[#176](https://github.com/caolan/async/issues/176)) + +## Bug Fixes + +- Improved handling of no dependency cases in `auto` & `autoInject` ([#1147](https://github.com/caolan/async/issues/1147)). +- Fixed a bug where the callback generated by `asyncify` with `Promises` could resolve twice ([#1197](https://github.com/caolan/async/issues/1197)). +- Fixed several documented optional callbacks not actually being optional ([#1223](https://github.com/caolan/async/issues/1223)). + +## Other + +- Added `someSeries` and `everySeries` for symmetry, as well as a complete set of `any`/`anyLimit`/`anySeries` and `all`/`/allLmit`/`allSeries` aliases. +- Added `find` as an alias for `detect. (as well as `findLimit` and `findSeries`). +- Various doc fixes ([#1005](https://github.com/caolan/async/issues/1005), [#1008](https://github.com/caolan/async/issues/1008), [#1010](https://github.com/caolan/async/issues/1010), [#1015](https://github.com/caolan/async/issues/1015), [#1021](https://github.com/caolan/async/issues/1021), [#1037](https://github.com/caolan/async/issues/1037), [#1039](https://github.com/caolan/async/issues/1039), [#1051](https://github.com/caolan/async/issues/1051), [#1102](https://github.com/caolan/async/issues/1102), [#1107](https://github.com/caolan/async/issues/1107), [#1121](https://github.com/caolan/async/issues/1121), [#1123](https://github.com/caolan/async/issues/1123), [#1129](https://github.com/caolan/async/issues/1129), [#1135](https://github.com/caolan/async/issues/1135), [#1138](https://github.com/caolan/async/issues/1138), [#1141](https://github.com/caolan/async/issues/1141), [#1153](https://github.com/caolan/async/issues/1153), [#1216](https://github.com/caolan/async/issues/1216), [#1217](https://github.com/caolan/async/issues/1217), [#1232](https://github.com/caolan/async/issues/1232), [#1233](https://github.com/caolan/async/issues/1233), [#1236](https://github.com/caolan/async/issues/1236), [#1238](https://github.com/caolan/async/issues/1238)) + +Thank you [**@aearly**](github.com/aearly) and [**@megawac**](github.com/megawac) for taking the lead on version 2 of async. + +------------------------------------------ + +# v1.5.2 +- Allow using `"constructor"` as an argument in `memoize` ([#998](https://github.com/caolan/async/issues/998)) +- Give a better error messsage when `auto` dependency checking fails ([#994](https://github.com/caolan/async/issues/994)) +- Various doc updates ([#936](https://github.com/caolan/async/issues/936), [#956](https://github.com/caolan/async/issues/956), [#979](https://github.com/caolan/async/issues/979), [#1002](https://github.com/caolan/async/issues/1002)) + +# v1.5.1 +- Fix issue with `pause` in `queue` with concurrency enabled ([#946](https://github.com/caolan/async/issues/946)) +- `while` and `until` now pass the final result to callback ([#963](https://github.com/caolan/async/issues/963)) +- `auto` will properly handle concurrency when there is no callback ([#966](https://github.com/caolan/async/issues/966)) +- `auto` will no. properly stop execution when an error occurs ([#988](https://github.com/caolan/async/issues/988), [#993](https://github.com/caolan/async/issues/993)) +- Various doc fixes ([#971](https://github.com/caolan/async/issues/971), [#980](https://github.com/caolan/async/issues/980)) + +# v1.5.0 + +- Added `transform`, analogous to [`_.transform`](http://lodash.com/docs#transform) ([#892](https://github.com/caolan/async/issues/892)) +- `map` now returns an object when an object is passed in, rather than array with non-numeric keys. `map` will begin always returning an array with numeric indexes in the next major release. ([#873](https://github.com/caolan/async/issues/873)) +- `auto` now accepts an optional `concurrency` argument to limit the number o. running tasks ([#637](https://github.com/caolan/async/issues/637)) +- Added `queue#workersList()`, to retrieve the lis. of currently running tasks. ([#891](https://github.com/caolan/async/issues/891)) +- Various code simplifications ([#896](https://github.com/caolan/async/issues/896), [#904](https://github.com/caolan/async/issues/904)) +- Various doc fixes :scroll: ([#890](https://github.com/caolan/async/issues/890), [#894](https://github.com/caolan/async/issues/894), [#903](https://github.com/caolan/async/issues/903), [#905](https://github.com/caolan/async/issues/905), [#912](https://github.com/caolan/async/issues/912)) + +# v1.4.2 + +- Ensure coverage files don't get published on npm ([#879](https://github.com/caolan/async/issues/879)) + +# v1.4.1 + +- Add in overlooked `detectLimit` method ([#866](https://github.com/caolan/async/issues/866)) +- Removed unnecessary files from npm releases ([#861](https://github.com/caolan/async/issues/861)) +- Removed usage of a reserved word to prevent :boom: in older environments ([#870](https://github.com/caolan/async/issues/870)) + +# v1.4.0 + +- `asyncify` now supports promises ([#840](https://github.com/caolan/async/issues/840)) +- Added `Limit` versions of `filter` and `reject` ([#836](https://github.com/caolan/async/issues/836)) +- Add `Limit` versions of `detect`, `some` and `every` ([#828](https://github.com/caolan/async/issues/828), [#829](https://github.com/caolan/async/issues/829)) +- `some`, `every` and `detect` now short circuit early ([#828](https://github.com/caolan/async/issues/828), [#829](https://github.com/caolan/async/issues/829)) +- Improve detection of the global object ([#804](https://github.com/caolan/async/issues/804)), enabling use in WebWorkers +- `whilst` now called with arguments from iterator ([#823](https://github.com/caolan/async/issues/823)) +- `during` now gets called with arguments from iterator ([#824](https://github.com/caolan/async/issues/824)) +- Code simplifications and optimizations aplenty ([diff](https://github.com/caolan/async/compare/v1.3.0...v1.4.0)) + + +# v1.3.0 + +New Features: +- Added `constant` +- Added `asyncify`/`wrapSync` for making sync functions work with callbacks. ([#671](https://github.com/caolan/async/issues/671), [#806](https://github.com/caolan/async/issues/806)) +- Added `during` and `doDuring`, which are like `whilst` with an async truth test. ([#800](https://github.com/caolan/async/issues/800)) +- `retry` now accepts an `interval` parameter to specify a delay between retries. ([#793](https://github.com/caolan/async/issues/793)) +- `async` should work better in Web Workers due to better `root` detection ([#804](https://github.com/caolan/async/issues/804)) +- Callbacks are now optional in `whilst`, `doWhilst`, `until`, and `doUntil` ([#642](https://github.com/caolan/async/issues/642)) +- Various internal updates ([#786](https://github.com/caolan/async/issues/786), [#801](https://github.com/caolan/async/issues/801), [#802](https://github.com/caolan/async/issues/802), [#803](https://github.com/caolan/async/issues/803)) +- Various doc fixes ([#790](https://github.com/caolan/async/issues/790), [#794](https://github.com/caolan/async/issues/794)) + +Bug Fixes: +- `cargo` now exposes the `payload` size, and `cargo.payload` can be changed on the fly after the `cargo` is created. ([#740](https://github.com/caolan/async/issues/740), [#744](https://github.com/caolan/async/issues/744), [#783](https://github.com/caolan/async/issues/783)) + + +# v1.2.1 + +Bug Fix: + +- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. ([#782](https://github.com/caolan/async/issues/782)) + + +# v1.2.0 + +New Features: + +- Added `timesLimit` ([#743](https://github.com/caolan/async/issues/743)) +- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. ([#747](https://github.com/caolan/async/issues/747), [#772](https://github.com/caolan/async/issues/772)) + +Bug Fixes: + +- Fixed a regression in `each` and family with empty arrays that have additional properties. ([#775](https://github.com/caolan/async/issues/775), [#777](https://github.com/caolan/async/issues/777)) + + +# v1.1.1 + +Bug Fix: + +- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. ([#782](https://github.com/caolan/async/issues/782)) + + +# v1.1.0 + +New Features: + +- `cargo` now supports all of the same methods and event callbacks as `queue`. +- Added `ensureAsync` - A wrapper that ensures an async function calls its callback on a later tick. ([#769](https://github.com/caolan/async/issues/769)) +- Optimized `map`, `eachOf`, and `waterfall` families of functions +- Passing a `null` or `undefined` array to `map`, `each`, `parallel` and families will be treated as an empty array ([#667](https://github.com/caolan/async/issues/667)). +- The callback is now optional for the composed results of `compose` and `seq`. ([#618](https://github.com/caolan/async/issues/618)) +- Reduced file size by 4kb, (minified version by 1kb) +- Added code coverage through `nyc` and `coveralls` ([#768](https://github.com/caolan/async/issues/768)) + +Bug Fixes: + +- `forever` will no longer stack overflow with a synchronous iterator ([#622](https://github.com/caolan/async/issues/622)) +- `eachLimit` and other limit functions will stop iterating once an error occurs ([#754](https://github.com/caolan/async/issues/754)) +- Always pass `null` in callbacks when there is no error ([#439](https://github.com/caolan/async/issues/439)) +- Ensure proper conditions when calling `drain()` after pushing an empty data set to a queue ([#668](https://github.com/caolan/async/issues/668)) +- `each` and family will properly handle an empty array ([#578](https://github.com/caolan/async/issues/578)) +- `eachSeries` and family will finish if the underlying array is modified during execution ([#557](https://github.com/caolan/async/issues/557)) +- `queue` will throw if a non-function is passed to `q.push()` ([#593](https://github.com/caolan/async/issues/593)) +- Doc fixes ([#629](https://github.com/caolan/async/issues/629), [#766](https://github.com/caolan/async/issues/766)) + + +# v1.0.0 + +No known breaking changes, we are simply complying with semver from here on out. + +Changes: + +- Start using a changelog! +- Add `forEachOf` for iterating over Objects (or to iterate Arrays with indexes available) ([#168](https://github.com/caolan/async/issues/168) [#704](https://github.com/caolan/async/issues/704) [#321](https://github.com/caolan/async/issues/321)) +- Detect deadlocks in `auto` ([#663](https://github.com/caolan/async/issues/663)) +- Better support for require.js ([#527](https://github.com/caolan/async/issues/527)) +- Throw if queue created with concurrency `0` ([#714](https://github.com/caolan/async/issues/714)) +- Fix unneeded iteration in `queue.resume()` ([#758](https://github.com/caolan/async/issues/758)) +- Guard against timer mocking overriding `setImmediate` ([#609](https://github.com/caolan/async/issues/609) [#611](https://github.com/caolan/async/issues/611)) +- Miscellaneous doc fixes ([#542](https://github.com/caolan/async/issues/542) [#596](https://github.com/caolan/async/issues/596) [#615](https://github.com/caolan/async/issues/615) [#628](https://github.com/caolan/async/issues/628) [#631](https://github.com/caolan/async/issues/631) [#690](https://github.com/caolan/async/issues/690) [#729](https://github.com/caolan/async/issues/729)) +- Use single noop function internally ([#546](https://github.com/caolan/async/issues/546)) +- Optimize internal `_each`, `_map` and `_keys` functions. diff --git a/Challenge/seokahi/010.star/node_modules/async/LICENSE b/Challenge/seokahi/010.star/node_modules/async/LICENSE new file mode 100644 index 0000000..b18aed6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2018 Caolan McMahon + +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/Challenge/seokahi/010.star/node_modules/async/README.md b/Challenge/seokahi/010.star/node_modules/async/README.md new file mode 100644 index 0000000..c679263 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/README.md @@ -0,0 +1,60 @@ +![Async Logo](https://raw.githubusercontent.com/caolan/async/master/logo/async-logo_readme.jpg) + +[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) +[![Build Status via Azure Pipelines](https://dev.azure.com/caolanmcmahon/async/_apis/build/status/caolan.async?branchName=master)](https://dev.azure.com/caolanmcmahon/async/_build/latest?definitionId=1&branchName=master) +[![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async) +[![Coverage Status](https://coveralls.io/repos/caolan/async/badge.svg?branch=master)](https://coveralls.io/r/caolan/async?branch=master) +[![Join the chat at https://gitter.im/caolan/async](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/caolan/async?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/async/badge?style=rounded)](https://www.jsdelivr.com/package/npm/async) + + + +Async is a utility module which provides straight-forward, powerful functions for working with [asynchronous JavaScript](http://caolan.github.io/async/v3/global.html). Although originally designed for use with [Node.js](https://nodejs.org/) and installable via `npm i async`, it can also be used directly in the browser. A ESM/MJS version is included in the main `async` package that should automatically be used with compatible bundlers such as Webpack and Rollup. + +A pure ESM version of Async is available as [`async-es`](https://www.npmjs.com/package/async-es). + +For Documentation, visit + +*For Async v1.5.x documentation, go [HERE](https://github.com/caolan/async/blob/v1.5.2/README.md)* + + +```javascript +// for use with Node-style callbacks... +var async = require("async"); + +var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; +var configs = {}; + +async.forEachOf(obj, (value, key, callback) => { + fs.readFile(__dirname + value, "utf8", (err, data) => { + if (err) return callback(err); + try { + configs[key] = JSON.parse(data); + } catch (e) { + return callback(e); + } + callback(); + }); +}, err => { + if (err) console.error(err.message); + // configs is now a map of JSON data + doSomethingWith(configs); +}); +``` + +```javascript +var async = require("async"); + +// ...or ES2017 async functions +async.mapLimit(urls, 5, async function(url) { + const response = await fetch(url) + return response.body +}, (err, results) => { + if (err) throw err + // results is now an array of the response bodies + console.log(results) +}) +``` diff --git a/Challenge/seokahi/010.star/node_modules/async/all.js b/Challenge/seokahi/010.star/node_modules/async/all.js new file mode 100644 index 0000000..148db68 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/all.js @@ -0,0 +1,119 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns `true` if every element in `coll` satisfies an async test. If any + * iteratee call returns `false`, the main `callback` is immediately called. + * + * @name every + * @static + * @memberOf module:Collections + * @method + * @alias all + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.every(fileList, fileExists, function(err, result) { + * console.log(result); + * // true + * // result is true since every file exists + * }); + * + * async.every(withMissingFileList, fileExists, function(err, result) { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }); + * + * // Using Promises + * async.every(fileList, fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.every(withMissingFileList, fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.every(fileList, fileExists); + * console.log(result); + * // true + * // result is true since every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.every(withMissingFileList, fileExists); + * console.log(result); + * // false + * // result is false since NOT every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function every(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(every, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/allLimit.js b/Challenge/seokahi/010.star/node_modules/async/allLimit.js new file mode 100644 index 0000000..25b2c08 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/allLimit.js @@ -0,0 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. + * + * @name everyLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everyLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(everyLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/allSeries.js b/Challenge/seokahi/010.star/node_modules/async/allSeries.js new file mode 100644 index 0000000..147c3dc --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/allSeries.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. + * + * @name everySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in series. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everySeries(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(everySeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/any.js b/Challenge/seokahi/010.star/node_modules/async/any.js new file mode 100644 index 0000000..2046cf6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/any.js @@ -0,0 +1,122 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns `true` if at least one element in the `coll` satisfies an async test. + * If any iteratee call returns `true`, the main `callback` is immediately + * called. + * + * @name some + * @static + * @memberOf module:Collections + * @method + * @alias any + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + *); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // false + * // result is false since none of the files exists + * } + *); + * + * // Using Promises + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since some file in the list exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since none of the files exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists); + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists); + * console.log(result); + * // false + * // result is false since none of the files exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function some(coll, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(some, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/anyLimit.js b/Challenge/seokahi/010.star/node_modules/async/anyLimit.js new file mode 100644 index 0000000..c8a295a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/anyLimit.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. + * + * @name someLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anyLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(someLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/anySeries.js b/Challenge/seokahi/010.star/node_modules/async/anySeries.js new file mode 100644 index 0000000..ee0654b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/anySeries.js @@ -0,0 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. + * + * @name someSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anySeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in series. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someSeries(coll, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(someSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/apply.js b/Challenge/seokahi/010.star/node_modules/async/apply.js new file mode 100644 index 0000000..5246833 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/apply.js @@ -0,0 +1,55 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (fn, ...args) { + return (...callArgs) => fn(...args, ...callArgs); +}; + +module.exports = exports["default"]; /** + * Creates a continuation function with some arguments already applied. + * + * Useful as a shorthand when combined with other control flow functions. Any + * arguments passed to the returned function are added to the arguments + * originally passed to apply. + * + * @name apply + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {Function} fn - The function you want to eventually apply all + * arguments to. Invokes with (arguments...). + * @param {...*} arguments... - Any number of arguments to automatically apply + * when the continuation is called. + * @returns {Function} the partially-applied function + * @example + * + * // using apply + * async.parallel([ + * async.apply(fs.writeFile, 'testfile1', 'test1'), + * async.apply(fs.writeFile, 'testfile2', 'test2') + * ]); + * + * + * // the same process without using apply + * async.parallel([ + * function(callback) { + * fs.writeFile('testfile1', 'test1', callback); + * }, + * function(callback) { + * fs.writeFile('testfile2', 'test2', callback); + * } + * ]); + * + * // It's possible to pass any number of additional arguments when calling the + * // continuation: + * + * node> var fn = async.apply(sys.puts, 'one'); + * node> fn('two', 'three'); + * one + * two + * three + */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/applyEach.js b/Challenge/seokahi/010.star/node_modules/async/applyEach.js new file mode 100644 index 0000000..b08c670 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/applyEach.js @@ -0,0 +1,57 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _applyEach = require('./internal/applyEach.js'); + +var _applyEach2 = _interopRequireDefault(_applyEach); + +var _map = require('./map.js'); + +var _map2 = _interopRequireDefault(_map); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Applies the provided arguments to each function in the array, calling + * `callback` after all functions have completed. If you only provide the first + * argument, `fns`, then it will return a function which lets you pass in the + * arguments as if it were a single function call. If more arguments are + * provided, `callback` is required while `args` is still optional. The results + * for each of the applied async functions are passed to the final callback + * as an array. + * + * @name applyEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s + * to all call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - Returns a function that takes no args other than + * an optional callback, that is the result of applying the `args` to each + * of the functions. + * @example + * + * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket') + * + * appliedFn((err, results) => { + * // results[0] is the results for `enableSearch` + * // results[1] is the results for `updateSchema` + * }); + * + * // partial application example: + * async.each( + * buckets, + * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(), + * callback + * ); + */ +exports.default = (0, _applyEach2.default)(_map2.default); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/applyEachSeries.js b/Challenge/seokahi/010.star/node_modules/async/applyEachSeries.js new file mode 100644 index 0000000..6a19ca3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/applyEachSeries.js @@ -0,0 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _applyEach = require('./internal/applyEach.js'); + +var _applyEach2 = _interopRequireDefault(_applyEach); + +var _mapSeries = require('./mapSeries.js'); + +var _mapSeries2 = _interopRequireDefault(_mapSeries); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. + * + * @name applyEachSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.applyEach]{@link module:ControlFlow.applyEach} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all + * call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - A function, that when called, is the result of + * appling the `args` to the list of functions. It takes no args, other than + * a callback. + */ +exports.default = (0, _applyEach2.default)(_mapSeries2.default); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/asyncify.js b/Challenge/seokahi/010.star/node_modules/async/asyncify.js new file mode 100644 index 0000000..3c3bf88 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/asyncify.js @@ -0,0 +1,118 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = asyncify; + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _setImmediate = require('./internal/setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Take a sync function and make it async, passing its return value to a + * callback. This is useful for plugging sync functions into a waterfall, + * series, or other async functions. Any arguments passed to the generated + * function will be passed to the wrapped function (except for the final + * callback argument). Errors thrown will be passed to the callback. + * + * If the function passed to `asyncify` returns a Promise, that promises's + * resolved/rejected state will be used to call the callback, rather than simply + * the synchronous return value. + * + * This also means you can asyncify ES2017 `async` functions. + * + * @name asyncify + * @static + * @memberOf module:Utils + * @method + * @alias wrapSync + * @category Util + * @param {Function} func - The synchronous function, or Promise-returning + * function to convert to an {@link AsyncFunction}. + * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be + * invoked with `(args..., callback)`. + * @example + * + * // passing a regular synchronous function + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(JSON.parse), + * function (data, next) { + * // data is the result of parsing the text. + * // If there was a parsing error, it would have been caught. + * } + * ], callback); + * + * // passing a function returning a promise + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(function (contents) { + * return db.model.create(contents); + * }), + * function (model, next) { + * // `model` is the instantiated model object. + * // If there was an error, this function would be skipped. + * } + * ], callback); + * + * // es2017 example, though `asyncify` is not needed if your JS environment + * // supports async functions out of the box + * var q = async.queue(async.asyncify(async function(file) { + * var intermediateStep = await processFile(file); + * return await somePromise(intermediateStep) + * })); + * + * q.push(files); + */ +function asyncify(func) { + if ((0, _wrapAsync.isAsync)(func)) { + return function (...args /*, callback*/) { + const callback = args.pop(); + const promise = func.apply(this, args); + return handlePromise(promise, callback); + }; + } + + return (0, _initialParams2.default)(function (args, callback) { + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (result && typeof result.then === 'function') { + return handlePromise(result, callback); + } else { + callback(null, result); + } + }); +} + +function handlePromise(promise, callback) { + return promise.then(value => { + invokeCallback(callback, null, value); + }, err => { + invokeCallback(callback, err && err.message ? err : new Error(err)); + }); +} + +function invokeCallback(callback, error, value) { + try { + callback(error, value); + } catch (err) { + (0, _setImmediate2.default)(e => { + throw e; + }, err); + } +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/auto.js b/Challenge/seokahi/010.star/node_modules/async/auto.js new file mode 100644 index 0000000..c4a85d4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/auto.js @@ -0,0 +1,333 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = auto; + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _promiseCallback = require('./internal/promiseCallback.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on + * their requirements. Each function can optionally depend on other functions + * being completed first, and each function is run as soon as its requirements + * are satisfied. + * + * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence + * will stop. Further tasks will not execute (so any other functions depending + * on it will not run), and the main `callback` is immediately called with the + * error. + * + * {@link AsyncFunction}s also receive an object containing the results of functions which + * have completed so far as the first argument, if they have dependencies. If a + * task function has no dependencies, it will only be passed a callback. + * + * @name auto + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Object} tasks - An object. Each of its properties is either a + * function or an array of requirements, with the {@link AsyncFunction} itself the last item + * in the array. The object's key of a property serves as the name of the task + * defined by that property, i.e. can be used when specifying requirements for + * other tasks. The function receives one or two arguments: + * * a `results` object, containing the results of the previously executed + * functions, only passed if the task has any dependencies, + * * a `callback(err, result)` function, which must be called when finished, + * passing an `error` (which can be `null`) and the result of the function's + * execution. + * @param {number} [concurrency=Infinity] - An optional `integer` for + * determining the maximum number of tasks that can be run in parallel. By + * default, as many as possible. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback. Results are always returned; however, if an + * error occurs, no further `tasks` will be performed, and the results object + * will only contain partial results. Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * @example + * + * //Using Callbacks + * async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }, function(err, results) { + * if (err) { + * console.log('err = ', err); + * } + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }); + * + * //Using Promises + * async.auto({ + * get_data: function(callback) { + * console.log('in get_data'); + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * console.log('in make_folder'); + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }).then(results => { + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }).catch(err => { + * console.log('err = ', err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }); + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function auto(tasks, concurrency, callback) { + if (typeof concurrency !== 'number') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = (0, _once2.default)(callback || (0, _promiseCallback.promiseCallback)()); + var numTasks = Object.keys(tasks).length; + if (!numTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = numTasks; + } + + var results = {}; + var runningTasks = 0; + var canceled = false; + var hasError = false; + + var listeners = Object.create(null); + + var readyTasks = []; + + // for cycle detection: + var readyToCheck = []; // tasks that have been identified as reachable + // without the possibility of returning to an ancestor task + var uncheckedDependencies = {}; + + Object.keys(tasks).forEach(key => { + var task = tasks[key]; + if (!Array.isArray(task)) { + // no dependencies + enqueueTask(key, [task]); + readyToCheck.push(key); + return; + } + + var dependencies = task.slice(0, task.length - 1); + var remainingDependencies = dependencies.length; + if (remainingDependencies === 0) { + enqueueTask(key, task); + readyToCheck.push(key); + return; + } + uncheckedDependencies[key] = remainingDependencies; + + dependencies.forEach(dependencyName => { + if (!tasks[dependencyName]) { + throw new Error('async.auto task `' + key + '` has a non-existent dependency `' + dependencyName + '` in ' + dependencies.join(', ')); + } + addListener(dependencyName, () => { + remainingDependencies--; + if (remainingDependencies === 0) { + enqueueTask(key, task); + } + }); + }); + }); + + checkForDeadlocks(); + processQueue(); + + function enqueueTask(key, task) { + readyTasks.push(() => runTask(key, task)); + } + + function processQueue() { + if (canceled) return; + if (readyTasks.length === 0 && runningTasks === 0) { + return callback(null, results); + } + while (readyTasks.length && runningTasks < concurrency) { + var run = readyTasks.shift(); + run(); + } + } + + function addListener(taskName, fn) { + var taskListeners = listeners[taskName]; + if (!taskListeners) { + taskListeners = listeners[taskName] = []; + } + + taskListeners.push(fn); + } + + function taskComplete(taskName) { + var taskListeners = listeners[taskName] || []; + taskListeners.forEach(fn => fn()); + processQueue(); + } + + function runTask(key, task) { + if (hasError) return; + + var taskCallback = (0, _onlyOnce2.default)((err, ...result) => { + runningTasks--; + if (err === false) { + canceled = true; + return; + } + if (result.length < 2) { + [result] = result; + } + if (err) { + var safeResults = {}; + Object.keys(results).forEach(rkey => { + safeResults[rkey] = results[rkey]; + }); + safeResults[key] = result; + hasError = true; + listeners = Object.create(null); + if (canceled) return; + callback(err, safeResults); + } else { + results[key] = result; + taskComplete(key); + } + }); + + runningTasks++; + var taskFn = (0, _wrapAsync2.default)(task[task.length - 1]); + if (task.length > 1) { + taskFn(results, taskCallback); + } else { + taskFn(taskCallback); + } + } + + function checkForDeadlocks() { + // Kahn's algorithm + // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm + // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html + var currentTask; + var counter = 0; + while (readyToCheck.length) { + currentTask = readyToCheck.pop(); + counter++; + getDependents(currentTask).forEach(dependent => { + if (--uncheckedDependencies[dependent] === 0) { + readyToCheck.push(dependent); + } + }); + } + + if (counter !== numTasks) { + throw new Error('async.auto cannot execute tasks due to a recursive dependency'); + } + } + + function getDependents(taskName) { + var result = []; + Object.keys(tasks).forEach(key => { + const task = tasks[key]; + if (Array.isArray(task) && task.indexOf(taskName) >= 0) { + result.push(key); + } + }); + return result; + } + + return callback[_promiseCallback.PROMISE_SYMBOL]; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/autoInject.js b/Challenge/seokahi/010.star/node_modules/async/autoInject.js new file mode 100644 index 0000000..393baad --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/autoInject.js @@ -0,0 +1,182 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = autoInject; + +var _auto = require('./auto.js'); + +var _auto2 = _interopRequireDefault(_auto); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/; +var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/; +var FN_ARG_SPLIT = /,/; +var FN_ARG = /(=.+)?(\s*)$/; + +function stripComments(string) { + let stripped = ''; + let index = 0; + let endBlockComment = string.indexOf('*/'); + while (index < string.length) { + if (string[index] === '/' && string[index + 1] === '/') { + // inline comment + let endIndex = string.indexOf('\n', index); + index = endIndex === -1 ? string.length : endIndex; + } else if (endBlockComment !== -1 && string[index] === '/' && string[index + 1] === '*') { + // block comment + let endIndex = string.indexOf('*/', index); + if (endIndex !== -1) { + index = endIndex + 2; + endBlockComment = string.indexOf('*/', index); + } else { + stripped += string[index]; + index++; + } + } else { + stripped += string[index]; + index++; + } + } + return stripped; +} + +function parseParams(func) { + const src = stripComments(func.toString()); + let match = src.match(FN_ARGS); + if (!match) { + match = src.match(ARROW_FN_ARGS); + } + if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src); + let [, args] = match; + return args.replace(/\s/g, '').split(FN_ARG_SPLIT).map(arg => arg.replace(FN_ARG, '').trim()); +} + +/** + * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent + * tasks are specified as parameters to the function, after the usual callback + * parameter, with the parameter names matching the names of the tasks it + * depends on. This can provide even more readable task graphs which can be + * easier to maintain. + * + * If a final callback is specified, the task results are similarly injected, + * specified as named parameters after the initial error parameter. + * + * The autoInject function is purely syntactic sugar and its semantics are + * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. + * + * @name autoInject + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.auto]{@link module:ControlFlow.auto} + * @category Control Flow + * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of + * the form 'func([dependencies...], callback). The object's key of a property + * serves as the name of the task defined by that property, i.e. can be used + * when specifying requirements for other tasks. + * * The `callback` parameter is a `callback(err, result)` which must be called + * when finished, passing an `error` (which can be `null`) and the result of + * the function's execution. The remaining parameters name other tasks on + * which the task is dependent, and the results from those tasks are the + * arguments of those parameters. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback, and a `results` object with any completed + * task results, similar to `auto`. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // The example from `auto` can be rewritten as follows: + * async.autoInject({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: function(get_data, make_folder, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }, + * email_link: function(write_file, callback) { + * // once the file is written let's email a link to it... + * // write_file contains the filename returned by write_file. + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * } + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + * + * // If you are using a JS minifier that mangles parameter names, `autoInject` + * // will not work with plain functions, since the parameter names will be + * // collapsed to a single letter identifier. To work around this, you can + * // explicitly specify the names of the parameters your task function needs + * // in an array, similar to Angular.js dependency injection. + * + * // This still has an advantage over plain `auto`, since the results a task + * // depends on are still spread into arguments. + * async.autoInject({ + * //... + * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(write_file, callback) { + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * }] + * //... + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + */ +function autoInject(tasks, callback) { + var newTasks = {}; + + Object.keys(tasks).forEach(key => { + var taskFn = tasks[key]; + var params; + var fnIsAsync = (0, _wrapAsync.isAsync)(taskFn); + var hasNoDeps = !fnIsAsync && taskFn.length === 1 || fnIsAsync && taskFn.length === 0; + + if (Array.isArray(taskFn)) { + params = [...taskFn]; + taskFn = params.pop(); + + newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); + } else if (hasNoDeps) { + // no dependencies, use the function as-is + newTasks[key] = taskFn; + } else { + params = parseParams(taskFn); + if (taskFn.length === 0 && !fnIsAsync && params.length === 0) { + throw new Error("autoInject task functions require explicit parameters."); + } + + // remove callback param + if (!fnIsAsync) params.pop(); + + newTasks[key] = params.concat(newTask); + } + + function newTask(results, taskCb) { + var newArgs = params.map(name => results[name]); + newArgs.push(taskCb); + (0, _wrapAsync2.default)(taskFn)(...newArgs); + } + }); + + return (0, _auto2.default)(newTasks, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/bower.json b/Challenge/seokahi/010.star/node_modules/async/bower.json new file mode 100644 index 0000000..390c650 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/bower.json @@ -0,0 +1,17 @@ +{ + "name": "async", + "main": "dist/async.js", + "ignore": [ + "bower_components", + "lib", + "test", + "node_modules", + "perf", + "support", + "**/.*", + "*.config.js", + "*.json", + "index.js", + "Makefile" + ] +} diff --git a/Challenge/seokahi/010.star/node_modules/async/cargo.js b/Challenge/seokahi/010.star/node_modules/async/cargo.js new file mode 100644 index 0000000..aa385f8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/cargo.js @@ -0,0 +1,63 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = cargo; + +var _queue = require('./internal/queue.js'); + +var _queue2 = _interopRequireDefault(_queue); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Creates a `cargo` object with the specified payload. Tasks added to the + * cargo will be processed altogether (up to the `payload` limit). If the + * `worker` is in progress, the task is queued until it becomes available. Once + * the `worker` has completed some tasks, each callback of those tasks is + * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) + * for how `cargo` and `queue` work. + * + * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers + * at a time, cargo passes an array of tasks to a single worker, repeating + * when the worker is finished. + * + * @name cargo + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An asynchronous function for processing an array + * of queued tasks. Invoked with `(tasks, callback)`. + * @param {number} [payload=Infinity] - An optional `integer` for determining + * how many tasks should be processed per round; if omitted, the default is + * unlimited. + * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can + * attached as certain properties to listen for specific events during the + * lifecycle of the cargo and inner queue. + * @example + * + * // create a cargo object with payload 2 + * var cargo = async.cargo(function(tasks, callback) { + * for (var i=0; i { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir) + * .then(results => { + * console.log(results); + * }).catch(err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.concat(directoryList, fs.readdir); + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.concat(withMissingDirectoryList, fs.readdir); + * console.log(results); + * } catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } + * } + * + */ +function concat(coll, iteratee, callback) { + return (0, _concatLimit2.default)(coll, Infinity, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(concat, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/concatLimit.js b/Challenge/seokahi/010.star/node_modules/async/concatLimit.js new file mode 100644 index 0000000..3d170f1 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/concatLimit.js @@ -0,0 +1,60 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _mapLimit = require('./mapLimit.js'); + +var _mapLimit2 = _interopRequireDefault(_mapLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time. + * + * @name concatLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapLimit + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatLimit(coll, limit, iteratee, callback) { + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _mapLimit2.default)(coll, limit, (val, iterCb) => { + _iteratee(val, (err, ...args) => { + if (err) return iterCb(err); + return iterCb(err, args); + }); + }, (err, mapResults) => { + var result = []; + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + result = result.concat(...mapResults[i]); + } + } + + return callback(err, result); + }); +} +exports.default = (0, _awaitify2.default)(concatLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/concatSeries.js b/Challenge/seokahi/010.star/node_modules/async/concatSeries.js new file mode 100644 index 0000000..84add3b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/concatSeries.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _concatLimit = require('./concatLimit.js'); + +var _concatLimit2 = _interopRequireDefault(_concatLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. + * + * @name concatSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapSeries + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. + * The iteratee should complete with an array an array of results. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatSeries(coll, iteratee, callback) { + return (0, _concatLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(concatSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/constant.js b/Challenge/seokahi/010.star/node_modules/async/constant.js new file mode 100644 index 0000000..0759653 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/constant.js @@ -0,0 +1,55 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (...args) { + return function (...ignoredArgs /*, callback*/) { + var callback = ignoredArgs.pop(); + return callback(null, ...args); + }; +}; + +module.exports = exports["default"]; /** + * Returns a function that when called, calls-back with the values provided. + * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to + * [`auto`]{@link module:ControlFlow.auto}. + * + * @name constant + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {...*} arguments... - Any number of arguments to automatically invoke + * callback with. + * @returns {AsyncFunction} Returns a function that when invoked, automatically + * invokes the callback with the previous given arguments. + * @example + * + * async.waterfall([ + * async.constant(42), + * function (value, next) { + * // value === 42 + * }, + * //... + * ], callback); + * + * async.waterfall([ + * async.constant(filename, "utf8"), + * fs.readFile, + * function (fileData, next) { + * //... + * } + * //... + * ], callback); + * + * async.auto({ + * hostname: async.constant("https://server.net/"), + * port: findFreePort, + * launchServer: ["hostname", "port", function (options, cb) { + * startServer(options, cb); + * }], + * //... + * }, callback); + */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/detect.js b/Challenge/seokahi/010.star/node_modules/async/detect.js new file mode 100644 index 0000000..b3ed7ab --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/detect.js @@ -0,0 +1,96 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns the first value in `coll` that passes an async truth test. The + * `iteratee` is applied in parallel, meaning the first iteratee to return + * `true` will fire the detect `callback` with that result. That means the + * result might not be the first item in the original `coll` (in terms of order) + * that passes the test. + + * If order within the original `coll` is important, then look at + * [`detectSeries`]{@link module:Collections.detectSeries}. + * + * @name detect + * @static + * @memberOf module:Collections + * @method + * @alias find + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * } + *); + * + * // Using Promises + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists) + * .then(result => { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists); + * console.log(result); + * // dir1/file1.txt + * // result now equals the file in the list that exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function detect(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(detect, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/detectLimit.js b/Challenge/seokahi/010.star/node_modules/async/detectLimit.js new file mode 100644 index 0000000..0ddb860 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/detectLimit.js @@ -0,0 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a + * time. + * + * @name detectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findLimit + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(detectLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/detectSeries.js b/Challenge/seokahi/010.star/node_modules/async/detectSeries.js new file mode 100644 index 0000000..0c4f26a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/detectSeries.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. + * + * @name detectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findSeries + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectSeries(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(1), coll, iteratee, callback); +} + +exports.default = (0, _awaitify2.default)(detectSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/dir.js b/Challenge/seokahi/010.star/node_modules/async/dir.js new file mode 100644 index 0000000..950d0a2 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/dir.js @@ -0,0 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _consoleFunc = require('./internal/consoleFunc.js'); + +var _consoleFunc2 = _interopRequireDefault(_consoleFunc); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Logs the result of an [`async` function]{@link AsyncFunction} to the + * `console` using `console.dir` to display the properties of the resulting object. + * Only works in Node.js or in browsers that support `console.dir` and + * `console.error` (such as FF and Chrome). + * If multiple arguments are returned from the async function, + * `console.dir` is called on each argument in order. + * + * @name dir + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, {hello: name}); + * }, 1000); + * }; + * + * // in the node repl + * node> async.dir(hello, 'world'); + * {hello: 'world'} + */ +exports.default = (0, _consoleFunc2.default)('dir'); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/dist/async.js b/Challenge/seokahi/010.star/node_modules/async/dist/async.js new file mode 100644 index 0000000..832ca57 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/dist/async.js @@ -0,0 +1,6057 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.async = {}))); +}(this, (function (exports) { 'use strict'; + + /** + * Creates a continuation function with some arguments already applied. + * + * Useful as a shorthand when combined with other control flow functions. Any + * arguments passed to the returned function are added to the arguments + * originally passed to apply. + * + * @name apply + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {Function} fn - The function you want to eventually apply all + * arguments to. Invokes with (arguments...). + * @param {...*} arguments... - Any number of arguments to automatically apply + * when the continuation is called. + * @returns {Function} the partially-applied function + * @example + * + * // using apply + * async.parallel([ + * async.apply(fs.writeFile, 'testfile1', 'test1'), + * async.apply(fs.writeFile, 'testfile2', 'test2') + * ]); + * + * + * // the same process without using apply + * async.parallel([ + * function(callback) { + * fs.writeFile('testfile1', 'test1', callback); + * }, + * function(callback) { + * fs.writeFile('testfile2', 'test2', callback); + * } + * ]); + * + * // It's possible to pass any number of additional arguments when calling the + * // continuation: + * + * node> var fn = async.apply(sys.puts, 'one'); + * node> fn('two', 'three'); + * one + * two + * three + */ + function apply(fn, ...args) { + return (...callArgs) => fn(...args,...callArgs); + } + + function initialParams (fn) { + return function (...args/*, callback*/) { + var callback = args.pop(); + return fn.call(this, args, callback); + }; + } + + /* istanbul ignore file */ + + var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask; + var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; + var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; + + function fallback(fn) { + setTimeout(fn, 0); + } + + function wrap(defer) { + return (fn, ...args) => defer(() => fn(...args)); + } + + var _defer; + + if (hasQueueMicrotask) { + _defer = queueMicrotask; + } else if (hasSetImmediate) { + _defer = setImmediate; + } else if (hasNextTick) { + _defer = process.nextTick; + } else { + _defer = fallback; + } + + var setImmediate$1 = wrap(_defer); + + /** + * Take a sync function and make it async, passing its return value to a + * callback. This is useful for plugging sync functions into a waterfall, + * series, or other async functions. Any arguments passed to the generated + * function will be passed to the wrapped function (except for the final + * callback argument). Errors thrown will be passed to the callback. + * + * If the function passed to `asyncify` returns a Promise, that promises's + * resolved/rejected state will be used to call the callback, rather than simply + * the synchronous return value. + * + * This also means you can asyncify ES2017 `async` functions. + * + * @name asyncify + * @static + * @memberOf module:Utils + * @method + * @alias wrapSync + * @category Util + * @param {Function} func - The synchronous function, or Promise-returning + * function to convert to an {@link AsyncFunction}. + * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be + * invoked with `(args..., callback)`. + * @example + * + * // passing a regular synchronous function + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(JSON.parse), + * function (data, next) { + * // data is the result of parsing the text. + * // If there was a parsing error, it would have been caught. + * } + * ], callback); + * + * // passing a function returning a promise + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(function (contents) { + * return db.model.create(contents); + * }), + * function (model, next) { + * // `model` is the instantiated model object. + * // If there was an error, this function would be skipped. + * } + * ], callback); + * + * // es2017 example, though `asyncify` is not needed if your JS environment + * // supports async functions out of the box + * var q = async.queue(async.asyncify(async function(file) { + * var intermediateStep = await processFile(file); + * return await somePromise(intermediateStep) + * })); + * + * q.push(files); + */ + function asyncify(func) { + if (isAsync(func)) { + return function (...args/*, callback*/) { + const callback = args.pop(); + const promise = func.apply(this, args); + return handlePromise(promise, callback) + } + } + + return initialParams(function (args, callback) { + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (result && typeof result.then === 'function') { + return handlePromise(result, callback) + } else { + callback(null, result); + } + }); + } + + function handlePromise(promise, callback) { + return promise.then(value => { + invokeCallback(callback, null, value); + }, err => { + invokeCallback(callback, err && err.message ? err : new Error(err)); + }); + } + + function invokeCallback(callback, error, value) { + try { + callback(error, value); + } catch (err) { + setImmediate$1(e => { throw e }, err); + } + } + + function isAsync(fn) { + return fn[Symbol.toStringTag] === 'AsyncFunction'; + } + + function isAsyncGenerator(fn) { + return fn[Symbol.toStringTag] === 'AsyncGenerator'; + } + + function isAsyncIterable(obj) { + return typeof obj[Symbol.asyncIterator] === 'function'; + } + + function wrapAsync(asyncFn) { + if (typeof asyncFn !== 'function') throw new Error('expected a function') + return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn; + } + + // conditionally promisify a function. + // only return a promise if a callback is omitted + function awaitify (asyncFn, arity = asyncFn.length) { + if (!arity) throw new Error('arity is undefined') + function awaitable (...args) { + if (typeof args[arity - 1] === 'function') { + return asyncFn.apply(this, args) + } + + return new Promise((resolve, reject) => { + args[arity - 1] = (err, ...cbArgs) => { + if (err) return reject(err) + resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]); + }; + asyncFn.apply(this, args); + }) + } + + return awaitable + } + + function applyEach (eachfn) { + return function applyEach(fns, ...callArgs) { + const go = awaitify(function (callback) { + var that = this; + return eachfn(fns, (fn, cb) => { + wrapAsync(fn).apply(that, callArgs.concat(cb)); + }, callback); + }); + return go; + }; + } + + function _asyncMap(eachfn, arr, iteratee, callback) { + arr = arr || []; + var results = []; + var counter = 0; + var _iteratee = wrapAsync(iteratee); + + return eachfn(arr, (value, _, iterCb) => { + var index = counter++; + _iteratee(value, (err, v) => { + results[index] = v; + iterCb(err); + }); + }, err => { + callback(err, results); + }); + } + + function isArrayLike(value) { + return value && + typeof value.length === 'number' && + value.length >= 0 && + value.length % 1 === 0; + } + + // A temporary value used to identify if the loop should be broken. + // See #1064, #1293 + const breakLoop = {}; + + function once(fn) { + function wrapper (...args) { + if (fn === null) return; + var callFn = fn; + fn = null; + callFn.apply(this, args); + } + Object.assign(wrapper, fn); + return wrapper + } + + function getIterator (coll) { + return coll[Symbol.iterator] && coll[Symbol.iterator](); + } + + function createArrayIterator(coll) { + var i = -1; + var len = coll.length; + return function next() { + return ++i < len ? {value: coll[i], key: i} : null; + } + } + + function createES2015Iterator(iterator) { + var i = -1; + return function next() { + var item = iterator.next(); + if (item.done) + return null; + i++; + return {value: item.value, key: i}; + } + } + + function createObjectIterator(obj) { + var okeys = obj ? Object.keys(obj) : []; + var i = -1; + var len = okeys.length; + return function next() { + var key = okeys[++i]; + if (key === '__proto__') { + return next(); + } + return i < len ? {value: obj[key], key} : null; + }; + } + + function createIterator(coll) { + if (isArrayLike(coll)) { + return createArrayIterator(coll); + } + + var iterator = getIterator(coll); + return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); + } + + function onlyOnce(fn) { + return function (...args) { + if (fn === null) throw new Error("Callback was already called."); + var callFn = fn; + fn = null; + callFn.apply(this, args); + }; + } + + // for async generators + function asyncEachOfLimit(generator, limit, iteratee, callback) { + let done = false; + let canceled = false; + let awaiting = false; + let running = 0; + let idx = 0; + + function replenish() { + //console.log('replenish') + if (running >= limit || awaiting || done) return + //console.log('replenish awaiting') + awaiting = true; + generator.next().then(({value, done: iterDone}) => { + //console.log('got value', value) + if (canceled || done) return + awaiting = false; + if (iterDone) { + done = true; + if (running <= 0) { + //console.log('done nextCb') + callback(null); + } + return; + } + running++; + iteratee(value, idx, iterateeCallback); + idx++; + replenish(); + }).catch(handleError); + } + + function iterateeCallback(err, result) { + //console.log('iterateeCallback') + running -= 1; + if (canceled) return + if (err) return handleError(err) + + if (err === false) { + done = true; + canceled = true; + return + } + + if (result === breakLoop || (done && running <= 0)) { + done = true; + //console.log('done iterCb') + return callback(null); + } + replenish(); + } + + function handleError(err) { + if (canceled) return + awaiting = false; + done = true; + callback(err); + } + + replenish(); + } + + var eachOfLimit = (limit) => { + return (obj, iteratee, callback) => { + callback = once(callback); + if (limit <= 0) { + throw new RangeError('concurrency limit cannot be less than 1') + } + if (!obj) { + return callback(null); + } + if (isAsyncGenerator(obj)) { + return asyncEachOfLimit(obj, limit, iteratee, callback) + } + if (isAsyncIterable(obj)) { + return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback) + } + var nextElem = createIterator(obj); + var done = false; + var canceled = false; + var running = 0; + var looping = false; + + function iterateeCallback(err, value) { + if (canceled) return + running -= 1; + if (err) { + done = true; + callback(err); + } + else if (err === false) { + done = true; + canceled = true; + } + else if (value === breakLoop || (done && running <= 0)) { + done = true; + return callback(null); + } + else if (!looping) { + replenish(); + } + } + + function replenish () { + looping = true; + while (running < limit && !done) { + var elem = nextElem(); + if (elem === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iteratee(elem.value, elem.key, onlyOnce(iterateeCallback)); + } + looping = false; + } + + replenish(); + }; + }; + + /** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a + * time. + * + * @name eachOfLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. The `key` is the item's key, or index in the case of an + * array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ + function eachOfLimit$1(coll, limit, iteratee, callback) { + return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback); + } + + var eachOfLimit$2 = awaitify(eachOfLimit$1, 4); + + // eachOf implementation optimized for array-likes + function eachOfArrayLike(coll, iteratee, callback) { + callback = once(callback); + var index = 0, + completed = 0, + {length} = coll, + canceled = false; + if (length === 0) { + callback(null); + } + + function iteratorCallback(err, value) { + if (err === false) { + canceled = true; + } + if (canceled === true) return + if (err) { + callback(err); + } else if ((++completed === length) || value === breakLoop) { + callback(null); + } + } + + for (; index < length; index++) { + iteratee(coll[index], index, onlyOnce(iteratorCallback)); + } + } + + // a generic version of eachOf which can handle array, object, and iterator cases. + function eachOfGeneric (coll, iteratee, callback) { + return eachOfLimit$2(coll, Infinity, iteratee, callback); + } + + /** + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument + * to the iteratee. + * + * @name eachOf + * @static + * @memberOf module:Collections + * @method + * @alias forEachOf + * @category Collection + * @see [async.each]{@link module:Collections.each} + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each + * item in `coll`. + * The `key` is the item's key, or index in the case of an array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dev.json is a file containing a valid json object config for dev environment + * // dev.json is a file containing a valid json object config for test environment + * // prod.json is a file containing a valid json object config for prod environment + * // invalid.json is a file with a malformed json object + * + * let configs = {}; //global variable + * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'}; + * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'}; + * + * // asynchronous function that reads a json file and parses the contents as json object + * function parseFile(file, key, callback) { + * fs.readFile(file, "utf8", function(err, data) { + * if (err) return calback(err); + * try { + * configs[key] = JSON.parse(data); + * } catch (e) { + * return callback(e); + * } + * callback(); + * }); + * } + * + * // Using callbacks + * async.forEachOf(validConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * } else { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * // JSON parse error exception + * } else { + * console.log(configs); + * } + * }); + * + * // Using Promises + * async.forEachOf(validConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * }).catch( err => { + * console.error(err); + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * }).catch( err => { + * console.error(err); + * // JSON parse error exception + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.forEachOf(validConfigFileMap, parseFile); + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * catch (err) { + * console.log(err); + * } + * } + * + * //Error handing + * async () => { + * try { + * let result = await async.forEachOf(invalidConfigFileMap, parseFile); + * console.log(configs); + * } + * catch (err) { + * console.log(err); + * // JSON parse error exception + * } + * } + * + */ + function eachOf(coll, iteratee, callback) { + var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric; + return eachOfImplementation(coll, wrapAsync(iteratee), callback); + } + + var eachOf$1 = awaitify(eachOf, 3); + + /** + * Produces a new collection of values by mapping each value in `coll` through + * the `iteratee` function. The `iteratee` is called with an item from `coll` + * and a callback for when it has finished processing. Each of these callbacks + * takes 2 arguments: an `error`, and the transformed item from `coll`. If + * `iteratee` passes an error to its callback, the main `callback` (for the + * `map` function) is immediately called with the error. + * + * Note, that since this function applies the `iteratee` to each item in + * parallel, there is no guarantee that the `iteratee` functions will complete + * in order. However, the results array will be in the same order as the + * original `coll`. + * + * If `map` is passed an Object, the results will be an Array. The results + * will roughly be in the order of the original Objects' keys (but this can + * vary across JavaScript engines). + * + * @name map + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an Array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.map(fileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.map(fileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.map(fileList, getFileSizeInBytes); + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.map(withMissingFileList, getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ + function map (coll, iteratee, callback) { + return _asyncMap(eachOf$1, coll, iteratee, callback) + } + var map$1 = awaitify(map, 3); + + /** + * Applies the provided arguments to each function in the array, calling + * `callback` after all functions have completed. If you only provide the first + * argument, `fns`, then it will return a function which lets you pass in the + * arguments as if it were a single function call. If more arguments are + * provided, `callback` is required while `args` is still optional. The results + * for each of the applied async functions are passed to the final callback + * as an array. + * + * @name applyEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s + * to all call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - Returns a function that takes no args other than + * an optional callback, that is the result of applying the `args` to each + * of the functions. + * @example + * + * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket') + * + * appliedFn((err, results) => { + * // results[0] is the results for `enableSearch` + * // results[1] is the results for `updateSchema` + * }); + * + * // partial application example: + * async.each( + * buckets, + * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(), + * callback + * ); + */ + var applyEach$1 = applyEach(map$1); + + /** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. + * + * @name eachOfSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ + function eachOfSeries(coll, iteratee, callback) { + return eachOfLimit$2(coll, 1, iteratee, callback) + } + var eachOfSeries$1 = awaitify(eachOfSeries, 3); + + /** + * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. + * + * @name mapSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ + function mapSeries (coll, iteratee, callback) { + return _asyncMap(eachOfSeries$1, coll, iteratee, callback) + } + var mapSeries$1 = awaitify(mapSeries, 3); + + /** + * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. + * + * @name applyEachSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.applyEach]{@link module:ControlFlow.applyEach} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all + * call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - A function, that when called, is the result of + * appling the `args` to the list of functions. It takes no args, other than + * a callback. + */ + var applyEachSeries = applyEach(mapSeries$1); + + const PROMISE_SYMBOL = Symbol('promiseCallback'); + + function promiseCallback () { + let resolve, reject; + function callback (err, ...args) { + if (err) return reject(err) + resolve(args.length > 1 ? args : args[0]); + } + + callback[PROMISE_SYMBOL] = new Promise((res, rej) => { + resolve = res, + reject = rej; + }); + + return callback + } + + /** + * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on + * their requirements. Each function can optionally depend on other functions + * being completed first, and each function is run as soon as its requirements + * are satisfied. + * + * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence + * will stop. Further tasks will not execute (so any other functions depending + * on it will not run), and the main `callback` is immediately called with the + * error. + * + * {@link AsyncFunction}s also receive an object containing the results of functions which + * have completed so far as the first argument, if they have dependencies. If a + * task function has no dependencies, it will only be passed a callback. + * + * @name auto + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Object} tasks - An object. Each of its properties is either a + * function or an array of requirements, with the {@link AsyncFunction} itself the last item + * in the array. The object's key of a property serves as the name of the task + * defined by that property, i.e. can be used when specifying requirements for + * other tasks. The function receives one or two arguments: + * * a `results` object, containing the results of the previously executed + * functions, only passed if the task has any dependencies, + * * a `callback(err, result)` function, which must be called when finished, + * passing an `error` (which can be `null`) and the result of the function's + * execution. + * @param {number} [concurrency=Infinity] - An optional `integer` for + * determining the maximum number of tasks that can be run in parallel. By + * default, as many as possible. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback. Results are always returned; however, if an + * error occurs, no further `tasks` will be performed, and the results object + * will only contain partial results. Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * @example + * + * //Using Callbacks + * async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }, function(err, results) { + * if (err) { + * console.log('err = ', err); + * } + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }); + * + * //Using Promises + * async.auto({ + * get_data: function(callback) { + * console.log('in get_data'); + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * console.log('in make_folder'); + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }).then(results => { + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }).catch(err => { + * console.log('err = ', err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }); + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function auto(tasks, concurrency, callback) { + if (typeof concurrency !== 'number') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = once(callback || promiseCallback()); + var numTasks = Object.keys(tasks).length; + if (!numTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = numTasks; + } + + var results = {}; + var runningTasks = 0; + var canceled = false; + var hasError = false; + + var listeners = Object.create(null); + + var readyTasks = []; + + // for cycle detection: + var readyToCheck = []; // tasks that have been identified as reachable + // without the possibility of returning to an ancestor task + var uncheckedDependencies = {}; + + Object.keys(tasks).forEach(key => { + var task = tasks[key]; + if (!Array.isArray(task)) { + // no dependencies + enqueueTask(key, [task]); + readyToCheck.push(key); + return; + } + + var dependencies = task.slice(0, task.length - 1); + var remainingDependencies = dependencies.length; + if (remainingDependencies === 0) { + enqueueTask(key, task); + readyToCheck.push(key); + return; + } + uncheckedDependencies[key] = remainingDependencies; + + dependencies.forEach(dependencyName => { + if (!tasks[dependencyName]) { + throw new Error('async.auto task `' + key + + '` has a non-existent dependency `' + + dependencyName + '` in ' + + dependencies.join(', ')); + } + addListener(dependencyName, () => { + remainingDependencies--; + if (remainingDependencies === 0) { + enqueueTask(key, task); + } + }); + }); + }); + + checkForDeadlocks(); + processQueue(); + + function enqueueTask(key, task) { + readyTasks.push(() => runTask(key, task)); + } + + function processQueue() { + if (canceled) return + if (readyTasks.length === 0 && runningTasks === 0) { + return callback(null, results); + } + while(readyTasks.length && runningTasks < concurrency) { + var run = readyTasks.shift(); + run(); + } + + } + + function addListener(taskName, fn) { + var taskListeners = listeners[taskName]; + if (!taskListeners) { + taskListeners = listeners[taskName] = []; + } + + taskListeners.push(fn); + } + + function taskComplete(taskName) { + var taskListeners = listeners[taskName] || []; + taskListeners.forEach(fn => fn()); + processQueue(); + } + + + function runTask(key, task) { + if (hasError) return; + + var taskCallback = onlyOnce((err, ...result) => { + runningTasks--; + if (err === false) { + canceled = true; + return + } + if (result.length < 2) { + [result] = result; + } + if (err) { + var safeResults = {}; + Object.keys(results).forEach(rkey => { + safeResults[rkey] = results[rkey]; + }); + safeResults[key] = result; + hasError = true; + listeners = Object.create(null); + if (canceled) return + callback(err, safeResults); + } else { + results[key] = result; + taskComplete(key); + } + }); + + runningTasks++; + var taskFn = wrapAsync(task[task.length - 1]); + if (task.length > 1) { + taskFn(results, taskCallback); + } else { + taskFn(taskCallback); + } + } + + function checkForDeadlocks() { + // Kahn's algorithm + // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm + // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html + var currentTask; + var counter = 0; + while (readyToCheck.length) { + currentTask = readyToCheck.pop(); + counter++; + getDependents(currentTask).forEach(dependent => { + if (--uncheckedDependencies[dependent] === 0) { + readyToCheck.push(dependent); + } + }); + } + + if (counter !== numTasks) { + throw new Error( + 'async.auto cannot execute tasks due to a recursive dependency' + ); + } + } + + function getDependents(taskName) { + var result = []; + Object.keys(tasks).forEach(key => { + const task = tasks[key]; + if (Array.isArray(task) && task.indexOf(taskName) >= 0) { + result.push(key); + } + }); + return result; + } + + return callback[PROMISE_SYMBOL] + } + + var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/; + var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/; + var FN_ARG_SPLIT = /,/; + var FN_ARG = /(=.+)?(\s*)$/; + + function stripComments(string) { + let stripped = ''; + let index = 0; + let endBlockComment = string.indexOf('*/'); + while (index < string.length) { + if (string[index] === '/' && string[index+1] === '/') { + // inline comment + let endIndex = string.indexOf('\n', index); + index = (endIndex === -1) ? string.length : endIndex; + } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) { + // block comment + let endIndex = string.indexOf('*/', index); + if (endIndex !== -1) { + index = endIndex + 2; + endBlockComment = string.indexOf('*/', index); + } else { + stripped += string[index]; + index++; + } + } else { + stripped += string[index]; + index++; + } + } + return stripped; + } + + function parseParams(func) { + const src = stripComments(func.toString()); + let match = src.match(FN_ARGS); + if (!match) { + match = src.match(ARROW_FN_ARGS); + } + if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src) + let [, args] = match; + return args + .replace(/\s/g, '') + .split(FN_ARG_SPLIT) + .map((arg) => arg.replace(FN_ARG, '').trim()); + } + + /** + * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent + * tasks are specified as parameters to the function, after the usual callback + * parameter, with the parameter names matching the names of the tasks it + * depends on. This can provide even more readable task graphs which can be + * easier to maintain. + * + * If a final callback is specified, the task results are similarly injected, + * specified as named parameters after the initial error parameter. + * + * The autoInject function is purely syntactic sugar and its semantics are + * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. + * + * @name autoInject + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.auto]{@link module:ControlFlow.auto} + * @category Control Flow + * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of + * the form 'func([dependencies...], callback). The object's key of a property + * serves as the name of the task defined by that property, i.e. can be used + * when specifying requirements for other tasks. + * * The `callback` parameter is a `callback(err, result)` which must be called + * when finished, passing an `error` (which can be `null`) and the result of + * the function's execution. The remaining parameters name other tasks on + * which the task is dependent, and the results from those tasks are the + * arguments of those parameters. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback, and a `results` object with any completed + * task results, similar to `auto`. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // The example from `auto` can be rewritten as follows: + * async.autoInject({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: function(get_data, make_folder, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }, + * email_link: function(write_file, callback) { + * // once the file is written let's email a link to it... + * // write_file contains the filename returned by write_file. + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * } + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + * + * // If you are using a JS minifier that mangles parameter names, `autoInject` + * // will not work with plain functions, since the parameter names will be + * // collapsed to a single letter identifier. To work around this, you can + * // explicitly specify the names of the parameters your task function needs + * // in an array, similar to Angular.js dependency injection. + * + * // This still has an advantage over plain `auto`, since the results a task + * // depends on are still spread into arguments. + * async.autoInject({ + * //... + * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(write_file, callback) { + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * }] + * //... + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + */ + function autoInject(tasks, callback) { + var newTasks = {}; + + Object.keys(tasks).forEach(key => { + var taskFn = tasks[key]; + var params; + var fnIsAsync = isAsync(taskFn); + var hasNoDeps = + (!fnIsAsync && taskFn.length === 1) || + (fnIsAsync && taskFn.length === 0); + + if (Array.isArray(taskFn)) { + params = [...taskFn]; + taskFn = params.pop(); + + newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); + } else if (hasNoDeps) { + // no dependencies, use the function as-is + newTasks[key] = taskFn; + } else { + params = parseParams(taskFn); + if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) { + throw new Error("autoInject task functions require explicit parameters."); + } + + // remove callback param + if (!fnIsAsync) params.pop(); + + newTasks[key] = params.concat(newTask); + } + + function newTask(results, taskCb) { + var newArgs = params.map(name => results[name]); + newArgs.push(taskCb); + wrapAsync(taskFn)(...newArgs); + } + }); + + return auto(newTasks, callback); + } + + // Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation + // used for queues. This implementation assumes that the node provided by the user can be modified + // to adjust the next and last properties. We implement only the minimal functionality + // for queue support. + class DLL { + constructor() { + this.head = this.tail = null; + this.length = 0; + } + + removeLink(node) { + if (node.prev) node.prev.next = node.next; + else this.head = node.next; + if (node.next) node.next.prev = node.prev; + else this.tail = node.prev; + + node.prev = node.next = null; + this.length -= 1; + return node; + } + + empty () { + while(this.head) this.shift(); + return this; + } + + insertAfter(node, newNode) { + newNode.prev = node; + newNode.next = node.next; + if (node.next) node.next.prev = newNode; + else this.tail = newNode; + node.next = newNode; + this.length += 1; + } + + insertBefore(node, newNode) { + newNode.prev = node.prev; + newNode.next = node; + if (node.prev) node.prev.next = newNode; + else this.head = newNode; + node.prev = newNode; + this.length += 1; + } + + unshift(node) { + if (this.head) this.insertBefore(this.head, node); + else setInitial(this, node); + } + + push(node) { + if (this.tail) this.insertAfter(this.tail, node); + else setInitial(this, node); + } + + shift() { + return this.head && this.removeLink(this.head); + } + + pop() { + return this.tail && this.removeLink(this.tail); + } + + toArray() { + return [...this] + } + + *[Symbol.iterator] () { + var cur = this.head; + while (cur) { + yield cur.data; + cur = cur.next; + } + } + + remove (testFn) { + var curr = this.head; + while(curr) { + var {next} = curr; + if (testFn(curr)) { + this.removeLink(curr); + } + curr = next; + } + return this; + } + } + + function setInitial(dll, node) { + dll.length = 1; + dll.head = dll.tail = node; + } + + function queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new RangeError('Concurrency must not be zero'); + } + + var _worker = wrapAsync(worker); + var numRunning = 0; + var workersList = []; + const events = { + error: [], + drain: [], + saturated: [], + unsaturated: [], + empty: [] + }; + + function on (event, handler) { + events[event].push(handler); + } + + function once (event, handler) { + const handleAndRemove = (...args) => { + off(event, handleAndRemove); + handler(...args); + }; + events[event].push(handleAndRemove); + } + + function off (event, handler) { + if (!event) return Object.keys(events).forEach(ev => events[ev] = []) + if (!handler) return events[event] = [] + events[event] = events[event].filter(ev => ev !== handler); + } + + function trigger (event, ...args) { + events[event].forEach(handler => handler(...args)); + } + + var processingScheduled = false; + function _insert(data, insertAtFront, rejectOnError, callback) { + if (callback != null && typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + + var res, rej; + function promiseCallback (err, ...args) { + // we don't care about the error, let the global error handler + // deal with it + if (err) return rejectOnError ? rej(err) : res() + if (args.length <= 1) return res(args[0]) + res(args); + } + + var item = { + data, + callback: rejectOnError ? + promiseCallback : + (callback || promiseCallback) + }; + + if (insertAtFront) { + q._tasks.unshift(item); + } else { + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + setImmediate$1(() => { + processingScheduled = false; + q.process(); + }); + } + + if (rejectOnError || !callback) { + return new Promise((resolve, reject) => { + res = resolve; + rej = reject; + }) + } + } + + function _createCB(tasks) { + return function (err, ...args) { + numRunning -= 1; + + for (var i = 0, l = tasks.length; i < l; i++) { + var task = tasks[i]; + + var index = workersList.indexOf(task); + if (index === 0) { + workersList.shift(); + } else if (index > 0) { + workersList.splice(index, 1); + } + + task.callback(err, ...args); + + if (err != null) { + trigger('error', err, task.data); + } + } + + if (numRunning <= (q.concurrency - q.buffer) ) { + trigger('unsaturated'); + } + + if (q.idle()) { + trigger('drain'); + } + q.process(); + }; + } + + function _maybeDrain(data) { + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + setImmediate$1(() => trigger('drain')); + return true + } + return false + } + + const eventMethod = (name) => (handler) => { + if (!handler) { + return new Promise((resolve, reject) => { + once(name, (err, data) => { + if (err) return reject(err) + resolve(data); + }); + }) + } + off(name); + on(name, handler); + + }; + + var isProcessing = false; + var q = { + _tasks: new DLL(), + *[Symbol.iterator] () { + yield* q._tasks[Symbol.iterator](); + }, + concurrency, + payload, + buffer: concurrency / 4, + started: false, + paused: false, + push (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, false, false, callback)) + } + return _insert(data, false, false, callback); + }, + pushAsync (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, false, true, callback)) + } + return _insert(data, false, true, callback); + }, + kill () { + off(); + q._tasks.empty(); + }, + unshift (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, true, false, callback)) + } + return _insert(data, true, false, callback); + }, + unshiftAsync (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, true, true, callback)) + } + return _insert(data, true, true, callback); + }, + remove (testFn) { + q._tasks.remove(testFn); + }, + process () { + // Avoid trying to start too many processing operations. This can occur + // when callbacks resolve synchronously (#1267). + if (isProcessing) { + return; + } + isProcessing = true; + while(!q.paused && numRunning < q.concurrency && q._tasks.length){ + var tasks = [], data = []; + var l = q._tasks.length; + if (q.payload) l = Math.min(l, q.payload); + for (var i = 0; i < l; i++) { + var node = q._tasks.shift(); + tasks.push(node); + workersList.push(node); + data.push(node.data); + } + + numRunning += 1; + + if (q._tasks.length === 0) { + trigger('empty'); + } + + if (numRunning === q.concurrency) { + trigger('saturated'); + } + + var cb = onlyOnce(_createCB(tasks)); + _worker(data, cb); + } + isProcessing = false; + }, + length () { + return q._tasks.length; + }, + running () { + return numRunning; + }, + workersList () { + return workersList; + }, + idle() { + return q._tasks.length + numRunning === 0; + }, + pause () { + q.paused = true; + }, + resume () { + if (q.paused === false) { return; } + q.paused = false; + setImmediate$1(q.process); + } + }; + // define these as fixed properties, so people get useful errors when updating + Object.defineProperties(q, { + saturated: { + writable: false, + value: eventMethod('saturated') + }, + unsaturated: { + writable: false, + value: eventMethod('unsaturated') + }, + empty: { + writable: false, + value: eventMethod('empty') + }, + drain: { + writable: false, + value: eventMethod('drain') + }, + error: { + writable: false, + value: eventMethod('error') + }, + }); + return q; + } + + /** + * Creates a `cargo` object with the specified payload. Tasks added to the + * cargo will be processed altogether (up to the `payload` limit). If the + * `worker` is in progress, the task is queued until it becomes available. Once + * the `worker` has completed some tasks, each callback of those tasks is + * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) + * for how `cargo` and `queue` work. + * + * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers + * at a time, cargo passes an array of tasks to a single worker, repeating + * when the worker is finished. + * + * @name cargo + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An asynchronous function for processing an array + * of queued tasks. Invoked with `(tasks, callback)`. + * @param {number} [payload=Infinity] - An optional `integer` for determining + * how many tasks should be processed per round; if omitted, the default is + * unlimited. + * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can + * attached as certain properties to listen for specific events during the + * lifecycle of the cargo and inner queue. + * @example + * + * // create a cargo object with payload 2 + * var cargo = async.cargo(function(tasks, callback) { + * for (var i=0; i { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.reduce(fileList, 0, getFileSizeInBytes); + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ + function reduce(coll, memo, iteratee, callback) { + callback = once(callback); + var _iteratee = wrapAsync(iteratee); + return eachOfSeries$1(coll, (x, i, iterCb) => { + _iteratee(memo, x, (err, v) => { + memo = v; + iterCb(err); + }); + }, err => callback(err, memo)); + } + var reduce$1 = awaitify(reduce, 4); + + /** + * Version of the compose function that is more natural to read. Each function + * consumes the return value of the previous function. It is the equivalent of + * [compose]{@link module:ControlFlow.compose} with the arguments reversed. + * + * Each function is executed with the `this` binding of the composed function. + * + * @name seq + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.compose]{@link module:ControlFlow.compose} + * @category Control Flow + * @param {...AsyncFunction} functions - the asynchronous functions to compose + * @returns {Function} a function that composes the `functions` in order + * @example + * + * // Requires lodash (or underscore), express3 and dresende's orm2. + * // Part of an app, that fetches cats of the logged user. + * // This example uses `seq` function to avoid overnesting and error + * // handling clutter. + * app.get('/cats', function(request, response) { + * var User = request.models.User; + * async.seq( + * User.get.bind(User), // 'User.get' has signature (id, callback(err, data)) + * function(user, fn) { + * user.getCats(fn); // 'getCats' has signature (callback(err, data)) + * } + * )(req.session.user_id, function (err, cats) { + * if (err) { + * console.error(err); + * response.json({ status: 'error', message: err.message }); + * } else { + * response.json({ status: 'ok', message: 'Cats found', data: cats }); + * } + * }); + * }); + */ + function seq(...functions) { + var _functions = functions.map(wrapAsync); + return function (...args) { + var that = this; + + var cb = args[args.length - 1]; + if (typeof cb == 'function') { + args.pop(); + } else { + cb = promiseCallback(); + } + + reduce$1(_functions, args, (newargs, fn, iterCb) => { + fn.apply(that, newargs.concat((err, ...nextargs) => { + iterCb(err, nextargs); + })); + }, + (err, results) => cb(err, ...results)); + + return cb[PROMISE_SYMBOL] + }; + } + + /** + * Creates a function which is a composition of the passed asynchronous + * functions. Each function consumes the return value of the function that + * follows. Composing functions `f()`, `g()`, and `h()` would produce the result + * of `f(g(h()))`, only this version uses callbacks to obtain the return values. + * + * If the last argument to the composed function is not a function, a promise + * is returned when you call it. + * + * Each function is executed with the `this` binding of the composed function. + * + * @name compose + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {...AsyncFunction} functions - the asynchronous functions to compose + * @returns {Function} an asynchronous function that is the composed + * asynchronous `functions` + * @example + * + * function add1(n, callback) { + * setTimeout(function () { + * callback(null, n + 1); + * }, 10); + * } + * + * function mul3(n, callback) { + * setTimeout(function () { + * callback(null, n * 3); + * }, 10); + * } + * + * var add1mul3 = async.compose(mul3, add1); + * add1mul3(4, function (err, result) { + * // result now equals 15 + * }); + */ + function compose(...args) { + return seq(...args.reverse()); + } + + /** + * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. + * + * @name mapLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ + function mapLimit (coll, limit, iteratee, callback) { + return _asyncMap(eachOfLimit(limit), coll, iteratee, callback) + } + var mapLimit$1 = awaitify(mapLimit, 4); + + /** + * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time. + * + * @name concatLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapLimit + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ + function concatLimit(coll, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(coll, limit, (val, iterCb) => { + _iteratee(val, (err, ...args) => { + if (err) return iterCb(err); + return iterCb(err, args); + }); + }, (err, mapResults) => { + var result = []; + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + result = result.concat(...mapResults[i]); + } + } + + return callback(err, result); + }); + } + var concatLimit$1 = awaitify(concatLimit, 4); + + /** + * Applies `iteratee` to each item in `coll`, concatenating the results. Returns + * the concatenated list. The `iteratee`s are called in parallel, and the + * results are concatenated as they return. The results array will be returned in + * the original order of `coll` passed to the `iteratee` function. + * + * @name concat + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @alias flatMap + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * let directoryList = ['dir1','dir2','dir3']; + * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4']; + * + * // Using callbacks + * async.concat(directoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.concat(directoryList, fs.readdir) + * .then(results => { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir) + * .then(results => { + * console.log(results); + * }).catch(err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.concat(directoryList, fs.readdir); + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.concat(withMissingDirectoryList, fs.readdir); + * console.log(results); + * } catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } + * } + * + */ + function concat(coll, iteratee, callback) { + return concatLimit$1(coll, Infinity, iteratee, callback) + } + var concat$1 = awaitify(concat, 3); + + /** + * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. + * + * @name concatSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapSeries + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. + * The iteratee should complete with an array an array of results. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ + function concatSeries(coll, iteratee, callback) { + return concatLimit$1(coll, 1, iteratee, callback) + } + var concatSeries$1 = awaitify(concatSeries, 3); + + /** + * Returns a function that when called, calls-back with the values provided. + * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to + * [`auto`]{@link module:ControlFlow.auto}. + * + * @name constant + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {...*} arguments... - Any number of arguments to automatically invoke + * callback with. + * @returns {AsyncFunction} Returns a function that when invoked, automatically + * invokes the callback with the previous given arguments. + * @example + * + * async.waterfall([ + * async.constant(42), + * function (value, next) { + * // value === 42 + * }, + * //... + * ], callback); + * + * async.waterfall([ + * async.constant(filename, "utf8"), + * fs.readFile, + * function (fileData, next) { + * //... + * } + * //... + * ], callback); + * + * async.auto({ + * hostname: async.constant("https://server.net/"), + * port: findFreePort, + * launchServer: ["hostname", "port", function (options, cb) { + * startServer(options, cb); + * }], + * //... + * }, callback); + */ + function constant(...args) { + return function (...ignoredArgs/*, callback*/) { + var callback = ignoredArgs.pop(); + return callback(null, ...args); + }; + } + + function _createTester(check, getResult) { + return (eachfn, arr, _iteratee, cb) => { + var testPassed = false; + var testResult; + const iteratee = wrapAsync(_iteratee); + eachfn(arr, (value, _, callback) => { + iteratee(value, (err, result) => { + if (err || err === false) return callback(err); + + if (check(result) && !testResult) { + testPassed = true; + testResult = getResult(true, value); + return callback(null, breakLoop); + } + callback(); + }); + }, err => { + if (err) return cb(err); + cb(null, testPassed ? testResult : getResult(false)); + }); + }; + } + + /** + * Returns the first value in `coll` that passes an async truth test. The + * `iteratee` is applied in parallel, meaning the first iteratee to return + * `true` will fire the detect `callback` with that result. That means the + * result might not be the first item in the original `coll` (in terms of order) + * that passes the test. + + * If order within the original `coll` is important, then look at + * [`detectSeries`]{@link module:Collections.detectSeries}. + * + * @name detect + * @static + * @memberOf module:Collections + * @method + * @alias find + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * } + *); + * + * // Using Promises + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists) + * .then(result => { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists); + * console.log(result); + * // dir1/file1.txt + * // result now equals the file in the list that exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function detect(coll, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback) + } + var detect$1 = awaitify(detect, 3); + + /** + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a + * time. + * + * @name detectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findLimit + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ + function detectLimit(coll, limit, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback) + } + var detectLimit$1 = awaitify(detectLimit, 4); + + /** + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. + * + * @name detectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findSeries + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ + function detectSeries(coll, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback) + } + + var detectSeries$1 = awaitify(detectSeries, 3); + + function consoleFunc(name) { + return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => { + /* istanbul ignore else */ + if (typeof console === 'object') { + /* istanbul ignore else */ + if (err) { + /* istanbul ignore else */ + if (console.error) { + console.error(err); + } + } else if (console[name]) { /* istanbul ignore else */ + resultArgs.forEach(x => console[name](x)); + } + } + }) + } + + /** + * Logs the result of an [`async` function]{@link AsyncFunction} to the + * `console` using `console.dir` to display the properties of the resulting object. + * Only works in Node.js or in browsers that support `console.dir` and + * `console.error` (such as FF and Chrome). + * If multiple arguments are returned from the async function, + * `console.dir` is called on each argument in order. + * + * @name dir + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, {hello: name}); + * }, 1000); + * }; + * + * // in the node repl + * node> async.dir(hello, 'world'); + * {hello: 'world'} + */ + var dir = consoleFunc('dir'); + + /** + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in + * the order of operations, the arguments `test` and `iteratee` are switched. + * + * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + * + * @name doWhilst + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - A function which is called each time `test` + * passes. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. + * `callback` will be passed an error and any arguments passed to the final + * `iteratee`'s callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ + function doWhilst(iteratee, test, callback) { + callback = onlyOnce(callback); + var _fn = wrapAsync(iteratee); + var _test = wrapAsync(test); + var results; + + function next(err, ...args) { + if (err) return callback(err); + if (err === false) return; + results = args; + _test(...args, check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return check(null, true); + } + + var doWhilst$1 = awaitify(doWhilst, 3); + + /** + * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the + * argument ordering differs from `until`. + * + * @name doUntil + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee` + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ + function doUntil(iteratee, test, callback) { + const _test = wrapAsync(test); + return doWhilst$1(iteratee, (...args) => { + const cb = args.pop(); + _test(...args, (err, truth) => cb (err, !truth)); + }, callback); + } + + function _withoutIndex(iteratee) { + return (value, index, callback) => iteratee(value, callback); + } + + /** + * Applies the function `iteratee` to each item in `coll`, in parallel. + * The `iteratee` is called with an item from the list, and a callback for when + * it has finished. If the `iteratee` passes an error to its `callback`, the + * main `callback` (for the `each` function) is immediately called with the + * error. + * + * Note, that since this function applies `iteratee` to each item in parallel, + * there is no guarantee that the iteratee functions will complete in order. + * + * @name each + * @static + * @memberOf module:Collections + * @method + * @alias forEach + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to + * each item in `coll`. Invoked with (item, callback). + * The array index is not passed to the iteratee. + * If you need the index, use `eachOf`. + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt']; + * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt']; + * + * // asynchronous function that deletes a file + * const deleteFile = function(file, callback) { + * fs.unlink(file, callback); + * }; + * + * // Using callbacks + * async.each(fileList, deleteFile, function(err) { + * if( err ) { + * console.log(err); + * } else { + * console.log('All files have been deleted successfully'); + * } + * }); + * + * // Error Handling + * async.each(withMissingFileList, deleteFile, function(err){ + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using Promises + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using async/await + * async () => { + * try { + * await async.each(files, deleteFile); + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * await async.each(withMissingFileList, deleteFile); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * } + * } + * + */ + function eachLimit(coll, iteratee, callback) { + return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback); + } + + var each = awaitify(eachLimit, 3); + + /** + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. + * + * @name eachLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfLimit`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ + function eachLimit$1(coll, limit, iteratee, callback) { + return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback); + } + var eachLimit$2 = awaitify(eachLimit$1, 4); + + /** + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. + * + * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item + * in series and therefore the iteratee functions will complete in order. + + * @name eachSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfSeries`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ + function eachSeries(coll, iteratee, callback) { + return eachLimit$2(coll, 1, iteratee, callback) + } + var eachSeries$1 = awaitify(eachSeries, 3); + + /** + * Wrap an async function and ensure it calls its callback on a later tick of + * the event loop. If the function already calls its callback on a next tick, + * no extra deferral is added. This is useful for preventing stack overflows + * (`RangeError: Maximum call stack size exceeded`) and generally keeping + * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) + * contained. ES2017 `async` functions are returned as-is -- they are immune + * to Zalgo's corrupting influences, as they always resolve on a later tick. + * + * @name ensureAsync + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - an async function, one that expects a node-style + * callback as its last argument. + * @returns {AsyncFunction} Returns a wrapped function with the exact same call + * signature as the function passed in. + * @example + * + * function sometimesAsync(arg, callback) { + * if (cache[arg]) { + * return callback(null, cache[arg]); // this would be synchronous!! + * } else { + * doSomeIO(arg, callback); // this IO would be asynchronous + * } + * } + * + * // this has a risk of stack overflows if many results are cached in a row + * async.mapSeries(args, sometimesAsync, done); + * + * // this will defer sometimesAsync's callback if necessary, + * // preventing stack overflows + * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + */ + function ensureAsync(fn) { + if (isAsync(fn)) return fn; + return function (...args/*, callback*/) { + var callback = args.pop(); + var sync = true; + args.push((...innerArgs) => { + if (sync) { + setImmediate$1(() => callback(...innerArgs)); + } else { + callback(...innerArgs); + } + }); + fn.apply(this, args); + sync = false; + }; + } + + /** + * Returns `true` if every element in `coll` satisfies an async test. If any + * iteratee call returns `false`, the main `callback` is immediately called. + * + * @name every + * @static + * @memberOf module:Collections + * @method + * @alias all + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.every(fileList, fileExists, function(err, result) { + * console.log(result); + * // true + * // result is true since every file exists + * }); + * + * async.every(withMissingFileList, fileExists, function(err, result) { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }); + * + * // Using Promises + * async.every(fileList, fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.every(withMissingFileList, fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.every(fileList, fileExists); + * console.log(result); + * // true + * // result is true since every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.every(withMissingFileList, fileExists); + * console.log(result); + * // false + * // result is false since NOT every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function every(coll, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback) + } + var every$1 = awaitify(every, 3); + + /** + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. + * + * @name everyLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ + function everyLimit(coll, limit, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback) + } + var everyLimit$1 = awaitify(everyLimit, 4); + + /** + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. + * + * @name everySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in series. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ + function everySeries(coll, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback) + } + var everySeries$1 = awaitify(everySeries, 3); + + function filterArray(eachfn, arr, iteratee, callback) { + var truthValues = new Array(arr.length); + eachfn(arr, (x, index, iterCb) => { + iteratee(x, (err, v) => { + truthValues[index] = !!v; + iterCb(err); + }); + }, err => { + if (err) return callback(err); + var results = []; + for (var i = 0; i < arr.length; i++) { + if (truthValues[i]) results.push(arr[i]); + } + callback(null, results); + }); + } + + function filterGeneric(eachfn, coll, iteratee, callback) { + var results = []; + eachfn(coll, (x, index, iterCb) => { + iteratee(x, (err, v) => { + if (err) return iterCb(err); + if (v) { + results.push({index, value: x}); + } + iterCb(err); + }); + }, err => { + if (err) return callback(err); + callback(null, results + .sort((a, b) => a.index - b.index) + .map(v => v.value)); + }); + } + + function _filter(eachfn, coll, iteratee, callback) { + var filter = isArrayLike(coll) ? filterArray : filterGeneric; + return filter(eachfn, coll, wrapAsync(iteratee), callback); + } + + /** + * Returns a new array of all the values in `coll` which pass an async truth + * test. This operation is performed in parallel, but the results array will be + * in the same order as the original. + * + * @name filter + * @static + * @memberOf module:Collections + * @method + * @alias select + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.filter(files, fileExists, function(err, results) { + * if(err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * }); + * + * // Using Promises + * async.filter(files, fileExists) + * .then(results => { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.filter(files, fileExists); + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function filter (coll, iteratee, callback) { + return _filter(eachOf$1, coll, iteratee, callback) + } + var filter$1 = awaitify(filter, 3); + + /** + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a + * time. + * + * @name filterLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + */ + function filterLimit (coll, limit, iteratee, callback) { + return _filter(eachOfLimit(limit), coll, iteratee, callback) + } + var filterLimit$1 = awaitify(filterLimit, 4); + + /** + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. + * + * @name filterSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results) + * @returns {Promise} a promise, if no callback provided + */ + function filterSeries (coll, iteratee, callback) { + return _filter(eachOfSeries$1, coll, iteratee, callback) + } + var filterSeries$1 = awaitify(filterSeries, 3); + + /** + * Calls the asynchronous function `fn` with a callback parameter that allows it + * to call itself again, in series, indefinitely. + + * If an error is passed to the callback then `errback` is called with the + * error, and execution stops, otherwise it will never be called. + * + * @name forever + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} fn - an async function to call repeatedly. + * Invoked with (next). + * @param {Function} [errback] - when `fn` passes an error to it's callback, + * this function will be called, and execution stops. Invoked with (err). + * @returns {Promise} a promise that rejects if an error occurs and an errback + * is not passed + * @example + * + * async.forever( + * function(next) { + * // next is suitable for passing to things that need a callback(err [, whatever]); + * // it will result in this function being called again. + * }, + * function(err) { + * // if next is called with a value in its first parameter, it will appear + * // in here as 'err', and execution will stop. + * } + * ); + */ + function forever(fn, errback) { + var done = onlyOnce(errback); + var task = wrapAsync(ensureAsync(fn)); + + function next(err) { + if (err) return done(err); + if (err === false) return; + task(next); + } + return next(); + } + var forever$1 = awaitify(forever, 2); + + /** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. + * + * @name groupByLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ + function groupByLimit(coll, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(coll, limit, (val, iterCb) => { + _iteratee(val, (err, key) => { + if (err) return iterCb(err); + return iterCb(err, {key, val}); + }); + }, (err, mapResults) => { + var result = {}; + // from MDN, handle object having an `hasOwnProperty` prop + var {hasOwnProperty} = Object.prototype; + + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + var {key} = mapResults[i]; + var {val} = mapResults[i]; + + if (hasOwnProperty.call(result, key)) { + result[key].push(val); + } else { + result[key] = [val]; + } + } + } + + return callback(err, result); + }); + } + + var groupByLimit$1 = awaitify(groupByLimit, 4); + + /** + * Returns a new object, where each value corresponds to an array of items, from + * `coll`, that returned the corresponding key. That is, the keys of the object + * correspond to the values passed to the `iteratee` callback. + * + * Note: Since this function applies the `iteratee` to each item in parallel, + * there is no guarantee that the `iteratee` functions will complete in order. + * However, the values for each key in the `result` will be in the same order as + * the original `coll`. For Objects, the values will roughly be in the order of + * the original Objects' keys (but this can vary across JavaScript engines). + * + * @name groupBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const files = ['dir1/file1.txt','dir2','dir4'] + * + * // asynchronous function that detects file type as none, file, or directory + * function detectFile(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(null, 'none'); + * } + * callback(null, stat.isDirectory() ? 'directory' : 'file'); + * }); + * } + * + * //Using callbacks + * async.groupBy(files, detectFile, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * }); + * + * // Using Promises + * async.groupBy(files, detectFile) + * .then( result => { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.groupBy(files, detectFile); + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function groupBy (coll, iteratee, callback) { + return groupByLimit$1(coll, Infinity, iteratee, callback) + } + + /** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. + * + * @name groupBySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whose + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ + function groupBySeries (coll, iteratee, callback) { + return groupByLimit$1(coll, 1, iteratee, callback) + } + + /** + * Logs the result of an `async` function to the `console`. Only works in + * Node.js or in browsers that support `console.log` and `console.error` (such + * as FF and Chrome). If multiple arguments are returned from the async + * function, `console.log` is called on each argument in order. + * + * @name log + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, 'hello ' + name); + * }, 1000); + * }; + * + * // in the node repl + * node> async.log(hello, 'world'); + * 'hello world' + */ + var log = consoleFunc('log'); + + /** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a + * time. + * + * @name mapValuesLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ + function mapValuesLimit(obj, limit, iteratee, callback) { + callback = once(callback); + var newObj = {}; + var _iteratee = wrapAsync(iteratee); + return eachOfLimit(limit)(obj, (val, key, next) => { + _iteratee(val, key, (err, result) => { + if (err) return next(err); + newObj[key] = result; + next(err); + }); + }, err => callback(err, newObj)); + } + + var mapValuesLimit$1 = awaitify(mapValuesLimit, 4); + + /** + * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. + * + * Produces a new Object by mapping each value of `obj` through the `iteratee` + * function. The `iteratee` is called each `value` and `key` from `obj` and a + * callback for when it has finished processing. Each of these callbacks takes + * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` + * passes an error to its callback, the main `callback` (for the `mapValues` + * function) is immediately called with the error. + * + * Note, the order of the keys in the result is not guaranteed. The keys will + * be roughly in the order they complete, (but this is very engine-specific) + * + * @name mapValues + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file3.txt' + * }; + * + * const withMissingFileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file4.txt' + * }; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, key, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * }); + * + * // Error handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.mapValues(fileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * }).catch (err => { + * console.log(err); + * }); + * + * // Error Handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch (err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.mapValues(fileMap, getFileSizeInBytes); + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ + function mapValues(obj, iteratee, callback) { + return mapValuesLimit$1(obj, Infinity, iteratee, callback) + } + + /** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. + * + * @name mapValuesSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ + function mapValuesSeries(obj, iteratee, callback) { + return mapValuesLimit$1(obj, 1, iteratee, callback) + } + + /** + * Caches the results of an async function. When creating a hash to store + * function results against, the callback is omitted from the hash and an + * optional hash function can be used. + * + * **Note: if the async function errs, the result will not be cached and + * subsequent calls will call the wrapped function.** + * + * If no hash function is specified, the first argument is used as a hash key, + * which may work reasonably if it is a string or a data type that converts to a + * distinct string. Note that objects and arrays will not behave reasonably. + * Neither will cases where the other arguments are significant. In such cases, + * specify your own hash function. + * + * The cache of results is exposed as the `memo` property of the function + * returned by `memoize`. + * + * @name memoize + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function to proxy and cache results from. + * @param {Function} hasher - An optional function for generating a custom hash + * for storing results. It has all the arguments applied to it apart from the + * callback, and must be synchronous. + * @returns {AsyncFunction} a memoized version of `fn` + * @example + * + * var slow_fn = function(name, callback) { + * // do something + * callback(null, result); + * }; + * var fn = async.memoize(slow_fn); + * + * // fn can now be used as if it were slow_fn + * fn('some name', function() { + * // callback + * }); + */ + function memoize(fn, hasher = v => v) { + var memo = Object.create(null); + var queues = Object.create(null); + var _fn = wrapAsync(fn); + var memoized = initialParams((args, callback) => { + var key = hasher(...args); + if (key in memo) { + setImmediate$1(() => callback(null, ...memo[key])); + } else if (key in queues) { + queues[key].push(callback); + } else { + queues[key] = [callback]; + _fn(...args, (err, ...resultArgs) => { + // #1465 don't memoize if an error occurred + if (!err) { + memo[key] = resultArgs; + } + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i](err, ...resultArgs); + } + }); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + } + + /* istanbul ignore file */ + + /** + * Calls `callback` on a later loop around the event loop. In Node.js this just + * calls `process.nextTick`. In the browser it will use `setImmediate` if + * available, otherwise `setTimeout(callback, 0)`, which means other higher + * priority events may precede the execution of `callback`. + * + * This is used internally for browser-compatibility purposes. + * + * @name nextTick + * @static + * @memberOf module:Utils + * @method + * @see [async.setImmediate]{@link module:Utils.setImmediate} + * @category Util + * @param {Function} callback - The function to call on a later loop around + * the event loop. Invoked with (args...). + * @param {...*} args... - any number of additional arguments to pass to the + * callback on the next tick. + * @example + * + * var call_order = []; + * async.nextTick(function() { + * call_order.push('two'); + * // call_order now equals ['one','two'] + * }); + * call_order.push('one'); + * + * async.setImmediate(function (a, b, c) { + * // a, b, and c equal 1, 2, and 3 + * }, 1, 2, 3); + */ + var _defer$1; + + if (hasNextTick) { + _defer$1 = process.nextTick; + } else if (hasSetImmediate) { + _defer$1 = setImmediate; + } else { + _defer$1 = fallback; + } + + var nextTick = wrap(_defer$1); + + var _parallel = awaitify((eachfn, tasks, callback) => { + var results = isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, (task, key, taskCb) => { + wrapAsync(task)((err, ...result) => { + if (result.length < 2) { + [result] = result; + } + results[key] = result; + taskCb(err); + }); + }, err => callback(err, results)); + }, 3); + + /** + * Run the `tasks` collection of functions in parallel, without waiting until + * the previous function has completed. If any of the functions pass an error to + * its callback, the main `callback` is immediately called with the value of the + * error. Once the `tasks` have completed, the results are passed to the final + * `callback` as an array. + * + * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about + * parallel execution of code. If your tasks do not use any timers or perform + * any I/O, they will actually be executed in series. Any synchronous setup + * sections for each task will happen one after the other. JavaScript remains + * single-threaded. + * + * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the + * execution of other tasks when a task fails. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.parallel}. + * + * @name parallel + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * + * //Using Callbacks + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function parallel(tasks, callback) { + return _parallel(eachOf$1, tasks, callback); + } + + /** + * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a + * time. + * + * @name parallelLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.parallel]{@link module:ControlFlow.parallel} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + */ + function parallelLimit(tasks, limit, callback) { + return _parallel(eachOfLimit(limit), tasks, callback); + } + + /** + * A queue of tasks for the worker function to complete. + * @typedef {Iterable} QueueObject + * @memberOf module:ControlFlow + * @property {Function} length - a function returning the number of items + * waiting to be processed. Invoke with `queue.length()`. + * @property {boolean} started - a boolean indicating whether or not any + * items have been pushed and processed by the queue. + * @property {Function} running - a function returning the number of items + * currently being processed. Invoke with `queue.running()`. + * @property {Function} workersList - a function returning the array of items + * currently being processed. Invoke with `queue.workersList()`. + * @property {Function} idle - a function returning false if there are items + * waiting or being processed, or true if not. Invoke with `queue.idle()`. + * @property {number} concurrency - an integer for determining how many `worker` + * functions should be run in parallel. This property can be changed after a + * `queue` is created to alter the concurrency on-the-fly. + * @property {number} payload - an integer that specifies how many items are + * passed to the worker function at a time. only applies if this is a + * [cargo]{@link module:ControlFlow.cargo} object + * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback` + * once the `worker` has finished processing the task. Instead of a single task, + * a `tasks` array can be submitted. The respective callback is used for every + * task in the list. Invoke with `queue.push(task, [callback])`, + * @property {AsyncFunction} unshift - add a new task to the front of the `queue`. + * Invoke with `queue.unshift(task, [callback])`. + * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns + * a promise that rejects if an error occurs. + * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns + * a promise that rejects if an error occurs. + * @property {Function} remove - remove items from the queue that match a test + * function. The test function will be passed an object with a `data` property, + * and a `priority` property, if this is a + * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. + * Invoked with `queue.remove(testFn)`, where `testFn` is of the form + * `function ({data, priority}) {}` and returns a Boolean. + * @property {Function} saturated - a function that sets a callback that is + * called when the number of running workers hits the `concurrency` limit, and + * further tasks will be queued. If the callback is omitted, `q.saturated()` + * returns a promise for the next occurrence. + * @property {Function} unsaturated - a function that sets a callback that is + * called when the number of running workers is less than the `concurrency` & + * `buffer` limits, and further tasks will not be queued. If the callback is + * omitted, `q.unsaturated()` returns a promise for the next occurrence. + * @property {number} buffer - A minimum threshold buffer in order to say that + * the `queue` is `unsaturated`. + * @property {Function} empty - a function that sets a callback that is called + * when the last item from the `queue` is given to a `worker`. If the callback + * is omitted, `q.empty()` returns a promise for the next occurrence. + * @property {Function} drain - a function that sets a callback that is called + * when the last item from the `queue` has returned from the `worker`. If the + * callback is omitted, `q.drain()` returns a promise for the next occurrence. + * @property {Function} error - a function that sets a callback that is called + * when a task errors. Has the signature `function(error, task)`. If the + * callback is omitted, `error()` returns a promise that rejects on the next + * error. + * @property {boolean} paused - a boolean for determining whether the queue is + * in a paused state. + * @property {Function} pause - a function that pauses the processing of tasks + * until `resume()` is called. Invoke with `queue.pause()`. + * @property {Function} resume - a function that resumes the processing of + * queued tasks when the queue is paused. Invoke with `queue.resume()`. + * @property {Function} kill - a function that removes the `drain` callback and + * empties remaining tasks from the queue forcing it to go idle. No more tasks + * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. + * + * @example + * const q = async.queue(worker, 2) + * q.push(item1) + * q.push(item2) + * q.push(item3) + * // queues are iterable, spread into an array to inspect + * const items = [...q] // [item1, item2, item3] + * // or use for of + * for (let item of q) { + * console.log(item) + * } + * + * q.drain(() => { + * console.log('all done') + * }) + * // or + * await q.drain() + */ + + /** + * Creates a `queue` object with the specified `concurrency`. Tasks added to the + * `queue` are processed in parallel (up to the `concurrency` limit). If all + * `worker`s are in progress, the task is queued until one becomes available. + * Once a `worker` completes a `task`, that `task`'s callback is called. + * + * @name queue + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. Invoked with (task, callback). + * @param {number} [concurrency=1] - An `integer` for determining how many + * `worker` functions should be run in parallel. If omitted, the concurrency + * defaults to `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be + * attached as certain properties to listen for specific events during the + * lifecycle of the queue. + * @example + * + * // create a queue object with concurrency 2 + * var q = async.queue(function(task, callback) { + * console.log('hello ' + task.name); + * callback(); + * }, 2); + * + * // assign a callback + * q.drain(function() { + * console.log('all items have been processed'); + * }); + * // or await the end + * await q.drain() + * + * // assign an error callback + * q.error(function(err, task) { + * console.error('task experienced an error'); + * }); + * + * // add some items to the queue + * q.push({name: 'foo'}, function(err) { + * console.log('finished processing foo'); + * }); + * // callback is optional + * q.push({name: 'bar'}); + * + * // add some items to the queue (batch-wise) + * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { + * console.log('finished processing item'); + * }); + * + * // add some items to the front of the queue + * q.unshift({name: 'bar'}, function (err) { + * console.log('finished processing bar'); + * }); + */ + function queue$1 (worker, concurrency) { + var _worker = wrapAsync(worker); + return queue((items, cb) => { + _worker(items[0], cb); + }, concurrency, 1); + } + + // Binary min-heap implementation used for priority queue. + // Implementation is stable, i.e. push time is considered for equal priorities + class Heap { + constructor() { + this.heap = []; + this.pushCount = Number.MIN_SAFE_INTEGER; + } + + get length() { + return this.heap.length; + } + + empty () { + this.heap = []; + return this; + } + + percUp(index) { + let p; + + while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) { + let t = this.heap[index]; + this.heap[index] = this.heap[p]; + this.heap[p] = t; + + index = p; + } + } + + percDown(index) { + let l; + + while ((l=leftChi(index)) < this.heap.length) { + if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) { + l = l+1; + } + + if (smaller(this.heap[index], this.heap[l])) { + break; + } + + let t = this.heap[index]; + this.heap[index] = this.heap[l]; + this.heap[l] = t; + + index = l; + } + } + + push(node) { + node.pushCount = ++this.pushCount; + this.heap.push(node); + this.percUp(this.heap.length-1); + } + + unshift(node) { + return this.heap.push(node); + } + + shift() { + let [top] = this.heap; + + this.heap[0] = this.heap[this.heap.length-1]; + this.heap.pop(); + this.percDown(0); + + return top; + } + + toArray() { + return [...this]; + } + + *[Symbol.iterator] () { + for (let i = 0; i < this.heap.length; i++) { + yield this.heap[i].data; + } + } + + remove (testFn) { + let j = 0; + for (let i = 0; i < this.heap.length; i++) { + if (!testFn(this.heap[i])) { + this.heap[j] = this.heap[i]; + j++; + } + } + + this.heap.splice(j); + + for (let i = parent(this.heap.length-1); i >= 0; i--) { + this.percDown(i); + } + + return this; + } + } + + function leftChi(i) { + return (i<<1)+1; + } + + function parent(i) { + return ((i+1)>>1)-1; + } + + function smaller(x, y) { + if (x.priority !== y.priority) { + return x.priority < y.priority; + } + else { + return x.pushCount < y.pushCount; + } + } + + /** + * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and + * completed in ascending priority order. + * + * @name priorityQueue + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. + * Invoked with (task, callback). + * @param {number} concurrency - An `integer` for determining how many `worker` + * functions should be run in parallel. If omitted, the concurrency defaults to + * `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two + * differences between `queue` and `priorityQueue` objects: + * * `push(task, priority, [callback])` - `priority` should be a number. If an + * array of `tasks` is given, all tasks will be assigned the same priority. + * * The `unshift` method was removed. + */ + function priorityQueue(worker, concurrency) { + // Start with a normal queue + var q = queue$1(worker, concurrency); + var processingScheduled = false; + + q._tasks = new Heap(); + + // Override push to accept second parameter representing priority + q.push = function(data, priority = 0, callback = () => {}) { + if (typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + if (!Array.isArray(data)) { + data = [data]; + } + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return setImmediate$1(() => q.drain()); + } + + for (var i = 0, l = data.length; i < l; i++) { + var item = { + data: data[i], + priority, + callback + }; + + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + setImmediate$1(() => { + processingScheduled = false; + q.process(); + }); + } + }; + + // Remove unshift function + delete q.unshift; + + return q; + } + + /** + * Runs the `tasks` array of functions in parallel, without waiting until the + * previous function has completed. Once any of the `tasks` complete or pass an + * error to its callback, the main `callback` is immediately called. It's + * equivalent to `Promise.race()`. + * + * @name race + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} + * to run. Each function can complete with an optional `result` value. + * @param {Function} callback - A callback to run once any of the functions have + * completed. This function gets an error or result from the first function that + * completed. Invoked with (err, result). + * @returns undefined + * @example + * + * async.race([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], + * // main callback + * function(err, result) { + * // the result will be equal to 'two' as it finishes earlier + * }); + */ + function race(tasks, callback) { + callback = once(callback); + if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); + if (!tasks.length) return callback(); + for (var i = 0, l = tasks.length; i < l; i++) { + wrapAsync(tasks[i])(callback); + } + } + + var race$1 = awaitify(race, 2); + + /** + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. + * + * @name reduceRight + * @static + * @memberOf module:Collections + * @method + * @see [async.reduce]{@link module:Collections.reduce} + * @alias foldr + * @category Collection + * @param {Array} array - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + */ + function reduceRight (array, memo, iteratee, callback) { + var reversed = [...array].reverse(); + return reduce$1(reversed, memo, iteratee, callback); + } + + /** + * Wraps the async function in another function that always completes with a + * result object, even when it errors. + * + * The result object has either the property `error` or `value`. + * + * @name reflect + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function you want to wrap + * @returns {Function} - A function that always passes null to it's callback as + * the error. The second argument to the callback will be an `object` with + * either an `error` or a `value` property. + * @example + * + * async.parallel([ + * async.reflect(function(callback) { + * // do some stuff ... + * callback(null, 'one'); + * }), + * async.reflect(function(callback) { + * // do some more stuff but error ... + * callback('bad stuff happened'); + * }), + * async.reflect(function(callback) { + * // do some more stuff ... + * callback(null, 'two'); + * }) + * ], + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = 'bad stuff happened' + * // results[2].value = 'two' + * }); + */ + function reflect(fn) { + var _fn = wrapAsync(fn); + return initialParams(function reflectOn(args, reflectCallback) { + args.push((error, ...cbArgs) => { + let retVal = {}; + if (error) { + retVal.error = error; + } + if (cbArgs.length > 0){ + var value = cbArgs; + if (cbArgs.length <= 1) { + [value] = cbArgs; + } + retVal.value = value; + } + reflectCallback(null, retVal); + }); + + return _fn.apply(this, args); + }); + } + + /** + * A helper function that wraps an array or an object of functions with `reflect`. + * + * @name reflectAll + * @static + * @memberOf module:Utils + * @method + * @see [async.reflect]{@link module:Utils.reflect} + * @category Util + * @param {Array|Object|Iterable} tasks - The collection of + * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. + * @returns {Array} Returns an array of async functions, each wrapped in + * `async.reflect` + * @example + * + * let tasks = [ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * // do some more stuff but error ... + * callback(new Error('bad stuff happened')); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = Error('bad stuff happened') + * // results[2].value = 'two' + * }); + * + * // an example using an object instead of an array + * let tasks = { + * one: function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * two: function(callback) { + * callback('two'); + * }, + * three: function(callback) { + * setTimeout(function() { + * callback(null, 'three'); + * }, 100); + * } + * }; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results.one.value = 'one' + * // results.two.error = 'two' + * // results.three.value = 'three' + * }); + */ + function reflectAll(tasks) { + var results; + if (Array.isArray(tasks)) { + results = tasks.map(reflect); + } else { + results = {}; + Object.keys(tasks).forEach(key => { + results[key] = reflect.call(this, tasks[key]); + }); + } + return results; + } + + function reject(eachfn, arr, _iteratee, callback) { + const iteratee = wrapAsync(_iteratee); + return _filter(eachfn, arr, (value, cb) => { + iteratee(value, (err, v) => { + cb(err, !v); + }); + }, callback); + } + + /** + * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. + * + * @name reject + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.reject(fileList, fileExists, function(err, results) { + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }); + * + * // Using Promises + * async.reject(fileList, fileExists) + * .then( results => { + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.reject(fileList, fileExists); + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function reject$1 (coll, iteratee, callback) { + return reject(eachOf$1, coll, iteratee, callback) + } + var reject$2 = awaitify(reject$1, 3); + + /** + * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a + * time. + * + * @name rejectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ + function rejectLimit (coll, limit, iteratee, callback) { + return reject(eachOfLimit(limit), coll, iteratee, callback) + } + var rejectLimit$1 = awaitify(rejectLimit, 4); + + /** + * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. + * + * @name rejectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ + function rejectSeries (coll, iteratee, callback) { + return reject(eachOfSeries$1, coll, iteratee, callback) + } + var rejectSeries$1 = awaitify(rejectSeries, 3); + + function constant$1(value) { + return function () { + return value; + } + } + + /** + * Attempts to get a successful response from `task` no more than `times` times + * before returning an error. If the task is successful, the `callback` will be + * passed the result of the successful task. If all attempts fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name retry + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @see [async.retryable]{@link module:ControlFlow.retryable} + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an + * object with `times` and `interval` or a number. + * * `times` - The number of attempts to make before giving up. The default + * is `5`. + * * `interval` - The time to wait between retries, in milliseconds. The + * default is `0`. The interval may also be specified as a function of the + * retry count (see example). + * * `errorFilter` - An optional synchronous function that is invoked on + * erroneous result. If it returns `true` the retry attempts will continue; + * if the function returns `false` the retry flow is aborted with the current + * attempt's error and result being returned to the final callback. + * Invoked with (err). + * * If `opts` is a number, the number specifies the number of times to retry, + * with the default interval of `0`. + * @param {AsyncFunction} task - An async function to retry. + * Invoked with (callback). + * @param {Function} [callback] - An optional callback which is called when the + * task has succeeded, or after the final failed attempt. It receives the `err` + * and `result` arguments of the last attempt at completing the `task`. Invoked + * with (err, results). + * @returns {Promise} a promise if no callback provided + * + * @example + * + * // The `retry` function can be used as a stand-alone control flow by passing + * // a callback, as shown below: + * + * // try calling apiMethod 3 times + * async.retry(3, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 3 times, waiting 200 ms between each retry + * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 10 times with exponential backoff + * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) + * async.retry({ + * times: 10, + * interval: function(retryCount) { + * return 50 * Math.pow(2, retryCount); + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod the default 5 times no delay between each retry + * async.retry(apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod only when error condition satisfies, all other + * // errors will abort the retry control flow and return to final callback + * async.retry({ + * errorFilter: function(err) { + * return err.message === 'Temporary error'; // only retry on a specific error + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // to retry individual methods that are not as reliable within other + * // control flow functions, use the `retryable` wrapper: + * async.auto({ + * users: api.getUsers.bind(api), + * payments: async.retryable(3, api.getPayments.bind(api)) + * }, function(err, results) { + * // do something with the results + * }); + * + */ + const DEFAULT_TIMES = 5; + const DEFAULT_INTERVAL = 0; + + function retry(opts, task, callback) { + var options = { + times: DEFAULT_TIMES, + intervalFunc: constant$1(DEFAULT_INTERVAL) + }; + + if (arguments.length < 3 && typeof opts === 'function') { + callback = task || promiseCallback(); + task = opts; + } else { + parseTimes(options, opts); + callback = callback || promiseCallback(); + } + + if (typeof task !== 'function') { + throw new Error("Invalid arguments for async.retry"); + } + + var _task = wrapAsync(task); + + var attempt = 1; + function retryAttempt() { + _task((err, ...args) => { + if (err === false) return + if (err && attempt++ < options.times && + (typeof options.errorFilter != 'function' || + options.errorFilter(err))) { + setTimeout(retryAttempt, options.intervalFunc(attempt - 1)); + } else { + callback(err, ...args); + } + }); + } + + retryAttempt(); + return callback[PROMISE_SYMBOL] + } + + function parseTimes(acc, t) { + if (typeof t === 'object') { + acc.times = +t.times || DEFAULT_TIMES; + + acc.intervalFunc = typeof t.interval === 'function' ? + t.interval : + constant$1(+t.interval || DEFAULT_INTERVAL); + + acc.errorFilter = t.errorFilter; + } else if (typeof t === 'number' || typeof t === 'string') { + acc.times = +t || DEFAULT_TIMES; + } else { + throw new Error("Invalid arguments for async.retry"); + } + } + + /** + * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method + * wraps a task and makes it retryable, rather than immediately calling it + * with retries. + * + * @name retryable + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.retry]{@link module:ControlFlow.retry} + * @category Control Flow + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional + * options, exactly the same as from `retry`, except for a `opts.arity` that + * is the arity of the `task` function, defaulting to `task.length` + * @param {AsyncFunction} task - the asynchronous function to wrap. + * This function will be passed any arguments passed to the returned wrapper. + * Invoked with (...args, callback). + * @returns {AsyncFunction} The wrapped function, which when invoked, will + * retry on an error, based on the parameters specified in `opts`. + * This function will accept the same parameters as `task`. + * @example + * + * async.auto({ + * dep1: async.retryable(3, getFromFlakyService), + * process: ["dep1", async.retryable(3, function (results, cb) { + * maybeProcessData(results.dep1, cb); + * })] + * }, callback); + */ + function retryable (opts, task) { + if (!task) { + task = opts; + opts = null; + } + let arity = (opts && opts.arity) || task.length; + if (isAsync(task)) { + arity += 1; + } + var _task = wrapAsync(task); + return initialParams((args, callback) => { + if (args.length < arity - 1 || callback == null) { + args.push(callback); + callback = promiseCallback(); + } + function taskFn(cb) { + _task(...args, cb); + } + + if (opts) retry(opts, taskFn, callback); + else retry(taskFn, callback); + + return callback[PROMISE_SYMBOL] + }); + } + + /** + * Run the functions in the `tasks` collection in series, each one running once + * the previous function has completed. If any functions in the series pass an + * error to its callback, no more functions are run, and `callback` is + * immediately called with the value of the error. Otherwise, `callback` + * receives an array of results when `tasks` have completed. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function, and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.series}. + * + * **Note** that while many implementations preserve the order of object + * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) + * explicitly states that + * + * > The mechanics and order of enumerating the properties is not specified. + * + * So if you rely on the order in which your series of functions are executed, + * and want this to work on all platforms, consider using an array. + * + * @name series + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing + * [async functions]{@link AsyncFunction} to run in series. + * Each function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This function gets a results array (or object) + * containing all the result arguments passed to the `task` callbacks. Invoked + * with (err, result). + * @return {Promise} a promise, if no callback is passed + * @example + * + * //Using Callbacks + * async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] + * }); + * + * // an example using objects instead of arrays + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.series([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function series(tasks, callback) { + return _parallel(eachOfSeries$1, tasks, callback); + } + + /** + * Returns `true` if at least one element in the `coll` satisfies an async test. + * If any iteratee call returns `true`, the main `callback` is immediately + * called. + * + * @name some + * @static + * @memberOf module:Collections + * @method + * @alias any + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + *); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // false + * // result is false since none of the files exists + * } + *); + * + * // Using Promises + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since some file in the list exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since none of the files exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists); + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists); + * console.log(result); + * // false + * // result is false since none of the files exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function some(coll, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback) + } + var some$1 = awaitify(some, 3); + + /** + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. + * + * @name someLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anyLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ + function someLimit(coll, limit, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback) + } + var someLimit$1 = awaitify(someLimit, 4); + + /** + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. + * + * @name someSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anySeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in series. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ + function someSeries(coll, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback) + } + var someSeries$1 = awaitify(someSeries, 3); + + /** + * Sorts a list by the results of running each `coll` value through an async + * `iteratee`. + * + * @name sortBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a value to use as the sort criteria as + * its `result`. + * Invoked with (item, callback). + * @param {Function} callback - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is the items + * from the original `coll` sorted by the values returned by the `iteratee` + * calls. Invoked with (err, results). + * @returns {Promise} a promise, if no callback passed + * @example + * + * // bigfile.txt is a file that is 251100 bytes in size + * // mediumfile.txt is a file that is 11000 bytes in size + * // smallfile.txt is a file that is 121 bytes in size + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // By modifying the callback parameter the + * // sorting order can be influenced: + * + * // ascending order + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) return callback(getFileSizeErr); + * callback(null, fileSize); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // descending order + * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) { + * return callback(getFileSizeErr); + * } + * callback(null, fileSize * -1); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt'] + * } + * } + * ); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * } + * ); + * + * // Using Promises + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * (async () => { + * try { + * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * // Error handling + * async () => { + * try { + * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ + function sortBy (coll, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return map$1(coll, (x, iterCb) => { + _iteratee(x, (err, criteria) => { + if (err) return iterCb(err); + iterCb(err, {value: x, criteria}); + }); + }, (err, results) => { + if (err) return callback(err); + callback(null, results.sort(comparator).map(v => v.value)); + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + } + var sortBy$1 = awaitify(sortBy, 3); + + /** + * Sets a time limit on an asynchronous function. If the function does not call + * its callback within the specified milliseconds, it will be called with a + * timeout error. The code property for the error object will be `'ETIMEDOUT'`. + * + * @name timeout + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} asyncFn - The async function to limit in time. + * @param {number} milliseconds - The specified time limit. + * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) + * to timeout Error for more information.. + * @returns {AsyncFunction} Returns a wrapped function that can be used with any + * of the control flow functions. + * Invoke this function with the same parameters as you would `asyncFunc`. + * @example + * + * function myFunction(foo, callback) { + * doAsyncTask(foo, function(err, data) { + * // handle errors + * if (err) return callback(err); + * + * // do some stuff ... + * + * // return processed data + * return callback(null, data); + * }); + * } + * + * var wrapped = async.timeout(myFunction, 1000); + * + * // call `wrapped` as you would `myFunction` + * wrapped({ bar: 'bar' }, function(err, data) { + * // if `myFunction` takes < 1000 ms to execute, `err` + * // and `data` will have their expected values + * + * // else `err` will be an Error with the code 'ETIMEDOUT' + * }); + */ + function timeout(asyncFn, milliseconds, info) { + var fn = wrapAsync(asyncFn); + + return initialParams((args, callback) => { + var timedOut = false; + var timer; + + function timeoutCallback() { + var name = asyncFn.name || 'anonymous'; + var error = new Error('Callback function "' + name + '" timed out.'); + error.code = 'ETIMEDOUT'; + if (info) { + error.info = info; + } + timedOut = true; + callback(error); + } + + args.push((...cbArgs) => { + if (!timedOut) { + callback(...cbArgs); + clearTimeout(timer); + } + }); + + // setup timer and call original function + timer = setTimeout(timeoutCallback, milliseconds); + fn(...args); + }); + } + + function range(size) { + var result = Array(size); + while (size--) { + result[size] = size; + } + return result; + } + + /** + * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a + * time. + * + * @name timesLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} count - The number of times to run the function. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see [async.map]{@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ + function timesLimit(count, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(range(count), limit, _iteratee, callback); + } + + /** + * Calls the `iteratee` function `n` times, and accumulates results in the same + * manner you would use with [map]{@link module:Collections.map}. + * + * @name times + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.map]{@link module:Collections.map} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + * @example + * + * // Pretend this is some complicated async factory + * var createUser = function(id, callback) { + * callback(null, { + * id: 'user' + id + * }); + * }; + * + * // generate 5 users + * async.times(5, function(n, next) { + * createUser(n, function(err, user) { + * next(err, user); + * }); + * }, function(err, users) { + * // we should now have 5 users + * }); + */ + function times (n, iteratee, callback) { + return timesLimit(n, Infinity, iteratee, callback) + } + + /** + * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. + * + * @name timesSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ + function timesSeries (n, iteratee, callback) { + return timesLimit(n, 1, iteratee, callback) + } + + /** + * A relative of `reduce`. Takes an Object or Array, and iterates over each + * element in parallel, each step potentially mutating an `accumulator` value. + * The type of the accumulator defaults to the type of collection passed in. + * + * @name transform + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} [accumulator] - The initial state of the transform. If omitted, + * it will default to an empty Object or Array, depending on the type of `coll` + * @param {AsyncFunction} iteratee - A function applied to each item in the + * collection that potentially modifies the accumulator. + * Invoked with (accumulator, item, key, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the transformed accumulator. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileList, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * }); + * + * // Using Promises + * async.transform(fileList, transformFileSize) + * .then(result => { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * (async () => { + * try { + * let result = await async.transform(fileList, transformFileSize); + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' }; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileMap, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * }); + * + * // Using Promises + * async.transform(fileMap, transformFileSize) + * .then(result => { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.transform(fileMap, transformFileSize); + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ + function transform (coll, accumulator, iteratee, callback) { + if (arguments.length <= 3 && typeof accumulator === 'function') { + callback = iteratee; + iteratee = accumulator; + accumulator = Array.isArray(coll) ? [] : {}; + } + callback = once(callback || promiseCallback()); + var _iteratee = wrapAsync(iteratee); + + eachOf$1(coll, (v, k, cb) => { + _iteratee(accumulator, v, k, cb); + }, err => callback(err, accumulator)); + return callback[PROMISE_SYMBOL] + } + + /** + * It runs each task in series but stops whenever any of the functions were + * successful. If one of the tasks were successful, the `callback` will be + * passed the result of the successful task. If all tasks fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name tryEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to + * run, each function is passed a `callback(err, result)` it must call on + * completion with an error `err` (which can be `null`) and an optional `result` + * value. + * @param {Function} [callback] - An optional callback which is called when one + * of the tasks has succeeded, or all have failed. It receives the `err` and + * `result` arguments of the last attempt at completing the `task`. Invoked with + * (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * async.tryEach([ + * function getDataFromFirstWebsite(callback) { + * // Try getting the data from the first website + * callback(err, data); + * }, + * function getDataFromSecondWebsite(callback) { + * // First website failed, + * // Try getting the data from the backup website + * callback(err, data); + * } + * ], + * // optional callback + * function(err, results) { + * Now do something with the data. + * }); + * + */ + function tryEach(tasks, callback) { + var error = null; + var result; + return eachSeries$1(tasks, (task, taskCb) => { + wrapAsync(task)((err, ...args) => { + if (err === false) return taskCb(err); + + if (args.length < 2) { + [result] = args; + } else { + result = args; + } + error = err; + taskCb(err ? null : {}); + }); + }, () => callback(error, result)); + } + + var tryEach$1 = awaitify(tryEach); + + /** + * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, + * unmemoized form. Handy for testing. + * + * @name unmemoize + * @static + * @memberOf module:Utils + * @method + * @see [async.memoize]{@link module:Utils.memoize} + * @category Util + * @param {AsyncFunction} fn - the memoized function + * @returns {AsyncFunction} a function that calls the original unmemoized function + */ + function unmemoize(fn) { + return (...args) => { + return (fn.unmemoized || fn)(...args); + }; + } + + /** + * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. + * + * @name whilst + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + * @example + * + * var count = 0; + * async.whilst( + * function test(cb) { cb(null, count < 5); }, + * function iter(callback) { + * count++; + * setTimeout(function() { + * callback(null, count); + * }, 1000); + * }, + * function (err, n) { + * // 5 seconds have passed, n = 5 + * } + * ); + */ + function whilst(test, iteratee, callback) { + callback = onlyOnce(callback); + var _fn = wrapAsync(iteratee); + var _test = wrapAsync(test); + var results = []; + + function next(err, ...rest) { + if (err) return callback(err); + results = rest; + if (err === false) return; + _test(check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return _test(check); + } + var whilst$1 = awaitify(whilst, 3); + + /** + * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. `callback` will be passed an error and any + * arguments passed to the final `iteratee`'s callback. + * + * The inverse of [whilst]{@link module:ControlFlow.whilst}. + * + * @name until + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (callback). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * const results = [] + * let finished = false + * async.until(function test(cb) { + * cb(null, finished) + * }, function iter(next) { + * fetchPage(url, (err, body) => { + * if (err) return next(err) + * results = results.concat(body.objects) + * finished = !!body.next + * next(err) + * }) + * }, function done (err) { + * // all pages have been fetched + * }) + */ + function until(test, iteratee, callback) { + const _test = wrapAsync(test); + return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback); + } + + /** + * Runs the `tasks` array of functions in series, each passing their results to + * the next in the array. However, if any of the `tasks` pass an error to their + * own callback, the next function is not executed, and the main `callback` is + * immediately called with the error. + * + * @name waterfall + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} + * to run. + * Each function should complete with any number of `result` values. + * The `result` values will be passed as arguments, in order, to the next task. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This will be passed the results of the last task's + * callback. Invoked with (err, [results]). + * @returns undefined + * @example + * + * async.waterfall([ + * function(callback) { + * callback(null, 'one', 'two'); + * }, + * function(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * }, + * function(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + * ], function (err, result) { + * // result now equals 'done' + * }); + * + * // Or, with named functions: + * async.waterfall([ + * myFirstFunction, + * mySecondFunction, + * myLastFunction, + * ], function (err, result) { + * // result now equals 'done' + * }); + * function myFirstFunction(callback) { + * callback(null, 'one', 'two'); + * } + * function mySecondFunction(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * } + * function myLastFunction(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + */ + function waterfall (tasks, callback) { + callback = once(callback); + if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); + if (!tasks.length) return callback(); + var taskIndex = 0; + + function nextTask(args) { + var task = wrapAsync(tasks[taskIndex++]); + task(...args, onlyOnce(next)); + } + + function next(err, ...args) { + if (err === false) return + if (err || taskIndex === tasks.length) { + return callback(err, ...args); + } + nextTask(args); + } + + nextTask([]); + } + + var waterfall$1 = awaitify(waterfall); + + /** + * An "async function" in the context of Async is an asynchronous function with + * a variable number of parameters, with the final parameter being a callback. + * (`function (arg1, arg2, ..., callback) {}`) + * The final callback is of the form `callback(err, results...)`, which must be + * called once the function is completed. The callback should be called with a + * Error as its first argument to signal that an error occurred. + * Otherwise, if no error occurred, it should be called with `null` as the first + * argument, and any additional `result` arguments that may apply, to signal + * successful completion. + * The callback must be called exactly once, ideally on a later tick of the + * JavaScript event loop. + * + * This type of function is also referred to as a "Node-style async function", + * or a "continuation passing-style function" (CPS). Most of the methods of this + * library are themselves CPS/Node-style async functions, or functions that + * return CPS/Node-style async functions. + * + * Wherever we accept a Node-style async function, we also directly accept an + * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. + * In this case, the `async` function will not be passed a final callback + * argument, and any thrown error will be used as the `err` argument of the + * implicit callback, and the return value will be used as the `result` value. + * (i.e. a `rejected` of the returned Promise becomes the `err` callback + * argument, and a `resolved` value becomes the `result`.) + * + * Note, due to JavaScript limitations, we can only detect native `async` + * functions and not transpilied implementations. + * Your environment must have `async`/`await` support for this to work. + * (e.g. Node > v7.6, or a recent version of a modern browser). + * If you are using `async` functions through a transpiler (e.g. Babel), you + * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, + * because the `async function` will be compiled to an ordinary function that + * returns a promise. + * + * @typedef {Function} AsyncFunction + * @static + */ + + var index = { + apply, + applyEach: applyEach$1, + applyEachSeries, + asyncify, + auto, + autoInject, + cargo, + cargoQueue: cargo$1, + compose, + concat: concat$1, + concatLimit: concatLimit$1, + concatSeries: concatSeries$1, + constant, + detect: detect$1, + detectLimit: detectLimit$1, + detectSeries: detectSeries$1, + dir, + doUntil, + doWhilst: doWhilst$1, + each, + eachLimit: eachLimit$2, + eachOf: eachOf$1, + eachOfLimit: eachOfLimit$2, + eachOfSeries: eachOfSeries$1, + eachSeries: eachSeries$1, + ensureAsync, + every: every$1, + everyLimit: everyLimit$1, + everySeries: everySeries$1, + filter: filter$1, + filterLimit: filterLimit$1, + filterSeries: filterSeries$1, + forever: forever$1, + groupBy, + groupByLimit: groupByLimit$1, + groupBySeries, + log, + map: map$1, + mapLimit: mapLimit$1, + mapSeries: mapSeries$1, + mapValues, + mapValuesLimit: mapValuesLimit$1, + mapValuesSeries, + memoize, + nextTick, + parallel, + parallelLimit, + priorityQueue, + queue: queue$1, + race: race$1, + reduce: reduce$1, + reduceRight, + reflect, + reflectAll, + reject: reject$2, + rejectLimit: rejectLimit$1, + rejectSeries: rejectSeries$1, + retry, + retryable, + seq, + series, + setImmediate: setImmediate$1, + some: some$1, + someLimit: someLimit$1, + someSeries: someSeries$1, + sortBy: sortBy$1, + timeout, + times, + timesLimit, + timesSeries, + transform, + tryEach: tryEach$1, + unmemoize, + until, + waterfall: waterfall$1, + whilst: whilst$1, + + // aliases + all: every$1, + allLimit: everyLimit$1, + allSeries: everySeries$1, + any: some$1, + anyLimit: someLimit$1, + anySeries: someSeries$1, + find: detect$1, + findLimit: detectLimit$1, + findSeries: detectSeries$1, + flatMap: concat$1, + flatMapLimit: concatLimit$1, + flatMapSeries: concatSeries$1, + forEach: each, + forEachSeries: eachSeries$1, + forEachLimit: eachLimit$2, + forEachOf: eachOf$1, + forEachOfSeries: eachOfSeries$1, + forEachOfLimit: eachOfLimit$2, + inject: reduce$1, + foldl: reduce$1, + foldr: reduceRight, + select: filter$1, + selectLimit: filterLimit$1, + selectSeries: filterSeries$1, + wrapSync: asyncify, + during: whilst$1, + doDuring: doWhilst$1 + }; + + exports.default = index; + exports.apply = apply; + exports.applyEach = applyEach$1; + exports.applyEachSeries = applyEachSeries; + exports.asyncify = asyncify; + exports.auto = auto; + exports.autoInject = autoInject; + exports.cargo = cargo; + exports.cargoQueue = cargo$1; + exports.compose = compose; + exports.concat = concat$1; + exports.concatLimit = concatLimit$1; + exports.concatSeries = concatSeries$1; + exports.constant = constant; + exports.detect = detect$1; + exports.detectLimit = detectLimit$1; + exports.detectSeries = detectSeries$1; + exports.dir = dir; + exports.doUntil = doUntil; + exports.doWhilst = doWhilst$1; + exports.each = each; + exports.eachLimit = eachLimit$2; + exports.eachOf = eachOf$1; + exports.eachOfLimit = eachOfLimit$2; + exports.eachOfSeries = eachOfSeries$1; + exports.eachSeries = eachSeries$1; + exports.ensureAsync = ensureAsync; + exports.every = every$1; + exports.everyLimit = everyLimit$1; + exports.everySeries = everySeries$1; + exports.filter = filter$1; + exports.filterLimit = filterLimit$1; + exports.filterSeries = filterSeries$1; + exports.forever = forever$1; + exports.groupBy = groupBy; + exports.groupByLimit = groupByLimit$1; + exports.groupBySeries = groupBySeries; + exports.log = log; + exports.map = map$1; + exports.mapLimit = mapLimit$1; + exports.mapSeries = mapSeries$1; + exports.mapValues = mapValues; + exports.mapValuesLimit = mapValuesLimit$1; + exports.mapValuesSeries = mapValuesSeries; + exports.memoize = memoize; + exports.nextTick = nextTick; + exports.parallel = parallel; + exports.parallelLimit = parallelLimit; + exports.priorityQueue = priorityQueue; + exports.queue = queue$1; + exports.race = race$1; + exports.reduce = reduce$1; + exports.reduceRight = reduceRight; + exports.reflect = reflect; + exports.reflectAll = reflectAll; + exports.reject = reject$2; + exports.rejectLimit = rejectLimit$1; + exports.rejectSeries = rejectSeries$1; + exports.retry = retry; + exports.retryable = retryable; + exports.seq = seq; + exports.series = series; + exports.setImmediate = setImmediate$1; + exports.some = some$1; + exports.someLimit = someLimit$1; + exports.someSeries = someSeries$1; + exports.sortBy = sortBy$1; + exports.timeout = timeout; + exports.times = times; + exports.timesLimit = timesLimit; + exports.timesSeries = timesSeries; + exports.transform = transform; + exports.tryEach = tryEach$1; + exports.unmemoize = unmemoize; + exports.until = until; + exports.waterfall = waterfall$1; + exports.whilst = whilst$1; + exports.all = every$1; + exports.allLimit = everyLimit$1; + exports.allSeries = everySeries$1; + exports.any = some$1; + exports.anyLimit = someLimit$1; + exports.anySeries = someSeries$1; + exports.find = detect$1; + exports.findLimit = detectLimit$1; + exports.findSeries = detectSeries$1; + exports.flatMap = concat$1; + exports.flatMapLimit = concatLimit$1; + exports.flatMapSeries = concatSeries$1; + exports.forEach = each; + exports.forEachSeries = eachSeries$1; + exports.forEachLimit = eachLimit$2; + exports.forEachOf = eachOf$1; + exports.forEachOfSeries = eachOfSeries$1; + exports.forEachOfLimit = eachOfLimit$2; + exports.inject = reduce$1; + exports.foldl = reduce$1; + exports.foldr = reduceRight; + exports.select = filter$1; + exports.selectLimit = filterLimit$1; + exports.selectSeries = filterSeries$1; + exports.wrapSync = asyncify; + exports.during = whilst$1; + exports.doDuring = doWhilst$1; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/Challenge/seokahi/010.star/node_modules/async/dist/async.min.js b/Challenge/seokahi/010.star/node_modules/async/dist/async.min.js new file mode 100644 index 0000000..63aa33c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/dist/async.min.js @@ -0,0 +1 @@ +(function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.async={})})(this,function(e){'use strict';function t(e,...t){return(...n)=>e(...t,...n)}function n(e){return function(...t){var n=t.pop();return e.call(this,t,n)}}function a(e){setTimeout(e,0)}function i(e){return(t,...n)=>e(()=>t(...n))}function r(e){return u(e)?function(...t){const n=t.pop(),a=e.apply(this,t);return s(a,n)}:n(function(t,n){var a;try{a=e.apply(this,t)}catch(t){return n(t)}return a&&"function"==typeof a.then?s(a,n):void n(null,a)})}function s(e,t){return e.then(e=>{l(t,null,e)},e=>{l(t,e&&e.message?e:new Error(e))})}function l(e,t,n){try{e(t,n)}catch(e){be(t=>{throw t},e)}}function u(e){return"AsyncFunction"===e[Symbol.toStringTag]}function d(e){return"AsyncGenerator"===e[Symbol.toStringTag]}function c(e){return"function"==typeof e[Symbol.asyncIterator]}function p(e){if("function"!=typeof e)throw new Error("expected a function");return u(e)?r(e):e}function o(e,t=e.length){if(!t)throw new Error("arity is undefined");return function(...n){return"function"==typeof n[t-1]?e.apply(this,n):new Promise((a,i)=>{n[t-1]=(e,...t)=>e?i(e):void a(1{p(e).apply(i,n.concat(t))},a)});return a}}function f(e,t,n,a){t=t||[];var i=[],r=0,s=p(n);return e(t,(e,t,n)=>{var a=r++;s(e,(e,t)=>{i[a]=t,n(e)})},e=>{a(e,i)})}function y(e){return e&&"number"==typeof e.length&&0<=e.length&&0==e.length%1}function m(e){function t(...t){if(null!==e){var n=e;e=null,n.apply(this,t)}}return Object.assign(t,e),t}function g(e){return e[Symbol.iterator]&&e[Symbol.iterator]()}function k(e){var t=-1,n=e.length;return function(){return++t=t||d||l||(d=!0,e.next().then(({value:e,done:t})=>{if(!(u||l))return d=!1,t?(l=!0,void(0>=c&&a(null))):void(c++,n(e,p,r),p++,i())}).catch(s))}function r(e,t){return c-=1,u?void 0:e?s(e):!1===e?(l=!0,void(u=!0)):t===_e||l&&0>=c?(l=!0,a(null)):void i()}function s(e){u||(d=!1,l=!0,a(e))}let l=!1,u=!1,d=!1,c=0,p=0;i()}function O(e,t,n){function a(e,t){!1===e&&(l=!0);!0===l||(e?n(e):(++r===s||t===_e)&&n(null))}n=m(n);var i=0,r=0,{length:s}=e,l=!1;for(0===s&&n(null);i{t=e,n=a}),e}function M(e,t,n){function a(e,t){g.push(()=>l(e,t))}function i(){if(!h){if(0===g.length&&0===o)return n(null,c);for(;g.length&&oe()),i()}function l(e,t){if(!f){var a=L((t,...a)=>{if(o--,!1===t)return void(h=!0);if(2>a.length&&([a]=a),t){var i={};if(Object.keys(c).forEach(e=>{i[e]=c[e]}),i[e]=a,f=!0,y=Object.create(null),h)return;n(t,i)}else c[e]=a,s(e)});o++;var i=p(t[t.length-1]);1{const i=e[a];Array.isArray(i)&&0<=i.indexOf(t)&&n.push(a)}),n}"number"!=typeof t&&(n=t,t=null),n=m(n||_());var d=Object.keys(e).length;if(!d)return n(null);t||(t=d);var c={},o=0,h=!1,f=!1,y=Object.create(null),g=[],k=[],v={};return Object.keys(e).forEach(t=>{var n=e[t];if(!Array.isArray(n))return a(t,[n]),void k.push(t);var i=n.slice(0,n.length-1),s=i.length;return 0===s?(a(t,n),void k.push(t)):void(v[t]=s,i.forEach(l=>{if(!e[l])throw new Error("async.auto task `"+t+"` has a non-existent dependency `"+l+"` in "+i.join(", "));r(l,()=>{s--,0===s&&a(t,n)})}))}),function(){for(var e,t=0;k.length;)e=k.pop(),t++,u(e).forEach(e=>{0==--v[e]&&k.push(e)});if(t!==d)throw new Error("async.auto cannot execute tasks due to a recursive dependency")}(),i(),n[Ce]}function A(e){let t="",n=0,a=e.indexOf("*/");for(;ne.replace(Ne,"").trim())}function j(e,t){var n={};return Object.keys(e).forEach(t=>{function a(e,t){var n=i.map(t=>e[t]);n.push(t),p(r)(...n)}var i,r=e[t],s=u(r),l=!s&&1===r.length||s&&0===r.length;if(Array.isArray(r))i=[...r],r=i.pop(),n[t]=i.concat(0{r(e,n),t(...a)};f[e].push(n)}function r(e,t){return e?t?void(f[e]=f[e].filter(e=>e!==t)):f[e]=[]:Object.keys(f).forEach(e=>f[e]=[])}function s(e,...t){f[e].forEach(e=>e(...t))}function l(e,t,n,a){function i(e,...t){return e?n?s(e):r():1>=t.length?r(t[0]):void r(t)}if(null!=a&&"function"!=typeof a)throw new Error("task callback must be a function");k.started=!0;var r,s,l={data:e,callback:n?i:a||i};if(t?k._tasks.unshift(l):k._tasks.push(l),y||(y=!0,be(()=>{y=!1,k.process()})),n||!a)return new Promise((e,t)=>{r=e,s=t})}function u(e){return function(t,...n){o-=1;for(var a=0,r=e.length;as("drain")),!0)}if(null==t)t=1;else if(0===t)throw new RangeError("Concurrency must not be zero");var c=p(e),o=0,h=[];const f={error:[],drain:[],saturated:[],unsaturated:[],empty:[]};var y=!1;const m=e=>t=>t?void(r(e),a(e,t)):new Promise((t,n)=>{i(e,(e,a)=>e?n(e):void t(a))});var g=!1,k={_tasks:new Ve,*[Symbol.iterator](){yield*k._tasks[Symbol.iterator]()},concurrency:t,payload:n,buffer:t/4,started:!1,paused:!1,push(e,t){return Array.isArray(e)?d(e)?void 0:e.map(e=>l(e,!1,!1,t)):l(e,!1,!1,t)},pushAsync(e,t){return Array.isArray(e)?d(e)?void 0:e.map(e=>l(e,!1,!0,t)):l(e,!1,!0,t)},kill(){r(),k._tasks.empty()},unshift(e,t){return Array.isArray(e)?d(e)?void 0:e.map(e=>l(e,!0,!1,t)):l(e,!0,!1,t)},unshiftAsync(e,t){return Array.isArray(e)?d(e)?void 0:e.map(e=>l(e,!0,!0,t)):l(e,!0,!0,t)},remove(e){k._tasks.remove(e)},process(){var e=Math.min;if(!g){for(g=!0;!k.paused&&o{t.apply(n,e.concat((e,...t)=>{a(e,t)}))},(e,t)=>a(e,...t)),a[Ce]}}function P(...e){return C(...e.reverse())}function R(...e){return function(...t){var n=t.pop();return n(null,...e)}}function z(e,t){return(n,a,i,r)=>{var s,l=!1;const u=p(i);n(a,(n,a,i)=>{u(n,(a,r)=>a||!1===a?i(a):e(r)&&!s?(l=!0,s=t(!0,n),i(null,_e)):void i())},e=>e?r(e):void r(null,l?s:t(!1)))}}function N(e){return(t,...n)=>p(t)(...n,(t,...n)=>{"object"==typeof console&&(t?console.error&&console.error(t):console[e]&&n.forEach(t=>console[e](t)))})}function V(e,t,n){const a=p(t);return Xe(e,(...e)=>{const t=e.pop();a(...e,(e,n)=>t(e,!n))},n)}function Y(e){return(t,n,a)=>e(t,a)}function q(e){return u(e)?e:function(...t){var n=t.pop(),a=!0;t.push((...e)=>{a?be(()=>n(...e)):n(...e)}),e.apply(this,t),a=!1}}function D(e,t,n,a){var r=Array(t.length);e(t,(e,t,a)=>{n(e,(e,n)=>{r[t]=!!n,a(e)})},e=>{if(e)return a(e);for(var n=[],s=0;s{n(e,(n,r)=>n?a(n):void(r&&i.push({index:t,value:e}),a(n)))},e=>e?a(e):void a(null,i.sort((e,t)=>e.index-t.index).map(e=>e.value)))}function U(e,t,n,a){var i=y(t)?D:Q;return i(e,t,p(n),a)}function G(e,t,n){return ut(e,1/0,t,n)}function W(e,t,n){return ut(e,1,t,n)}function H(e,t,n){return ct(e,1/0,t,n)}function J(e,t,n){return ct(e,1,t,n)}function K(e,t=e=>e){var a=Object.create(null),r=Object.create(null),s=p(e),l=n((e,n)=>{var u=t(...e);u in a?be(()=>n(null,...a[u])):u in r?r[u].push(n):(r[u]=[n],s(...e,(e,...t)=>{e||(a[u]=t);var n=r[u];delete r[u];for(var s=0,d=n.length;s{n(e[0],t)},t,1)}function ee(e){return(e<<1)+1}function te(e){return(e+1>>1)-1}function ne(e,t){return e.priority===t.priority?e.pushCount{}){if("function"!=typeof r)throw new Error("task callback must be a function");if(n.started=!0,Array.isArray(e)||(e=[e]),0===e.length&&n.idle())return be(()=>n.drain());for(var s,u=0,d=e.length;u{a=!1,n.process()}))},delete n.unshift,n}function ie(e,t,n,a){var i=[...e].reverse();return qe(i,t,n,a)}function re(e){var t=p(e);return n(function(e,n){return e.push((e,...t)=>{let a={};if(e&&(a.error=e),0=t.length&&([i]=t),a.value=i}n(null,a)}),t.apply(this,e)})}function se(e){var t;return Array.isArray(e)?t=e.map(re):(t={},Object.keys(e).forEach(n=>{t[n]=re.call(this,e[n])})),t}function le(e,t,n,a){const i=p(n);return U(e,t,(e,t)=>{i(e,(e,n)=>{t(e,!n)})},a)}function ue(e){return function(){return e}}function de(e,t,n){function a(){r((e,...t)=>{!1===e||(e&&s++arguments.length&&"function"==typeof e?(n=t||_(),t=e):(ce(i,e),n=n||_()),"function"!=typeof t)throw new Error("Invalid arguments for async.retry");var r=p(t),s=1;return a(),n[Ce]}function ce(e,n){if("object"==typeof n)e.times=+n.times||kt,e.intervalFunc="function"==typeof n.interval?n.interval:ue(+n.interval||vt),e.errorFilter=n.errorFilter;else if("number"==typeof n||"string"==typeof n)e.times=+n||kt;else throw new Error("Invalid arguments for async.retry")}function pe(e,t){t||(t=e,e=null);let a=e&&e.arity||t.length;u(t)&&(a+=1);var i=p(t);return n((t,n)=>{function r(e){i(...t,e)}return(t.length{var s,l=!1;n.push((...e)=>{l||(r(...e),clearTimeout(s))}),s=setTimeout(function(){var t=e.name||"anonymous",n=new Error("Callback function \""+t+"\" timed out.");n.code="ETIMEDOUT",a&&(n.info=a),l=!0,r(n)},t),i(...n)})}function fe(e){for(var t=Array(e);e--;)t[e]=e;return t}function ye(e,t,n,a){var i=p(n);return De(fe(e),t,i,a)}function me(e,t,n){return ye(e,1/0,t,n)}function ge(e,t,n){return ye(e,1,t,n)}function ke(e,t,n,a){3>=arguments.length&&"function"==typeof t&&(a=n,n=t,t=Array.isArray(e)?[]:{}),a=m(a||_());var i=p(n);return Ie(e,(e,n,a)=>{i(t,e,n,a)},e=>a(e,t)),a[Ce]}function ve(e){return(...t)=>(e.unmemoized||e)(...t)}function Se(e,t,n){const a=p(e);return bt(e=>a((t,n)=>e(t,!n)),t,n)}var xe,Le="function"==typeof queueMicrotask&&queueMicrotask,Ee="function"==typeof setImmediate&&setImmediate,Oe="object"==typeof process&&"function"==typeof process.nextTick;xe=Le?queueMicrotask:Ee?setImmediate:Oe?process.nextTick:a;var be=i(xe);const _e={};var Me=e=>(t,n,a)=>{function i(e,t){if(!u)if(p-=1,e)l=!0,a(e);else if(!1===e)l=!0,u=!0;else{if(t===_e||l&&0>=p)return l=!0,a(null);o||r()}}function r(){for(o=!0;p=p&&a(null));p+=1,n(t.value,t.key,L(i))}o=!1}if(a=m(a),0>=e)throw new RangeError("concurrency limit cannot be less than 1");if(!t)return a(null);if(d(t))return E(t,e,n,a);if(c(t))return E(t[Symbol.asyncIterator](),e,n,a);var s=x(t),l=!1,u=!1,p=0,o=!1;r()},Ae=o(function(e,t,n,a){return Me(t)(e,p(n),a)},4),Ie=o(function(e,t,n){var a=y(e)?O:b;return a(e,p(t),n)},3),je=o(function(e,t,n){return f(Ie,e,t,n)},3),we=h(je),Be=o(function(e,t,n){return Ae(e,1,t,n)},3),Fe=o(function(e,t,n){return f(Be,e,t,n)},3),Te=h(Fe);const Ce=Symbol("promiseCallback");var Pe=/^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/,Re=/^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/,ze=/,/,Ne=/(=.+)?(\s*)$/;class Ve{constructor(){this.head=this.tail=null,this.length=0}removeLink(e){return e.prev?e.prev.next=e.next:this.head=e.next,e.next?e.next.prev=e.prev:this.tail=e.prev,e.prev=e.next=null,this.length-=1,e}empty(){for(;this.head;)this.shift();return this}insertAfter(e,t){t.prev=e,t.next=e.next,e.next?e.next.prev=t:this.tail=t,e.next=t,this.length+=1}insertBefore(e,t){t.prev=e.prev,t.next=e,e.prev?e.prev.next=t:this.head=t,e.prev=t,this.length+=1}unshift(e){this.head?this.insertBefore(this.head,e):w(this,e)}push(e){this.tail?this.insertAfter(this.tail,e):w(this,e)}shift(){return this.head&&this.removeLink(this.head)}pop(){return this.tail&&this.removeLink(this.tail)}toArray(){return[...this]}*[Symbol.iterator](){for(var e=this.head;e;)yield e.data,e=e.next}remove(e){for(var t=this.head;t;){var{next:n}=t;e(t)&&this.removeLink(t),t=n}return this}}var Ye,qe=o(function(e,t,n,a){a=m(a);var r=p(n);return Be(e,(e,n,a)=>{r(t,e,(e,n)=>{t=n,a(e)})},e=>a(e,t))},4),De=o(function(e,t,n,a){return f(Me(t),e,n,a)},4),Qe=o(function(e,t,n,a){var i=p(n);return De(e,t,(e,t)=>{i(e,(e,...n)=>e?t(e):t(e,n))},(e,t)=>{for(var n=[],r=0;re,(e,t)=>t)(Ie,e,t,n)},3),He=o(function(e,t,n,a){return z(e=>e,(e,t)=>t)(Me(t),e,n,a)},4),Je=o(function(e,t,n){return z(e=>e,(e,t)=>t)(Me(1),e,t,n)},3),Ke=N("dir"),Xe=o(function(e,t,n){function a(e,...t){return e?n(e):void(!1===e||(r=t,l(...t,i)))}function i(e,t){return e?n(e):!1===e?void 0:t?void s(a):n(null,...r)}n=L(n);var r,s=p(e),l=p(t);return i(null,!0)},3),Ze=o(function(e,t,n){return Ie(e,Y(p(t)),n)},3),$e=o(function(e,t,n,a){return Me(t)(e,Y(p(n)),a)},4),et=o(function(e,t,n){return $e(e,1,t,n)},3),tt=o(function(e,t,n){return z(e=>!e,e=>!e)(Ie,e,t,n)},3),nt=o(function(e,t,n,a){return z(e=>!e,e=>!e)(Me(t),e,n,a)},4),at=o(function(e,t,n){return z(e=>!e,e=>!e)(Be,e,t,n)},3),it=o(function(e,t,n){return U(Ie,e,t,n)},3),rt=o(function(e,t,n,a){return U(Me(t),e,n,a)},4),st=o(function(e,t,n){return U(Be,e,t,n)},3),lt=o(function(e,t){function n(e){return e?a(e):void(!1===e||i(n))}var a=L(t),i=p(q(e));return n()},2),ut=o(function(e,t,n,a){var i=p(n);return De(e,t,(e,t)=>{i(e,(n,a)=>n?t(n):t(n,{key:a,val:e}))},(e,t)=>{for(var n={},{hasOwnProperty:r}=Object.prototype,s=0;s{r(e,t,(e,a)=>e?n(e):void(i[t]=a,n(e)))},e=>a(e,i))},4);Ye=Oe?process.nextTick:Ee?setImmediate:a;var pt=i(Ye),ot=o((e,t,n)=>{var a=y(t)?[]:{};e(t,(e,t,n)=>{p(e)((e,...i)=>{2>i.length&&([i]=i),a[t]=i,n(e)})},e=>n(e,a))},3);class ht{constructor(){this.heap=[],this.pushCount=Number.MIN_SAFE_INTEGER}get length(){return this.heap.length}empty(){return this.heap=[],this}percUp(e){for(let n;0e)(Ie,e,t,n)},3),xt=o(function(e,t,n,a){return z(Boolean,e=>e)(Me(t),e,n,a)},4),Lt=o(function(e,t,n){return z(Boolean,e=>e)(Be,e,t,n)},3),Et=o(function(e,t,n){function a(e,t){var n=e.criteria,a=t.criteria;return na?1:0}var i=p(t);return je(e,(e,t)=>{i(e,(n,a)=>n?t(n):void t(n,{value:e,criteria:a}))},(e,t)=>e?n(e):void n(null,t.sort(a).map(e=>e.value)))},3),Ot=o(function(e,t){var n,a=null;return et(e,(e,t)=>{p(e)((e,...i)=>!1===e?t(e):void(2>i.length?[n]=i:n=i,a=e,t(e?null:{})))},()=>t(a,n))}),bt=o(function(e,t,n){function a(e,...t){if(e)return n(e);l=t;!1===e||s(i)}function i(e,t){return e?n(e):!1===e?void 0:t?void r(a):n(null,...l)}n=L(n);var r=p(t),s=p(e),l=[];return s(i)},3),_t=o(function(e,t){function n(t){var n=p(e[i++]);n(...t,L(a))}function a(a,...r){return!1===a?void 0:a||i===e.length?t(a,...r):void n(r)}if(t=m(t),!Array.isArray(e))return t(new Error("First argument to waterfall must be an array of functions"));if(!e.length)return t();var i=0;n([])});e.default={apply:t,applyEach:we,applyEachSeries:Te,asyncify:r,auto:M,autoInject:j,cargo:F,cargoQueue:T,compose:P,concat:Ue,concatLimit:Qe,concatSeries:Ge,constant:R,detect:We,detectLimit:He,detectSeries:Je,dir:Ke,doUntil:V,doWhilst:Xe,each:Ze,eachLimit:$e,eachOf:Ie,eachOfLimit:Ae,eachOfSeries:Be,eachSeries:et,ensureAsync:q,every:tt,everyLimit:nt,everySeries:at,filter:it,filterLimit:rt,filterSeries:st,forever:lt,groupBy:G,groupByLimit:ut,groupBySeries:W,log:dt,map:je,mapLimit:De,mapSeries:Fe,mapValues:H,mapValuesLimit:ct,mapValuesSeries:J,memoize:K,nextTick:pt,parallel:X,parallelLimit:Z,priorityQueue:ae,queue:$,race:ft,reduce:qe,reduceRight:ie,reflect:re,reflectAll:se,reject:yt,rejectLimit:mt,rejectSeries:gt,retry:de,retryable:pe,seq:C,series:oe,setImmediate:be,some:St,someLimit:xt,someSeries:Lt,sortBy:Et,timeout:he,times:me,timesLimit:ye,timesSeries:ge,transform:ke,tryEach:Ot,unmemoize:ve,until:Se,waterfall:_t,whilst:bt,all:tt,allLimit:nt,allSeries:at,any:St,anyLimit:xt,anySeries:Lt,find:We,findLimit:He,findSeries:Je,flatMap:Ue,flatMapLimit:Qe,flatMapSeries:Ge,forEach:Ze,forEachSeries:et,forEachLimit:$e,forEachOf:Ie,forEachOfSeries:Be,forEachOfLimit:Ae,inject:qe,foldl:qe,foldr:ie,select:it,selectLimit:rt,selectSeries:st,wrapSync:r,during:bt,doDuring:Xe},e.apply=t,e.applyEach=we,e.applyEachSeries=Te,e.asyncify=r,e.auto=M,e.autoInject=j,e.cargo=F,e.cargoQueue=T,e.compose=P,e.concat=Ue,e.concatLimit=Qe,e.concatSeries=Ge,e.constant=R,e.detect=We,e.detectLimit=He,e.detectSeries=Je,e.dir=Ke,e.doUntil=V,e.doWhilst=Xe,e.each=Ze,e.eachLimit=$e,e.eachOf=Ie,e.eachOfLimit=Ae,e.eachOfSeries=Be,e.eachSeries=et,e.ensureAsync=q,e.every=tt,e.everyLimit=nt,e.everySeries=at,e.filter=it,e.filterLimit=rt,e.filterSeries=st,e.forever=lt,e.groupBy=G,e.groupByLimit=ut,e.groupBySeries=W,e.log=dt,e.map=je,e.mapLimit=De,e.mapSeries=Fe,e.mapValues=H,e.mapValuesLimit=ct,e.mapValuesSeries=J,e.memoize=K,e.nextTick=pt,e.parallel=X,e.parallelLimit=Z,e.priorityQueue=ae,e.queue=$,e.race=ft,e.reduce=qe,e.reduceRight=ie,e.reflect=re,e.reflectAll=se,e.reject=yt,e.rejectLimit=mt,e.rejectSeries=gt,e.retry=de,e.retryable=pe,e.seq=C,e.series=oe,e.setImmediate=be,e.some=St,e.someLimit=xt,e.someSeries=Lt,e.sortBy=Et,e.timeout=he,e.times=me,e.timesLimit=ye,e.timesSeries=ge,e.transform=ke,e.tryEach=Ot,e.unmemoize=ve,e.until=Se,e.waterfall=_t,e.whilst=bt,e.all=tt,e.allLimit=nt,e.allSeries=at,e.any=St,e.anyLimit=xt,e.anySeries=Lt,e.find=We,e.findLimit=He,e.findSeries=Je,e.flatMap=Ue,e.flatMapLimit=Qe,e.flatMapSeries=Ge,e.forEach=Ze,e.forEachSeries=et,e.forEachLimit=$e,e.forEachOf=Ie,e.forEachOfSeries=Be,e.forEachOfLimit=Ae,e.inject=qe,e.foldl=qe,e.foldr=ie,e.select=it,e.selectLimit=rt,e.selectSeries=st,e.wrapSync=r,e.during=bt,e.doDuring=Xe,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/dist/async.mjs b/Challenge/seokahi/010.star/node_modules/async/dist/async.mjs new file mode 100644 index 0000000..5453a4b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/dist/async.mjs @@ -0,0 +1,5945 @@ +/** + * Creates a continuation function with some arguments already applied. + * + * Useful as a shorthand when combined with other control flow functions. Any + * arguments passed to the returned function are added to the arguments + * originally passed to apply. + * + * @name apply + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {Function} fn - The function you want to eventually apply all + * arguments to. Invokes with (arguments...). + * @param {...*} arguments... - Any number of arguments to automatically apply + * when the continuation is called. + * @returns {Function} the partially-applied function + * @example + * + * // using apply + * async.parallel([ + * async.apply(fs.writeFile, 'testfile1', 'test1'), + * async.apply(fs.writeFile, 'testfile2', 'test2') + * ]); + * + * + * // the same process without using apply + * async.parallel([ + * function(callback) { + * fs.writeFile('testfile1', 'test1', callback); + * }, + * function(callback) { + * fs.writeFile('testfile2', 'test2', callback); + * } + * ]); + * + * // It's possible to pass any number of additional arguments when calling the + * // continuation: + * + * node> var fn = async.apply(sys.puts, 'one'); + * node> fn('two', 'three'); + * one + * two + * three + */ +function apply(fn, ...args) { + return (...callArgs) => fn(...args,...callArgs); +} + +function initialParams (fn) { + return function (...args/*, callback*/) { + var callback = args.pop(); + return fn.call(this, args, callback); + }; +} + +/* istanbul ignore file */ + +var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask; +var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; +var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; + +function fallback(fn) { + setTimeout(fn, 0); +} + +function wrap(defer) { + return (fn, ...args) => defer(() => fn(...args)); +} + +var _defer; + +if (hasQueueMicrotask) { + _defer = queueMicrotask; +} else if (hasSetImmediate) { + _defer = setImmediate; +} else if (hasNextTick) { + _defer = process.nextTick; +} else { + _defer = fallback; +} + +var setImmediate$1 = wrap(_defer); + +/** + * Take a sync function and make it async, passing its return value to a + * callback. This is useful for plugging sync functions into a waterfall, + * series, or other async functions. Any arguments passed to the generated + * function will be passed to the wrapped function (except for the final + * callback argument). Errors thrown will be passed to the callback. + * + * If the function passed to `asyncify` returns a Promise, that promises's + * resolved/rejected state will be used to call the callback, rather than simply + * the synchronous return value. + * + * This also means you can asyncify ES2017 `async` functions. + * + * @name asyncify + * @static + * @memberOf module:Utils + * @method + * @alias wrapSync + * @category Util + * @param {Function} func - The synchronous function, or Promise-returning + * function to convert to an {@link AsyncFunction}. + * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be + * invoked with `(args..., callback)`. + * @example + * + * // passing a regular synchronous function + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(JSON.parse), + * function (data, next) { + * // data is the result of parsing the text. + * // If there was a parsing error, it would have been caught. + * } + * ], callback); + * + * // passing a function returning a promise + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(function (contents) { + * return db.model.create(contents); + * }), + * function (model, next) { + * // `model` is the instantiated model object. + * // If there was an error, this function would be skipped. + * } + * ], callback); + * + * // es2017 example, though `asyncify` is not needed if your JS environment + * // supports async functions out of the box + * var q = async.queue(async.asyncify(async function(file) { + * var intermediateStep = await processFile(file); + * return await somePromise(intermediateStep) + * })); + * + * q.push(files); + */ +function asyncify(func) { + if (isAsync(func)) { + return function (...args/*, callback*/) { + const callback = args.pop(); + const promise = func.apply(this, args); + return handlePromise(promise, callback) + } + } + + return initialParams(function (args, callback) { + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (result && typeof result.then === 'function') { + return handlePromise(result, callback) + } else { + callback(null, result); + } + }); +} + +function handlePromise(promise, callback) { + return promise.then(value => { + invokeCallback(callback, null, value); + }, err => { + invokeCallback(callback, err && err.message ? err : new Error(err)); + }); +} + +function invokeCallback(callback, error, value) { + try { + callback(error, value); + } catch (err) { + setImmediate$1(e => { throw e }, err); + } +} + +function isAsync(fn) { + return fn[Symbol.toStringTag] === 'AsyncFunction'; +} + +function isAsyncGenerator(fn) { + return fn[Symbol.toStringTag] === 'AsyncGenerator'; +} + +function isAsyncIterable(obj) { + return typeof obj[Symbol.asyncIterator] === 'function'; +} + +function wrapAsync(asyncFn) { + if (typeof asyncFn !== 'function') throw new Error('expected a function') + return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn; +} + +// conditionally promisify a function. +// only return a promise if a callback is omitted +function awaitify (asyncFn, arity = asyncFn.length) { + if (!arity) throw new Error('arity is undefined') + function awaitable (...args) { + if (typeof args[arity - 1] === 'function') { + return asyncFn.apply(this, args) + } + + return new Promise((resolve, reject) => { + args[arity - 1] = (err, ...cbArgs) => { + if (err) return reject(err) + resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]); + }; + asyncFn.apply(this, args); + }) + } + + return awaitable +} + +function applyEach (eachfn) { + return function applyEach(fns, ...callArgs) { + const go = awaitify(function (callback) { + var that = this; + return eachfn(fns, (fn, cb) => { + wrapAsync(fn).apply(that, callArgs.concat(cb)); + }, callback); + }); + return go; + }; +} + +function _asyncMap(eachfn, arr, iteratee, callback) { + arr = arr || []; + var results = []; + var counter = 0; + var _iteratee = wrapAsync(iteratee); + + return eachfn(arr, (value, _, iterCb) => { + var index = counter++; + _iteratee(value, (err, v) => { + results[index] = v; + iterCb(err); + }); + }, err => { + callback(err, results); + }); +} + +function isArrayLike(value) { + return value && + typeof value.length === 'number' && + value.length >= 0 && + value.length % 1 === 0; +} + +// A temporary value used to identify if the loop should be broken. +// See #1064, #1293 +const breakLoop = {}; + +function once(fn) { + function wrapper (...args) { + if (fn === null) return; + var callFn = fn; + fn = null; + callFn.apply(this, args); + } + Object.assign(wrapper, fn); + return wrapper +} + +function getIterator (coll) { + return coll[Symbol.iterator] && coll[Symbol.iterator](); +} + +function createArrayIterator(coll) { + var i = -1; + var len = coll.length; + return function next() { + return ++i < len ? {value: coll[i], key: i} : null; + } +} + +function createES2015Iterator(iterator) { + var i = -1; + return function next() { + var item = iterator.next(); + if (item.done) + return null; + i++; + return {value: item.value, key: i}; + } +} + +function createObjectIterator(obj) { + var okeys = obj ? Object.keys(obj) : []; + var i = -1; + var len = okeys.length; + return function next() { + var key = okeys[++i]; + if (key === '__proto__') { + return next(); + } + return i < len ? {value: obj[key], key} : null; + }; +} + +function createIterator(coll) { + if (isArrayLike(coll)) { + return createArrayIterator(coll); + } + + var iterator = getIterator(coll); + return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); +} + +function onlyOnce(fn) { + return function (...args) { + if (fn === null) throw new Error("Callback was already called."); + var callFn = fn; + fn = null; + callFn.apply(this, args); + }; +} + +// for async generators +function asyncEachOfLimit(generator, limit, iteratee, callback) { + let done = false; + let canceled = false; + let awaiting = false; + let running = 0; + let idx = 0; + + function replenish() { + //console.log('replenish') + if (running >= limit || awaiting || done) return + //console.log('replenish awaiting') + awaiting = true; + generator.next().then(({value, done: iterDone}) => { + //console.log('got value', value) + if (canceled || done) return + awaiting = false; + if (iterDone) { + done = true; + if (running <= 0) { + //console.log('done nextCb') + callback(null); + } + return; + } + running++; + iteratee(value, idx, iterateeCallback); + idx++; + replenish(); + }).catch(handleError); + } + + function iterateeCallback(err, result) { + //console.log('iterateeCallback') + running -= 1; + if (canceled) return + if (err) return handleError(err) + + if (err === false) { + done = true; + canceled = true; + return + } + + if (result === breakLoop || (done && running <= 0)) { + done = true; + //console.log('done iterCb') + return callback(null); + } + replenish(); + } + + function handleError(err) { + if (canceled) return + awaiting = false; + done = true; + callback(err); + } + + replenish(); +} + +var eachOfLimit = (limit) => { + return (obj, iteratee, callback) => { + callback = once(callback); + if (limit <= 0) { + throw new RangeError('concurrency limit cannot be less than 1') + } + if (!obj) { + return callback(null); + } + if (isAsyncGenerator(obj)) { + return asyncEachOfLimit(obj, limit, iteratee, callback) + } + if (isAsyncIterable(obj)) { + return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback) + } + var nextElem = createIterator(obj); + var done = false; + var canceled = false; + var running = 0; + var looping = false; + + function iterateeCallback(err, value) { + if (canceled) return + running -= 1; + if (err) { + done = true; + callback(err); + } + else if (err === false) { + done = true; + canceled = true; + } + else if (value === breakLoop || (done && running <= 0)) { + done = true; + return callback(null); + } + else if (!looping) { + replenish(); + } + } + + function replenish () { + looping = true; + while (running < limit && !done) { + var elem = nextElem(); + if (elem === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iteratee(elem.value, elem.key, onlyOnce(iterateeCallback)); + } + looping = false; + } + + replenish(); + }; +}; + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a + * time. + * + * @name eachOfLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. The `key` is the item's key, or index in the case of an + * array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfLimit$1(coll, limit, iteratee, callback) { + return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback); +} + +var eachOfLimit$2 = awaitify(eachOfLimit$1, 4); + +// eachOf implementation optimized for array-likes +function eachOfArrayLike(coll, iteratee, callback) { + callback = once(callback); + var index = 0, + completed = 0, + {length} = coll, + canceled = false; + if (length === 0) { + callback(null); + } + + function iteratorCallback(err, value) { + if (err === false) { + canceled = true; + } + if (canceled === true) return + if (err) { + callback(err); + } else if ((++completed === length) || value === breakLoop) { + callback(null); + } + } + + for (; index < length; index++) { + iteratee(coll[index], index, onlyOnce(iteratorCallback)); + } +} + +// a generic version of eachOf which can handle array, object, and iterator cases. +function eachOfGeneric (coll, iteratee, callback) { + return eachOfLimit$2(coll, Infinity, iteratee, callback); +} + +/** + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument + * to the iteratee. + * + * @name eachOf + * @static + * @memberOf module:Collections + * @method + * @alias forEachOf + * @category Collection + * @see [async.each]{@link module:Collections.each} + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each + * item in `coll`. + * The `key` is the item's key, or index in the case of an array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dev.json is a file containing a valid json object config for dev environment + * // dev.json is a file containing a valid json object config for test environment + * // prod.json is a file containing a valid json object config for prod environment + * // invalid.json is a file with a malformed json object + * + * let configs = {}; //global variable + * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'}; + * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'}; + * + * // asynchronous function that reads a json file and parses the contents as json object + * function parseFile(file, key, callback) { + * fs.readFile(file, "utf8", function(err, data) { + * if (err) return calback(err); + * try { + * configs[key] = JSON.parse(data); + * } catch (e) { + * return callback(e); + * } + * callback(); + * }); + * } + * + * // Using callbacks + * async.forEachOf(validConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * } else { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * // JSON parse error exception + * } else { + * console.log(configs); + * } + * }); + * + * // Using Promises + * async.forEachOf(validConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * }).catch( err => { + * console.error(err); + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * }).catch( err => { + * console.error(err); + * // JSON parse error exception + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.forEachOf(validConfigFileMap, parseFile); + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * catch (err) { + * console.log(err); + * } + * } + * + * //Error handing + * async () => { + * try { + * let result = await async.forEachOf(invalidConfigFileMap, parseFile); + * console.log(configs); + * } + * catch (err) { + * console.log(err); + * // JSON parse error exception + * } + * } + * + */ +function eachOf(coll, iteratee, callback) { + var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric; + return eachOfImplementation(coll, wrapAsync(iteratee), callback); +} + +var eachOf$1 = awaitify(eachOf, 3); + +/** + * Produces a new collection of values by mapping each value in `coll` through + * the `iteratee` function. The `iteratee` is called with an item from `coll` + * and a callback for when it has finished processing. Each of these callbacks + * takes 2 arguments: an `error`, and the transformed item from `coll`. If + * `iteratee` passes an error to its callback, the main `callback` (for the + * `map` function) is immediately called with the error. + * + * Note, that since this function applies the `iteratee` to each item in + * parallel, there is no guarantee that the `iteratee` functions will complete + * in order. However, the results array will be in the same order as the + * original `coll`. + * + * If `map` is passed an Object, the results will be an Array. The results + * will roughly be in the order of the original Objects' keys (but this can + * vary across JavaScript engines). + * + * @name map + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an Array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.map(fileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.map(fileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.map(fileList, getFileSizeInBytes); + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.map(withMissingFileList, getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function map (coll, iteratee, callback) { + return _asyncMap(eachOf$1, coll, iteratee, callback) +} +var map$1 = awaitify(map, 3); + +/** + * Applies the provided arguments to each function in the array, calling + * `callback` after all functions have completed. If you only provide the first + * argument, `fns`, then it will return a function which lets you pass in the + * arguments as if it were a single function call. If more arguments are + * provided, `callback` is required while `args` is still optional. The results + * for each of the applied async functions are passed to the final callback + * as an array. + * + * @name applyEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s + * to all call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - Returns a function that takes no args other than + * an optional callback, that is the result of applying the `args` to each + * of the functions. + * @example + * + * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket') + * + * appliedFn((err, results) => { + * // results[0] is the results for `enableSearch` + * // results[1] is the results for `updateSchema` + * }); + * + * // partial application example: + * async.each( + * buckets, + * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(), + * callback + * ); + */ +var applyEach$1 = applyEach(map$1); + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. + * + * @name eachOfSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfSeries(coll, iteratee, callback) { + return eachOfLimit$2(coll, 1, iteratee, callback) +} +var eachOfSeries$1 = awaitify(eachOfSeries, 3); + +/** + * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. + * + * @name mapSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function mapSeries (coll, iteratee, callback) { + return _asyncMap(eachOfSeries$1, coll, iteratee, callback) +} +var mapSeries$1 = awaitify(mapSeries, 3); + +/** + * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. + * + * @name applyEachSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.applyEach]{@link module:ControlFlow.applyEach} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all + * call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {AsyncFunction} - A function, that when called, is the result of + * appling the `args` to the list of functions. It takes no args, other than + * a callback. + */ +var applyEachSeries = applyEach(mapSeries$1); + +const PROMISE_SYMBOL = Symbol('promiseCallback'); + +function promiseCallback () { + let resolve, reject; + function callback (err, ...args) { + if (err) return reject(err) + resolve(args.length > 1 ? args : args[0]); + } + + callback[PROMISE_SYMBOL] = new Promise((res, rej) => { + resolve = res, + reject = rej; + }); + + return callback +} + +/** + * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on + * their requirements. Each function can optionally depend on other functions + * being completed first, and each function is run as soon as its requirements + * are satisfied. + * + * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence + * will stop. Further tasks will not execute (so any other functions depending + * on it will not run), and the main `callback` is immediately called with the + * error. + * + * {@link AsyncFunction}s also receive an object containing the results of functions which + * have completed so far as the first argument, if they have dependencies. If a + * task function has no dependencies, it will only be passed a callback. + * + * @name auto + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Object} tasks - An object. Each of its properties is either a + * function or an array of requirements, with the {@link AsyncFunction} itself the last item + * in the array. The object's key of a property serves as the name of the task + * defined by that property, i.e. can be used when specifying requirements for + * other tasks. The function receives one or two arguments: + * * a `results` object, containing the results of the previously executed + * functions, only passed if the task has any dependencies, + * * a `callback(err, result)` function, which must be called when finished, + * passing an `error` (which can be `null`) and the result of the function's + * execution. + * @param {number} [concurrency=Infinity] - An optional `integer` for + * determining the maximum number of tasks that can be run in parallel. By + * default, as many as possible. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback. Results are always returned; however, if an + * error occurs, no further `tasks` will be performed, and the results object + * will only contain partial results. Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * @example + * + * //Using Callbacks + * async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }, function(err, results) { + * if (err) { + * console.log('err = ', err); + * } + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }); + * + * //Using Promises + * async.auto({ + * get_data: function(callback) { + * console.log('in get_data'); + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * console.log('in make_folder'); + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }).then(results => { + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * }).catch(err => { + * console.log('err = ', err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.auto({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * // once the file is written let's email a link to it... + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }); + * console.log('results = ', results); + * // results = { + * // get_data: ['data', 'converted to array'] + * // make_folder; 'folder', + * // write_file: 'filename' + * // email_link: { file: 'filename', email: 'user@example.com' } + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function auto(tasks, concurrency, callback) { + if (typeof concurrency !== 'number') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = once(callback || promiseCallback()); + var numTasks = Object.keys(tasks).length; + if (!numTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = numTasks; + } + + var results = {}; + var runningTasks = 0; + var canceled = false; + var hasError = false; + + var listeners = Object.create(null); + + var readyTasks = []; + + // for cycle detection: + var readyToCheck = []; // tasks that have been identified as reachable + // without the possibility of returning to an ancestor task + var uncheckedDependencies = {}; + + Object.keys(tasks).forEach(key => { + var task = tasks[key]; + if (!Array.isArray(task)) { + // no dependencies + enqueueTask(key, [task]); + readyToCheck.push(key); + return; + } + + var dependencies = task.slice(0, task.length - 1); + var remainingDependencies = dependencies.length; + if (remainingDependencies === 0) { + enqueueTask(key, task); + readyToCheck.push(key); + return; + } + uncheckedDependencies[key] = remainingDependencies; + + dependencies.forEach(dependencyName => { + if (!tasks[dependencyName]) { + throw new Error('async.auto task `' + key + + '` has a non-existent dependency `' + + dependencyName + '` in ' + + dependencies.join(', ')); + } + addListener(dependencyName, () => { + remainingDependencies--; + if (remainingDependencies === 0) { + enqueueTask(key, task); + } + }); + }); + }); + + checkForDeadlocks(); + processQueue(); + + function enqueueTask(key, task) { + readyTasks.push(() => runTask(key, task)); + } + + function processQueue() { + if (canceled) return + if (readyTasks.length === 0 && runningTasks === 0) { + return callback(null, results); + } + while(readyTasks.length && runningTasks < concurrency) { + var run = readyTasks.shift(); + run(); + } + + } + + function addListener(taskName, fn) { + var taskListeners = listeners[taskName]; + if (!taskListeners) { + taskListeners = listeners[taskName] = []; + } + + taskListeners.push(fn); + } + + function taskComplete(taskName) { + var taskListeners = listeners[taskName] || []; + taskListeners.forEach(fn => fn()); + processQueue(); + } + + + function runTask(key, task) { + if (hasError) return; + + var taskCallback = onlyOnce((err, ...result) => { + runningTasks--; + if (err === false) { + canceled = true; + return + } + if (result.length < 2) { + [result] = result; + } + if (err) { + var safeResults = {}; + Object.keys(results).forEach(rkey => { + safeResults[rkey] = results[rkey]; + }); + safeResults[key] = result; + hasError = true; + listeners = Object.create(null); + if (canceled) return + callback(err, safeResults); + } else { + results[key] = result; + taskComplete(key); + } + }); + + runningTasks++; + var taskFn = wrapAsync(task[task.length - 1]); + if (task.length > 1) { + taskFn(results, taskCallback); + } else { + taskFn(taskCallback); + } + } + + function checkForDeadlocks() { + // Kahn's algorithm + // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm + // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html + var currentTask; + var counter = 0; + while (readyToCheck.length) { + currentTask = readyToCheck.pop(); + counter++; + getDependents(currentTask).forEach(dependent => { + if (--uncheckedDependencies[dependent] === 0) { + readyToCheck.push(dependent); + } + }); + } + + if (counter !== numTasks) { + throw new Error( + 'async.auto cannot execute tasks due to a recursive dependency' + ); + } + } + + function getDependents(taskName) { + var result = []; + Object.keys(tasks).forEach(key => { + const task = tasks[key]; + if (Array.isArray(task) && task.indexOf(taskName) >= 0) { + result.push(key); + } + }); + return result; + } + + return callback[PROMISE_SYMBOL] +} + +var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/; +var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/; +var FN_ARG_SPLIT = /,/; +var FN_ARG = /(=.+)?(\s*)$/; + +function stripComments(string) { + let stripped = ''; + let index = 0; + let endBlockComment = string.indexOf('*/'); + while (index < string.length) { + if (string[index] === '/' && string[index+1] === '/') { + // inline comment + let endIndex = string.indexOf('\n', index); + index = (endIndex === -1) ? string.length : endIndex; + } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) { + // block comment + let endIndex = string.indexOf('*/', index); + if (endIndex !== -1) { + index = endIndex + 2; + endBlockComment = string.indexOf('*/', index); + } else { + stripped += string[index]; + index++; + } + } else { + stripped += string[index]; + index++; + } + } + return stripped; +} + +function parseParams(func) { + const src = stripComments(func.toString()); + let match = src.match(FN_ARGS); + if (!match) { + match = src.match(ARROW_FN_ARGS); + } + if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src) + let [, args] = match; + return args + .replace(/\s/g, '') + .split(FN_ARG_SPLIT) + .map((arg) => arg.replace(FN_ARG, '').trim()); +} + +/** + * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent + * tasks are specified as parameters to the function, after the usual callback + * parameter, with the parameter names matching the names of the tasks it + * depends on. This can provide even more readable task graphs which can be + * easier to maintain. + * + * If a final callback is specified, the task results are similarly injected, + * specified as named parameters after the initial error parameter. + * + * The autoInject function is purely syntactic sugar and its semantics are + * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. + * + * @name autoInject + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.auto]{@link module:ControlFlow.auto} + * @category Control Flow + * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of + * the form 'func([dependencies...], callback). The object's key of a property + * serves as the name of the task defined by that property, i.e. can be used + * when specifying requirements for other tasks. + * * The `callback` parameter is a `callback(err, result)` which must be called + * when finished, passing an `error` (which can be `null`) and the result of + * the function's execution. The remaining parameters name other tasks on + * which the task is dependent, and the results from those tasks are the + * arguments of those parameters. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback, and a `results` object with any completed + * task results, similar to `auto`. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // The example from `auto` can be rewritten as follows: + * async.autoInject({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: function(get_data, make_folder, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }, + * email_link: function(write_file, callback) { + * // once the file is written let's email a link to it... + * // write_file contains the filename returned by write_file. + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * } + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + * + * // If you are using a JS minifier that mangles parameter names, `autoInject` + * // will not work with plain functions, since the parameter names will be + * // collapsed to a single letter identifier. To work around this, you can + * // explicitly specify the names of the parameters your task function needs + * // in an array, similar to Angular.js dependency injection. + * + * // This still has an advantage over plain `auto`, since the results a task + * // depends on are still spread into arguments. + * async.autoInject({ + * //... + * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(write_file, callback) { + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * }] + * //... + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + */ +function autoInject(tasks, callback) { + var newTasks = {}; + + Object.keys(tasks).forEach(key => { + var taskFn = tasks[key]; + var params; + var fnIsAsync = isAsync(taskFn); + var hasNoDeps = + (!fnIsAsync && taskFn.length === 1) || + (fnIsAsync && taskFn.length === 0); + + if (Array.isArray(taskFn)) { + params = [...taskFn]; + taskFn = params.pop(); + + newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); + } else if (hasNoDeps) { + // no dependencies, use the function as-is + newTasks[key] = taskFn; + } else { + params = parseParams(taskFn); + if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) { + throw new Error("autoInject task functions require explicit parameters."); + } + + // remove callback param + if (!fnIsAsync) params.pop(); + + newTasks[key] = params.concat(newTask); + } + + function newTask(results, taskCb) { + var newArgs = params.map(name => results[name]); + newArgs.push(taskCb); + wrapAsync(taskFn)(...newArgs); + } + }); + + return auto(newTasks, callback); +} + +// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation +// used for queues. This implementation assumes that the node provided by the user can be modified +// to adjust the next and last properties. We implement only the minimal functionality +// for queue support. +class DLL { + constructor() { + this.head = this.tail = null; + this.length = 0; + } + + removeLink(node) { + if (node.prev) node.prev.next = node.next; + else this.head = node.next; + if (node.next) node.next.prev = node.prev; + else this.tail = node.prev; + + node.prev = node.next = null; + this.length -= 1; + return node; + } + + empty () { + while(this.head) this.shift(); + return this; + } + + insertAfter(node, newNode) { + newNode.prev = node; + newNode.next = node.next; + if (node.next) node.next.prev = newNode; + else this.tail = newNode; + node.next = newNode; + this.length += 1; + } + + insertBefore(node, newNode) { + newNode.prev = node.prev; + newNode.next = node; + if (node.prev) node.prev.next = newNode; + else this.head = newNode; + node.prev = newNode; + this.length += 1; + } + + unshift(node) { + if (this.head) this.insertBefore(this.head, node); + else setInitial(this, node); + } + + push(node) { + if (this.tail) this.insertAfter(this.tail, node); + else setInitial(this, node); + } + + shift() { + return this.head && this.removeLink(this.head); + } + + pop() { + return this.tail && this.removeLink(this.tail); + } + + toArray() { + return [...this] + } + + *[Symbol.iterator] () { + var cur = this.head; + while (cur) { + yield cur.data; + cur = cur.next; + } + } + + remove (testFn) { + var curr = this.head; + while(curr) { + var {next} = curr; + if (testFn(curr)) { + this.removeLink(curr); + } + curr = next; + } + return this; + } +} + +function setInitial(dll, node) { + dll.length = 1; + dll.head = dll.tail = node; +} + +function queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new RangeError('Concurrency must not be zero'); + } + + var _worker = wrapAsync(worker); + var numRunning = 0; + var workersList = []; + const events = { + error: [], + drain: [], + saturated: [], + unsaturated: [], + empty: [] + }; + + function on (event, handler) { + events[event].push(handler); + } + + function once (event, handler) { + const handleAndRemove = (...args) => { + off(event, handleAndRemove); + handler(...args); + }; + events[event].push(handleAndRemove); + } + + function off (event, handler) { + if (!event) return Object.keys(events).forEach(ev => events[ev] = []) + if (!handler) return events[event] = [] + events[event] = events[event].filter(ev => ev !== handler); + } + + function trigger (event, ...args) { + events[event].forEach(handler => handler(...args)); + } + + var processingScheduled = false; + function _insert(data, insertAtFront, rejectOnError, callback) { + if (callback != null && typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + + var res, rej; + function promiseCallback (err, ...args) { + // we don't care about the error, let the global error handler + // deal with it + if (err) return rejectOnError ? rej(err) : res() + if (args.length <= 1) return res(args[0]) + res(args); + } + + var item = { + data, + callback: rejectOnError ? + promiseCallback : + (callback || promiseCallback) + }; + + if (insertAtFront) { + q._tasks.unshift(item); + } else { + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + setImmediate$1(() => { + processingScheduled = false; + q.process(); + }); + } + + if (rejectOnError || !callback) { + return new Promise((resolve, reject) => { + res = resolve; + rej = reject; + }) + } + } + + function _createCB(tasks) { + return function (err, ...args) { + numRunning -= 1; + + for (var i = 0, l = tasks.length; i < l; i++) { + var task = tasks[i]; + + var index = workersList.indexOf(task); + if (index === 0) { + workersList.shift(); + } else if (index > 0) { + workersList.splice(index, 1); + } + + task.callback(err, ...args); + + if (err != null) { + trigger('error', err, task.data); + } + } + + if (numRunning <= (q.concurrency - q.buffer) ) { + trigger('unsaturated'); + } + + if (q.idle()) { + trigger('drain'); + } + q.process(); + }; + } + + function _maybeDrain(data) { + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + setImmediate$1(() => trigger('drain')); + return true + } + return false + } + + const eventMethod = (name) => (handler) => { + if (!handler) { + return new Promise((resolve, reject) => { + once(name, (err, data) => { + if (err) return reject(err) + resolve(data); + }); + }) + } + off(name); + on(name, handler); + + }; + + var isProcessing = false; + var q = { + _tasks: new DLL(), + *[Symbol.iterator] () { + yield* q._tasks[Symbol.iterator](); + }, + concurrency, + payload, + buffer: concurrency / 4, + started: false, + paused: false, + push (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, false, false, callback)) + } + return _insert(data, false, false, callback); + }, + pushAsync (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, false, true, callback)) + } + return _insert(data, false, true, callback); + }, + kill () { + off(); + q._tasks.empty(); + }, + unshift (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, true, false, callback)) + } + return _insert(data, true, false, callback); + }, + unshiftAsync (data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return + return data.map(datum => _insert(datum, true, true, callback)) + } + return _insert(data, true, true, callback); + }, + remove (testFn) { + q._tasks.remove(testFn); + }, + process () { + // Avoid trying to start too many processing operations. This can occur + // when callbacks resolve synchronously (#1267). + if (isProcessing) { + return; + } + isProcessing = true; + while(!q.paused && numRunning < q.concurrency && q._tasks.length){ + var tasks = [], data = []; + var l = q._tasks.length; + if (q.payload) l = Math.min(l, q.payload); + for (var i = 0; i < l; i++) { + var node = q._tasks.shift(); + tasks.push(node); + workersList.push(node); + data.push(node.data); + } + + numRunning += 1; + + if (q._tasks.length === 0) { + trigger('empty'); + } + + if (numRunning === q.concurrency) { + trigger('saturated'); + } + + var cb = onlyOnce(_createCB(tasks)); + _worker(data, cb); + } + isProcessing = false; + }, + length () { + return q._tasks.length; + }, + running () { + return numRunning; + }, + workersList () { + return workersList; + }, + idle() { + return q._tasks.length + numRunning === 0; + }, + pause () { + q.paused = true; + }, + resume () { + if (q.paused === false) { return; } + q.paused = false; + setImmediate$1(q.process); + } + }; + // define these as fixed properties, so people get useful errors when updating + Object.defineProperties(q, { + saturated: { + writable: false, + value: eventMethod('saturated') + }, + unsaturated: { + writable: false, + value: eventMethod('unsaturated') + }, + empty: { + writable: false, + value: eventMethod('empty') + }, + drain: { + writable: false, + value: eventMethod('drain') + }, + error: { + writable: false, + value: eventMethod('error') + }, + }); + return q; +} + +/** + * Creates a `cargo` object with the specified payload. Tasks added to the + * cargo will be processed altogether (up to the `payload` limit). If the + * `worker` is in progress, the task is queued until it becomes available. Once + * the `worker` has completed some tasks, each callback of those tasks is + * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) + * for how `cargo` and `queue` work. + * + * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers + * at a time, cargo passes an array of tasks to a single worker, repeating + * when the worker is finished. + * + * @name cargo + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An asynchronous function for processing an array + * of queued tasks. Invoked with `(tasks, callback)`. + * @param {number} [payload=Infinity] - An optional `integer` for determining + * how many tasks should be processed per round; if omitted, the default is + * unlimited. + * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can + * attached as certain properties to listen for specific events during the + * lifecycle of the cargo and inner queue. + * @example + * + * // create a cargo object with payload 2 + * var cargo = async.cargo(function(tasks, callback) { + * for (var i=0; i { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.reduce(fileList, 0, getFileSizeInBytes); + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function reduce(coll, memo, iteratee, callback) { + callback = once(callback); + var _iteratee = wrapAsync(iteratee); + return eachOfSeries$1(coll, (x, i, iterCb) => { + _iteratee(memo, x, (err, v) => { + memo = v; + iterCb(err); + }); + }, err => callback(err, memo)); +} +var reduce$1 = awaitify(reduce, 4); + +/** + * Version of the compose function that is more natural to read. Each function + * consumes the return value of the previous function. It is the equivalent of + * [compose]{@link module:ControlFlow.compose} with the arguments reversed. + * + * Each function is executed with the `this` binding of the composed function. + * + * @name seq + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.compose]{@link module:ControlFlow.compose} + * @category Control Flow + * @param {...AsyncFunction} functions - the asynchronous functions to compose + * @returns {Function} a function that composes the `functions` in order + * @example + * + * // Requires lodash (or underscore), express3 and dresende's orm2. + * // Part of an app, that fetches cats of the logged user. + * // This example uses `seq` function to avoid overnesting and error + * // handling clutter. + * app.get('/cats', function(request, response) { + * var User = request.models.User; + * async.seq( + * User.get.bind(User), // 'User.get' has signature (id, callback(err, data)) + * function(user, fn) { + * user.getCats(fn); // 'getCats' has signature (callback(err, data)) + * } + * )(req.session.user_id, function (err, cats) { + * if (err) { + * console.error(err); + * response.json({ status: 'error', message: err.message }); + * } else { + * response.json({ status: 'ok', message: 'Cats found', data: cats }); + * } + * }); + * }); + */ +function seq(...functions) { + var _functions = functions.map(wrapAsync); + return function (...args) { + var that = this; + + var cb = args[args.length - 1]; + if (typeof cb == 'function') { + args.pop(); + } else { + cb = promiseCallback(); + } + + reduce$1(_functions, args, (newargs, fn, iterCb) => { + fn.apply(that, newargs.concat((err, ...nextargs) => { + iterCb(err, nextargs); + })); + }, + (err, results) => cb(err, ...results)); + + return cb[PROMISE_SYMBOL] + }; +} + +/** + * Creates a function which is a composition of the passed asynchronous + * functions. Each function consumes the return value of the function that + * follows. Composing functions `f()`, `g()`, and `h()` would produce the result + * of `f(g(h()))`, only this version uses callbacks to obtain the return values. + * + * If the last argument to the composed function is not a function, a promise + * is returned when you call it. + * + * Each function is executed with the `this` binding of the composed function. + * + * @name compose + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {...AsyncFunction} functions - the asynchronous functions to compose + * @returns {Function} an asynchronous function that is the composed + * asynchronous `functions` + * @example + * + * function add1(n, callback) { + * setTimeout(function () { + * callback(null, n + 1); + * }, 10); + * } + * + * function mul3(n, callback) { + * setTimeout(function () { + * callback(null, n * 3); + * }, 10); + * } + * + * var add1mul3 = async.compose(mul3, add1); + * add1mul3(4, function (err, result) { + * // result now equals 15 + * }); + */ +function compose(...args) { + return seq(...args.reverse()); +} + +/** + * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. + * + * @name mapLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function mapLimit (coll, limit, iteratee, callback) { + return _asyncMap(eachOfLimit(limit), coll, iteratee, callback) +} +var mapLimit$1 = awaitify(mapLimit, 4); + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time. + * + * @name concatLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapLimit + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatLimit(coll, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(coll, limit, (val, iterCb) => { + _iteratee(val, (err, ...args) => { + if (err) return iterCb(err); + return iterCb(err, args); + }); + }, (err, mapResults) => { + var result = []; + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + result = result.concat(...mapResults[i]); + } + } + + return callback(err, result); + }); +} +var concatLimit$1 = awaitify(concatLimit, 4); + +/** + * Applies `iteratee` to each item in `coll`, concatenating the results. Returns + * the concatenated list. The `iteratee`s are called in parallel, and the + * results are concatenated as they return. The results array will be returned in + * the original order of `coll` passed to the `iteratee` function. + * + * @name concat + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @alias flatMap + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * let directoryList = ['dir1','dir2','dir3']; + * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4']; + * + * // Using callbacks + * async.concat(directoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.concat(directoryList, fs.readdir) + * .then(results => { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir) + * .then(results => { + * console.log(results); + * }).catch(err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.concat(directoryList, fs.readdir); + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.concat(withMissingDirectoryList, fs.readdir); + * console.log(results); + * } catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } + * } + * + */ +function concat(coll, iteratee, callback) { + return concatLimit$1(coll, Infinity, iteratee, callback) +} +var concat$1 = awaitify(concat, 3); + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. + * + * @name concatSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapSeries + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. + * The iteratee should complete with an array an array of results. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatSeries(coll, iteratee, callback) { + return concatLimit$1(coll, 1, iteratee, callback) +} +var concatSeries$1 = awaitify(concatSeries, 3); + +/** + * Returns a function that when called, calls-back with the values provided. + * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to + * [`auto`]{@link module:ControlFlow.auto}. + * + * @name constant + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {...*} arguments... - Any number of arguments to automatically invoke + * callback with. + * @returns {AsyncFunction} Returns a function that when invoked, automatically + * invokes the callback with the previous given arguments. + * @example + * + * async.waterfall([ + * async.constant(42), + * function (value, next) { + * // value === 42 + * }, + * //... + * ], callback); + * + * async.waterfall([ + * async.constant(filename, "utf8"), + * fs.readFile, + * function (fileData, next) { + * //... + * } + * //... + * ], callback); + * + * async.auto({ + * hostname: async.constant("https://server.net/"), + * port: findFreePort, + * launchServer: ["hostname", "port", function (options, cb) { + * startServer(options, cb); + * }], + * //... + * }, callback); + */ +function constant(...args) { + return function (...ignoredArgs/*, callback*/) { + var callback = ignoredArgs.pop(); + return callback(null, ...args); + }; +} + +function _createTester(check, getResult) { + return (eachfn, arr, _iteratee, cb) => { + var testPassed = false; + var testResult; + const iteratee = wrapAsync(_iteratee); + eachfn(arr, (value, _, callback) => { + iteratee(value, (err, result) => { + if (err || err === false) return callback(err); + + if (check(result) && !testResult) { + testPassed = true; + testResult = getResult(true, value); + return callback(null, breakLoop); + } + callback(); + }); + }, err => { + if (err) return cb(err); + cb(null, testPassed ? testResult : getResult(false)); + }); + }; +} + +/** + * Returns the first value in `coll` that passes an async truth test. The + * `iteratee` is applied in parallel, meaning the first iteratee to return + * `true` will fire the detect `callback` with that result. That means the + * result might not be the first item in the original `coll` (in terms of order) + * that passes the test. + + * If order within the original `coll` is important, then look at + * [`detectSeries`]{@link module:Collections.detectSeries}. + * + * @name detect + * @static + * @memberOf module:Collections + * @method + * @alias find + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * } + *); + * + * // Using Promises + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists) + * .then(result => { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists); + * console.log(result); + * // dir1/file1.txt + * // result now equals the file in the list that exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function detect(coll, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback) +} +var detect$1 = awaitify(detect, 3); + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a + * time. + * + * @name detectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findLimit + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectLimit(coll, limit, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback) +} +var detectLimit$1 = awaitify(detectLimit, 4); + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. + * + * @name detectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findSeries + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectSeries(coll, iteratee, callback) { + return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback) +} + +var detectSeries$1 = awaitify(detectSeries, 3); + +function consoleFunc(name) { + return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => { + /* istanbul ignore else */ + if (typeof console === 'object') { + /* istanbul ignore else */ + if (err) { + /* istanbul ignore else */ + if (console.error) { + console.error(err); + } + } else if (console[name]) { /* istanbul ignore else */ + resultArgs.forEach(x => console[name](x)); + } + } + }) +} + +/** + * Logs the result of an [`async` function]{@link AsyncFunction} to the + * `console` using `console.dir` to display the properties of the resulting object. + * Only works in Node.js or in browsers that support `console.dir` and + * `console.error` (such as FF and Chrome). + * If multiple arguments are returned from the async function, + * `console.dir` is called on each argument in order. + * + * @name dir + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, {hello: name}); + * }, 1000); + * }; + * + * // in the node repl + * node> async.dir(hello, 'world'); + * {hello: 'world'} + */ +var dir = consoleFunc('dir'); + +/** + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in + * the order of operations, the arguments `test` and `iteratee` are switched. + * + * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + * + * @name doWhilst + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - A function which is called each time `test` + * passes. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. + * `callback` will be passed an error and any arguments passed to the final + * `iteratee`'s callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ +function doWhilst(iteratee, test, callback) { + callback = onlyOnce(callback); + var _fn = wrapAsync(iteratee); + var _test = wrapAsync(test); + var results; + + function next(err, ...args) { + if (err) return callback(err); + if (err === false) return; + results = args; + _test(...args, check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return check(null, true); +} + +var doWhilst$1 = awaitify(doWhilst, 3); + +/** + * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the + * argument ordering differs from `until`. + * + * @name doUntil + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee` + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ +function doUntil(iteratee, test, callback) { + const _test = wrapAsync(test); + return doWhilst$1(iteratee, (...args) => { + const cb = args.pop(); + _test(...args, (err, truth) => cb (err, !truth)); + }, callback); +} + +function _withoutIndex(iteratee) { + return (value, index, callback) => iteratee(value, callback); +} + +/** + * Applies the function `iteratee` to each item in `coll`, in parallel. + * The `iteratee` is called with an item from the list, and a callback for when + * it has finished. If the `iteratee` passes an error to its `callback`, the + * main `callback` (for the `each` function) is immediately called with the + * error. + * + * Note, that since this function applies `iteratee` to each item in parallel, + * there is no guarantee that the iteratee functions will complete in order. + * + * @name each + * @static + * @memberOf module:Collections + * @method + * @alias forEach + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to + * each item in `coll`. Invoked with (item, callback). + * The array index is not passed to the iteratee. + * If you need the index, use `eachOf`. + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt']; + * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt']; + * + * // asynchronous function that deletes a file + * const deleteFile = function(file, callback) { + * fs.unlink(file, callback); + * }; + * + * // Using callbacks + * async.each(fileList, deleteFile, function(err) { + * if( err ) { + * console.log(err); + * } else { + * console.log('All files have been deleted successfully'); + * } + * }); + * + * // Error Handling + * async.each(withMissingFileList, deleteFile, function(err){ + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using Promises + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using async/await + * async () => { + * try { + * await async.each(files, deleteFile); + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * await async.each(withMissingFileList, deleteFile); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * } + * } + * + */ +function eachLimit(coll, iteratee, callback) { + return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback); +} + +var each = awaitify(eachLimit, 3); + +/** + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. + * + * @name eachLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfLimit`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachLimit$1(coll, limit, iteratee, callback) { + return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback); +} +var eachLimit$2 = awaitify(eachLimit$1, 4); + +/** + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. + * + * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item + * in series and therefore the iteratee functions will complete in order. + + * @name eachSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfSeries`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachSeries(coll, iteratee, callback) { + return eachLimit$2(coll, 1, iteratee, callback) +} +var eachSeries$1 = awaitify(eachSeries, 3); + +/** + * Wrap an async function and ensure it calls its callback on a later tick of + * the event loop. If the function already calls its callback on a next tick, + * no extra deferral is added. This is useful for preventing stack overflows + * (`RangeError: Maximum call stack size exceeded`) and generally keeping + * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) + * contained. ES2017 `async` functions are returned as-is -- they are immune + * to Zalgo's corrupting influences, as they always resolve on a later tick. + * + * @name ensureAsync + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - an async function, one that expects a node-style + * callback as its last argument. + * @returns {AsyncFunction} Returns a wrapped function with the exact same call + * signature as the function passed in. + * @example + * + * function sometimesAsync(arg, callback) { + * if (cache[arg]) { + * return callback(null, cache[arg]); // this would be synchronous!! + * } else { + * doSomeIO(arg, callback); // this IO would be asynchronous + * } + * } + * + * // this has a risk of stack overflows if many results are cached in a row + * async.mapSeries(args, sometimesAsync, done); + * + * // this will defer sometimesAsync's callback if necessary, + * // preventing stack overflows + * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + */ +function ensureAsync(fn) { + if (isAsync(fn)) return fn; + return function (...args/*, callback*/) { + var callback = args.pop(); + var sync = true; + args.push((...innerArgs) => { + if (sync) { + setImmediate$1(() => callback(...innerArgs)); + } else { + callback(...innerArgs); + } + }); + fn.apply(this, args); + sync = false; + }; +} + +/** + * Returns `true` if every element in `coll` satisfies an async test. If any + * iteratee call returns `false`, the main `callback` is immediately called. + * + * @name every + * @static + * @memberOf module:Collections + * @method + * @alias all + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.every(fileList, fileExists, function(err, result) { + * console.log(result); + * // true + * // result is true since every file exists + * }); + * + * async.every(withMissingFileList, fileExists, function(err, result) { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }); + * + * // Using Promises + * async.every(fileList, fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.every(withMissingFileList, fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.every(fileList, fileExists); + * console.log(result); + * // true + * // result is true since every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.every(withMissingFileList, fileExists); + * console.log(result); + * // false + * // result is false since NOT every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function every(coll, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback) +} +var every$1 = awaitify(every, 3); + +/** + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. + * + * @name everyLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everyLimit(coll, limit, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback) +} +var everyLimit$1 = awaitify(everyLimit, 4); + +/** + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. + * + * @name everySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in series. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everySeries(coll, iteratee, callback) { + return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback) +} +var everySeries$1 = awaitify(everySeries, 3); + +function filterArray(eachfn, arr, iteratee, callback) { + var truthValues = new Array(arr.length); + eachfn(arr, (x, index, iterCb) => { + iteratee(x, (err, v) => { + truthValues[index] = !!v; + iterCb(err); + }); + }, err => { + if (err) return callback(err); + var results = []; + for (var i = 0; i < arr.length; i++) { + if (truthValues[i]) results.push(arr[i]); + } + callback(null, results); + }); +} + +function filterGeneric(eachfn, coll, iteratee, callback) { + var results = []; + eachfn(coll, (x, index, iterCb) => { + iteratee(x, (err, v) => { + if (err) return iterCb(err); + if (v) { + results.push({index, value: x}); + } + iterCb(err); + }); + }, err => { + if (err) return callback(err); + callback(null, results + .sort((a, b) => a.index - b.index) + .map(v => v.value)); + }); +} + +function _filter(eachfn, coll, iteratee, callback) { + var filter = isArrayLike(coll) ? filterArray : filterGeneric; + return filter(eachfn, coll, wrapAsync(iteratee), callback); +} + +/** + * Returns a new array of all the values in `coll` which pass an async truth + * test. This operation is performed in parallel, but the results array will be + * in the same order as the original. + * + * @name filter + * @static + * @memberOf module:Collections + * @method + * @alias select + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.filter(files, fileExists, function(err, results) { + * if(err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * }); + * + * // Using Promises + * async.filter(files, fileExists) + * .then(results => { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.filter(files, fileExists); + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function filter (coll, iteratee, callback) { + return _filter(eachOf$1, coll, iteratee, callback) +} +var filter$1 = awaitify(filter, 3); + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a + * time. + * + * @name filterLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + */ +function filterLimit (coll, limit, iteratee, callback) { + return _filter(eachOfLimit(limit), coll, iteratee, callback) +} +var filterLimit$1 = awaitify(filterLimit, 4); + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. + * + * @name filterSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results) + * @returns {Promise} a promise, if no callback provided + */ +function filterSeries (coll, iteratee, callback) { + return _filter(eachOfSeries$1, coll, iteratee, callback) +} +var filterSeries$1 = awaitify(filterSeries, 3); + +/** + * Calls the asynchronous function `fn` with a callback parameter that allows it + * to call itself again, in series, indefinitely. + + * If an error is passed to the callback then `errback` is called with the + * error, and execution stops, otherwise it will never be called. + * + * @name forever + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} fn - an async function to call repeatedly. + * Invoked with (next). + * @param {Function} [errback] - when `fn` passes an error to it's callback, + * this function will be called, and execution stops. Invoked with (err). + * @returns {Promise} a promise that rejects if an error occurs and an errback + * is not passed + * @example + * + * async.forever( + * function(next) { + * // next is suitable for passing to things that need a callback(err [, whatever]); + * // it will result in this function being called again. + * }, + * function(err) { + * // if next is called with a value in its first parameter, it will appear + * // in here as 'err', and execution will stop. + * } + * ); + */ +function forever(fn, errback) { + var done = onlyOnce(errback); + var task = wrapAsync(ensureAsync(fn)); + + function next(err) { + if (err) return done(err); + if (err === false) return; + task(next); + } + return next(); +} +var forever$1 = awaitify(forever, 2); + +/** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. + * + * @name groupByLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ +function groupByLimit(coll, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(coll, limit, (val, iterCb) => { + _iteratee(val, (err, key) => { + if (err) return iterCb(err); + return iterCb(err, {key, val}); + }); + }, (err, mapResults) => { + var result = {}; + // from MDN, handle object having an `hasOwnProperty` prop + var {hasOwnProperty} = Object.prototype; + + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + var {key} = mapResults[i]; + var {val} = mapResults[i]; + + if (hasOwnProperty.call(result, key)) { + result[key].push(val); + } else { + result[key] = [val]; + } + } + } + + return callback(err, result); + }); +} + +var groupByLimit$1 = awaitify(groupByLimit, 4); + +/** + * Returns a new object, where each value corresponds to an array of items, from + * `coll`, that returned the corresponding key. That is, the keys of the object + * correspond to the values passed to the `iteratee` callback. + * + * Note: Since this function applies the `iteratee` to each item in parallel, + * there is no guarantee that the `iteratee` functions will complete in order. + * However, the values for each key in the `result` will be in the same order as + * the original `coll`. For Objects, the values will roughly be in the order of + * the original Objects' keys (but this can vary across JavaScript engines). + * + * @name groupBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const files = ['dir1/file1.txt','dir2','dir4'] + * + * // asynchronous function that detects file type as none, file, or directory + * function detectFile(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(null, 'none'); + * } + * callback(null, stat.isDirectory() ? 'directory' : 'file'); + * }); + * } + * + * //Using callbacks + * async.groupBy(files, detectFile, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * }); + * + * // Using Promises + * async.groupBy(files, detectFile) + * .then( result => { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.groupBy(files, detectFile); + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function groupBy (coll, iteratee, callback) { + return groupByLimit$1(coll, Infinity, iteratee, callback) +} + +/** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. + * + * @name groupBySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whose + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ +function groupBySeries (coll, iteratee, callback) { + return groupByLimit$1(coll, 1, iteratee, callback) +} + +/** + * Logs the result of an `async` function to the `console`. Only works in + * Node.js or in browsers that support `console.log` and `console.error` (such + * as FF and Chrome). If multiple arguments are returned from the async + * function, `console.log` is called on each argument in order. + * + * @name log + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, 'hello ' + name); + * }, 1000); + * }; + * + * // in the node repl + * node> async.log(hello, 'world'); + * 'hello world' + */ +var log = consoleFunc('log'); + +/** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a + * time. + * + * @name mapValuesLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function mapValuesLimit(obj, limit, iteratee, callback) { + callback = once(callback); + var newObj = {}; + var _iteratee = wrapAsync(iteratee); + return eachOfLimit(limit)(obj, (val, key, next) => { + _iteratee(val, key, (err, result) => { + if (err) return next(err); + newObj[key] = result; + next(err); + }); + }, err => callback(err, newObj)); +} + +var mapValuesLimit$1 = awaitify(mapValuesLimit, 4); + +/** + * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. + * + * Produces a new Object by mapping each value of `obj` through the `iteratee` + * function. The `iteratee` is called each `value` and `key` from `obj` and a + * callback for when it has finished processing. Each of these callbacks takes + * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` + * passes an error to its callback, the main `callback` (for the `mapValues` + * function) is immediately called with the error. + * + * Note, the order of the keys in the result is not guaranteed. The keys will + * be roughly in the order they complete, (but this is very engine-specific) + * + * @name mapValues + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file3.txt' + * }; + * + * const withMissingFileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file4.txt' + * }; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, key, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * }); + * + * // Error handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.mapValues(fileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * }).catch (err => { + * console.log(err); + * }); + * + * // Error Handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch (err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.mapValues(fileMap, getFileSizeInBytes); + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function mapValues(obj, iteratee, callback) { + return mapValuesLimit$1(obj, Infinity, iteratee, callback) +} + +/** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. + * + * @name mapValuesSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function mapValuesSeries(obj, iteratee, callback) { + return mapValuesLimit$1(obj, 1, iteratee, callback) +} + +/** + * Caches the results of an async function. When creating a hash to store + * function results against, the callback is omitted from the hash and an + * optional hash function can be used. + * + * **Note: if the async function errs, the result will not be cached and + * subsequent calls will call the wrapped function.** + * + * If no hash function is specified, the first argument is used as a hash key, + * which may work reasonably if it is a string or a data type that converts to a + * distinct string. Note that objects and arrays will not behave reasonably. + * Neither will cases where the other arguments are significant. In such cases, + * specify your own hash function. + * + * The cache of results is exposed as the `memo` property of the function + * returned by `memoize`. + * + * @name memoize + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function to proxy and cache results from. + * @param {Function} hasher - An optional function for generating a custom hash + * for storing results. It has all the arguments applied to it apart from the + * callback, and must be synchronous. + * @returns {AsyncFunction} a memoized version of `fn` + * @example + * + * var slow_fn = function(name, callback) { + * // do something + * callback(null, result); + * }; + * var fn = async.memoize(slow_fn); + * + * // fn can now be used as if it were slow_fn + * fn('some name', function() { + * // callback + * }); + */ +function memoize(fn, hasher = v => v) { + var memo = Object.create(null); + var queues = Object.create(null); + var _fn = wrapAsync(fn); + var memoized = initialParams((args, callback) => { + var key = hasher(...args); + if (key in memo) { + setImmediate$1(() => callback(null, ...memo[key])); + } else if (key in queues) { + queues[key].push(callback); + } else { + queues[key] = [callback]; + _fn(...args, (err, ...resultArgs) => { + // #1465 don't memoize if an error occurred + if (!err) { + memo[key] = resultArgs; + } + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i](err, ...resultArgs); + } + }); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; +} + +/* istanbul ignore file */ + +/** + * Calls `callback` on a later loop around the event loop. In Node.js this just + * calls `process.nextTick`. In the browser it will use `setImmediate` if + * available, otherwise `setTimeout(callback, 0)`, which means other higher + * priority events may precede the execution of `callback`. + * + * This is used internally for browser-compatibility purposes. + * + * @name nextTick + * @static + * @memberOf module:Utils + * @method + * @see [async.setImmediate]{@link module:Utils.setImmediate} + * @category Util + * @param {Function} callback - The function to call on a later loop around + * the event loop. Invoked with (args...). + * @param {...*} args... - any number of additional arguments to pass to the + * callback on the next tick. + * @example + * + * var call_order = []; + * async.nextTick(function() { + * call_order.push('two'); + * // call_order now equals ['one','two'] + * }); + * call_order.push('one'); + * + * async.setImmediate(function (a, b, c) { + * // a, b, and c equal 1, 2, and 3 + * }, 1, 2, 3); + */ +var _defer$1; + +if (hasNextTick) { + _defer$1 = process.nextTick; +} else if (hasSetImmediate) { + _defer$1 = setImmediate; +} else { + _defer$1 = fallback; +} + +var nextTick = wrap(_defer$1); + +var _parallel = awaitify((eachfn, tasks, callback) => { + var results = isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, (task, key, taskCb) => { + wrapAsync(task)((err, ...result) => { + if (result.length < 2) { + [result] = result; + } + results[key] = result; + taskCb(err); + }); + }, err => callback(err, results)); +}, 3); + +/** + * Run the `tasks` collection of functions in parallel, without waiting until + * the previous function has completed. If any of the functions pass an error to + * its callback, the main `callback` is immediately called with the value of the + * error. Once the `tasks` have completed, the results are passed to the final + * `callback` as an array. + * + * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about + * parallel execution of code. If your tasks do not use any timers or perform + * any I/O, they will actually be executed in series. Any synchronous setup + * sections for each task will happen one after the other. JavaScript remains + * single-threaded. + * + * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the + * execution of other tasks when a task fails. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.parallel}. + * + * @name parallel + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * + * //Using Callbacks + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function parallel(tasks, callback) { + return _parallel(eachOf$1, tasks, callback); +} + +/** + * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a + * time. + * + * @name parallelLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.parallel]{@link module:ControlFlow.parallel} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + */ +function parallelLimit(tasks, limit, callback) { + return _parallel(eachOfLimit(limit), tasks, callback); +} + +/** + * A queue of tasks for the worker function to complete. + * @typedef {Iterable} QueueObject + * @memberOf module:ControlFlow + * @property {Function} length - a function returning the number of items + * waiting to be processed. Invoke with `queue.length()`. + * @property {boolean} started - a boolean indicating whether or not any + * items have been pushed and processed by the queue. + * @property {Function} running - a function returning the number of items + * currently being processed. Invoke with `queue.running()`. + * @property {Function} workersList - a function returning the array of items + * currently being processed. Invoke with `queue.workersList()`. + * @property {Function} idle - a function returning false if there are items + * waiting or being processed, or true if not. Invoke with `queue.idle()`. + * @property {number} concurrency - an integer for determining how many `worker` + * functions should be run in parallel. This property can be changed after a + * `queue` is created to alter the concurrency on-the-fly. + * @property {number} payload - an integer that specifies how many items are + * passed to the worker function at a time. only applies if this is a + * [cargo]{@link module:ControlFlow.cargo} object + * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback` + * once the `worker` has finished processing the task. Instead of a single task, + * a `tasks` array can be submitted. The respective callback is used for every + * task in the list. Invoke with `queue.push(task, [callback])`, + * @property {AsyncFunction} unshift - add a new task to the front of the `queue`. + * Invoke with `queue.unshift(task, [callback])`. + * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns + * a promise that rejects if an error occurs. + * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns + * a promise that rejects if an error occurs. + * @property {Function} remove - remove items from the queue that match a test + * function. The test function will be passed an object with a `data` property, + * and a `priority` property, if this is a + * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. + * Invoked with `queue.remove(testFn)`, where `testFn` is of the form + * `function ({data, priority}) {}` and returns a Boolean. + * @property {Function} saturated - a function that sets a callback that is + * called when the number of running workers hits the `concurrency` limit, and + * further tasks will be queued. If the callback is omitted, `q.saturated()` + * returns a promise for the next occurrence. + * @property {Function} unsaturated - a function that sets a callback that is + * called when the number of running workers is less than the `concurrency` & + * `buffer` limits, and further tasks will not be queued. If the callback is + * omitted, `q.unsaturated()` returns a promise for the next occurrence. + * @property {number} buffer - A minimum threshold buffer in order to say that + * the `queue` is `unsaturated`. + * @property {Function} empty - a function that sets a callback that is called + * when the last item from the `queue` is given to a `worker`. If the callback + * is omitted, `q.empty()` returns a promise for the next occurrence. + * @property {Function} drain - a function that sets a callback that is called + * when the last item from the `queue` has returned from the `worker`. If the + * callback is omitted, `q.drain()` returns a promise for the next occurrence. + * @property {Function} error - a function that sets a callback that is called + * when a task errors. Has the signature `function(error, task)`. If the + * callback is omitted, `error()` returns a promise that rejects on the next + * error. + * @property {boolean} paused - a boolean for determining whether the queue is + * in a paused state. + * @property {Function} pause - a function that pauses the processing of tasks + * until `resume()` is called. Invoke with `queue.pause()`. + * @property {Function} resume - a function that resumes the processing of + * queued tasks when the queue is paused. Invoke with `queue.resume()`. + * @property {Function} kill - a function that removes the `drain` callback and + * empties remaining tasks from the queue forcing it to go idle. No more tasks + * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. + * + * @example + * const q = async.queue(worker, 2) + * q.push(item1) + * q.push(item2) + * q.push(item3) + * // queues are iterable, spread into an array to inspect + * const items = [...q] // [item1, item2, item3] + * // or use for of + * for (let item of q) { + * console.log(item) + * } + * + * q.drain(() => { + * console.log('all done') + * }) + * // or + * await q.drain() + */ + +/** + * Creates a `queue` object with the specified `concurrency`. Tasks added to the + * `queue` are processed in parallel (up to the `concurrency` limit). If all + * `worker`s are in progress, the task is queued until one becomes available. + * Once a `worker` completes a `task`, that `task`'s callback is called. + * + * @name queue + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. Invoked with (task, callback). + * @param {number} [concurrency=1] - An `integer` for determining how many + * `worker` functions should be run in parallel. If omitted, the concurrency + * defaults to `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be + * attached as certain properties to listen for specific events during the + * lifecycle of the queue. + * @example + * + * // create a queue object with concurrency 2 + * var q = async.queue(function(task, callback) { + * console.log('hello ' + task.name); + * callback(); + * }, 2); + * + * // assign a callback + * q.drain(function() { + * console.log('all items have been processed'); + * }); + * // or await the end + * await q.drain() + * + * // assign an error callback + * q.error(function(err, task) { + * console.error('task experienced an error'); + * }); + * + * // add some items to the queue + * q.push({name: 'foo'}, function(err) { + * console.log('finished processing foo'); + * }); + * // callback is optional + * q.push({name: 'bar'}); + * + * // add some items to the queue (batch-wise) + * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { + * console.log('finished processing item'); + * }); + * + * // add some items to the front of the queue + * q.unshift({name: 'bar'}, function (err) { + * console.log('finished processing bar'); + * }); + */ +function queue$1 (worker, concurrency) { + var _worker = wrapAsync(worker); + return queue((items, cb) => { + _worker(items[0], cb); + }, concurrency, 1); +} + +// Binary min-heap implementation used for priority queue. +// Implementation is stable, i.e. push time is considered for equal priorities +class Heap { + constructor() { + this.heap = []; + this.pushCount = Number.MIN_SAFE_INTEGER; + } + + get length() { + return this.heap.length; + } + + empty () { + this.heap = []; + return this; + } + + percUp(index) { + let p; + + while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) { + let t = this.heap[index]; + this.heap[index] = this.heap[p]; + this.heap[p] = t; + + index = p; + } + } + + percDown(index) { + let l; + + while ((l=leftChi(index)) < this.heap.length) { + if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) { + l = l+1; + } + + if (smaller(this.heap[index], this.heap[l])) { + break; + } + + let t = this.heap[index]; + this.heap[index] = this.heap[l]; + this.heap[l] = t; + + index = l; + } + } + + push(node) { + node.pushCount = ++this.pushCount; + this.heap.push(node); + this.percUp(this.heap.length-1); + } + + unshift(node) { + return this.heap.push(node); + } + + shift() { + let [top] = this.heap; + + this.heap[0] = this.heap[this.heap.length-1]; + this.heap.pop(); + this.percDown(0); + + return top; + } + + toArray() { + return [...this]; + } + + *[Symbol.iterator] () { + for (let i = 0; i < this.heap.length; i++) { + yield this.heap[i].data; + } + } + + remove (testFn) { + let j = 0; + for (let i = 0; i < this.heap.length; i++) { + if (!testFn(this.heap[i])) { + this.heap[j] = this.heap[i]; + j++; + } + } + + this.heap.splice(j); + + for (let i = parent(this.heap.length-1); i >= 0; i--) { + this.percDown(i); + } + + return this; + } +} + +function leftChi(i) { + return (i<<1)+1; +} + +function parent(i) { + return ((i+1)>>1)-1; +} + +function smaller(x, y) { + if (x.priority !== y.priority) { + return x.priority < y.priority; + } + else { + return x.pushCount < y.pushCount; + } +} + +/** + * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and + * completed in ascending priority order. + * + * @name priorityQueue + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. + * Invoked with (task, callback). + * @param {number} concurrency - An `integer` for determining how many `worker` + * functions should be run in parallel. If omitted, the concurrency defaults to + * `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two + * differences between `queue` and `priorityQueue` objects: + * * `push(task, priority, [callback])` - `priority` should be a number. If an + * array of `tasks` is given, all tasks will be assigned the same priority. + * * The `unshift` method was removed. + */ +function priorityQueue(worker, concurrency) { + // Start with a normal queue + var q = queue$1(worker, concurrency); + var processingScheduled = false; + + q._tasks = new Heap(); + + // Override push to accept second parameter representing priority + q.push = function(data, priority = 0, callback = () => {}) { + if (typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + if (!Array.isArray(data)) { + data = [data]; + } + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return setImmediate$1(() => q.drain()); + } + + for (var i = 0, l = data.length; i < l; i++) { + var item = { + data: data[i], + priority, + callback + }; + + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + setImmediate$1(() => { + processingScheduled = false; + q.process(); + }); + } + }; + + // Remove unshift function + delete q.unshift; + + return q; +} + +/** + * Runs the `tasks` array of functions in parallel, without waiting until the + * previous function has completed. Once any of the `tasks` complete or pass an + * error to its callback, the main `callback` is immediately called. It's + * equivalent to `Promise.race()`. + * + * @name race + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} + * to run. Each function can complete with an optional `result` value. + * @param {Function} callback - A callback to run once any of the functions have + * completed. This function gets an error or result from the first function that + * completed. Invoked with (err, result). + * @returns undefined + * @example + * + * async.race([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], + * // main callback + * function(err, result) { + * // the result will be equal to 'two' as it finishes earlier + * }); + */ +function race(tasks, callback) { + callback = once(callback); + if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); + if (!tasks.length) return callback(); + for (var i = 0, l = tasks.length; i < l; i++) { + wrapAsync(tasks[i])(callback); + } +} + +var race$1 = awaitify(race, 2); + +/** + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. + * + * @name reduceRight + * @static + * @memberOf module:Collections + * @method + * @see [async.reduce]{@link module:Collections.reduce} + * @alias foldr + * @category Collection + * @param {Array} array - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function reduceRight (array, memo, iteratee, callback) { + var reversed = [...array].reverse(); + return reduce$1(reversed, memo, iteratee, callback); +} + +/** + * Wraps the async function in another function that always completes with a + * result object, even when it errors. + * + * The result object has either the property `error` or `value`. + * + * @name reflect + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function you want to wrap + * @returns {Function} - A function that always passes null to it's callback as + * the error. The second argument to the callback will be an `object` with + * either an `error` or a `value` property. + * @example + * + * async.parallel([ + * async.reflect(function(callback) { + * // do some stuff ... + * callback(null, 'one'); + * }), + * async.reflect(function(callback) { + * // do some more stuff but error ... + * callback('bad stuff happened'); + * }), + * async.reflect(function(callback) { + * // do some more stuff ... + * callback(null, 'two'); + * }) + * ], + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = 'bad stuff happened' + * // results[2].value = 'two' + * }); + */ +function reflect(fn) { + var _fn = wrapAsync(fn); + return initialParams(function reflectOn(args, reflectCallback) { + args.push((error, ...cbArgs) => { + let retVal = {}; + if (error) { + retVal.error = error; + } + if (cbArgs.length > 0){ + var value = cbArgs; + if (cbArgs.length <= 1) { + [value] = cbArgs; + } + retVal.value = value; + } + reflectCallback(null, retVal); + }); + + return _fn.apply(this, args); + }); +} + +/** + * A helper function that wraps an array or an object of functions with `reflect`. + * + * @name reflectAll + * @static + * @memberOf module:Utils + * @method + * @see [async.reflect]{@link module:Utils.reflect} + * @category Util + * @param {Array|Object|Iterable} tasks - The collection of + * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. + * @returns {Array} Returns an array of async functions, each wrapped in + * `async.reflect` + * @example + * + * let tasks = [ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * // do some more stuff but error ... + * callback(new Error('bad stuff happened')); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = Error('bad stuff happened') + * // results[2].value = 'two' + * }); + * + * // an example using an object instead of an array + * let tasks = { + * one: function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * two: function(callback) { + * callback('two'); + * }, + * three: function(callback) { + * setTimeout(function() { + * callback(null, 'three'); + * }, 100); + * } + * }; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results.one.value = 'one' + * // results.two.error = 'two' + * // results.three.value = 'three' + * }); + */ +function reflectAll(tasks) { + var results; + if (Array.isArray(tasks)) { + results = tasks.map(reflect); + } else { + results = {}; + Object.keys(tasks).forEach(key => { + results[key] = reflect.call(this, tasks[key]); + }); + } + return results; +} + +function reject(eachfn, arr, _iteratee, callback) { + const iteratee = wrapAsync(_iteratee); + return _filter(eachfn, arr, (value, cb) => { + iteratee(value, (err, v) => { + cb(err, !v); + }); + }, callback); +} + +/** + * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. + * + * @name reject + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.reject(fileList, fileExists, function(err, results) { + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }); + * + * // Using Promises + * async.reject(fileList, fileExists) + * .then( results => { + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.reject(fileList, fileExists); + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function reject$1 (coll, iteratee, callback) { + return reject(eachOf$1, coll, iteratee, callback) +} +var reject$2 = awaitify(reject$1, 3); + +/** + * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a + * time. + * + * @name rejectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function rejectLimit (coll, limit, iteratee, callback) { + return reject(eachOfLimit(limit), coll, iteratee, callback) +} +var rejectLimit$1 = awaitify(rejectLimit, 4); + +/** + * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. + * + * @name rejectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function rejectSeries (coll, iteratee, callback) { + return reject(eachOfSeries$1, coll, iteratee, callback) +} +var rejectSeries$1 = awaitify(rejectSeries, 3); + +function constant$1(value) { + return function () { + return value; + } +} + +/** + * Attempts to get a successful response from `task` no more than `times` times + * before returning an error. If the task is successful, the `callback` will be + * passed the result of the successful task. If all attempts fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name retry + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @see [async.retryable]{@link module:ControlFlow.retryable} + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an + * object with `times` and `interval` or a number. + * * `times` - The number of attempts to make before giving up. The default + * is `5`. + * * `interval` - The time to wait between retries, in milliseconds. The + * default is `0`. The interval may also be specified as a function of the + * retry count (see example). + * * `errorFilter` - An optional synchronous function that is invoked on + * erroneous result. If it returns `true` the retry attempts will continue; + * if the function returns `false` the retry flow is aborted with the current + * attempt's error and result being returned to the final callback. + * Invoked with (err). + * * If `opts` is a number, the number specifies the number of times to retry, + * with the default interval of `0`. + * @param {AsyncFunction} task - An async function to retry. + * Invoked with (callback). + * @param {Function} [callback] - An optional callback which is called when the + * task has succeeded, or after the final failed attempt. It receives the `err` + * and `result` arguments of the last attempt at completing the `task`. Invoked + * with (err, results). + * @returns {Promise} a promise if no callback provided + * + * @example + * + * // The `retry` function can be used as a stand-alone control flow by passing + * // a callback, as shown below: + * + * // try calling apiMethod 3 times + * async.retry(3, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 3 times, waiting 200 ms between each retry + * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 10 times with exponential backoff + * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) + * async.retry({ + * times: 10, + * interval: function(retryCount) { + * return 50 * Math.pow(2, retryCount); + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod the default 5 times no delay between each retry + * async.retry(apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod only when error condition satisfies, all other + * // errors will abort the retry control flow and return to final callback + * async.retry({ + * errorFilter: function(err) { + * return err.message === 'Temporary error'; // only retry on a specific error + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // to retry individual methods that are not as reliable within other + * // control flow functions, use the `retryable` wrapper: + * async.auto({ + * users: api.getUsers.bind(api), + * payments: async.retryable(3, api.getPayments.bind(api)) + * }, function(err, results) { + * // do something with the results + * }); + * + */ +const DEFAULT_TIMES = 5; +const DEFAULT_INTERVAL = 0; + +function retry(opts, task, callback) { + var options = { + times: DEFAULT_TIMES, + intervalFunc: constant$1(DEFAULT_INTERVAL) + }; + + if (arguments.length < 3 && typeof opts === 'function') { + callback = task || promiseCallback(); + task = opts; + } else { + parseTimes(options, opts); + callback = callback || promiseCallback(); + } + + if (typeof task !== 'function') { + throw new Error("Invalid arguments for async.retry"); + } + + var _task = wrapAsync(task); + + var attempt = 1; + function retryAttempt() { + _task((err, ...args) => { + if (err === false) return + if (err && attempt++ < options.times && + (typeof options.errorFilter != 'function' || + options.errorFilter(err))) { + setTimeout(retryAttempt, options.intervalFunc(attempt - 1)); + } else { + callback(err, ...args); + } + }); + } + + retryAttempt(); + return callback[PROMISE_SYMBOL] +} + +function parseTimes(acc, t) { + if (typeof t === 'object') { + acc.times = +t.times || DEFAULT_TIMES; + + acc.intervalFunc = typeof t.interval === 'function' ? + t.interval : + constant$1(+t.interval || DEFAULT_INTERVAL); + + acc.errorFilter = t.errorFilter; + } else if (typeof t === 'number' || typeof t === 'string') { + acc.times = +t || DEFAULT_TIMES; + } else { + throw new Error("Invalid arguments for async.retry"); + } +} + +/** + * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method + * wraps a task and makes it retryable, rather than immediately calling it + * with retries. + * + * @name retryable + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.retry]{@link module:ControlFlow.retry} + * @category Control Flow + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional + * options, exactly the same as from `retry`, except for a `opts.arity` that + * is the arity of the `task` function, defaulting to `task.length` + * @param {AsyncFunction} task - the asynchronous function to wrap. + * This function will be passed any arguments passed to the returned wrapper. + * Invoked with (...args, callback). + * @returns {AsyncFunction} The wrapped function, which when invoked, will + * retry on an error, based on the parameters specified in `opts`. + * This function will accept the same parameters as `task`. + * @example + * + * async.auto({ + * dep1: async.retryable(3, getFromFlakyService), + * process: ["dep1", async.retryable(3, function (results, cb) { + * maybeProcessData(results.dep1, cb); + * })] + * }, callback); + */ +function retryable (opts, task) { + if (!task) { + task = opts; + opts = null; + } + let arity = (opts && opts.arity) || task.length; + if (isAsync(task)) { + arity += 1; + } + var _task = wrapAsync(task); + return initialParams((args, callback) => { + if (args.length < arity - 1 || callback == null) { + args.push(callback); + callback = promiseCallback(); + } + function taskFn(cb) { + _task(...args, cb); + } + + if (opts) retry(opts, taskFn, callback); + else retry(taskFn, callback); + + return callback[PROMISE_SYMBOL] + }); +} + +/** + * Run the functions in the `tasks` collection in series, each one running once + * the previous function has completed. If any functions in the series pass an + * error to its callback, no more functions are run, and `callback` is + * immediately called with the value of the error. Otherwise, `callback` + * receives an array of results when `tasks` have completed. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function, and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.series}. + * + * **Note** that while many implementations preserve the order of object + * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) + * explicitly states that + * + * > The mechanics and order of enumerating the properties is not specified. + * + * So if you rely on the order in which your series of functions are executed, + * and want this to work on all platforms, consider using an array. + * + * @name series + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing + * [async functions]{@link AsyncFunction} to run in series. + * Each function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This function gets a results array (or object) + * containing all the result arguments passed to the `task` callbacks. Invoked + * with (err, result). + * @return {Promise} a promise, if no callback is passed + * @example + * + * //Using Callbacks + * async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] + * }); + * + * // an example using objects instead of arrays + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.series([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function series(tasks, callback) { + return _parallel(eachOfSeries$1, tasks, callback); +} + +/** + * Returns `true` if at least one element in the `coll` satisfies an async test. + * If any iteratee call returns `true`, the main `callback` is immediately + * called. + * + * @name some + * @static + * @memberOf module:Collections + * @method + * @alias any + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + *); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // false + * // result is false since none of the files exists + * } + *); + * + * // Using Promises + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since some file in the list exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since none of the files exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists); + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists); + * console.log(result); + * // false + * // result is false since none of the files exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function some(coll, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback) +} +var some$1 = awaitify(some, 3); + +/** + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. + * + * @name someLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anyLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someLimit(coll, limit, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback) +} +var someLimit$1 = awaitify(someLimit, 4); + +/** + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. + * + * @name someSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anySeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in series. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someSeries(coll, iteratee, callback) { + return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback) +} +var someSeries$1 = awaitify(someSeries, 3); + +/** + * Sorts a list by the results of running each `coll` value through an async + * `iteratee`. + * + * @name sortBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a value to use as the sort criteria as + * its `result`. + * Invoked with (item, callback). + * @param {Function} callback - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is the items + * from the original `coll` sorted by the values returned by the `iteratee` + * calls. Invoked with (err, results). + * @returns {Promise} a promise, if no callback passed + * @example + * + * // bigfile.txt is a file that is 251100 bytes in size + * // mediumfile.txt is a file that is 11000 bytes in size + * // smallfile.txt is a file that is 121 bytes in size + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // By modifying the callback parameter the + * // sorting order can be influenced: + * + * // ascending order + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) return callback(getFileSizeErr); + * callback(null, fileSize); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // descending order + * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) { + * return callback(getFileSizeErr); + * } + * callback(null, fileSize * -1); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt'] + * } + * } + * ); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * } + * ); + * + * // Using Promises + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * (async () => { + * try { + * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * // Error handling + * async () => { + * try { + * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function sortBy (coll, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return map$1(coll, (x, iterCb) => { + _iteratee(x, (err, criteria) => { + if (err) return iterCb(err); + iterCb(err, {value: x, criteria}); + }); + }, (err, results) => { + if (err) return callback(err); + callback(null, results.sort(comparator).map(v => v.value)); + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } +} +var sortBy$1 = awaitify(sortBy, 3); + +/** + * Sets a time limit on an asynchronous function. If the function does not call + * its callback within the specified milliseconds, it will be called with a + * timeout error. The code property for the error object will be `'ETIMEDOUT'`. + * + * @name timeout + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} asyncFn - The async function to limit in time. + * @param {number} milliseconds - The specified time limit. + * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) + * to timeout Error for more information.. + * @returns {AsyncFunction} Returns a wrapped function that can be used with any + * of the control flow functions. + * Invoke this function with the same parameters as you would `asyncFunc`. + * @example + * + * function myFunction(foo, callback) { + * doAsyncTask(foo, function(err, data) { + * // handle errors + * if (err) return callback(err); + * + * // do some stuff ... + * + * // return processed data + * return callback(null, data); + * }); + * } + * + * var wrapped = async.timeout(myFunction, 1000); + * + * // call `wrapped` as you would `myFunction` + * wrapped({ bar: 'bar' }, function(err, data) { + * // if `myFunction` takes < 1000 ms to execute, `err` + * // and `data` will have their expected values + * + * // else `err` will be an Error with the code 'ETIMEDOUT' + * }); + */ +function timeout(asyncFn, milliseconds, info) { + var fn = wrapAsync(asyncFn); + + return initialParams((args, callback) => { + var timedOut = false; + var timer; + + function timeoutCallback() { + var name = asyncFn.name || 'anonymous'; + var error = new Error('Callback function "' + name + '" timed out.'); + error.code = 'ETIMEDOUT'; + if (info) { + error.info = info; + } + timedOut = true; + callback(error); + } + + args.push((...cbArgs) => { + if (!timedOut) { + callback(...cbArgs); + clearTimeout(timer); + } + }); + + // setup timer and call original function + timer = setTimeout(timeoutCallback, milliseconds); + fn(...args); + }); +} + +function range(size) { + var result = Array(size); + while (size--) { + result[size] = size; + } + return result; +} + +/** + * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a + * time. + * + * @name timesLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} count - The number of times to run the function. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see [async.map]{@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ +function timesLimit(count, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + return mapLimit$1(range(count), limit, _iteratee, callback); +} + +/** + * Calls the `iteratee` function `n` times, and accumulates results in the same + * manner you would use with [map]{@link module:Collections.map}. + * + * @name times + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.map]{@link module:Collections.map} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + * @example + * + * // Pretend this is some complicated async factory + * var createUser = function(id, callback) { + * callback(null, { + * id: 'user' + id + * }); + * }; + * + * // generate 5 users + * async.times(5, function(n, next) { + * createUser(n, function(err, user) { + * next(err, user); + * }); + * }, function(err, users) { + * // we should now have 5 users + * }); + */ +function times (n, iteratee, callback) { + return timesLimit(n, Infinity, iteratee, callback) +} + +/** + * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. + * + * @name timesSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ +function timesSeries (n, iteratee, callback) { + return timesLimit(n, 1, iteratee, callback) +} + +/** + * A relative of `reduce`. Takes an Object or Array, and iterates over each + * element in parallel, each step potentially mutating an `accumulator` value. + * The type of the accumulator defaults to the type of collection passed in. + * + * @name transform + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} [accumulator] - The initial state of the transform. If omitted, + * it will default to an empty Object or Array, depending on the type of `coll` + * @param {AsyncFunction} iteratee - A function applied to each item in the + * collection that potentially modifies the accumulator. + * Invoked with (accumulator, item, key, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the transformed accumulator. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileList, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * }); + * + * // Using Promises + * async.transform(fileList, transformFileSize) + * .then(result => { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * (async () => { + * try { + * let result = await async.transform(fileList, transformFileSize); + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' }; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileMap, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * }); + * + * // Using Promises + * async.transform(fileMap, transformFileSize) + * .then(result => { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.transform(fileMap, transformFileSize); + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function transform (coll, accumulator, iteratee, callback) { + if (arguments.length <= 3 && typeof accumulator === 'function') { + callback = iteratee; + iteratee = accumulator; + accumulator = Array.isArray(coll) ? [] : {}; + } + callback = once(callback || promiseCallback()); + var _iteratee = wrapAsync(iteratee); + + eachOf$1(coll, (v, k, cb) => { + _iteratee(accumulator, v, k, cb); + }, err => callback(err, accumulator)); + return callback[PROMISE_SYMBOL] +} + +/** + * It runs each task in series but stops whenever any of the functions were + * successful. If one of the tasks were successful, the `callback` will be + * passed the result of the successful task. If all tasks fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name tryEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to + * run, each function is passed a `callback(err, result)` it must call on + * completion with an error `err` (which can be `null`) and an optional `result` + * value. + * @param {Function} [callback] - An optional callback which is called when one + * of the tasks has succeeded, or all have failed. It receives the `err` and + * `result` arguments of the last attempt at completing the `task`. Invoked with + * (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * async.tryEach([ + * function getDataFromFirstWebsite(callback) { + * // Try getting the data from the first website + * callback(err, data); + * }, + * function getDataFromSecondWebsite(callback) { + * // First website failed, + * // Try getting the data from the backup website + * callback(err, data); + * } + * ], + * // optional callback + * function(err, results) { + * Now do something with the data. + * }); + * + */ +function tryEach(tasks, callback) { + var error = null; + var result; + return eachSeries$1(tasks, (task, taskCb) => { + wrapAsync(task)((err, ...args) => { + if (err === false) return taskCb(err); + + if (args.length < 2) { + [result] = args; + } else { + result = args; + } + error = err; + taskCb(err ? null : {}); + }); + }, () => callback(error, result)); +} + +var tryEach$1 = awaitify(tryEach); + +/** + * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, + * unmemoized form. Handy for testing. + * + * @name unmemoize + * @static + * @memberOf module:Utils + * @method + * @see [async.memoize]{@link module:Utils.memoize} + * @category Util + * @param {AsyncFunction} fn - the memoized function + * @returns {AsyncFunction} a function that calls the original unmemoized function + */ +function unmemoize(fn) { + return (...args) => { + return (fn.unmemoized || fn)(...args); + }; +} + +/** + * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. + * + * @name whilst + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + * @example + * + * var count = 0; + * async.whilst( + * function test(cb) { cb(null, count < 5); }, + * function iter(callback) { + * count++; + * setTimeout(function() { + * callback(null, count); + * }, 1000); + * }, + * function (err, n) { + * // 5 seconds have passed, n = 5 + * } + * ); + */ +function whilst(test, iteratee, callback) { + callback = onlyOnce(callback); + var _fn = wrapAsync(iteratee); + var _test = wrapAsync(test); + var results = []; + + function next(err, ...rest) { + if (err) return callback(err); + results = rest; + if (err === false) return; + _test(check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return _test(check); +} +var whilst$1 = awaitify(whilst, 3); + +/** + * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. `callback` will be passed an error and any + * arguments passed to the final `iteratee`'s callback. + * + * The inverse of [whilst]{@link module:ControlFlow.whilst}. + * + * @name until + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (callback). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * const results = [] + * let finished = false + * async.until(function test(cb) { + * cb(null, finished) + * }, function iter(next) { + * fetchPage(url, (err, body) => { + * if (err) return next(err) + * results = results.concat(body.objects) + * finished = !!body.next + * next(err) + * }) + * }, function done (err) { + * // all pages have been fetched + * }) + */ +function until(test, iteratee, callback) { + const _test = wrapAsync(test); + return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback); +} + +/** + * Runs the `tasks` array of functions in series, each passing their results to + * the next in the array. However, if any of the `tasks` pass an error to their + * own callback, the next function is not executed, and the main `callback` is + * immediately called with the error. + * + * @name waterfall + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} + * to run. + * Each function should complete with any number of `result` values. + * The `result` values will be passed as arguments, in order, to the next task. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This will be passed the results of the last task's + * callback. Invoked with (err, [results]). + * @returns undefined + * @example + * + * async.waterfall([ + * function(callback) { + * callback(null, 'one', 'two'); + * }, + * function(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * }, + * function(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + * ], function (err, result) { + * // result now equals 'done' + * }); + * + * // Or, with named functions: + * async.waterfall([ + * myFirstFunction, + * mySecondFunction, + * myLastFunction, + * ], function (err, result) { + * // result now equals 'done' + * }); + * function myFirstFunction(callback) { + * callback(null, 'one', 'two'); + * } + * function mySecondFunction(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * } + * function myLastFunction(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + */ +function waterfall (tasks, callback) { + callback = once(callback); + if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); + if (!tasks.length) return callback(); + var taskIndex = 0; + + function nextTask(args) { + var task = wrapAsync(tasks[taskIndex++]); + task(...args, onlyOnce(next)); + } + + function next(err, ...args) { + if (err === false) return + if (err || taskIndex === tasks.length) { + return callback(err, ...args); + } + nextTask(args); + } + + nextTask([]); +} + +var waterfall$1 = awaitify(waterfall); + +/** + * An "async function" in the context of Async is an asynchronous function with + * a variable number of parameters, with the final parameter being a callback. + * (`function (arg1, arg2, ..., callback) {}`) + * The final callback is of the form `callback(err, results...)`, which must be + * called once the function is completed. The callback should be called with a + * Error as its first argument to signal that an error occurred. + * Otherwise, if no error occurred, it should be called with `null` as the first + * argument, and any additional `result` arguments that may apply, to signal + * successful completion. + * The callback must be called exactly once, ideally on a later tick of the + * JavaScript event loop. + * + * This type of function is also referred to as a "Node-style async function", + * or a "continuation passing-style function" (CPS). Most of the methods of this + * library are themselves CPS/Node-style async functions, or functions that + * return CPS/Node-style async functions. + * + * Wherever we accept a Node-style async function, we also directly accept an + * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. + * In this case, the `async` function will not be passed a final callback + * argument, and any thrown error will be used as the `err` argument of the + * implicit callback, and the return value will be used as the `result` value. + * (i.e. a `rejected` of the returned Promise becomes the `err` callback + * argument, and a `resolved` value becomes the `result`.) + * + * Note, due to JavaScript limitations, we can only detect native `async` + * functions and not transpilied implementations. + * Your environment must have `async`/`await` support for this to work. + * (e.g. Node > v7.6, or a recent version of a modern browser). + * If you are using `async` functions through a transpiler (e.g. Babel), you + * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, + * because the `async function` will be compiled to an ordinary function that + * returns a promise. + * + * @typedef {Function} AsyncFunction + * @static + */ + +var index = { + apply, + applyEach: applyEach$1, + applyEachSeries, + asyncify, + auto, + autoInject, + cargo, + cargoQueue: cargo$1, + compose, + concat: concat$1, + concatLimit: concatLimit$1, + concatSeries: concatSeries$1, + constant, + detect: detect$1, + detectLimit: detectLimit$1, + detectSeries: detectSeries$1, + dir, + doUntil, + doWhilst: doWhilst$1, + each, + eachLimit: eachLimit$2, + eachOf: eachOf$1, + eachOfLimit: eachOfLimit$2, + eachOfSeries: eachOfSeries$1, + eachSeries: eachSeries$1, + ensureAsync, + every: every$1, + everyLimit: everyLimit$1, + everySeries: everySeries$1, + filter: filter$1, + filterLimit: filterLimit$1, + filterSeries: filterSeries$1, + forever: forever$1, + groupBy, + groupByLimit: groupByLimit$1, + groupBySeries, + log, + map: map$1, + mapLimit: mapLimit$1, + mapSeries: mapSeries$1, + mapValues, + mapValuesLimit: mapValuesLimit$1, + mapValuesSeries, + memoize, + nextTick, + parallel, + parallelLimit, + priorityQueue, + queue: queue$1, + race: race$1, + reduce: reduce$1, + reduceRight, + reflect, + reflectAll, + reject: reject$2, + rejectLimit: rejectLimit$1, + rejectSeries: rejectSeries$1, + retry, + retryable, + seq, + series, + setImmediate: setImmediate$1, + some: some$1, + someLimit: someLimit$1, + someSeries: someSeries$1, + sortBy: sortBy$1, + timeout, + times, + timesLimit, + timesSeries, + transform, + tryEach: tryEach$1, + unmemoize, + until, + waterfall: waterfall$1, + whilst: whilst$1, + + // aliases + all: every$1, + allLimit: everyLimit$1, + allSeries: everySeries$1, + any: some$1, + anyLimit: someLimit$1, + anySeries: someSeries$1, + find: detect$1, + findLimit: detectLimit$1, + findSeries: detectSeries$1, + flatMap: concat$1, + flatMapLimit: concatLimit$1, + flatMapSeries: concatSeries$1, + forEach: each, + forEachSeries: eachSeries$1, + forEachLimit: eachLimit$2, + forEachOf: eachOf$1, + forEachOfSeries: eachOfSeries$1, + forEachOfLimit: eachOfLimit$2, + inject: reduce$1, + foldl: reduce$1, + foldr: reduceRight, + select: filter$1, + selectLimit: filterLimit$1, + selectSeries: filterSeries$1, + wrapSync: asyncify, + during: whilst$1, + doDuring: doWhilst$1 +}; + +export default index; +export { apply, applyEach$1 as applyEach, applyEachSeries, asyncify, auto, autoInject, cargo, cargo$1 as cargoQueue, compose, concat$1 as concat, concatLimit$1 as concatLimit, concatSeries$1 as concatSeries, constant, detect$1 as detect, detectLimit$1 as detectLimit, detectSeries$1 as detectSeries, dir, doUntil, doWhilst$1 as doWhilst, each, eachLimit$2 as eachLimit, eachOf$1 as eachOf, eachOfLimit$2 as eachOfLimit, eachOfSeries$1 as eachOfSeries, eachSeries$1 as eachSeries, ensureAsync, every$1 as every, everyLimit$1 as everyLimit, everySeries$1 as everySeries, filter$1 as filter, filterLimit$1 as filterLimit, filterSeries$1 as filterSeries, forever$1 as forever, groupBy, groupByLimit$1 as groupByLimit, groupBySeries, log, map$1 as map, mapLimit$1 as mapLimit, mapSeries$1 as mapSeries, mapValues, mapValuesLimit$1 as mapValuesLimit, mapValuesSeries, memoize, nextTick, parallel, parallelLimit, priorityQueue, queue$1 as queue, race$1 as race, reduce$1 as reduce, reduceRight, reflect, reflectAll, reject$2 as reject, rejectLimit$1 as rejectLimit, rejectSeries$1 as rejectSeries, retry, retryable, seq, series, setImmediate$1 as setImmediate, some$1 as some, someLimit$1 as someLimit, someSeries$1 as someSeries, sortBy$1 as sortBy, timeout, times, timesLimit, timesSeries, transform, tryEach$1 as tryEach, unmemoize, until, waterfall$1 as waterfall, whilst$1 as whilst, every$1 as all, everyLimit$1 as allLimit, everySeries$1 as allSeries, some$1 as any, someLimit$1 as anyLimit, someSeries$1 as anySeries, detect$1 as find, detectLimit$1 as findLimit, detectSeries$1 as findSeries, concat$1 as flatMap, concatLimit$1 as flatMapLimit, concatSeries$1 as flatMapSeries, each as forEach, eachSeries$1 as forEachSeries, eachLimit$2 as forEachLimit, eachOf$1 as forEachOf, eachOfSeries$1 as forEachOfSeries, eachOfLimit$2 as forEachOfLimit, reduce$1 as inject, reduce$1 as foldl, reduceRight as foldr, filter$1 as select, filterLimit$1 as selectLimit, filterSeries$1 as selectSeries, asyncify as wrapSync, whilst$1 as during, doWhilst$1 as doDuring }; diff --git a/Challenge/seokahi/010.star/node_modules/async/doDuring.js b/Challenge/seokahi/010.star/node_modules/async/doDuring.js new file mode 100644 index 0000000..4c98e9e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/doDuring.js @@ -0,0 +1,68 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in + * the order of operations, the arguments `test` and `iteratee` are switched. + * + * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + * + * @name doWhilst + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - A function which is called each time `test` + * passes. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. + * `callback` will be passed an error and any arguments passed to the final + * `iteratee`'s callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ +function doWhilst(iteratee, test, callback) { + callback = (0, _onlyOnce2.default)(callback); + var _fn = (0, _wrapAsync2.default)(iteratee); + var _test = (0, _wrapAsync2.default)(test); + var results; + + function next(err, ...args) { + if (err) return callback(err); + if (err === false) return; + results = args; + _test(...args, check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return check(null, true); +} + +exports.default = (0, _awaitify2.default)(doWhilst, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/doUntil.js b/Challenge/seokahi/010.star/node_modules/async/doUntil.js new file mode 100644 index 0000000..8aa0935 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/doUntil.js @@ -0,0 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = doUntil; + +var _doWhilst = require('./doWhilst.js'); + +var _doWhilst2 = _interopRequireDefault(_doWhilst); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the + * argument ordering differs from `until`. + * + * @name doUntil + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee` + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ +function doUntil(iteratee, test, callback) { + const _test = (0, _wrapAsync2.default)(test); + return (0, _doWhilst2.default)(iteratee, (...args) => { + const cb = args.pop(); + _test(...args, (err, truth) => cb(err, !truth)); + }, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/doWhilst.js b/Challenge/seokahi/010.star/node_modules/async/doWhilst.js new file mode 100644 index 0000000..4c98e9e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/doWhilst.js @@ -0,0 +1,68 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in + * the order of operations, the arguments `test` and `iteratee` are switched. + * + * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + * + * @name doWhilst + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - A function which is called each time `test` + * passes. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform after each + * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. + * `callback` will be passed an error and any arguments passed to the final + * `iteratee`'s callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + */ +function doWhilst(iteratee, test, callback) { + callback = (0, _onlyOnce2.default)(callback); + var _fn = (0, _wrapAsync2.default)(iteratee); + var _test = (0, _wrapAsync2.default)(test); + var results; + + function next(err, ...args) { + if (err) return callback(err); + if (err === false) return; + results = args; + _test(...args, check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return check(null, true); +} + +exports.default = (0, _awaitify2.default)(doWhilst, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/during.js b/Challenge/seokahi/010.star/node_modules/async/during.js new file mode 100644 index 0000000..32a4776 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/during.js @@ -0,0 +1,78 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. + * + * @name whilst + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + * @example + * + * var count = 0; + * async.whilst( + * function test(cb) { cb(null, count < 5); }, + * function iter(callback) { + * count++; + * setTimeout(function() { + * callback(null, count); + * }, 1000); + * }, + * function (err, n) { + * // 5 seconds have passed, n = 5 + * } + * ); + */ +function whilst(test, iteratee, callback) { + callback = (0, _onlyOnce2.default)(callback); + var _fn = (0, _wrapAsync2.default)(iteratee); + var _test = (0, _wrapAsync2.default)(test); + var results = []; + + function next(err, ...rest) { + if (err) return callback(err); + results = rest; + if (err === false) return; + _test(check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return _test(check); +} +exports.default = (0, _awaitify2.default)(whilst, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/each.js b/Challenge/seokahi/010.star/node_modules/async/each.js new file mode 100644 index 0000000..405d495 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/each.js @@ -0,0 +1,129 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _withoutIndex = require('./internal/withoutIndex.js'); + +var _withoutIndex2 = _interopRequireDefault(_withoutIndex); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Applies the function `iteratee` to each item in `coll`, in parallel. + * The `iteratee` is called with an item from the list, and a callback for when + * it has finished. If the `iteratee` passes an error to its `callback`, the + * main `callback` (for the `each` function) is immediately called with the + * error. + * + * Note, that since this function applies `iteratee` to each item in parallel, + * there is no guarantee that the iteratee functions will complete in order. + * + * @name each + * @static + * @memberOf module:Collections + * @method + * @alias forEach + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to + * each item in `coll`. Invoked with (item, callback). + * The array index is not passed to the iteratee. + * If you need the index, use `eachOf`. + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt']; + * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt']; + * + * // asynchronous function that deletes a file + * const deleteFile = function(file, callback) { + * fs.unlink(file, callback); + * }; + * + * // Using callbacks + * async.each(fileList, deleteFile, function(err) { + * if( err ) { + * console.log(err); + * } else { + * console.log('All files have been deleted successfully'); + * } + * }); + * + * // Error Handling + * async.each(withMissingFileList, deleteFile, function(err){ + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using Promises + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using async/await + * async () => { + * try { + * await async.each(files, deleteFile); + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * await async.each(withMissingFileList, deleteFile); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * } + * } + * + */ +function eachLimit(coll, iteratee, callback) { + return (0, _eachOf2.default)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback); +} + +exports.default = (0, _awaitify2.default)(eachLimit, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/eachLimit.js b/Challenge/seokahi/010.star/node_modules/async/eachLimit.js new file mode 100644 index 0000000..5f3d009 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/eachLimit.js @@ -0,0 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _withoutIndex = require('./internal/withoutIndex.js'); + +var _withoutIndex2 = _interopRequireDefault(_withoutIndex); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. + * + * @name eachLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfLimit`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachLimit(coll, limit, iteratee, callback) { + return (0, _eachOfLimit2.default)(limit)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback); +} +exports.default = (0, _awaitify2.default)(eachLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/eachOf.js b/Challenge/seokahi/010.star/node_modules/async/eachOf.js new file mode 100644 index 0000000..c22614f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/eachOf.js @@ -0,0 +1,185 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _isArrayLike = require('./internal/isArrayLike.js'); + +var _isArrayLike2 = _interopRequireDefault(_isArrayLike); + +var _breakLoop = require('./internal/breakLoop.js'); + +var _breakLoop2 = _interopRequireDefault(_breakLoop); + +var _eachOfLimit = require('./eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eachOf implementation optimized for array-likes +function eachOfArrayLike(coll, iteratee, callback) { + callback = (0, _once2.default)(callback); + var index = 0, + completed = 0, + { length } = coll, + canceled = false; + if (length === 0) { + callback(null); + } + + function iteratorCallback(err, value) { + if (err === false) { + canceled = true; + } + if (canceled === true) return; + if (err) { + callback(err); + } else if (++completed === length || value === _breakLoop2.default) { + callback(null); + } + } + + for (; index < length; index++) { + iteratee(coll[index], index, (0, _onlyOnce2.default)(iteratorCallback)); + } +} + +// a generic version of eachOf which can handle array, object, and iterator cases. +function eachOfGeneric(coll, iteratee, callback) { + return (0, _eachOfLimit2.default)(coll, Infinity, iteratee, callback); +} + +/** + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument + * to the iteratee. + * + * @name eachOf + * @static + * @memberOf module:Collections + * @method + * @alias forEachOf + * @category Collection + * @see [async.each]{@link module:Collections.each} + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each + * item in `coll`. + * The `key` is the item's key, or index in the case of an array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dev.json is a file containing a valid json object config for dev environment + * // dev.json is a file containing a valid json object config for test environment + * // prod.json is a file containing a valid json object config for prod environment + * // invalid.json is a file with a malformed json object + * + * let configs = {}; //global variable + * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'}; + * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'}; + * + * // asynchronous function that reads a json file and parses the contents as json object + * function parseFile(file, key, callback) { + * fs.readFile(file, "utf8", function(err, data) { + * if (err) return calback(err); + * try { + * configs[key] = JSON.parse(data); + * } catch (e) { + * return callback(e); + * } + * callback(); + * }); + * } + * + * // Using callbacks + * async.forEachOf(validConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * } else { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * // JSON parse error exception + * } else { + * console.log(configs); + * } + * }); + * + * // Using Promises + * async.forEachOf(validConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * }).catch( err => { + * console.error(err); + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * }).catch( err => { + * console.error(err); + * // JSON parse error exception + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.forEachOf(validConfigFileMap, parseFile); + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * catch (err) { + * console.log(err); + * } + * } + * + * //Error handing + * async () => { + * try { + * let result = await async.forEachOf(invalidConfigFileMap, parseFile); + * console.log(configs); + * } + * catch (err) { + * console.log(err); + * // JSON parse error exception + * } + * } + * + */ +function eachOf(coll, iteratee, callback) { + var eachOfImplementation = (0, _isArrayLike2.default)(coll) ? eachOfArrayLike : eachOfGeneric; + return eachOfImplementation(coll, (0, _wrapAsync2.default)(iteratee), callback); +} + +exports.default = (0, _awaitify2.default)(eachOf, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/eachOfLimit.js b/Challenge/seokahi/010.star/node_modules/async/eachOfLimit.js new file mode 100644 index 0000000..e9fc4db --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/eachOfLimit.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit2 = require('./internal/eachOfLimit.js'); + +var _eachOfLimit3 = _interopRequireDefault(_eachOfLimit2); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a + * time. + * + * @name eachOfLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. The `key` is the item's key, or index in the case of an + * array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfLimit(coll, limit, iteratee, callback) { + return (0, _eachOfLimit3.default)(limit)(coll, (0, _wrapAsync2.default)(iteratee), callback); +} + +exports.default = (0, _awaitify2.default)(eachOfLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/eachOfSeries.js b/Challenge/seokahi/010.star/node_modules/async/eachOfSeries.js new file mode 100644 index 0000000..cfb0f33 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/eachOfSeries.js @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit = require('./eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. + * + * @name eachOfSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfSeries(coll, iteratee, callback) { + return (0, _eachOfLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(eachOfSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/eachSeries.js b/Challenge/seokahi/010.star/node_modules/async/eachSeries.js new file mode 100644 index 0000000..d674d0c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/eachSeries.js @@ -0,0 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachLimit = require('./eachLimit.js'); + +var _eachLimit2 = _interopRequireDefault(_eachLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. + * + * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item + * in series and therefore the iteratee functions will complete in order. + + * @name eachSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfSeries`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachSeries(coll, iteratee, callback) { + return (0, _eachLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(eachSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/ensureAsync.js b/Challenge/seokahi/010.star/node_modules/async/ensureAsync.js new file mode 100644 index 0000000..ad8beb5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/ensureAsync.js @@ -0,0 +1,67 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = ensureAsync; + +var _setImmediate = require('./internal/setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Wrap an async function and ensure it calls its callback on a later tick of + * the event loop. If the function already calls its callback on a next tick, + * no extra deferral is added. This is useful for preventing stack overflows + * (`RangeError: Maximum call stack size exceeded`) and generally keeping + * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) + * contained. ES2017 `async` functions are returned as-is -- they are immune + * to Zalgo's corrupting influences, as they always resolve on a later tick. + * + * @name ensureAsync + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - an async function, one that expects a node-style + * callback as its last argument. + * @returns {AsyncFunction} Returns a wrapped function with the exact same call + * signature as the function passed in. + * @example + * + * function sometimesAsync(arg, callback) { + * if (cache[arg]) { + * return callback(null, cache[arg]); // this would be synchronous!! + * } else { + * doSomeIO(arg, callback); // this IO would be asynchronous + * } + * } + * + * // this has a risk of stack overflows if many results are cached in a row + * async.mapSeries(args, sometimesAsync, done); + * + * // this will defer sometimesAsync's callback if necessary, + * // preventing stack overflows + * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + */ +function ensureAsync(fn) { + if ((0, _wrapAsync.isAsync)(fn)) return fn; + return function (...args /*, callback*/) { + var callback = args.pop(); + var sync = true; + args.push((...innerArgs) => { + if (sync) { + (0, _setImmediate2.default)(() => callback(...innerArgs)); + } else { + callback(...innerArgs); + } + }); + fn.apply(this, args); + sync = false; + }; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/every.js b/Challenge/seokahi/010.star/node_modules/async/every.js new file mode 100644 index 0000000..148db68 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/every.js @@ -0,0 +1,119 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns `true` if every element in `coll` satisfies an async test. If any + * iteratee call returns `false`, the main `callback` is immediately called. + * + * @name every + * @static + * @memberOf module:Collections + * @method + * @alias all + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.every(fileList, fileExists, function(err, result) { + * console.log(result); + * // true + * // result is true since every file exists + * }); + * + * async.every(withMissingFileList, fileExists, function(err, result) { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }); + * + * // Using Promises + * async.every(fileList, fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.every(withMissingFileList, fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since NOT every file exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.every(fileList, fileExists); + * console.log(result); + * // true + * // result is true since every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.every(withMissingFileList, fileExists); + * console.log(result); + * // false + * // result is false since NOT every file exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function every(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(every, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/everyLimit.js b/Challenge/seokahi/010.star/node_modules/async/everyLimit.js new file mode 100644 index 0000000..25b2c08 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/everyLimit.js @@ -0,0 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. + * + * @name everyLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everyLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(everyLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/everySeries.js b/Challenge/seokahi/010.star/node_modules/async/everySeries.js new file mode 100644 index 0000000..147c3dc --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/everySeries.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. + * + * @name everySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in series. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function everySeries(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(everySeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/filter.js b/Challenge/seokahi/010.star/node_modules/async/filter.js new file mode 100644 index 0000000..303dc1f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/filter.js @@ -0,0 +1,93 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a new array of all the values in `coll` which pass an async truth + * test. This operation is performed in parallel, but the results array will be + * in the same order as the original. + * + * @name filter + * @static + * @memberOf module:Collections + * @method + * @alias select + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.filter(files, fileExists, function(err, results) { + * if(err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * }); + * + * // Using Promises + * async.filter(files, fileExists) + * .then(results => { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.filter(files, fileExists); + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function filter(coll, iteratee, callback) { + return (0, _filter3.default)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filter, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/filterLimit.js b/Challenge/seokahi/010.star/node_modules/async/filterLimit.js new file mode 100644 index 0000000..89e55f5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/filterLimit.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a + * time. + * + * @name filterLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + */ +function filterLimit(coll, limit, iteratee, callback) { + return (0, _filter3.default)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filterLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/filterSeries.js b/Challenge/seokahi/010.star/node_modules/async/filterSeries.js new file mode 100644 index 0000000..a045e52 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/filterSeries.js @@ -0,0 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. + * + * @name filterSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results) + * @returns {Promise} a promise, if no callback provided + */ +function filterSeries(coll, iteratee, callback) { + return (0, _filter3.default)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filterSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/find.js b/Challenge/seokahi/010.star/node_modules/async/find.js new file mode 100644 index 0000000..b3ed7ab --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/find.js @@ -0,0 +1,96 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns the first value in `coll` that passes an async truth test. The + * `iteratee` is applied in parallel, meaning the first iteratee to return + * `true` will fire the detect `callback` with that result. That means the + * result might not be the first item in the original `coll` (in terms of order) + * that passes the test. + + * If order within the original `coll` is important, then look at + * [`detectSeries`]{@link module:Collections.detectSeries}. + * + * @name detect + * @static + * @memberOf module:Collections + * @method + * @alias find + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * } + *); + * + * // Using Promises + * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists) + * .then(result => { + * console.log(result); + * // dir1/file1.txt + * // result now equals the first file in the list that exists + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists); + * console.log(result); + * // dir1/file1.txt + * // result now equals the file in the list that exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function detect(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(detect, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/findLimit.js b/Challenge/seokahi/010.star/node_modules/async/findLimit.js new file mode 100644 index 0000000..0ddb860 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/findLimit.js @@ -0,0 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a + * time. + * + * @name detectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findLimit + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(detectLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/findSeries.js b/Challenge/seokahi/010.star/node_modules/async/findSeries.js new file mode 100644 index 0000000..0c4f26a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/findSeries.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. + * + * @name detectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findSeries + * @category Collections + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @returns a Promise if no callback is passed + */ +function detectSeries(coll, iteratee, callback) { + return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(1), coll, iteratee, callback); +} + +exports.default = (0, _awaitify2.default)(detectSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/flatMap.js b/Challenge/seokahi/010.star/node_modules/async/flatMap.js new file mode 100644 index 0000000..8eed1ac --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/flatMap.js @@ -0,0 +1,115 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _concatLimit = require('./concatLimit.js'); + +var _concatLimit2 = _interopRequireDefault(_concatLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Applies `iteratee` to each item in `coll`, concatenating the results. Returns + * the concatenated list. The `iteratee`s are called in parallel, and the + * results are concatenated as they return. The results array will be returned in + * the original order of `coll` passed to the `iteratee` function. + * + * @name concat + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @alias flatMap + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * let directoryList = ['dir1','dir2','dir3']; + * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4']; + * + * // Using callbacks + * async.concat(directoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.concat(directoryList, fs.readdir) + * .then(results => { + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Error Handling + * async.concat(withMissingDirectoryList, fs.readdir) + * .then(results => { + * console.log(results); + * }).catch(err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.concat(directoryList, fs.readdir); + * console.log(results); + * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ] + * } catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.concat(withMissingDirectoryList, fs.readdir); + * console.log(results); + * } catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4 does not exist + * } + * } + * + */ +function concat(coll, iteratee, callback) { + return (0, _concatLimit2.default)(coll, Infinity, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(concat, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/flatMapLimit.js b/Challenge/seokahi/010.star/node_modules/async/flatMapLimit.js new file mode 100644 index 0000000..3d170f1 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/flatMapLimit.js @@ -0,0 +1,60 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _mapLimit = require('./mapLimit.js'); + +var _mapLimit2 = _interopRequireDefault(_mapLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time. + * + * @name concatLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapLimit + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, + * which should use an array as its result. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatLimit(coll, limit, iteratee, callback) { + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _mapLimit2.default)(coll, limit, (val, iterCb) => { + _iteratee(val, (err, ...args) => { + if (err) return iterCb(err); + return iterCb(err, args); + }); + }, (err, mapResults) => { + var result = []; + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + result = result.concat(...mapResults[i]); + } + } + + return callback(err, result); + }); +} +exports.default = (0, _awaitify2.default)(concatLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/flatMapSeries.js b/Challenge/seokahi/010.star/node_modules/async/flatMapSeries.js new file mode 100644 index 0000000..84add3b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/flatMapSeries.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _concatLimit = require('./concatLimit.js'); + +var _concatLimit2 = _interopRequireDefault(_concatLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. + * + * @name concatSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.concat]{@link module:Collections.concat} + * @category Collection + * @alias flatMapSeries + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. + * The iteratee should complete with an array an array of results. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is an array + * containing the concatenated results of the `iteratee` function. Invoked with + * (err, results). + * @returns A Promise, if no callback is passed + */ +function concatSeries(coll, iteratee, callback) { + return (0, _concatLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(concatSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/foldl.js b/Challenge/seokahi/010.star/node_modules/async/foldl.js new file mode 100644 index 0000000..56e2db8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/foldl.js @@ -0,0 +1,153 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Reduces `coll` into a single value using an async `iteratee` to return each + * successive step. `memo` is the initial state of the reduction. This function + * only operates in series. + * + * For performance reasons, it may make sense to split a call to this function + * into a parallel map, and then use the normal `Array.prototype.reduce` on the + * results. This function is for situations where each step in the reduction + * needs to be async; if you can get the data before reducing it, then it's + * probably a good idea to do so. + * + * @name reduce + * @static + * @memberOf module:Collections + * @method + * @alias inject + * @alias foldl + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt']; + * + * // asynchronous function that computes the file size in bytes + * // file size is added to the memoized value, then returned + * function getFileSizeInBytes(memo, file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, memo + stat.size); + * }); + * } + * + * // Using callbacks + * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.reduce(fileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.reduce(fileList, 0, getFileSizeInBytes); + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function reduce(coll, memo, iteratee, callback) { + callback = (0, _once2.default)(callback); + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _eachOfSeries2.default)(coll, (x, i, iterCb) => { + _iteratee(memo, x, (err, v) => { + memo = v; + iterCb(err); + }); + }, err => callback(err, memo)); +} +exports.default = (0, _awaitify2.default)(reduce, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/foldr.js b/Challenge/seokahi/010.star/node_modules/async/foldr.js new file mode 100644 index 0000000..bee5391 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/foldr.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = reduceRight; + +var _reduce = require('./reduce.js'); + +var _reduce2 = _interopRequireDefault(_reduce); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. + * + * @name reduceRight + * @static + * @memberOf module:Collections + * @method + * @see [async.reduce]{@link module:Collections.reduce} + * @alias foldr + * @category Collection + * @param {Array} array - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function reduceRight(array, memo, iteratee, callback) { + var reversed = [...array].reverse(); + return (0, _reduce2.default)(reversed, memo, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEach.js b/Challenge/seokahi/010.star/node_modules/async/forEach.js new file mode 100644 index 0000000..405d495 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEach.js @@ -0,0 +1,129 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _withoutIndex = require('./internal/withoutIndex.js'); + +var _withoutIndex2 = _interopRequireDefault(_withoutIndex); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Applies the function `iteratee` to each item in `coll`, in parallel. + * The `iteratee` is called with an item from the list, and a callback for when + * it has finished. If the `iteratee` passes an error to its `callback`, the + * main `callback` (for the `each` function) is immediately called with the + * error. + * + * Note, that since this function applies `iteratee` to each item in parallel, + * there is no guarantee that the iteratee functions will complete in order. + * + * @name each + * @static + * @memberOf module:Collections + * @method + * @alias forEach + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to + * each item in `coll`. Invoked with (item, callback). + * The array index is not passed to the iteratee. + * If you need the index, use `eachOf`. + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt']; + * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt']; + * + * // asynchronous function that deletes a file + * const deleteFile = function(file, callback) { + * fs.unlink(file, callback); + * }; + * + * // Using callbacks + * async.each(fileList, deleteFile, function(err) { + * if( err ) { + * console.log(err); + * } else { + * console.log('All files have been deleted successfully'); + * } + * }); + * + * // Error Handling + * async.each(withMissingFileList, deleteFile, function(err){ + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using Promises + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.each(fileList, deleteFile) + * .then( () => { + * console.log('All files have been deleted successfully'); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * }); + * + * // Using async/await + * async () => { + * try { + * await async.each(files, deleteFile); + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * await async.each(withMissingFileList, deleteFile); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * // since dir4/file2.txt does not exist + * // dir1/file1.txt could have been deleted + * } + * } + * + */ +function eachLimit(coll, iteratee, callback) { + return (0, _eachOf2.default)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback); +} + +exports.default = (0, _awaitify2.default)(eachLimit, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEachLimit.js b/Challenge/seokahi/010.star/node_modules/async/forEachLimit.js new file mode 100644 index 0000000..5f3d009 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEachLimit.js @@ -0,0 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _withoutIndex = require('./internal/withoutIndex.js'); + +var _withoutIndex2 = _interopRequireDefault(_withoutIndex); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. + * + * @name eachLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfLimit`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachLimit(coll, limit, iteratee, callback) { + return (0, _eachOfLimit2.default)(limit)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback); +} +exports.default = (0, _awaitify2.default)(eachLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEachOf.js b/Challenge/seokahi/010.star/node_modules/async/forEachOf.js new file mode 100644 index 0000000..c22614f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEachOf.js @@ -0,0 +1,185 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _isArrayLike = require('./internal/isArrayLike.js'); + +var _isArrayLike2 = _interopRequireDefault(_isArrayLike); + +var _breakLoop = require('./internal/breakLoop.js'); + +var _breakLoop2 = _interopRequireDefault(_breakLoop); + +var _eachOfLimit = require('./eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eachOf implementation optimized for array-likes +function eachOfArrayLike(coll, iteratee, callback) { + callback = (0, _once2.default)(callback); + var index = 0, + completed = 0, + { length } = coll, + canceled = false; + if (length === 0) { + callback(null); + } + + function iteratorCallback(err, value) { + if (err === false) { + canceled = true; + } + if (canceled === true) return; + if (err) { + callback(err); + } else if (++completed === length || value === _breakLoop2.default) { + callback(null); + } + } + + for (; index < length; index++) { + iteratee(coll[index], index, (0, _onlyOnce2.default)(iteratorCallback)); + } +} + +// a generic version of eachOf which can handle array, object, and iterator cases. +function eachOfGeneric(coll, iteratee, callback) { + return (0, _eachOfLimit2.default)(coll, Infinity, iteratee, callback); +} + +/** + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument + * to the iteratee. + * + * @name eachOf + * @static + * @memberOf module:Collections + * @method + * @alias forEachOf + * @category Collection + * @see [async.each]{@link module:Collections.each} + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each + * item in `coll`. + * The `key` is the item's key, or index in the case of an array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + * @example + * + * // dev.json is a file containing a valid json object config for dev environment + * // dev.json is a file containing a valid json object config for test environment + * // prod.json is a file containing a valid json object config for prod environment + * // invalid.json is a file with a malformed json object + * + * let configs = {}; //global variable + * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'}; + * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'}; + * + * // asynchronous function that reads a json file and parses the contents as json object + * function parseFile(file, key, callback) { + * fs.readFile(file, "utf8", function(err, data) { + * if (err) return calback(err); + * try { + * configs[key] = JSON.parse(data); + * } catch (e) { + * return callback(e); + * } + * callback(); + * }); + * } + * + * // Using callbacks + * async.forEachOf(validConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * } else { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile, function (err) { + * if (err) { + * console.error(err); + * // JSON parse error exception + * } else { + * console.log(configs); + * } + * }); + * + * // Using Promises + * async.forEachOf(validConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * }).catch( err => { + * console.error(err); + * }); + * + * //Error handing + * async.forEachOf(invalidConfigFileMap, parseFile) + * .then( () => { + * console.log(configs); + * }).catch( err => { + * console.error(err); + * // JSON parse error exception + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.forEachOf(validConfigFileMap, parseFile); + * console.log(configs); + * // configs is now a map of JSON data, e.g. + * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json} + * } + * catch (err) { + * console.log(err); + * } + * } + * + * //Error handing + * async () => { + * try { + * let result = await async.forEachOf(invalidConfigFileMap, parseFile); + * console.log(configs); + * } + * catch (err) { + * console.log(err); + * // JSON parse error exception + * } + * } + * + */ +function eachOf(coll, iteratee, callback) { + var eachOfImplementation = (0, _isArrayLike2.default)(coll) ? eachOfArrayLike : eachOfGeneric; + return eachOfImplementation(coll, (0, _wrapAsync2.default)(iteratee), callback); +} + +exports.default = (0, _awaitify2.default)(eachOf, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEachOfLimit.js b/Challenge/seokahi/010.star/node_modules/async/forEachOfLimit.js new file mode 100644 index 0000000..e9fc4db --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEachOfLimit.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit2 = require('./internal/eachOfLimit.js'); + +var _eachOfLimit3 = _interopRequireDefault(_eachOfLimit2); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a + * time. + * + * @name eachOfLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. The `key` is the item's key, or index in the case of an + * array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfLimit(coll, limit, iteratee, callback) { + return (0, _eachOfLimit3.default)(limit)(coll, (0, _wrapAsync2.default)(iteratee), callback); +} + +exports.default = (0, _awaitify2.default)(eachOfLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEachOfSeries.js b/Challenge/seokahi/010.star/node_modules/async/forEachOfSeries.js new file mode 100644 index 0000000..cfb0f33 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEachOfSeries.js @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit = require('./eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. + * + * @name eachOfSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachOfSeries(coll, iteratee, callback) { + return (0, _eachOfLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(eachOfSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forEachSeries.js b/Challenge/seokahi/010.star/node_modules/async/forEachSeries.js new file mode 100644 index 0000000..d674d0c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forEachSeries.js @@ -0,0 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachLimit = require('./eachLimit.js'); + +var _eachLimit2 = _interopRequireDefault(_eachLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. + * + * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item + * in series and therefore the iteratee functions will complete in order. + + * @name eachSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfSeries`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @returns {Promise} a promise, if a callback is omitted + */ +function eachSeries(coll, iteratee, callback) { + return (0, _eachLimit2.default)(coll, 1, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(eachSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/forever.js b/Challenge/seokahi/010.star/node_modules/async/forever.js new file mode 100644 index 0000000..2c8d5b8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/forever.js @@ -0,0 +1,68 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _ensureAsync = require('./ensureAsync.js'); + +var _ensureAsync2 = _interopRequireDefault(_ensureAsync); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Calls the asynchronous function `fn` with a callback parameter that allows it + * to call itself again, in series, indefinitely. + + * If an error is passed to the callback then `errback` is called with the + * error, and execution stops, otherwise it will never be called. + * + * @name forever + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} fn - an async function to call repeatedly. + * Invoked with (next). + * @param {Function} [errback] - when `fn` passes an error to it's callback, + * this function will be called, and execution stops. Invoked with (err). + * @returns {Promise} a promise that rejects if an error occurs and an errback + * is not passed + * @example + * + * async.forever( + * function(next) { + * // next is suitable for passing to things that need a callback(err [, whatever]); + * // it will result in this function being called again. + * }, + * function(err) { + * // if next is called with a value in its first parameter, it will appear + * // in here as 'err', and execution will stop. + * } + * ); + */ +function forever(fn, errback) { + var done = (0, _onlyOnce2.default)(errback); + var task = (0, _wrapAsync2.default)((0, _ensureAsync2.default)(fn)); + + function next(err) { + if (err) return done(err); + if (err === false) return; + task(next); + } + return next(); +} +exports.default = (0, _awaitify2.default)(forever, 2); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/groupBy.js b/Challenge/seokahi/010.star/node_modules/async/groupBy.js new file mode 100644 index 0000000..6bb52aa --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/groupBy.js @@ -0,0 +1,108 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = groupBy; + +var _groupByLimit = require('./groupByLimit.js'); + +var _groupByLimit2 = _interopRequireDefault(_groupByLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a new object, where each value corresponds to an array of items, from + * `coll`, that returned the corresponding key. That is, the keys of the object + * correspond to the values passed to the `iteratee` callback. + * + * Note: Since this function applies the `iteratee` to each item in parallel, + * there is no guarantee that the `iteratee` functions will complete in order. + * However, the values for each key in the `result` will be in the same order as + * the original `coll`. For Objects, the values will roughly be in the order of + * the original Objects' keys (but this can vary across JavaScript engines). + * + * @name groupBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * const files = ['dir1/file1.txt','dir2','dir4'] + * + * // asynchronous function that detects file type as none, file, or directory + * function detectFile(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(null, 'none'); + * } + * callback(null, stat.isDirectory() ? 'directory' : 'file'); + * }); + * } + * + * //Using callbacks + * async.groupBy(files, detectFile, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * }); + * + * // Using Promises + * async.groupBy(files, detectFile) + * .then( result => { + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.groupBy(files, detectFile); + * console.log(result); + * // { + * // file: [ 'dir1/file1.txt' ], + * // none: [ 'dir4' ], + * // directory: [ 'dir2'] + * // } + * // result is object containing the files grouped by type + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function groupBy(coll, iteratee, callback) { + return (0, _groupByLimit2.default)(coll, Infinity, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/groupByLimit.js b/Challenge/seokahi/010.star/node_modules/async/groupByLimit.js new file mode 100644 index 0000000..5766d6e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/groupByLimit.js @@ -0,0 +1,71 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _mapLimit = require('./mapLimit.js'); + +var _mapLimit2 = _interopRequireDefault(_mapLimit); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. + * + * @name groupByLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ +function groupByLimit(coll, limit, iteratee, callback) { + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _mapLimit2.default)(coll, limit, (val, iterCb) => { + _iteratee(val, (err, key) => { + if (err) return iterCb(err); + return iterCb(err, { key, val }); + }); + }, (err, mapResults) => { + var result = {}; + // from MDN, handle object having an `hasOwnProperty` prop + var { hasOwnProperty } = Object.prototype; + + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + var { key } = mapResults[i]; + var { val } = mapResults[i]; + + if (hasOwnProperty.call(result, key)) { + result[key].push(val); + } else { + result[key] = [val]; + } + } + } + + return callback(err, result); + }); +} + +exports.default = (0, _awaitify2.default)(groupByLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/groupBySeries.js b/Challenge/seokahi/010.star/node_modules/async/groupBySeries.js new file mode 100644 index 0000000..6056743 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/groupBySeries.js @@ -0,0 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = groupBySeries; + +var _groupByLimit = require('./groupByLimit.js'); + +var _groupByLimit2 = _interopRequireDefault(_groupByLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. + * + * @name groupBySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whose + * properties are arrays of values which returned the corresponding key. + * @returns {Promise} a promise, if no callback is passed + */ +function groupBySeries(coll, iteratee, callback) { + return (0, _groupByLimit2.default)(coll, 1, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/index.js b/Challenge/seokahi/010.star/node_modules/async/index.js new file mode 100644 index 0000000..ce647d5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/index.js @@ -0,0 +1,588 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.doDuring = exports.during = exports.wrapSync = undefined; +exports.selectSeries = exports.selectLimit = exports.select = exports.foldr = exports.foldl = exports.inject = exports.forEachOfLimit = exports.forEachOfSeries = exports.forEachOf = exports.forEachLimit = exports.forEachSeries = exports.forEach = exports.flatMapSeries = exports.flatMapLimit = exports.flatMap = exports.findSeries = exports.findLimit = exports.find = exports.anySeries = exports.anyLimit = exports.any = exports.allSeries = exports.allLimit = exports.all = exports.whilst = exports.waterfall = exports.until = exports.unmemoize = exports.tryEach = exports.transform = exports.timesSeries = exports.timesLimit = exports.times = exports.timeout = exports.sortBy = exports.someSeries = exports.someLimit = exports.some = exports.setImmediate = exports.series = exports.seq = exports.retryable = exports.retry = exports.rejectSeries = exports.rejectLimit = exports.reject = exports.reflectAll = exports.reflect = exports.reduceRight = exports.reduce = exports.race = exports.queue = exports.priorityQueue = exports.parallelLimit = exports.parallel = exports.nextTick = exports.memoize = exports.mapValuesSeries = exports.mapValuesLimit = exports.mapValues = exports.mapSeries = exports.mapLimit = exports.map = exports.log = exports.groupBySeries = exports.groupByLimit = exports.groupBy = exports.forever = exports.filterSeries = exports.filterLimit = exports.filter = exports.everySeries = exports.everyLimit = exports.every = exports.ensureAsync = exports.eachSeries = exports.eachOfSeries = exports.eachOfLimit = exports.eachOf = exports.eachLimit = exports.each = exports.doWhilst = exports.doUntil = exports.dir = exports.detectSeries = exports.detectLimit = exports.detect = exports.constant = exports.concatSeries = exports.concatLimit = exports.concat = exports.compose = exports.cargoQueue = exports.cargo = exports.autoInject = exports.auto = exports.asyncify = exports.applyEachSeries = exports.applyEach = exports.apply = undefined; + +var _apply = require('./apply'); + +var _apply2 = _interopRequireDefault(_apply); + +var _applyEach = require('./applyEach'); + +var _applyEach2 = _interopRequireDefault(_applyEach); + +var _applyEachSeries = require('./applyEachSeries'); + +var _applyEachSeries2 = _interopRequireDefault(_applyEachSeries); + +var _asyncify = require('./asyncify'); + +var _asyncify2 = _interopRequireDefault(_asyncify); + +var _auto = require('./auto'); + +var _auto2 = _interopRequireDefault(_auto); + +var _autoInject = require('./autoInject'); + +var _autoInject2 = _interopRequireDefault(_autoInject); + +var _cargo = require('./cargo'); + +var _cargo2 = _interopRequireDefault(_cargo); + +var _cargoQueue = require('./cargoQueue'); + +var _cargoQueue2 = _interopRequireDefault(_cargoQueue); + +var _compose = require('./compose'); + +var _compose2 = _interopRequireDefault(_compose); + +var _concat = require('./concat'); + +var _concat2 = _interopRequireDefault(_concat); + +var _concatLimit = require('./concatLimit'); + +var _concatLimit2 = _interopRequireDefault(_concatLimit); + +var _concatSeries = require('./concatSeries'); + +var _concatSeries2 = _interopRequireDefault(_concatSeries); + +var _constant = require('./constant'); + +var _constant2 = _interopRequireDefault(_constant); + +var _detect = require('./detect'); + +var _detect2 = _interopRequireDefault(_detect); + +var _detectLimit = require('./detectLimit'); + +var _detectLimit2 = _interopRequireDefault(_detectLimit); + +var _detectSeries = require('./detectSeries'); + +var _detectSeries2 = _interopRequireDefault(_detectSeries); + +var _dir = require('./dir'); + +var _dir2 = _interopRequireDefault(_dir); + +var _doUntil = require('./doUntil'); + +var _doUntil2 = _interopRequireDefault(_doUntil); + +var _doWhilst = require('./doWhilst'); + +var _doWhilst2 = _interopRequireDefault(_doWhilst); + +var _each = require('./each'); + +var _each2 = _interopRequireDefault(_each); + +var _eachLimit = require('./eachLimit'); + +var _eachLimit2 = _interopRequireDefault(_eachLimit); + +var _eachOf = require('./eachOf'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _eachOfLimit = require('./eachOfLimit'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _eachOfSeries = require('./eachOfSeries'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _eachSeries = require('./eachSeries'); + +var _eachSeries2 = _interopRequireDefault(_eachSeries); + +var _ensureAsync = require('./ensureAsync'); + +var _ensureAsync2 = _interopRequireDefault(_ensureAsync); + +var _every = require('./every'); + +var _every2 = _interopRequireDefault(_every); + +var _everyLimit = require('./everyLimit'); + +var _everyLimit2 = _interopRequireDefault(_everyLimit); + +var _everySeries = require('./everySeries'); + +var _everySeries2 = _interopRequireDefault(_everySeries); + +var _filter = require('./filter'); + +var _filter2 = _interopRequireDefault(_filter); + +var _filterLimit = require('./filterLimit'); + +var _filterLimit2 = _interopRequireDefault(_filterLimit); + +var _filterSeries = require('./filterSeries'); + +var _filterSeries2 = _interopRequireDefault(_filterSeries); + +var _forever = require('./forever'); + +var _forever2 = _interopRequireDefault(_forever); + +var _groupBy = require('./groupBy'); + +var _groupBy2 = _interopRequireDefault(_groupBy); + +var _groupByLimit = require('./groupByLimit'); + +var _groupByLimit2 = _interopRequireDefault(_groupByLimit); + +var _groupBySeries = require('./groupBySeries'); + +var _groupBySeries2 = _interopRequireDefault(_groupBySeries); + +var _log = require('./log'); + +var _log2 = _interopRequireDefault(_log); + +var _map = require('./map'); + +var _map2 = _interopRequireDefault(_map); + +var _mapLimit = require('./mapLimit'); + +var _mapLimit2 = _interopRequireDefault(_mapLimit); + +var _mapSeries = require('./mapSeries'); + +var _mapSeries2 = _interopRequireDefault(_mapSeries); + +var _mapValues = require('./mapValues'); + +var _mapValues2 = _interopRequireDefault(_mapValues); + +var _mapValuesLimit = require('./mapValuesLimit'); + +var _mapValuesLimit2 = _interopRequireDefault(_mapValuesLimit); + +var _mapValuesSeries = require('./mapValuesSeries'); + +var _mapValuesSeries2 = _interopRequireDefault(_mapValuesSeries); + +var _memoize = require('./memoize'); + +var _memoize2 = _interopRequireDefault(_memoize); + +var _nextTick = require('./nextTick'); + +var _nextTick2 = _interopRequireDefault(_nextTick); + +var _parallel = require('./parallel'); + +var _parallel2 = _interopRequireDefault(_parallel); + +var _parallelLimit = require('./parallelLimit'); + +var _parallelLimit2 = _interopRequireDefault(_parallelLimit); + +var _priorityQueue = require('./priorityQueue'); + +var _priorityQueue2 = _interopRequireDefault(_priorityQueue); + +var _queue = require('./queue'); + +var _queue2 = _interopRequireDefault(_queue); + +var _race = require('./race'); + +var _race2 = _interopRequireDefault(_race); + +var _reduce = require('./reduce'); + +var _reduce2 = _interopRequireDefault(_reduce); + +var _reduceRight = require('./reduceRight'); + +var _reduceRight2 = _interopRequireDefault(_reduceRight); + +var _reflect = require('./reflect'); + +var _reflect2 = _interopRequireDefault(_reflect); + +var _reflectAll = require('./reflectAll'); + +var _reflectAll2 = _interopRequireDefault(_reflectAll); + +var _reject = require('./reject'); + +var _reject2 = _interopRequireDefault(_reject); + +var _rejectLimit = require('./rejectLimit'); + +var _rejectLimit2 = _interopRequireDefault(_rejectLimit); + +var _rejectSeries = require('./rejectSeries'); + +var _rejectSeries2 = _interopRequireDefault(_rejectSeries); + +var _retry = require('./retry'); + +var _retry2 = _interopRequireDefault(_retry); + +var _retryable = require('./retryable'); + +var _retryable2 = _interopRequireDefault(_retryable); + +var _seq = require('./seq'); + +var _seq2 = _interopRequireDefault(_seq); + +var _series = require('./series'); + +var _series2 = _interopRequireDefault(_series); + +var _setImmediate = require('./setImmediate'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _some = require('./some'); + +var _some2 = _interopRequireDefault(_some); + +var _someLimit = require('./someLimit'); + +var _someLimit2 = _interopRequireDefault(_someLimit); + +var _someSeries = require('./someSeries'); + +var _someSeries2 = _interopRequireDefault(_someSeries); + +var _sortBy = require('./sortBy'); + +var _sortBy2 = _interopRequireDefault(_sortBy); + +var _timeout = require('./timeout'); + +var _timeout2 = _interopRequireDefault(_timeout); + +var _times = require('./times'); + +var _times2 = _interopRequireDefault(_times); + +var _timesLimit = require('./timesLimit'); + +var _timesLimit2 = _interopRequireDefault(_timesLimit); + +var _timesSeries = require('./timesSeries'); + +var _timesSeries2 = _interopRequireDefault(_timesSeries); + +var _transform = require('./transform'); + +var _transform2 = _interopRequireDefault(_transform); + +var _tryEach = require('./tryEach'); + +var _tryEach2 = _interopRequireDefault(_tryEach); + +var _unmemoize = require('./unmemoize'); + +var _unmemoize2 = _interopRequireDefault(_unmemoize); + +var _until = require('./until'); + +var _until2 = _interopRequireDefault(_until); + +var _waterfall = require('./waterfall'); + +var _waterfall2 = _interopRequireDefault(_waterfall); + +var _whilst = require('./whilst'); + +var _whilst2 = _interopRequireDefault(_whilst); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * An "async function" in the context of Async is an asynchronous function with + * a variable number of parameters, with the final parameter being a callback. + * (`function (arg1, arg2, ..., callback) {}`) + * The final callback is of the form `callback(err, results...)`, which must be + * called once the function is completed. The callback should be called with a + * Error as its first argument to signal that an error occurred. + * Otherwise, if no error occurred, it should be called with `null` as the first + * argument, and any additional `result` arguments that may apply, to signal + * successful completion. + * The callback must be called exactly once, ideally on a later tick of the + * JavaScript event loop. + * + * This type of function is also referred to as a "Node-style async function", + * or a "continuation passing-style function" (CPS). Most of the methods of this + * library are themselves CPS/Node-style async functions, or functions that + * return CPS/Node-style async functions. + * + * Wherever we accept a Node-style async function, we also directly accept an + * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. + * In this case, the `async` function will not be passed a final callback + * argument, and any thrown error will be used as the `err` argument of the + * implicit callback, and the return value will be used as the `result` value. + * (i.e. a `rejected` of the returned Promise becomes the `err` callback + * argument, and a `resolved` value becomes the `result`.) + * + * Note, due to JavaScript limitations, we can only detect native `async` + * functions and not transpilied implementations. + * Your environment must have `async`/`await` support for this to work. + * (e.g. Node > v7.6, or a recent version of a modern browser). + * If you are using `async` functions through a transpiler (e.g. Babel), you + * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, + * because the `async function` will be compiled to an ordinary function that + * returns a promise. + * + * @typedef {Function} AsyncFunction + * @static + */ + +/** + * Async is a utility module which provides straight-forward, powerful functions + * for working with asynchronous JavaScript. Although originally designed for + * use with [Node.js](http://nodejs.org) and installable via + * `npm install --save async`, it can also be used directly in the browser. + * @module async + * @see AsyncFunction + */ + +/** + * A collection of `async` functions for manipulating collections, such as + * arrays and objects. + * @module Collections + */ + +/** + * A collection of `async` functions for controlling the flow through a script. + * @module ControlFlow + */ + +/** + * A collection of `async` utility functions. + * @module Utils + */ + +exports.default = { + apply: _apply2.default, + applyEach: _applyEach2.default, + applyEachSeries: _applyEachSeries2.default, + asyncify: _asyncify2.default, + auto: _auto2.default, + autoInject: _autoInject2.default, + cargo: _cargo2.default, + cargoQueue: _cargoQueue2.default, + compose: _compose2.default, + concat: _concat2.default, + concatLimit: _concatLimit2.default, + concatSeries: _concatSeries2.default, + constant: _constant2.default, + detect: _detect2.default, + detectLimit: _detectLimit2.default, + detectSeries: _detectSeries2.default, + dir: _dir2.default, + doUntil: _doUntil2.default, + doWhilst: _doWhilst2.default, + each: _each2.default, + eachLimit: _eachLimit2.default, + eachOf: _eachOf2.default, + eachOfLimit: _eachOfLimit2.default, + eachOfSeries: _eachOfSeries2.default, + eachSeries: _eachSeries2.default, + ensureAsync: _ensureAsync2.default, + every: _every2.default, + everyLimit: _everyLimit2.default, + everySeries: _everySeries2.default, + filter: _filter2.default, + filterLimit: _filterLimit2.default, + filterSeries: _filterSeries2.default, + forever: _forever2.default, + groupBy: _groupBy2.default, + groupByLimit: _groupByLimit2.default, + groupBySeries: _groupBySeries2.default, + log: _log2.default, + map: _map2.default, + mapLimit: _mapLimit2.default, + mapSeries: _mapSeries2.default, + mapValues: _mapValues2.default, + mapValuesLimit: _mapValuesLimit2.default, + mapValuesSeries: _mapValuesSeries2.default, + memoize: _memoize2.default, + nextTick: _nextTick2.default, + parallel: _parallel2.default, + parallelLimit: _parallelLimit2.default, + priorityQueue: _priorityQueue2.default, + queue: _queue2.default, + race: _race2.default, + reduce: _reduce2.default, + reduceRight: _reduceRight2.default, + reflect: _reflect2.default, + reflectAll: _reflectAll2.default, + reject: _reject2.default, + rejectLimit: _rejectLimit2.default, + rejectSeries: _rejectSeries2.default, + retry: _retry2.default, + retryable: _retryable2.default, + seq: _seq2.default, + series: _series2.default, + setImmediate: _setImmediate2.default, + some: _some2.default, + someLimit: _someLimit2.default, + someSeries: _someSeries2.default, + sortBy: _sortBy2.default, + timeout: _timeout2.default, + times: _times2.default, + timesLimit: _timesLimit2.default, + timesSeries: _timesSeries2.default, + transform: _transform2.default, + tryEach: _tryEach2.default, + unmemoize: _unmemoize2.default, + until: _until2.default, + waterfall: _waterfall2.default, + whilst: _whilst2.default, + + // aliases + all: _every2.default, + allLimit: _everyLimit2.default, + allSeries: _everySeries2.default, + any: _some2.default, + anyLimit: _someLimit2.default, + anySeries: _someSeries2.default, + find: _detect2.default, + findLimit: _detectLimit2.default, + findSeries: _detectSeries2.default, + flatMap: _concat2.default, + flatMapLimit: _concatLimit2.default, + flatMapSeries: _concatSeries2.default, + forEach: _each2.default, + forEachSeries: _eachSeries2.default, + forEachLimit: _eachLimit2.default, + forEachOf: _eachOf2.default, + forEachOfSeries: _eachOfSeries2.default, + forEachOfLimit: _eachOfLimit2.default, + inject: _reduce2.default, + foldl: _reduce2.default, + foldr: _reduceRight2.default, + select: _filter2.default, + selectLimit: _filterLimit2.default, + selectSeries: _filterSeries2.default, + wrapSync: _asyncify2.default, + during: _whilst2.default, + doDuring: _doWhilst2.default +}; +exports.apply = _apply2.default; +exports.applyEach = _applyEach2.default; +exports.applyEachSeries = _applyEachSeries2.default; +exports.asyncify = _asyncify2.default; +exports.auto = _auto2.default; +exports.autoInject = _autoInject2.default; +exports.cargo = _cargo2.default; +exports.cargoQueue = _cargoQueue2.default; +exports.compose = _compose2.default; +exports.concat = _concat2.default; +exports.concatLimit = _concatLimit2.default; +exports.concatSeries = _concatSeries2.default; +exports.constant = _constant2.default; +exports.detect = _detect2.default; +exports.detectLimit = _detectLimit2.default; +exports.detectSeries = _detectSeries2.default; +exports.dir = _dir2.default; +exports.doUntil = _doUntil2.default; +exports.doWhilst = _doWhilst2.default; +exports.each = _each2.default; +exports.eachLimit = _eachLimit2.default; +exports.eachOf = _eachOf2.default; +exports.eachOfLimit = _eachOfLimit2.default; +exports.eachOfSeries = _eachOfSeries2.default; +exports.eachSeries = _eachSeries2.default; +exports.ensureAsync = _ensureAsync2.default; +exports.every = _every2.default; +exports.everyLimit = _everyLimit2.default; +exports.everySeries = _everySeries2.default; +exports.filter = _filter2.default; +exports.filterLimit = _filterLimit2.default; +exports.filterSeries = _filterSeries2.default; +exports.forever = _forever2.default; +exports.groupBy = _groupBy2.default; +exports.groupByLimit = _groupByLimit2.default; +exports.groupBySeries = _groupBySeries2.default; +exports.log = _log2.default; +exports.map = _map2.default; +exports.mapLimit = _mapLimit2.default; +exports.mapSeries = _mapSeries2.default; +exports.mapValues = _mapValues2.default; +exports.mapValuesLimit = _mapValuesLimit2.default; +exports.mapValuesSeries = _mapValuesSeries2.default; +exports.memoize = _memoize2.default; +exports.nextTick = _nextTick2.default; +exports.parallel = _parallel2.default; +exports.parallelLimit = _parallelLimit2.default; +exports.priorityQueue = _priorityQueue2.default; +exports.queue = _queue2.default; +exports.race = _race2.default; +exports.reduce = _reduce2.default; +exports.reduceRight = _reduceRight2.default; +exports.reflect = _reflect2.default; +exports.reflectAll = _reflectAll2.default; +exports.reject = _reject2.default; +exports.rejectLimit = _rejectLimit2.default; +exports.rejectSeries = _rejectSeries2.default; +exports.retry = _retry2.default; +exports.retryable = _retryable2.default; +exports.seq = _seq2.default; +exports.series = _series2.default; +exports.setImmediate = _setImmediate2.default; +exports.some = _some2.default; +exports.someLimit = _someLimit2.default; +exports.someSeries = _someSeries2.default; +exports.sortBy = _sortBy2.default; +exports.timeout = _timeout2.default; +exports.times = _times2.default; +exports.timesLimit = _timesLimit2.default; +exports.timesSeries = _timesSeries2.default; +exports.transform = _transform2.default; +exports.tryEach = _tryEach2.default; +exports.unmemoize = _unmemoize2.default; +exports.until = _until2.default; +exports.waterfall = _waterfall2.default; +exports.whilst = _whilst2.default; +exports.all = _every2.default; +exports.allLimit = _everyLimit2.default; +exports.allSeries = _everySeries2.default; +exports.any = _some2.default; +exports.anyLimit = _someLimit2.default; +exports.anySeries = _someSeries2.default; +exports.find = _detect2.default; +exports.findLimit = _detectLimit2.default; +exports.findSeries = _detectSeries2.default; +exports.flatMap = _concat2.default; +exports.flatMapLimit = _concatLimit2.default; +exports.flatMapSeries = _concatSeries2.default; +exports.forEach = _each2.default; +exports.forEachSeries = _eachSeries2.default; +exports.forEachLimit = _eachLimit2.default; +exports.forEachOf = _eachOf2.default; +exports.forEachOfSeries = _eachOfSeries2.default; +exports.forEachOfLimit = _eachOfLimit2.default; +exports.inject = _reduce2.default; +exports.foldl = _reduce2.default; +exports.foldr = _reduceRight2.default; +exports.select = _filter2.default; +exports.selectLimit = _filterLimit2.default; +exports.selectSeries = _filterSeries2.default; +exports.wrapSync = _asyncify2.default; +exports.during = _whilst2.default; +exports.doDuring = _doWhilst2.default; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/inject.js b/Challenge/seokahi/010.star/node_modules/async/inject.js new file mode 100644 index 0000000..56e2db8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/inject.js @@ -0,0 +1,153 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Reduces `coll` into a single value using an async `iteratee` to return each + * successive step. `memo` is the initial state of the reduction. This function + * only operates in series. + * + * For performance reasons, it may make sense to split a call to this function + * into a parallel map, and then use the normal `Array.prototype.reduce` on the + * results. This function is for situations where each step in the reduction + * needs to be async; if you can get the data before reducing it, then it's + * probably a good idea to do so. + * + * @name reduce + * @static + * @memberOf module:Collections + * @method + * @alias inject + * @alias foldl + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt']; + * + * // asynchronous function that computes the file size in bytes + * // file size is added to the memoized value, then returned + * function getFileSizeInBytes(memo, file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, memo + stat.size); + * }); + * } + * + * // Using callbacks + * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.reduce(fileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.reduce(fileList, 0, getFileSizeInBytes); + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function reduce(coll, memo, iteratee, callback) { + callback = (0, _once2.default)(callback); + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _eachOfSeries2.default)(coll, (x, i, iterCb) => { + _iteratee(memo, x, (err, v) => { + memo = v; + iterCb(err); + }); + }, err => callback(err, memo)); +} +exports.default = (0, _awaitify2.default)(reduce, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/DoublyLinkedList.js b/Challenge/seokahi/010.star/node_modules/async/internal/DoublyLinkedList.js new file mode 100644 index 0000000..cd11c3b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/DoublyLinkedList.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation +// used for queues. This implementation assumes that the node provided by the user can be modified +// to adjust the next and last properties. We implement only the minimal functionality +// for queue support. +class DLL { + constructor() { + this.head = this.tail = null; + this.length = 0; + } + + removeLink(node) { + if (node.prev) node.prev.next = node.next;else this.head = node.next; + if (node.next) node.next.prev = node.prev;else this.tail = node.prev; + + node.prev = node.next = null; + this.length -= 1; + return node; + } + + empty() { + while (this.head) this.shift(); + return this; + } + + insertAfter(node, newNode) { + newNode.prev = node; + newNode.next = node.next; + if (node.next) node.next.prev = newNode;else this.tail = newNode; + node.next = newNode; + this.length += 1; + } + + insertBefore(node, newNode) { + newNode.prev = node.prev; + newNode.next = node; + if (node.prev) node.prev.next = newNode;else this.head = newNode; + node.prev = newNode; + this.length += 1; + } + + unshift(node) { + if (this.head) this.insertBefore(this.head, node);else setInitial(this, node); + } + + push(node) { + if (this.tail) this.insertAfter(this.tail, node);else setInitial(this, node); + } + + shift() { + return this.head && this.removeLink(this.head); + } + + pop() { + return this.tail && this.removeLink(this.tail); + } + + toArray() { + return [...this]; + } + + *[Symbol.iterator]() { + var cur = this.head; + while (cur) { + yield cur.data; + cur = cur.next; + } + } + + remove(testFn) { + var curr = this.head; + while (curr) { + var { next } = curr; + if (testFn(curr)) { + this.removeLink(curr); + } + curr = next; + } + return this; + } +} + +exports.default = DLL; +function setInitial(dll, node) { + dll.length = 1; + dll.head = dll.tail = node; +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/Heap.js b/Challenge/seokahi/010.star/node_modules/async/internal/Heap.js new file mode 100644 index 0000000..80762fe --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/Heap.js @@ -0,0 +1,120 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +// Binary min-heap implementation used for priority queue. +// Implementation is stable, i.e. push time is considered for equal priorities +class Heap { + constructor() { + this.heap = []; + this.pushCount = Number.MIN_SAFE_INTEGER; + } + + get length() { + return this.heap.length; + } + + empty() { + this.heap = []; + return this; + } + + percUp(index) { + let p; + + while (index > 0 && smaller(this.heap[index], this.heap[p = parent(index)])) { + let t = this.heap[index]; + this.heap[index] = this.heap[p]; + this.heap[p] = t; + + index = p; + } + } + + percDown(index) { + let l; + + while ((l = leftChi(index)) < this.heap.length) { + if (l + 1 < this.heap.length && smaller(this.heap[l + 1], this.heap[l])) { + l = l + 1; + } + + if (smaller(this.heap[index], this.heap[l])) { + break; + } + + let t = this.heap[index]; + this.heap[index] = this.heap[l]; + this.heap[l] = t; + + index = l; + } + } + + push(node) { + node.pushCount = ++this.pushCount; + this.heap.push(node); + this.percUp(this.heap.length - 1); + } + + unshift(node) { + return this.heap.push(node); + } + + shift() { + let [top] = this.heap; + + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap.pop(); + this.percDown(0); + + return top; + } + + toArray() { + return [...this]; + } + + *[Symbol.iterator]() { + for (let i = 0; i < this.heap.length; i++) { + yield this.heap[i].data; + } + } + + remove(testFn) { + let j = 0; + for (let i = 0; i < this.heap.length; i++) { + if (!testFn(this.heap[i])) { + this.heap[j] = this.heap[i]; + j++; + } + } + + this.heap.splice(j); + + for (let i = parent(this.heap.length - 1); i >= 0; i--) { + this.percDown(i); + } + + return this; + } +} + +exports.default = Heap; +function leftChi(i) { + return (i << 1) + 1; +} + +function parent(i) { + return (i + 1 >> 1) - 1; +} + +function smaller(x, y) { + if (x.priority !== y.priority) { + return x.priority < y.priority; + } else { + return x.pushCount < y.pushCount; + } +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/applyEach.js b/Challenge/seokahi/010.star/node_modules/async/internal/applyEach.js new file mode 100644 index 0000000..a3f4ef1 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/applyEach.js @@ -0,0 +1,29 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (eachfn) { + return function applyEach(fns, ...callArgs) { + const go = (0, _awaitify2.default)(function (callback) { + var that = this; + return eachfn(fns, (fn, cb) => { + (0, _wrapAsync2.default)(fn).apply(that, callArgs.concat(cb)); + }, callback); + }); + return go; + }; +}; + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/asyncEachOfLimit.js b/Challenge/seokahi/010.star/node_modules/async/internal/asyncEachOfLimit.js new file mode 100644 index 0000000..bba74c7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/asyncEachOfLimit.js @@ -0,0 +1,75 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = asyncEachOfLimit; + +var _breakLoop = require('./breakLoop.js'); + +var _breakLoop2 = _interopRequireDefault(_breakLoop); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// for async generators +function asyncEachOfLimit(generator, limit, iteratee, callback) { + let done = false; + let canceled = false; + let awaiting = false; + let running = 0; + let idx = 0; + + function replenish() { + //console.log('replenish') + if (running >= limit || awaiting || done) return; + //console.log('replenish awaiting') + awaiting = true; + generator.next().then(({ value, done: iterDone }) => { + //console.log('got value', value) + if (canceled || done) return; + awaiting = false; + if (iterDone) { + done = true; + if (running <= 0) { + //console.log('done nextCb') + callback(null); + } + return; + } + running++; + iteratee(value, idx, iterateeCallback); + idx++; + replenish(); + }).catch(handleError); + } + + function iterateeCallback(err, result) { + //console.log('iterateeCallback') + running -= 1; + if (canceled) return; + if (err) return handleError(err); + + if (err === false) { + done = true; + canceled = true; + return; + } + + if (result === _breakLoop2.default || done && running <= 0) { + done = true; + //console.log('done iterCb') + return callback(null); + } + replenish(); + } + + function handleError(err) { + if (canceled) return; + awaiting = false; + done = true; + callback(err); + } + + replenish(); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/awaitify.js b/Challenge/seokahi/010.star/node_modules/async/internal/awaitify.js new file mode 100644 index 0000000..7b36f1a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/awaitify.js @@ -0,0 +1,27 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = awaitify; +// conditionally promisify a function. +// only return a promise if a callback is omitted +function awaitify(asyncFn, arity = asyncFn.length) { + if (!arity) throw new Error('arity is undefined'); + function awaitable(...args) { + if (typeof args[arity - 1] === 'function') { + return asyncFn.apply(this, args); + } + + return new Promise((resolve, reject) => { + args[arity - 1] = (err, ...cbArgs) => { + if (err) return reject(err); + resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]); + }; + asyncFn.apply(this, args); + }); + } + + return awaitable; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/breakLoop.js b/Challenge/seokahi/010.star/node_modules/async/internal/breakLoop.js new file mode 100644 index 0000000..8245e55 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/breakLoop.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +// A temporary value used to identify if the loop should be broken. +// See #1064, #1293 +const breakLoop = {}; +exports.default = breakLoop; +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/consoleFunc.js b/Challenge/seokahi/010.star/node_modules/async/internal/consoleFunc.js new file mode 100644 index 0000000..70347a5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/consoleFunc.js @@ -0,0 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = consoleFunc; + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function consoleFunc(name) { + return (fn, ...args) => (0, _wrapAsync2.default)(fn)(...args, (err, ...resultArgs) => { + /* istanbul ignore else */ + if (typeof console === 'object') { + /* istanbul ignore else */ + if (err) { + /* istanbul ignore else */ + if (console.error) { + console.error(err); + } + } else if (console[name]) { + /* istanbul ignore else */ + resultArgs.forEach(x => console[name](x)); + } + } + }); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/createTester.js b/Challenge/seokahi/010.star/node_modules/async/internal/createTester.js new file mode 100644 index 0000000..7b2d734 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/createTester.js @@ -0,0 +1,40 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _createTester; + +var _breakLoop = require('./breakLoop.js'); + +var _breakLoop2 = _interopRequireDefault(_breakLoop); + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _createTester(check, getResult) { + return (eachfn, arr, _iteratee, cb) => { + var testPassed = false; + var testResult; + const iteratee = (0, _wrapAsync2.default)(_iteratee); + eachfn(arr, (value, _, callback) => { + iteratee(value, (err, result) => { + if (err || err === false) return callback(err); + + if (check(result) && !testResult) { + testPassed = true; + testResult = getResult(true, value); + return callback(null, _breakLoop2.default); + } + callback(); + }); + }, err => { + if (err) return cb(err); + cb(null, testPassed ? testResult : getResult(false)); + }); + }; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/eachOfLimit.js b/Challenge/seokahi/010.star/node_modules/async/internal/eachOfLimit.js new file mode 100644 index 0000000..fc26b20 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/eachOfLimit.js @@ -0,0 +1,90 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _once = require('./once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _iterator = require('./iterator.js'); + +var _iterator2 = _interopRequireDefault(_iterator); + +var _onlyOnce = require('./onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./wrapAsync.js'); + +var _asyncEachOfLimit = require('./asyncEachOfLimit.js'); + +var _asyncEachOfLimit2 = _interopRequireDefault(_asyncEachOfLimit); + +var _breakLoop = require('./breakLoop.js'); + +var _breakLoop2 = _interopRequireDefault(_breakLoop); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = limit => { + return (obj, iteratee, callback) => { + callback = (0, _once2.default)(callback); + if (limit <= 0) { + throw new RangeError('concurrency limit cannot be less than 1'); + } + if (!obj) { + return callback(null); + } + if ((0, _wrapAsync.isAsyncGenerator)(obj)) { + return (0, _asyncEachOfLimit2.default)(obj, limit, iteratee, callback); + } + if ((0, _wrapAsync.isAsyncIterable)(obj)) { + return (0, _asyncEachOfLimit2.default)(obj[Symbol.asyncIterator](), limit, iteratee, callback); + } + var nextElem = (0, _iterator2.default)(obj); + var done = false; + var canceled = false; + var running = 0; + var looping = false; + + function iterateeCallback(err, value) { + if (canceled) return; + running -= 1; + if (err) { + done = true; + callback(err); + } else if (err === false) { + done = true; + canceled = true; + } else if (value === _breakLoop2.default || done && running <= 0) { + done = true; + return callback(null); + } else if (!looping) { + replenish(); + } + } + + function replenish() { + looping = true; + while (running < limit && !done) { + var elem = nextElem(); + if (elem === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iteratee(elem.value, elem.key, (0, _onlyOnce2.default)(iterateeCallback)); + } + looping = false; + } + + replenish(); + }; +}; + +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/filter.js b/Challenge/seokahi/010.star/node_modules/async/internal/filter.js new file mode 100644 index 0000000..aef2b9d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/filter.js @@ -0,0 +1,55 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _filter; + +var _isArrayLike = require('./isArrayLike.js'); + +var _isArrayLike2 = _interopRequireDefault(_isArrayLike); + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function filterArray(eachfn, arr, iteratee, callback) { + var truthValues = new Array(arr.length); + eachfn(arr, (x, index, iterCb) => { + iteratee(x, (err, v) => { + truthValues[index] = !!v; + iterCb(err); + }); + }, err => { + if (err) return callback(err); + var results = []; + for (var i = 0; i < arr.length; i++) { + if (truthValues[i]) results.push(arr[i]); + } + callback(null, results); + }); +} + +function filterGeneric(eachfn, coll, iteratee, callback) { + var results = []; + eachfn(coll, (x, index, iterCb) => { + iteratee(x, (err, v) => { + if (err) return iterCb(err); + if (v) { + results.push({ index, value: x }); + } + iterCb(err); + }); + }, err => { + if (err) return callback(err); + callback(null, results.sort((a, b) => a.index - b.index).map(v => v.value)); + }); +} + +function _filter(eachfn, coll, iteratee, callback) { + var filter = (0, _isArrayLike2.default)(coll) ? filterArray : filterGeneric; + return filter(eachfn, coll, (0, _wrapAsync2.default)(iteratee), callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/getIterator.js b/Challenge/seokahi/010.star/node_modules/async/internal/getIterator.js new file mode 100644 index 0000000..830a545 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/getIterator.js @@ -0,0 +1,11 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (coll) { + return coll[Symbol.iterator] && coll[Symbol.iterator](); +}; + +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/initialParams.js b/Challenge/seokahi/010.star/node_modules/async/internal/initialParams.js new file mode 100644 index 0000000..245378c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/initialParams.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (fn) { + return function (...args /*, callback*/) { + var callback = args.pop(); + return fn.call(this, args, callback); + }; +}; + +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/isArrayLike.js b/Challenge/seokahi/010.star/node_modules/async/internal/isArrayLike.js new file mode 100644 index 0000000..ce07670 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/isArrayLike.js @@ -0,0 +1,10 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = isArrayLike; +function isArrayLike(value) { + return value && typeof value.length === 'number' && value.length >= 0 && value.length % 1 === 0; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/iterator.js b/Challenge/seokahi/010.star/node_modules/async/internal/iterator.js new file mode 100644 index 0000000..90b0223 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/iterator.js @@ -0,0 +1,57 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createIterator; + +var _isArrayLike = require('./isArrayLike.js'); + +var _isArrayLike2 = _interopRequireDefault(_isArrayLike); + +var _getIterator = require('./getIterator.js'); + +var _getIterator2 = _interopRequireDefault(_getIterator); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createArrayIterator(coll) { + var i = -1; + var len = coll.length; + return function next() { + return ++i < len ? { value: coll[i], key: i } : null; + }; +} + +function createES2015Iterator(iterator) { + var i = -1; + return function next() { + var item = iterator.next(); + if (item.done) return null; + i++; + return { value: item.value, key: i }; + }; +} + +function createObjectIterator(obj) { + var okeys = obj ? Object.keys(obj) : []; + var i = -1; + var len = okeys.length; + return function next() { + var key = okeys[++i]; + if (key === '__proto__') { + return next(); + } + return i < len ? { value: obj[key], key } : null; + }; +} + +function createIterator(coll) { + if ((0, _isArrayLike2.default)(coll)) { + return createArrayIterator(coll); + } + + var iterator = (0, _getIterator2.default)(coll); + return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/map.js b/Challenge/seokahi/010.star/node_modules/async/internal/map.js new file mode 100644 index 0000000..af3fd09 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/map.js @@ -0,0 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _asyncMap; + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncMap(eachfn, arr, iteratee, callback) { + arr = arr || []; + var results = []; + var counter = 0; + var _iteratee = (0, _wrapAsync2.default)(iteratee); + + return eachfn(arr, (value, _, iterCb) => { + var index = counter++; + _iteratee(value, (err, v) => { + results[index] = v; + iterCb(err); + }); + }, err => { + callback(err, results); + }); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/once.js b/Challenge/seokahi/010.star/node_modules/async/internal/once.js new file mode 100644 index 0000000..49f3727 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/once.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = once; +function once(fn) { + function wrapper(...args) { + if (fn === null) return; + var callFn = fn; + fn = null; + callFn.apply(this, args); + } + Object.assign(wrapper, fn); + return wrapper; +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/onlyOnce.js b/Challenge/seokahi/010.star/node_modules/async/internal/onlyOnce.js new file mode 100644 index 0000000..6ad721b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/onlyOnce.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = onlyOnce; +function onlyOnce(fn) { + return function (...args) { + if (fn === null) throw new Error("Callback was already called."); + var callFn = fn; + fn = null; + callFn.apply(this, args); + }; +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/parallel.js b/Challenge/seokahi/010.star/node_modules/async/internal/parallel.js new file mode 100644 index 0000000..75741bb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/parallel.js @@ -0,0 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _isArrayLike = require('./isArrayLike.js'); + +var _isArrayLike2 = _interopRequireDefault(_isArrayLike); + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (0, _awaitify2.default)((eachfn, tasks, callback) => { + var results = (0, _isArrayLike2.default)(tasks) ? [] : {}; + + eachfn(tasks, (task, key, taskCb) => { + (0, _wrapAsync2.default)(task)((err, ...result) => { + if (result.length < 2) { + [result] = result; + } + results[key] = result; + taskCb(err); + }); + }, err => callback(err, results)); +}, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/promiseCallback.js b/Challenge/seokahi/010.star/node_modules/async/internal/promiseCallback.js new file mode 100644 index 0000000..17a8301 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/promiseCallback.js @@ -0,0 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const PROMISE_SYMBOL = Symbol('promiseCallback'); + +function promiseCallback() { + let resolve, reject; + function callback(err, ...args) { + if (err) return reject(err); + resolve(args.length > 1 ? args : args[0]); + } + + callback[PROMISE_SYMBOL] = new Promise((res, rej) => { + resolve = res, reject = rej; + }); + + return callback; +} + +exports.promiseCallback = promiseCallback; +exports.PROMISE_SYMBOL = PROMISE_SYMBOL; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/queue.js b/Challenge/seokahi/010.star/node_modules/async/internal/queue.js new file mode 100644 index 0000000..c22b5b8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/queue.js @@ -0,0 +1,291 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = queue; + +var _onlyOnce = require('./onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _setImmediate = require('./setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _DoublyLinkedList = require('./DoublyLinkedList.js'); + +var _DoublyLinkedList2 = _interopRequireDefault(_DoublyLinkedList); + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } else if (concurrency === 0) { + throw new RangeError('Concurrency must not be zero'); + } + + var _worker = (0, _wrapAsync2.default)(worker); + var numRunning = 0; + var workersList = []; + const events = { + error: [], + drain: [], + saturated: [], + unsaturated: [], + empty: [] + }; + + function on(event, handler) { + events[event].push(handler); + } + + function once(event, handler) { + const handleAndRemove = (...args) => { + off(event, handleAndRemove); + handler(...args); + }; + events[event].push(handleAndRemove); + } + + function off(event, handler) { + if (!event) return Object.keys(events).forEach(ev => events[ev] = []); + if (!handler) return events[event] = []; + events[event] = events[event].filter(ev => ev !== handler); + } + + function trigger(event, ...args) { + events[event].forEach(handler => handler(...args)); + } + + var processingScheduled = false; + function _insert(data, insertAtFront, rejectOnError, callback) { + if (callback != null && typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + + var res, rej; + function promiseCallback(err, ...args) { + // we don't care about the error, let the global error handler + // deal with it + if (err) return rejectOnError ? rej(err) : res(); + if (args.length <= 1) return res(args[0]); + res(args); + } + + var item = { + data, + callback: rejectOnError ? promiseCallback : callback || promiseCallback + }; + + if (insertAtFront) { + q._tasks.unshift(item); + } else { + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + (0, _setImmediate2.default)(() => { + processingScheduled = false; + q.process(); + }); + } + + if (rejectOnError || !callback) { + return new Promise((resolve, reject) => { + res = resolve; + rej = reject; + }); + } + } + + function _createCB(tasks) { + return function (err, ...args) { + numRunning -= 1; + + for (var i = 0, l = tasks.length; i < l; i++) { + var task = tasks[i]; + + var index = workersList.indexOf(task); + if (index === 0) { + workersList.shift(); + } else if (index > 0) { + workersList.splice(index, 1); + } + + task.callback(err, ...args); + + if (err != null) { + trigger('error', err, task.data); + } + } + + if (numRunning <= q.concurrency - q.buffer) { + trigger('unsaturated'); + } + + if (q.idle()) { + trigger('drain'); + } + q.process(); + }; + } + + function _maybeDrain(data) { + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + (0, _setImmediate2.default)(() => trigger('drain')); + return true; + } + return false; + } + + const eventMethod = name => handler => { + if (!handler) { + return new Promise((resolve, reject) => { + once(name, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); + } + off(name); + on(name, handler); + }; + + var isProcessing = false; + var q = { + _tasks: new _DoublyLinkedList2.default(), + *[Symbol.iterator]() { + yield* q._tasks[Symbol.iterator](); + }, + concurrency, + payload, + buffer: concurrency / 4, + started: false, + paused: false, + push(data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return; + return data.map(datum => _insert(datum, false, false, callback)); + } + return _insert(data, false, false, callback); + }, + pushAsync(data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return; + return data.map(datum => _insert(datum, false, true, callback)); + } + return _insert(data, false, true, callback); + }, + kill() { + off(); + q._tasks.empty(); + }, + unshift(data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return; + return data.map(datum => _insert(datum, true, false, callback)); + } + return _insert(data, true, false, callback); + }, + unshiftAsync(data, callback) { + if (Array.isArray(data)) { + if (_maybeDrain(data)) return; + return data.map(datum => _insert(datum, true, true, callback)); + } + return _insert(data, true, true, callback); + }, + remove(testFn) { + q._tasks.remove(testFn); + }, + process() { + // Avoid trying to start too many processing operations. This can occur + // when callbacks resolve synchronously (#1267). + if (isProcessing) { + return; + } + isProcessing = true; + while (!q.paused && numRunning < q.concurrency && q._tasks.length) { + var tasks = [], + data = []; + var l = q._tasks.length; + if (q.payload) l = Math.min(l, q.payload); + for (var i = 0; i < l; i++) { + var node = q._tasks.shift(); + tasks.push(node); + workersList.push(node); + data.push(node.data); + } + + numRunning += 1; + + if (q._tasks.length === 0) { + trigger('empty'); + } + + if (numRunning === q.concurrency) { + trigger('saturated'); + } + + var cb = (0, _onlyOnce2.default)(_createCB(tasks)); + _worker(data, cb); + } + isProcessing = false; + }, + length() { + return q._tasks.length; + }, + running() { + return numRunning; + }, + workersList() { + return workersList; + }, + idle() { + return q._tasks.length + numRunning === 0; + }, + pause() { + q.paused = true; + }, + resume() { + if (q.paused === false) { + return; + } + q.paused = false; + (0, _setImmediate2.default)(q.process); + } + }; + // define these as fixed properties, so people get useful errors when updating + Object.defineProperties(q, { + saturated: { + writable: false, + value: eventMethod('saturated') + }, + unsaturated: { + writable: false, + value: eventMethod('unsaturated') + }, + empty: { + writable: false, + value: eventMethod('empty') + }, + drain: { + writable: false, + value: eventMethod('drain') + }, + error: { + writable: false, + value: eventMethod('error') + } + }); + return q; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/range.js b/Challenge/seokahi/010.star/node_modules/async/internal/range.js new file mode 100644 index 0000000..6680e64 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/range.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = range; +function range(size) { + var result = Array(size); + while (size--) { + result[size] = size; + } + return result; +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/reject.js b/Challenge/seokahi/010.star/node_modules/async/internal/reject.js new file mode 100644 index 0000000..7388ef4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/reject.js @@ -0,0 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = reject; + +var _filter = require('./filter.js'); + +var _filter2 = _interopRequireDefault(_filter); + +var _wrapAsync = require('./wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function reject(eachfn, arr, _iteratee, callback) { + const iteratee = (0, _wrapAsync2.default)(_iteratee); + return (0, _filter2.default)(eachfn, arr, (value, cb) => { + iteratee(value, (err, v) => { + cb(err, !v); + }); + }, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/setImmediate.js b/Challenge/seokahi/010.star/node_modules/async/internal/setImmediate.js new file mode 100644 index 0000000..513efd1 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/setImmediate.js @@ -0,0 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fallback = fallback; +exports.wrap = wrap; +/* istanbul ignore file */ + +var hasQueueMicrotask = exports.hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask; +var hasSetImmediate = exports.hasSetImmediate = typeof setImmediate === 'function' && setImmediate; +var hasNextTick = exports.hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; + +function fallback(fn) { + setTimeout(fn, 0); +} + +function wrap(defer) { + return (fn, ...args) => defer(() => fn(...args)); +} + +var _defer; + +if (hasQueueMicrotask) { + _defer = queueMicrotask; +} else if (hasSetImmediate) { + _defer = setImmediate; +} else if (hasNextTick) { + _defer = process.nextTick; +} else { + _defer = fallback; +} + +exports.default = wrap(_defer); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/withoutIndex.js b/Challenge/seokahi/010.star/node_modules/async/internal/withoutIndex.js new file mode 100644 index 0000000..ec45fa3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/withoutIndex.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _withoutIndex; +function _withoutIndex(iteratee) { + return (value, index, callback) => iteratee(value, callback); +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/internal/wrapAsync.js b/Challenge/seokahi/010.star/node_modules/async/internal/wrapAsync.js new file mode 100644 index 0000000..ad4d619 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/internal/wrapAsync.js @@ -0,0 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isAsyncIterable = exports.isAsyncGenerator = exports.isAsync = undefined; + +var _asyncify = require('../asyncify.js'); + +var _asyncify2 = _interopRequireDefault(_asyncify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function isAsync(fn) { + return fn[Symbol.toStringTag] === 'AsyncFunction'; +} + +function isAsyncGenerator(fn) { + return fn[Symbol.toStringTag] === 'AsyncGenerator'; +} + +function isAsyncIterable(obj) { + return typeof obj[Symbol.asyncIterator] === 'function'; +} + +function wrapAsync(asyncFn) { + if (typeof asyncFn !== 'function') throw new Error('expected a function'); + return isAsync(asyncFn) ? (0, _asyncify2.default)(asyncFn) : asyncFn; +} + +exports.default = wrapAsync; +exports.isAsync = isAsync; +exports.isAsyncGenerator = isAsyncGenerator; +exports.isAsyncIterable = isAsyncIterable; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/log.js b/Challenge/seokahi/010.star/node_modules/async/log.js new file mode 100644 index 0000000..8fc1ed5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/log.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _consoleFunc = require('./internal/consoleFunc.js'); + +var _consoleFunc2 = _interopRequireDefault(_consoleFunc); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Logs the result of an `async` function to the `console`. Only works in + * Node.js or in browsers that support `console.log` and `console.error` (such + * as FF and Chrome). If multiple arguments are returned from the async + * function, `console.log` is called on each argument in order. + * + * @name log + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, 'hello ' + name); + * }, 1000); + * }; + * + * // in the node repl + * node> async.log(hello, 'world'); + * 'hello world' + */ +exports.default = (0, _consoleFunc2.default)('log'); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/map.js b/Challenge/seokahi/010.star/node_modules/async/map.js new file mode 100644 index 0000000..ec4135d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/map.js @@ -0,0 +1,142 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _map2 = require('./internal/map.js'); + +var _map3 = _interopRequireDefault(_map2); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Produces a new collection of values by mapping each value in `coll` through + * the `iteratee` function. The `iteratee` is called with an item from `coll` + * and a callback for when it has finished processing. Each of these callbacks + * takes 2 arguments: an `error`, and the transformed item from `coll`. If + * `iteratee` passes an error to its callback, the main `callback` (for the + * `map` function) is immediately called with the error. + * + * Note, that since this function applies the `iteratee` to each item in + * parallel, there is no guarantee that the `iteratee` functions will complete + * in order. However, the results array will be in the same order as the + * original `coll`. + * + * If `map` is passed an Object, the results will be an Array. The results + * will roughly be in the order of the original Objects' keys (but this can + * vary across JavaScript engines). + * + * @name map + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an Array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file4.txt']; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.map(fileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * }); + * + * // Using Promises + * async.map(fileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.map(withMissingFileList, getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.map(fileList, getFileSizeInBytes); + * console.log(results); + * // results is now an array of the file size in bytes for each file, e.g. + * // [ 1000, 2000, 3000] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let results = await async.map(withMissingFileList, getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function map(coll, iteratee, callback) { + return (0, _map3.default)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(map, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/mapLimit.js b/Challenge/seokahi/010.star/node_modules/async/mapLimit.js new file mode 100644 index 0000000..b5e461c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/mapLimit.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _map2 = require('./internal/map.js'); + +var _map3 = _interopRequireDefault(_map2); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. + * + * @name mapLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function mapLimit(coll, limit, iteratee, callback) { + return (0, _map3.default)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(mapLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/mapSeries.js b/Challenge/seokahi/010.star/node_modules/async/mapSeries.js new file mode 100644 index 0000000..91f36bf --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/mapSeries.js @@ -0,0 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _map2 = require('./internal/map.js'); + +var _map3 = _interopRequireDefault(_map2); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. + * + * @name mapSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function mapSeries(coll, iteratee, callback) { + return (0, _map3.default)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(mapSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/mapValues.js b/Challenge/seokahi/010.star/node_modules/async/mapValues.js new file mode 100644 index 0000000..00da926 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/mapValues.js @@ -0,0 +1,152 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = mapValues; + +var _mapValuesLimit = require('./mapValuesLimit.js'); + +var _mapValuesLimit2 = _interopRequireDefault(_mapValuesLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. + * + * Produces a new Object by mapping each value of `obj` through the `iteratee` + * function. The `iteratee` is called each `value` and `key` from `obj` and a + * callback for when it has finished processing. Each of these callbacks takes + * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` + * passes an error to its callback, the main `callback` (for the `mapValues` + * function) is immediately called with the error. + * + * Note, the order of the keys in the result is not guaranteed. The keys will + * be roughly in the order they complete, (but this is very engine-specific) + * + * @name mapValues + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file3.txt' + * }; + * + * const withMissingFileMap = { + * f1: 'file1.txt', + * f2: 'file2.txt', + * f3: 'file4.txt' + * }; + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, key, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * }); + * + * // Error handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.mapValues(fileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * }).catch (err => { + * console.log(err); + * }); + * + * // Error Handling + * async.mapValues(withMissingFileMap, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch (err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.mapValues(fileMap, getFileSizeInBytes); + * console.log(result); + * // result is now a map of file size in bytes for each file, e.g. + * // { + * // f1: 1000, + * // f2: 2000, + * // f3: 3000 + * // } + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function mapValues(obj, iteratee, callback) { + return (0, _mapValuesLimit2.default)(obj, Infinity, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/mapValuesLimit.js b/Challenge/seokahi/010.star/node_modules/async/mapValuesLimit.js new file mode 100644 index 0000000..93066ee --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/mapValuesLimit.js @@ -0,0 +1,61 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a + * time. + * + * @name mapValuesLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function mapValuesLimit(obj, limit, iteratee, callback) { + callback = (0, _once2.default)(callback); + var newObj = {}; + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _eachOfLimit2.default)(limit)(obj, (val, key, next) => { + _iteratee(val, key, (err, result) => { + if (err) return next(err); + newObj[key] = result; + next(err); + }); + }, err => callback(err, newObj)); +} + +exports.default = (0, _awaitify2.default)(mapValuesLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/mapValuesSeries.js b/Challenge/seokahi/010.star/node_modules/async/mapValuesSeries.js new file mode 100644 index 0000000..560058a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/mapValuesSeries.js @@ -0,0 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = mapValuesSeries; + +var _mapValuesLimit = require('./mapValuesLimit.js'); + +var _mapValuesLimit2 = _interopRequireDefault(_mapValuesLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. + * + * @name mapValuesSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function mapValuesSeries(obj, iteratee, callback) { + return (0, _mapValuesLimit2.default)(obj, 1, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/memoize.js b/Challenge/seokahi/010.star/node_modules/async/memoize.js new file mode 100644 index 0000000..6003e41 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/memoize.js @@ -0,0 +1,91 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = memoize; + +var _setImmediate = require('./internal/setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Caches the results of an async function. When creating a hash to store + * function results against, the callback is omitted from the hash and an + * optional hash function can be used. + * + * **Note: if the async function errs, the result will not be cached and + * subsequent calls will call the wrapped function.** + * + * If no hash function is specified, the first argument is used as a hash key, + * which may work reasonably if it is a string or a data type that converts to a + * distinct string. Note that objects and arrays will not behave reasonably. + * Neither will cases where the other arguments are significant. In such cases, + * specify your own hash function. + * + * The cache of results is exposed as the `memo` property of the function + * returned by `memoize`. + * + * @name memoize + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function to proxy and cache results from. + * @param {Function} hasher - An optional function for generating a custom hash + * for storing results. It has all the arguments applied to it apart from the + * callback, and must be synchronous. + * @returns {AsyncFunction} a memoized version of `fn` + * @example + * + * var slow_fn = function(name, callback) { + * // do something + * callback(null, result); + * }; + * var fn = async.memoize(slow_fn); + * + * // fn can now be used as if it were slow_fn + * fn('some name', function() { + * // callback + * }); + */ +function memoize(fn, hasher = v => v) { + var memo = Object.create(null); + var queues = Object.create(null); + var _fn = (0, _wrapAsync2.default)(fn); + var memoized = (0, _initialParams2.default)((args, callback) => { + var key = hasher(...args); + if (key in memo) { + (0, _setImmediate2.default)(() => callback(null, ...memo[key])); + } else if (key in queues) { + queues[key].push(callback); + } else { + queues[key] = [callback]; + _fn(...args, (err, ...resultArgs) => { + // #1465 don't memoize if an error occurred + if (!err) { + memo[key] = resultArgs; + } + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i](err, ...resultArgs); + } + }); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/nextTick.js b/Challenge/seokahi/010.star/node_modules/async/nextTick.js new file mode 100644 index 0000000..e6d321b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/nextTick.js @@ -0,0 +1,52 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _setImmediate = require('./internal/setImmediate.js'); + +/** + * Calls `callback` on a later loop around the event loop. In Node.js this just + * calls `process.nextTick`. In the browser it will use `setImmediate` if + * available, otherwise `setTimeout(callback, 0)`, which means other higher + * priority events may precede the execution of `callback`. + * + * This is used internally for browser-compatibility purposes. + * + * @name nextTick + * @static + * @memberOf module:Utils + * @method + * @see [async.setImmediate]{@link module:Utils.setImmediate} + * @category Util + * @param {Function} callback - The function to call on a later loop around + * the event loop. Invoked with (args...). + * @param {...*} args... - any number of additional arguments to pass to the + * callback on the next tick. + * @example + * + * var call_order = []; + * async.nextTick(function() { + * call_order.push('two'); + * // call_order now equals ['one','two'] + * }); + * call_order.push('one'); + * + * async.setImmediate(function (a, b, c) { + * // a, b, and c equal 1, 2, and 3 + * }, 1, 2, 3); + */ +var _defer; /* istanbul ignore file */ + + +if (_setImmediate.hasNextTick) { + _defer = process.nextTick; +} else if (_setImmediate.hasSetImmediate) { + _defer = setImmediate; +} else { + _defer = _setImmediate.fallback; +} + +exports.default = (0, _setImmediate.wrap)(_defer); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/package.json b/Challenge/seokahi/010.star/node_modules/async/package.json new file mode 100644 index 0000000..2c729a8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/package.json @@ -0,0 +1,80 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "3.2.3", + "main": "dist/async.js", + "author": "Caolan McMahon", + "homepage": "https://caolan.github.io/async/", + "repository": { + "type": "git", + "url": "https://github.com/caolan/async.git" + }, + "bugs": { + "url": "https://github.com/caolan/async/issues" + }, + "keywords": [ + "async", + "callback", + "module", + "utility" + ], + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.6", + "babel-minify": "^0.5.0", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-istanbul": "^5.1.4", + "babel-plugin-syntax-async-generators": "^6.13.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "babel-preset-es2015": "^6.3.13", + "babel-preset-es2017": "^6.22.0", + "babel-register": "^6.26.0", + "babelify": "^8.0.0", + "benchmark": "^2.1.1", + "bluebird": "^3.4.6", + "browserify": "^16.2.3", + "chai": "^4.2.0", + "cheerio": "^0.22.0", + "coveralls": "^3.0.4", + "es6-promise": "^2.3.0", + "eslint": "^6.0.1", + "eslint-plugin-prefer-arrow": "^1.1.5", + "fs-extra": "^0.26.7", + "jsdoc": "^3.6.2", + "karma": "^4.1.0", + "karma-browserify": "^5.3.0", + "karma-edge-launcher": "^0.4.2", + "karma-firefox-launcher": "^1.1.0", + "karma-junit-reporter": "^1.2.0", + "karma-mocha": "^1.2.0", + "karma-mocha-reporter": "^2.2.0", + "karma-safari-launcher": "^1.0.0", + "mocha": "^6.1.4", + "mocha-junit-reporter": "^1.18.0", + "native-promise-only": "^0.8.0-a", + "nyc": "^14.1.1", + "rollup": "^0.63.4", + "rollup-plugin-node-resolve": "^2.0.0", + "rollup-plugin-npm": "^2.0.0", + "rsvp": "^3.0.18", + "semver": "^5.5.0", + "yargs": "^11.0.0" + }, + "scripts": { + "coverage": "nyc npm run mocha-node-test -- --grep @nycinvalid --invert", + "coveralls": "npm run coverage && nyc report --reporter=text-lcov | coveralls", + "jsdoc": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", + "lint": "eslint --fix lib/ test/ perf/memory.js perf/suites.js perf/benchmark.js support/build/ support/*.js karma.conf.js", + "mocha-browser-test": "karma start", + "mocha-node-test": "mocha", + "mocha-test": "npm run mocha-node-test && npm run mocha-browser-test", + "test": "npm run lint && npm run mocha-node-test" + }, + "license": "MIT", + "nyc": { + "exclude": [ + "test" + ] + }, + "module": "dist/async.mjs" +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/parallel.js b/Challenge/seokahi/010.star/node_modules/async/parallel.js new file mode 100644 index 0000000..76bc624 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/parallel.js @@ -0,0 +1,180 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = parallel; + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _parallel2 = require('./internal/parallel.js'); + +var _parallel3 = _interopRequireDefault(_parallel2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Run the `tasks` collection of functions in parallel, without waiting until + * the previous function has completed. If any of the functions pass an error to + * its callback, the main `callback` is immediately called with the value of the + * error. Once the `tasks` have completed, the results are passed to the final + * `callback` as an array. + * + * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about + * parallel execution of code. If your tasks do not use any timers or perform + * any I/O, they will actually be executed in series. Any synchronous setup + * sections for each task will happen one after the other. JavaScript remains + * single-threaded. + * + * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the + * execution of other tasks when a task fails. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.parallel}. + * + * @name parallel + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * + * //Using Callbacks + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] even though + * // the second function had a shorter timeout. + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function parallel(tasks, callback) { + return (0, _parallel3.default)(_eachOf2.default, tasks, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/parallelLimit.js b/Challenge/seokahi/010.star/node_modules/async/parallelLimit.js new file mode 100644 index 0000000..dbe0bb8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/parallelLimit.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = parallelLimit; + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _parallel = require('./internal/parallel.js'); + +var _parallel2 = _interopRequireDefault(_parallel); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a + * time. + * + * @name parallelLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.parallel]{@link module:ControlFlow.parallel} + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * @returns {Promise} a promise, if a callback is not passed + */ +function parallelLimit(tasks, limit, callback) { + return (0, _parallel2.default)((0, _eachOfLimit2.default)(limit), tasks, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/priorityQueue.js b/Challenge/seokahi/010.star/node_modules/async/priorityQueue.js new file mode 100644 index 0000000..6b7c331 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/priorityQueue.js @@ -0,0 +1,91 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (worker, concurrency) { + // Start with a normal queue + var q = (0, _queue2.default)(worker, concurrency); + var processingScheduled = false; + + q._tasks = new _Heap2.default(); + + // Override push to accept second parameter representing priority + q.push = function (data, priority = 0, callback = () => {}) { + if (typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + if (!Array.isArray(data)) { + data = [data]; + } + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return (0, _setImmediate2.default)(() => q.drain()); + } + + for (var i = 0, l = data.length; i < l; i++) { + var item = { + data: data[i], + priority, + callback + }; + + q._tasks.push(item); + } + + if (!processingScheduled) { + processingScheduled = true; + (0, _setImmediate2.default)(() => { + processingScheduled = false; + q.process(); + }); + } + }; + + // Remove unshift function + delete q.unshift; + + return q; +}; + +var _setImmediate = require('./setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _queue = require('./queue.js'); + +var _queue2 = _interopRequireDefault(_queue); + +var _Heap = require('./internal/Heap.js'); + +var _Heap2 = _interopRequireDefault(_Heap); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = exports['default']; + +/** + * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and + * completed in ascending priority order. + * + * @name priorityQueue + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. + * Invoked with (task, callback). + * @param {number} concurrency - An `integer` for determining how many `worker` + * functions should be run in parallel. If omitted, the concurrency defaults to + * `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two + * differences between `queue` and `priorityQueue` objects: + * * `push(task, priority, [callback])` - `priority` should be a number. If an + * array of `tasks` is given, all tasks will be assigned the same priority. + * * The `unshift` method was removed. + */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/queue.js b/Challenge/seokahi/010.star/node_modules/async/queue.js new file mode 100644 index 0000000..c69becb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/queue.js @@ -0,0 +1,167 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (worker, concurrency) { + var _worker = (0, _wrapAsync2.default)(worker); + return (0, _queue2.default)((items, cb) => { + _worker(items[0], cb); + }, concurrency, 1); +}; + +var _queue = require('./internal/queue.js'); + +var _queue2 = _interopRequireDefault(_queue); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = exports['default']; + +/** + * A queue of tasks for the worker function to complete. + * @typedef {Iterable} QueueObject + * @memberOf module:ControlFlow + * @property {Function} length - a function returning the number of items + * waiting to be processed. Invoke with `queue.length()`. + * @property {boolean} started - a boolean indicating whether or not any + * items have been pushed and processed by the queue. + * @property {Function} running - a function returning the number of items + * currently being processed. Invoke with `queue.running()`. + * @property {Function} workersList - a function returning the array of items + * currently being processed. Invoke with `queue.workersList()`. + * @property {Function} idle - a function returning false if there are items + * waiting or being processed, or true if not. Invoke with `queue.idle()`. + * @property {number} concurrency - an integer for determining how many `worker` + * functions should be run in parallel. This property can be changed after a + * `queue` is created to alter the concurrency on-the-fly. + * @property {number} payload - an integer that specifies how many items are + * passed to the worker function at a time. only applies if this is a + * [cargo]{@link module:ControlFlow.cargo} object + * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback` + * once the `worker` has finished processing the task. Instead of a single task, + * a `tasks` array can be submitted. The respective callback is used for every + * task in the list. Invoke with `queue.push(task, [callback])`, + * @property {AsyncFunction} unshift - add a new task to the front of the `queue`. + * Invoke with `queue.unshift(task, [callback])`. + * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns + * a promise that rejects if an error occurs. + * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns + * a promise that rejects if an error occurs. + * @property {Function} remove - remove items from the queue that match a test + * function. The test function will be passed an object with a `data` property, + * and a `priority` property, if this is a + * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. + * Invoked with `queue.remove(testFn)`, where `testFn` is of the form + * `function ({data, priority}) {}` and returns a Boolean. + * @property {Function} saturated - a function that sets a callback that is + * called when the number of running workers hits the `concurrency` limit, and + * further tasks will be queued. If the callback is omitted, `q.saturated()` + * returns a promise for the next occurrence. + * @property {Function} unsaturated - a function that sets a callback that is + * called when the number of running workers is less than the `concurrency` & + * `buffer` limits, and further tasks will not be queued. If the callback is + * omitted, `q.unsaturated()` returns a promise for the next occurrence. + * @property {number} buffer - A minimum threshold buffer in order to say that + * the `queue` is `unsaturated`. + * @property {Function} empty - a function that sets a callback that is called + * when the last item from the `queue` is given to a `worker`. If the callback + * is omitted, `q.empty()` returns a promise for the next occurrence. + * @property {Function} drain - a function that sets a callback that is called + * when the last item from the `queue` has returned from the `worker`. If the + * callback is omitted, `q.drain()` returns a promise for the next occurrence. + * @property {Function} error - a function that sets a callback that is called + * when a task errors. Has the signature `function(error, task)`. If the + * callback is omitted, `error()` returns a promise that rejects on the next + * error. + * @property {boolean} paused - a boolean for determining whether the queue is + * in a paused state. + * @property {Function} pause - a function that pauses the processing of tasks + * until `resume()` is called. Invoke with `queue.pause()`. + * @property {Function} resume - a function that resumes the processing of + * queued tasks when the queue is paused. Invoke with `queue.resume()`. + * @property {Function} kill - a function that removes the `drain` callback and + * empties remaining tasks from the queue forcing it to go idle. No more tasks + * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. + * + * @example + * const q = async.queue(worker, 2) + * q.push(item1) + * q.push(item2) + * q.push(item3) + * // queues are iterable, spread into an array to inspect + * const items = [...q] // [item1, item2, item3] + * // or use for of + * for (let item of q) { + * console.log(item) + * } + * + * q.drain(() => { + * console.log('all done') + * }) + * // or + * await q.drain() + */ + +/** + * Creates a `queue` object with the specified `concurrency`. Tasks added to the + * `queue` are processed in parallel (up to the `concurrency` limit). If all + * `worker`s are in progress, the task is queued until one becomes available. + * Once a `worker` completes a `task`, that `task`'s callback is called. + * + * @name queue + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. Invoked with (task, callback). + * @param {number} [concurrency=1] - An `integer` for determining how many + * `worker` functions should be run in parallel. If omitted, the concurrency + * defaults to `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be + * attached as certain properties to listen for specific events during the + * lifecycle of the queue. + * @example + * + * // create a queue object with concurrency 2 + * var q = async.queue(function(task, callback) { + * console.log('hello ' + task.name); + * callback(); + * }, 2); + * + * // assign a callback + * q.drain(function() { + * console.log('all items have been processed'); + * }); + * // or await the end + * await q.drain() + * + * // assign an error callback + * q.error(function(err, task) { + * console.error('task experienced an error'); + * }); + * + * // add some items to the queue + * q.push({name: 'foo'}, function(err) { + * console.log('finished processing foo'); + * }); + * // callback is optional + * q.push({name: 'bar'}); + * + * // add some items to the queue (batch-wise) + * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { + * console.log('finished processing item'); + * }); + * + * // add some items to the front of the queue + * q.unshift({name: 'bar'}, function (err) { + * console.log('finished processing bar'); + * }); + */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/race.js b/Challenge/seokahi/010.star/node_modules/async/race.js new file mode 100644 index 0000000..236a9f0 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/race.js @@ -0,0 +1,67 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Runs the `tasks` array of functions in parallel, without waiting until the + * previous function has completed. Once any of the `tasks` complete or pass an + * error to its callback, the main `callback` is immediately called. It's + * equivalent to `Promise.race()`. + * + * @name race + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} + * to run. Each function can complete with an optional `result` value. + * @param {Function} callback - A callback to run once any of the functions have + * completed. This function gets an error or result from the first function that + * completed. Invoked with (err, result). + * @returns undefined + * @example + * + * async.race([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], + * // main callback + * function(err, result) { + * // the result will be equal to 'two' as it finishes earlier + * }); + */ +function race(tasks, callback) { + callback = (0, _once2.default)(callback); + if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); + if (!tasks.length) return callback(); + for (var i = 0, l = tasks.length; i < l; i++) { + (0, _wrapAsync2.default)(tasks[i])(callback); + } +} + +exports.default = (0, _awaitify2.default)(race, 2); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/reduce.js b/Challenge/seokahi/010.star/node_modules/async/reduce.js new file mode 100644 index 0000000..56e2db8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/reduce.js @@ -0,0 +1,153 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Reduces `coll` into a single value using an async `iteratee` to return each + * successive step. `memo` is the initial state of the reduction. This function + * only operates in series. + * + * For performance reasons, it may make sense to split a call to this function + * into a parallel map, and then use the normal `Array.prototype.reduce` on the + * results. This function is for situations where each step in the reduction + * needs to be async; if you can get the data before reducing it, then it's + * probably a good idea to do so. + * + * @name reduce + * @static + * @memberOf module:Collections + * @method + * @alias inject + * @alias foldl + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * // file4.txt does not exist + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt']; + * + * // asynchronous function that computes the file size in bytes + * // file size is added to the memoized value, then returned + * function getFileSizeInBytes(memo, file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, memo + stat.size); + * }); + * } + * + * // Using callbacks + * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * } else { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(result); + * } + * }); + * + * // Using Promises + * async.reduce(fileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * }).catch( err => { + * console.log(err); + * }); + * + * // Error Handling + * async.reduce(withMissingFileList, 0, getFileSizeInBytes) + * .then( result => { + * console.log(result); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.reduce(fileList, 0, getFileSizeInBytes); + * console.log(result); + * // 6000 + * // which is the sum of the file sizes of the three files + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // Error Handling + * async () => { + * try { + * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes); + * console.log(result); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function reduce(coll, memo, iteratee, callback) { + callback = (0, _once2.default)(callback); + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _eachOfSeries2.default)(coll, (x, i, iterCb) => { + _iteratee(memo, x, (err, v) => { + memo = v; + iterCb(err); + }); + }, err => callback(err, memo)); +} +exports.default = (0, _awaitify2.default)(reduce, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/reduceRight.js b/Challenge/seokahi/010.star/node_modules/async/reduceRight.js new file mode 100644 index 0000000..bee5391 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/reduceRight.js @@ -0,0 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = reduceRight; + +var _reduce = require('./reduce.js'); + +var _reduce2 = _interopRequireDefault(_reduce); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. + * + * @name reduceRight + * @static + * @memberOf module:Collections + * @method + * @see [async.reduce]{@link module:Collections.reduce} + * @alias foldr + * @category Collection + * @param {Array} array - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee completes with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + * @returns {Promise} a promise, if no callback is passed + */ +function reduceRight(array, memo, iteratee, callback) { + var reversed = [...array].reverse(); + return (0, _reduce2.default)(reversed, memo, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/reflect.js b/Challenge/seokahi/010.star/node_modules/async/reflect.js new file mode 100644 index 0000000..297ed79 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/reflect.js @@ -0,0 +1,78 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = reflect; + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Wraps the async function in another function that always completes with a + * result object, even when it errors. + * + * The result object has either the property `error` or `value`. + * + * @name reflect + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function you want to wrap + * @returns {Function} - A function that always passes null to it's callback as + * the error. The second argument to the callback will be an `object` with + * either an `error` or a `value` property. + * @example + * + * async.parallel([ + * async.reflect(function(callback) { + * // do some stuff ... + * callback(null, 'one'); + * }), + * async.reflect(function(callback) { + * // do some more stuff but error ... + * callback('bad stuff happened'); + * }), + * async.reflect(function(callback) { + * // do some more stuff ... + * callback(null, 'two'); + * }) + * ], + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = 'bad stuff happened' + * // results[2].value = 'two' + * }); + */ +function reflect(fn) { + var _fn = (0, _wrapAsync2.default)(fn); + return (0, _initialParams2.default)(function reflectOn(args, reflectCallback) { + args.push((error, ...cbArgs) => { + let retVal = {}; + if (error) { + retVal.error = error; + } + if (cbArgs.length > 0) { + var value = cbArgs; + if (cbArgs.length <= 1) { + [value] = cbArgs; + } + retVal.value = value; + } + reflectCallback(null, retVal); + }); + + return _fn.apply(this, args); + }); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/reflectAll.js b/Challenge/seokahi/010.star/node_modules/async/reflectAll.js new file mode 100644 index 0000000..a862ff0 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/reflectAll.js @@ -0,0 +1,93 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = reflectAll; + +var _reflect = require('./reflect.js'); + +var _reflect2 = _interopRequireDefault(_reflect); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * A helper function that wraps an array or an object of functions with `reflect`. + * + * @name reflectAll + * @static + * @memberOf module:Utils + * @method + * @see [async.reflect]{@link module:Utils.reflect} + * @category Util + * @param {Array|Object|Iterable} tasks - The collection of + * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. + * @returns {Array} Returns an array of async functions, each wrapped in + * `async.reflect` + * @example + * + * let tasks = [ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * // do some more stuff but error ... + * callback(new Error('bad stuff happened')); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = Error('bad stuff happened') + * // results[2].value = 'two' + * }); + * + * // an example using an object instead of an array + * let tasks = { + * one: function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * two: function(callback) { + * callback('two'); + * }, + * three: function(callback) { + * setTimeout(function() { + * callback(null, 'three'); + * }, 100); + * } + * }; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results.one.value = 'one' + * // results.two.error = 'two' + * // results.three.value = 'three' + * }); + */ +function reflectAll(tasks) { + var results; + if (Array.isArray(tasks)) { + results = tasks.map(_reflect2.default); + } else { + results = {}; + Object.keys(tasks).forEach(key => { + results[key] = _reflect2.default.call(this, tasks[key]); + }); + } + return results; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/reject.js b/Challenge/seokahi/010.star/node_modules/async/reject.js new file mode 100644 index 0000000..cabd96e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/reject.js @@ -0,0 +1,87 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reject2 = require('./internal/reject.js'); + +var _reject3 = _interopRequireDefault(_reject2); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. + * + * @name reject + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.reject(fileList, fileExists, function(err, results) { + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }); + * + * // Using Promises + * async.reject(fileList, fileExists) + * .then( results => { + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.reject(fileList, fileExists); + * console.log(results); + * // [ 'dir3/file6.txt' ] + * // results now equals an array of the non-existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function reject(coll, iteratee, callback) { + return (0, _reject3.default)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(reject, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/rejectLimit.js b/Challenge/seokahi/010.star/node_modules/async/rejectLimit.js new file mode 100644 index 0000000..1a89925 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/rejectLimit.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reject2 = require('./internal/reject.js'); + +var _reject3 = _interopRequireDefault(_reject2); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a + * time. + * + * @name rejectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function rejectLimit(coll, limit, iteratee, callback) { + return (0, _reject3.default)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(rejectLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/rejectSeries.js b/Challenge/seokahi/010.star/node_modules/async/rejectSeries.js new file mode 100644 index 0000000..6e1a1c5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/rejectSeries.js @@ -0,0 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reject2 = require('./internal/reject.js'); + +var _reject3 = _interopRequireDefault(_reject2); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. + * + * @name rejectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback is passed + */ +function rejectSeries(coll, iteratee, callback) { + return (0, _reject3.default)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(rejectSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/retry.js b/Challenge/seokahi/010.star/node_modules/async/retry.js new file mode 100644 index 0000000..dba3030 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/retry.js @@ -0,0 +1,159 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = retry; + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _promiseCallback = require('./internal/promiseCallback.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function constant(value) { + return function () { + return value; + }; +} + +/** + * Attempts to get a successful response from `task` no more than `times` times + * before returning an error. If the task is successful, the `callback` will be + * passed the result of the successful task. If all attempts fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name retry + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @see [async.retryable]{@link module:ControlFlow.retryable} + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an + * object with `times` and `interval` or a number. + * * `times` - The number of attempts to make before giving up. The default + * is `5`. + * * `interval` - The time to wait between retries, in milliseconds. The + * default is `0`. The interval may also be specified as a function of the + * retry count (see example). + * * `errorFilter` - An optional synchronous function that is invoked on + * erroneous result. If it returns `true` the retry attempts will continue; + * if the function returns `false` the retry flow is aborted with the current + * attempt's error and result being returned to the final callback. + * Invoked with (err). + * * If `opts` is a number, the number specifies the number of times to retry, + * with the default interval of `0`. + * @param {AsyncFunction} task - An async function to retry. + * Invoked with (callback). + * @param {Function} [callback] - An optional callback which is called when the + * task has succeeded, or after the final failed attempt. It receives the `err` + * and `result` arguments of the last attempt at completing the `task`. Invoked + * with (err, results). + * @returns {Promise} a promise if no callback provided + * + * @example + * + * // The `retry` function can be used as a stand-alone control flow by passing + * // a callback, as shown below: + * + * // try calling apiMethod 3 times + * async.retry(3, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 3 times, waiting 200 ms between each retry + * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 10 times with exponential backoff + * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) + * async.retry({ + * times: 10, + * interval: function(retryCount) { + * return 50 * Math.pow(2, retryCount); + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod the default 5 times no delay between each retry + * async.retry(apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod only when error condition satisfies, all other + * // errors will abort the retry control flow and return to final callback + * async.retry({ + * errorFilter: function(err) { + * return err.message === 'Temporary error'; // only retry on a specific error + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // to retry individual methods that are not as reliable within other + * // control flow functions, use the `retryable` wrapper: + * async.auto({ + * users: api.getUsers.bind(api), + * payments: async.retryable(3, api.getPayments.bind(api)) + * }, function(err, results) { + * // do something with the results + * }); + * + */ +const DEFAULT_TIMES = 5; +const DEFAULT_INTERVAL = 0; + +function retry(opts, task, callback) { + var options = { + times: DEFAULT_TIMES, + intervalFunc: constant(DEFAULT_INTERVAL) + }; + + if (arguments.length < 3 && typeof opts === 'function') { + callback = task || (0, _promiseCallback.promiseCallback)(); + task = opts; + } else { + parseTimes(options, opts); + callback = callback || (0, _promiseCallback.promiseCallback)(); + } + + if (typeof task !== 'function') { + throw new Error("Invalid arguments for async.retry"); + } + + var _task = (0, _wrapAsync2.default)(task); + + var attempt = 1; + function retryAttempt() { + _task((err, ...args) => { + if (err === false) return; + if (err && attempt++ < options.times && (typeof options.errorFilter != 'function' || options.errorFilter(err))) { + setTimeout(retryAttempt, options.intervalFunc(attempt - 1)); + } else { + callback(err, ...args); + } + }); + } + + retryAttempt(); + return callback[_promiseCallback.PROMISE_SYMBOL]; +} + +function parseTimes(acc, t) { + if (typeof t === 'object') { + acc.times = +t.times || DEFAULT_TIMES; + + acc.intervalFunc = typeof t.interval === 'function' ? t.interval : constant(+t.interval || DEFAULT_INTERVAL); + + acc.errorFilter = t.errorFilter; + } else if (typeof t === 'number' || typeof t === 'string') { + acc.times = +t || DEFAULT_TIMES; + } else { + throw new Error("Invalid arguments for async.retry"); + } +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/retryable.js b/Challenge/seokahi/010.star/node_modules/async/retryable.js new file mode 100644 index 0000000..1b1147c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/retryable.js @@ -0,0 +1,77 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = retryable; + +var _retry = require('./retry.js'); + +var _retry2 = _interopRequireDefault(_retry); + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _promiseCallback = require('./internal/promiseCallback.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method + * wraps a task and makes it retryable, rather than immediately calling it + * with retries. + * + * @name retryable + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.retry]{@link module:ControlFlow.retry} + * @category Control Flow + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional + * options, exactly the same as from `retry`, except for a `opts.arity` that + * is the arity of the `task` function, defaulting to `task.length` + * @param {AsyncFunction} task - the asynchronous function to wrap. + * This function will be passed any arguments passed to the returned wrapper. + * Invoked with (...args, callback). + * @returns {AsyncFunction} The wrapped function, which when invoked, will + * retry on an error, based on the parameters specified in `opts`. + * This function will accept the same parameters as `task`. + * @example + * + * async.auto({ + * dep1: async.retryable(3, getFromFlakyService), + * process: ["dep1", async.retryable(3, function (results, cb) { + * maybeProcessData(results.dep1, cb); + * })] + * }, callback); + */ +function retryable(opts, task) { + if (!task) { + task = opts; + opts = null; + } + let arity = opts && opts.arity || task.length; + if ((0, _wrapAsync.isAsync)(task)) { + arity += 1; + } + var _task = (0, _wrapAsync2.default)(task); + return (0, _initialParams2.default)((args, callback) => { + if (args.length < arity - 1 || callback == null) { + args.push(callback); + callback = (0, _promiseCallback.promiseCallback)(); + } + function taskFn(cb) { + _task(...args, cb); + } + + if (opts) (0, _retry2.default)(opts, taskFn, callback);else (0, _retry2.default)(taskFn, callback); + + return callback[_promiseCallback.PROMISE_SYMBOL]; + }); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/select.js b/Challenge/seokahi/010.star/node_modules/async/select.js new file mode 100644 index 0000000..303dc1f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/select.js @@ -0,0 +1,93 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a new array of all the values in `coll` which pass an async truth + * test. This operation is performed in parallel, but the results array will be + * in the same order as the original. + * + * @name filter + * @static + * @memberOf module:Collections + * @method + * @alias select + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * + * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt']; + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.filter(files, fileExists, function(err, results) { + * if(err) { + * console.log(err); + * } else { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * }); + * + * // Using Promises + * async.filter(files, fileExists) + * .then(results => { + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let results = await async.filter(files, fileExists); + * console.log(results); + * // [ 'dir1/file1.txt', 'dir2/file3.txt' ] + * // results is now an array of the existing files + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function filter(coll, iteratee, callback) { + return (0, _filter3.default)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filter, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/selectLimit.js b/Challenge/seokahi/010.star/node_modules/async/selectLimit.js new file mode 100644 index 0000000..89e55f5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/selectLimit.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a + * time. + * + * @name filterLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @returns {Promise} a promise, if no callback provided + */ +function filterLimit(coll, limit, iteratee, callback) { + return (0, _filter3.default)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filterLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/selectSeries.js b/Challenge/seokahi/010.star/node_modules/async/selectSeries.js new file mode 100644 index 0000000..a045e52 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/selectSeries.js @@ -0,0 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _filter2 = require('./internal/filter.js'); + +var _filter3 = _interopRequireDefault(_filter2); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. + * + * @name filterSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectSeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results) + * @returns {Promise} a promise, if no callback provided + */ +function filterSeries(coll, iteratee, callback) { + return (0, _filter3.default)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(filterSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/seq.js b/Challenge/seokahi/010.star/node_modules/async/seq.js new file mode 100644 index 0000000..28c825f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/seq.js @@ -0,0 +1,79 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = seq; + +var _reduce = require('./reduce.js'); + +var _reduce2 = _interopRequireDefault(_reduce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _promiseCallback = require('./internal/promiseCallback.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Version of the compose function that is more natural to read. Each function + * consumes the return value of the previous function. It is the equivalent of + * [compose]{@link module:ControlFlow.compose} with the arguments reversed. + * + * Each function is executed with the `this` binding of the composed function. + * + * @name seq + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.compose]{@link module:ControlFlow.compose} + * @category Control Flow + * @param {...AsyncFunction} functions - the asynchronous functions to compose + * @returns {Function} a function that composes the `functions` in order + * @example + * + * // Requires lodash (or underscore), express3 and dresende's orm2. + * // Part of an app, that fetches cats of the logged user. + * // This example uses `seq` function to avoid overnesting and error + * // handling clutter. + * app.get('/cats', function(request, response) { + * var User = request.models.User; + * async.seq( + * User.get.bind(User), // 'User.get' has signature (id, callback(err, data)) + * function(user, fn) { + * user.getCats(fn); // 'getCats' has signature (callback(err, data)) + * } + * )(req.session.user_id, function (err, cats) { + * if (err) { + * console.error(err); + * response.json({ status: 'error', message: err.message }); + * } else { + * response.json({ status: 'ok', message: 'Cats found', data: cats }); + * } + * }); + * }); + */ +function seq(...functions) { + var _functions = functions.map(_wrapAsync2.default); + return function (...args) { + var that = this; + + var cb = args[args.length - 1]; + if (typeof cb == 'function') { + args.pop(); + } else { + cb = (0, _promiseCallback.promiseCallback)(); + } + + (0, _reduce2.default)(_functions, args, (newargs, fn, iterCb) => { + fn.apply(that, newargs.concat((err, ...nextargs) => { + iterCb(err, nextargs); + })); + }, (err, results) => cb(err, ...results)); + + return cb[_promiseCallback.PROMISE_SYMBOL]; + }; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/series.js b/Challenge/seokahi/010.star/node_modules/async/series.js new file mode 100644 index 0000000..56e78f9 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/series.js @@ -0,0 +1,186 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = series; + +var _parallel2 = require('./internal/parallel.js'); + +var _parallel3 = _interopRequireDefault(_parallel2); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Run the functions in the `tasks` collection in series, each one running once + * the previous function has completed. If any functions in the series pass an + * error to its callback, no more functions are run, and `callback` is + * immediately called with the value of the error. Otherwise, `callback` + * receives an array of results when `tasks` have completed. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function, and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.series}. + * + * **Note** that while many implementations preserve the order of object + * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) + * explicitly states that + * + * > The mechanics and order of enumerating the properties is not specified. + * + * So if you rely on the order in which your series of functions are executed, + * and want this to work on all platforms, consider using an array. + * + * @name series + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing + * [async functions]{@link AsyncFunction} to run in series. + * Each function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This function gets a results array (or object) + * containing all the result arguments passed to the `task` callbacks. Invoked + * with (err, result). + * @return {Promise} a promise, if no callback is passed + * @example + * + * //Using Callbacks + * async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ], function(err, results) { + * console.log(results); + * // results is equal to ['one','two'] + * }); + * + * // an example using objects instead of arrays + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }); + * + * //Using Promises + * async.series([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]).then(results => { + * console.log(results); + * // results is equal to ['one','two'] + * }).catch(err => { + * console.log(err); + * }); + * + * // an example using an object instead of an array + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }).then(results => { + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * }).catch(err => { + * console.log(err); + * }); + * + * //Using async/await + * async () => { + * try { + * let results = await async.series([ + * function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 'two'); + * }, 100); + * } + * ]); + * console.log(results); + * // results is equal to ['one','two'] + * } + * catch (err) { + * console.log(err); + * } + * } + * + * // an example using an object instead of an array + * async () => { + * try { + * let results = await async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * // do some async task + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * // then do another async task + * callback(null, 2); + * }, 100); + * } + * }); + * console.log(results); + * // results is equal to: { one: 1, two: 2 } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function series(tasks, callback) { + return (0, _parallel3.default)(_eachOfSeries2.default, tasks, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/setImmediate.js b/Challenge/seokahi/010.star/node_modules/async/setImmediate.js new file mode 100644 index 0000000..c712ec3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/setImmediate.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _setImmediate = require('./internal/setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Calls `callback` on a later loop around the event loop. In Node.js this just + * calls `setImmediate`. In the browser it will use `setImmediate` if + * available, otherwise `setTimeout(callback, 0)`, which means other higher + * priority events may precede the execution of `callback`. + * + * This is used internally for browser-compatibility purposes. + * + * @name setImmediate + * @static + * @memberOf module:Utils + * @method + * @see [async.nextTick]{@link module:Utils.nextTick} + * @category Util + * @param {Function} callback - The function to call on a later loop around + * the event loop. Invoked with (args...). + * @param {...*} args... - any number of additional arguments to pass to the + * callback on the next tick. + * @example + * + * var call_order = []; + * async.nextTick(function() { + * call_order.push('two'); + * // call_order now equals ['one','two'] + * }); + * call_order.push('one'); + * + * async.setImmediate(function (a, b, c) { + * // a, b, and c equal 1, 2, and 3 + * }, 1, 2, 3); + */ +exports.default = _setImmediate2.default; +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/some.js b/Challenge/seokahi/010.star/node_modules/async/some.js new file mode 100644 index 0000000..2046cf6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/some.js @@ -0,0 +1,122 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns `true` if at least one element in the `coll` satisfies an async test. + * If any iteratee call returns `true`, the main `callback` is immediately + * called. + * + * @name some + * @static + * @memberOf module:Collections + * @method + * @alias any + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // dir1 is a directory that contains file1.txt, file2.txt + * // dir2 is a directory that contains file3.txt, file4.txt + * // dir3 is a directory that contains file5.txt + * // dir4 does not exist + * + * // asynchronous function that checks if a file exists + * function fileExists(file, callback) { + * fs.access(file, fs.constants.F_OK, (err) => { + * callback(null, !err); + * }); + * } + * + * // Using callbacks + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + *); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists, + * function(err, result) { + * console.log(result); + * // false + * // result is false since none of the files exists + * } + *); + * + * // Using Promises + * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists) + * .then( result => { + * console.log(result); + * // true + * // result is true since some file in the list exists + * }).catch( err => { + * console.log(err); + * }); + * + * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists) + * .then( result => { + * console.log(result); + * // false + * // result is false since none of the files exists + * }).catch( err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists); + * console.log(result); + * // true + * // result is true since some file in the list exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + * async () => { + * try { + * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists); + * console.log(result); + * // false + * // result is false since none of the files exists + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function some(coll, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)(_eachOf2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(some, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/someLimit.js b/Challenge/seokahi/010.star/node_modules/async/someLimit.js new file mode 100644 index 0000000..c8a295a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/someLimit.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfLimit = require('./internal/eachOfLimit.js'); + +var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. + * + * @name someLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anyLimit + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someLimit(coll, limit, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(someLimit, 4); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/someSeries.js b/Challenge/seokahi/010.star/node_modules/async/someSeries.js new file mode 100644 index 0000000..ee0654b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/someSeries.js @@ -0,0 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createTester = require('./internal/createTester.js'); + +var _createTester2 = _interopRequireDefault(_createTester); + +var _eachOfSeries = require('./eachOfSeries.js'); + +var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. + * + * @name someSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anySeries + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in series. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + */ +function someSeries(coll, iteratee, callback) { + return (0, _createTester2.default)(Boolean, res => res)(_eachOfSeries2.default, coll, iteratee, callback); +} +exports.default = (0, _awaitify2.default)(someSeries, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/sortBy.js b/Challenge/seokahi/010.star/node_modules/async/sortBy.js new file mode 100644 index 0000000..d17fb6a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/sortBy.js @@ -0,0 +1,190 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _map = require('./map.js'); + +var _map2 = _interopRequireDefault(_map); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Sorts a list by the results of running each `coll` value through an async + * `iteratee`. + * + * @name sortBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a value to use as the sort criteria as + * its `result`. + * Invoked with (item, callback). + * @param {Function} callback - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is the items + * from the original `coll` sorted by the values returned by the `iteratee` + * calls. Invoked with (err, results). + * @returns {Promise} a promise, if no callback passed + * @example + * + * // bigfile.txt is a file that is 251100 bytes in size + * // mediumfile.txt is a file that is 11000 bytes in size + * // smallfile.txt is a file that is 121 bytes in size + * + * // asynchronous function that returns the file size in bytes + * function getFileSizeInBytes(file, callback) { + * fs.stat(file, function(err, stat) { + * if (err) { + * return callback(err); + * } + * callback(null, stat.size); + * }); + * } + * + * // Using callbacks + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // By modifying the callback parameter the + * // sorting order can be influenced: + * + * // ascending order + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) return callback(getFileSizeErr); + * callback(null, fileSize); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * } + * ); + * + * // descending order + * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) { + * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) { + * if (getFileSizeErr) { + * return callback(getFileSizeErr); + * } + * callback(null, fileSize * -1); + * }); + * }, function(err, results) { + * if (err) { + * console.log(err); + * } else { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt'] + * } + * } + * ); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes, + * function(err, results) { + * if (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } else { + * console.log(results); + * } + * } + * ); + * + * // Using Promises + * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * }).catch( err => { + * console.log(err); + * }); + * + * // Error handling + * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes) + * .then( results => { + * console.log(results); + * }).catch( err => { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * }); + * + * // Using async/await + * (async () => { + * try { + * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * // results is now the original array of files sorted by + * // file size (ascending by default), e.g. + * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt'] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * // Error handling + * async () => { + * try { + * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes); + * console.log(results); + * } + * catch (err) { + * console.log(err); + * // [ Error: ENOENT: no such file or directory ] + * } + * } + * + */ +function sortBy(coll, iteratee, callback) { + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _map2.default)(coll, (x, iterCb) => { + _iteratee(x, (err, criteria) => { + if (err) return iterCb(err); + iterCb(err, { value: x, criteria }); + }); + }, (err, results) => { + if (err) return callback(err); + callback(null, results.sort(comparator).map(v => v.value)); + }); + + function comparator(left, right) { + var a = left.criteria, + b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } +} +exports.default = (0, _awaitify2.default)(sortBy, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/timeout.js b/Challenge/seokahi/010.star/node_modules/async/timeout.js new file mode 100644 index 0000000..dd58eb3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/timeout.js @@ -0,0 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = timeout; + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Sets a time limit on an asynchronous function. If the function does not call + * its callback within the specified milliseconds, it will be called with a + * timeout error. The code property for the error object will be `'ETIMEDOUT'`. + * + * @name timeout + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} asyncFn - The async function to limit in time. + * @param {number} milliseconds - The specified time limit. + * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) + * to timeout Error for more information.. + * @returns {AsyncFunction} Returns a wrapped function that can be used with any + * of the control flow functions. + * Invoke this function with the same parameters as you would `asyncFunc`. + * @example + * + * function myFunction(foo, callback) { + * doAsyncTask(foo, function(err, data) { + * // handle errors + * if (err) return callback(err); + * + * // do some stuff ... + * + * // return processed data + * return callback(null, data); + * }); + * } + * + * var wrapped = async.timeout(myFunction, 1000); + * + * // call `wrapped` as you would `myFunction` + * wrapped({ bar: 'bar' }, function(err, data) { + * // if `myFunction` takes < 1000 ms to execute, `err` + * // and `data` will have their expected values + * + * // else `err` will be an Error with the code 'ETIMEDOUT' + * }); + */ +function timeout(asyncFn, milliseconds, info) { + var fn = (0, _wrapAsync2.default)(asyncFn); + + return (0, _initialParams2.default)((args, callback) => { + var timedOut = false; + var timer; + + function timeoutCallback() { + var name = asyncFn.name || 'anonymous'; + var error = new Error('Callback function "' + name + '" timed out.'); + error.code = 'ETIMEDOUT'; + if (info) { + error.info = info; + } + timedOut = true; + callback(error); + } + + args.push((...cbArgs) => { + if (!timedOut) { + callback(...cbArgs); + clearTimeout(timer); + } + }); + + // setup timer and call original function + timer = setTimeout(timeoutCallback, milliseconds); + fn(...args); + }); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/times.js b/Challenge/seokahi/010.star/node_modules/async/times.js new file mode 100644 index 0000000..4484c73 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/times.js @@ -0,0 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = times; + +var _timesLimit = require('./timesLimit.js'); + +var _timesLimit2 = _interopRequireDefault(_timesLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Calls the `iteratee` function `n` times, and accumulates results in the same + * manner you would use with [map]{@link module:Collections.map}. + * + * @name times + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.map]{@link module:Collections.map} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + * @example + * + * // Pretend this is some complicated async factory + * var createUser = function(id, callback) { + * callback(null, { + * id: 'user' + id + * }); + * }; + * + * // generate 5 users + * async.times(5, function(n, next) { + * createUser(n, function(err, user) { + * next(err, user); + * }); + * }, function(err, users) { + * // we should now have 5 users + * }); + */ +function times(n, iteratee, callback) { + return (0, _timesLimit2.default)(n, Infinity, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/timesLimit.js b/Challenge/seokahi/010.star/node_modules/async/timesLimit.js new file mode 100644 index 0000000..9fb0ba3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/timesLimit.js @@ -0,0 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = timesLimit; + +var _mapLimit = require('./mapLimit.js'); + +var _mapLimit2 = _interopRequireDefault(_mapLimit); + +var _range = require('./internal/range.js'); + +var _range2 = _interopRequireDefault(_range); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a + * time. + * + * @name timesLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} count - The number of times to run the function. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see [async.map]{@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ +function timesLimit(count, limit, iteratee, callback) { + var _iteratee = (0, _wrapAsync2.default)(iteratee); + return (0, _mapLimit2.default)((0, _range2.default)(count), limit, _iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/timesSeries.js b/Challenge/seokahi/010.star/node_modules/async/timesSeries.js new file mode 100644 index 0000000..a10f0cb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/timesSeries.js @@ -0,0 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = timesSeries; + +var _timesLimit = require('./timesLimit.js'); + +var _timesLimit2 = _interopRequireDefault(_timesLimit); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. + * + * @name timesSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @returns {Promise} a promise, if no callback is provided + */ +function timesSeries(n, iteratee, callback) { + return (0, _timesLimit2.default)(n, 1, iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/transform.js b/Challenge/seokahi/010.star/node_modules/async/transform.js new file mode 100644 index 0000000..75b754e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/transform.js @@ -0,0 +1,173 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = transform; + +var _eachOf = require('./eachOf.js'); + +var _eachOf2 = _interopRequireDefault(_eachOf); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _promiseCallback = require('./internal/promiseCallback.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * A relative of `reduce`. Takes an Object or Array, and iterates over each + * element in parallel, each step potentially mutating an `accumulator` value. + * The type of the accumulator defaults to the type of collection passed in. + * + * @name transform + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. + * @param {*} [accumulator] - The initial state of the transform. If omitted, + * it will default to an empty Object or Array, depending on the type of `coll` + * @param {AsyncFunction} iteratee - A function applied to each item in the + * collection that potentially modifies the accumulator. + * Invoked with (accumulator, item, key, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the transformed accumulator. + * Invoked with (err, result). + * @returns {Promise} a promise, if no callback provided + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileList = ['file1.txt','file2.txt','file3.txt']; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileList, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * }); + * + * // Using Promises + * async.transform(fileList, transformFileSize) + * .then(result => { + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * (async () => { + * try { + * let result = await async.transform(fileList, transformFileSize); + * console.log(result); + * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ] + * } + * catch (err) { + * console.log(err); + * } + * })(); + * + * @example + * + * // file1.txt is a file that is 1000 bytes in size + * // file2.txt is a file that is 2000 bytes in size + * // file3.txt is a file that is 3000 bytes in size + * + * // helper function that returns human-readable size format from bytes + * function formatBytes(bytes, decimals = 2) { + * // implementation not included for brevity + * return humanReadbleFilesize; + * } + * + * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' }; + * + * // asynchronous function that returns the file size, transformed to human-readable format + * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc. + * function transformFileSize(acc, value, key, callback) { + * fs.stat(value, function(err, stat) { + * if (err) { + * return callback(err); + * } + * acc[key] = formatBytes(stat.size); + * callback(null); + * }); + * } + * + * // Using callbacks + * async.transform(fileMap, transformFileSize, function(err, result) { + * if(err) { + * console.log(err); + * } else { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * }); + * + * // Using Promises + * async.transform(fileMap, transformFileSize) + * .then(result => { + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * }).catch(err => { + * console.log(err); + * }); + * + * // Using async/await + * async () => { + * try { + * let result = await async.transform(fileMap, transformFileSize); + * console.log(result); + * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' } + * } + * catch (err) { + * console.log(err); + * } + * } + * + */ +function transform(coll, accumulator, iteratee, callback) { + if (arguments.length <= 3 && typeof accumulator === 'function') { + callback = iteratee; + iteratee = accumulator; + accumulator = Array.isArray(coll) ? [] : {}; + } + callback = (0, _once2.default)(callback || (0, _promiseCallback.promiseCallback)()); + var _iteratee = (0, _wrapAsync2.default)(iteratee); + + (0, _eachOf2.default)(coll, (v, k, cb) => { + _iteratee(accumulator, v, k, cb); + }, err => callback(err, accumulator)); + return callback[_promiseCallback.PROMISE_SYMBOL]; +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/tryEach.js b/Challenge/seokahi/010.star/node_modules/async/tryEach.js new file mode 100644 index 0000000..82fe8ec --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/tryEach.js @@ -0,0 +1,78 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _eachSeries = require('./eachSeries.js'); + +var _eachSeries2 = _interopRequireDefault(_eachSeries); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * It runs each task in series but stops whenever any of the functions were + * successful. If one of the tasks were successful, the `callback` will be + * passed the result of the successful task. If all tasks fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name tryEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to + * run, each function is passed a `callback(err, result)` it must call on + * completion with an error `err` (which can be `null`) and an optional `result` + * value. + * @param {Function} [callback] - An optional callback which is called when one + * of the tasks has succeeded, or all have failed. It receives the `err` and + * `result` arguments of the last attempt at completing the `task`. Invoked with + * (err, results). + * @returns {Promise} a promise, if no callback is passed + * @example + * async.tryEach([ + * function getDataFromFirstWebsite(callback) { + * // Try getting the data from the first website + * callback(err, data); + * }, + * function getDataFromSecondWebsite(callback) { + * // First website failed, + * // Try getting the data from the backup website + * callback(err, data); + * } + * ], + * // optional callback + * function(err, results) { + * Now do something with the data. + * }); + * + */ +function tryEach(tasks, callback) { + var error = null; + var result; + return (0, _eachSeries2.default)(tasks, (task, taskCb) => { + (0, _wrapAsync2.default)(task)((err, ...args) => { + if (err === false) return taskCb(err); + + if (args.length < 2) { + [result] = args; + } else { + result = args; + } + error = err; + taskCb(err ? null : {}); + }); + }, () => callback(error, result)); +} + +exports.default = (0, _awaitify2.default)(tryEach); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/unmemoize.js b/Challenge/seokahi/010.star/node_modules/async/unmemoize.js new file mode 100644 index 0000000..47a92b4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/unmemoize.js @@ -0,0 +1,25 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = unmemoize; +/** + * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, + * unmemoized form. Handy for testing. + * + * @name unmemoize + * @static + * @memberOf module:Utils + * @method + * @see [async.memoize]{@link module:Utils.memoize} + * @category Util + * @param {AsyncFunction} fn - the memoized function + * @returns {AsyncFunction} a function that calls the original unmemoized function + */ +function unmemoize(fn) { + return (...args) => { + return (fn.unmemoized || fn)(...args); + }; +} +module.exports = exports["default"]; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/until.js b/Challenge/seokahi/010.star/node_modules/async/until.js new file mode 100644 index 0000000..3c71e51 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/until.js @@ -0,0 +1,61 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = until; + +var _whilst = require('./whilst.js'); + +var _whilst2 = _interopRequireDefault(_whilst); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. `callback` will be passed an error and any + * arguments passed to the final `iteratee`'s callback. + * + * The inverse of [whilst]{@link module:ControlFlow.whilst}. + * + * @name until + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (callback). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if a callback is not passed + * + * @example + * const results = [] + * let finished = false + * async.until(function test(cb) { + * cb(null, finished) + * }, function iter(next) { + * fetchPage(url, (err, body) => { + * if (err) return next(err) + * results = results.concat(body.objects) + * finished = !!body.next + * next(err) + * }) + * }, function done (err) { + * // all pages have been fetched + * }) + */ +function until(test, iteratee, callback) { + const _test = (0, _wrapAsync2.default)(test); + return (0, _whilst2.default)(cb => _test((err, truth) => cb(err, !truth)), iteratee, callback); +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/waterfall.js b/Challenge/seokahi/010.star/node_modules/async/waterfall.js new file mode 100644 index 0000000..8d88829 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/waterfall.js @@ -0,0 +1,105 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _once = require('./internal/once.js'); + +var _once2 = _interopRequireDefault(_once); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Runs the `tasks` array of functions in series, each passing their results to + * the next in the array. However, if any of the `tasks` pass an error to their + * own callback, the next function is not executed, and the main `callback` is + * immediately called with the error. + * + * @name waterfall + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} + * to run. + * Each function should complete with any number of `result` values. + * The `result` values will be passed as arguments, in order, to the next task. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This will be passed the results of the last task's + * callback. Invoked with (err, [results]). + * @returns undefined + * @example + * + * async.waterfall([ + * function(callback) { + * callback(null, 'one', 'two'); + * }, + * function(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * }, + * function(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + * ], function (err, result) { + * // result now equals 'done' + * }); + * + * // Or, with named functions: + * async.waterfall([ + * myFirstFunction, + * mySecondFunction, + * myLastFunction, + * ], function (err, result) { + * // result now equals 'done' + * }); + * function myFirstFunction(callback) { + * callback(null, 'one', 'two'); + * } + * function mySecondFunction(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * } + * function myLastFunction(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + */ +function waterfall(tasks, callback) { + callback = (0, _once2.default)(callback); + if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); + if (!tasks.length) return callback(); + var taskIndex = 0; + + function nextTask(args) { + var task = (0, _wrapAsync2.default)(tasks[taskIndex++]); + task(...args, (0, _onlyOnce2.default)(next)); + } + + function next(err, ...args) { + if (err === false) return; + if (err || taskIndex === tasks.length) { + return callback(err, ...args); + } + nextTask(args); + } + + nextTask([]); +} + +exports.default = (0, _awaitify2.default)(waterfall); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/whilst.js b/Challenge/seokahi/010.star/node_modules/async/whilst.js new file mode 100644 index 0000000..32a4776 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/whilst.js @@ -0,0 +1,78 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _onlyOnce = require('./internal/onlyOnce.js'); + +var _onlyOnce2 = _interopRequireDefault(_onlyOnce); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +var _wrapAsync2 = _interopRequireDefault(_wrapAsync); + +var _awaitify = require('./internal/awaitify.js'); + +var _awaitify2 = _interopRequireDefault(_awaitify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. + * + * @name whilst + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns {Promise} a promise, if no callback is passed + * @example + * + * var count = 0; + * async.whilst( + * function test(cb) { cb(null, count < 5); }, + * function iter(callback) { + * count++; + * setTimeout(function() { + * callback(null, count); + * }, 1000); + * }, + * function (err, n) { + * // 5 seconds have passed, n = 5 + * } + * ); + */ +function whilst(test, iteratee, callback) { + callback = (0, _onlyOnce2.default)(callback); + var _fn = (0, _wrapAsync2.default)(iteratee); + var _test = (0, _wrapAsync2.default)(test); + var results = []; + + function next(err, ...rest) { + if (err) return callback(err); + results = rest; + if (err === false) return; + _test(check); + } + + function check(err, truth) { + if (err) return callback(err); + if (err === false) return; + if (!truth) return callback(null, ...results); + _fn(next); + } + + return _test(check); +} +exports.default = (0, _awaitify2.default)(whilst, 3); +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/async/wrapSync.js b/Challenge/seokahi/010.star/node_modules/async/wrapSync.js new file mode 100644 index 0000000..3c3bf88 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/async/wrapSync.js @@ -0,0 +1,118 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = asyncify; + +var _initialParams = require('./internal/initialParams.js'); + +var _initialParams2 = _interopRequireDefault(_initialParams); + +var _setImmediate = require('./internal/setImmediate.js'); + +var _setImmediate2 = _interopRequireDefault(_setImmediate); + +var _wrapAsync = require('./internal/wrapAsync.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Take a sync function and make it async, passing its return value to a + * callback. This is useful for plugging sync functions into a waterfall, + * series, or other async functions. Any arguments passed to the generated + * function will be passed to the wrapped function (except for the final + * callback argument). Errors thrown will be passed to the callback. + * + * If the function passed to `asyncify` returns a Promise, that promises's + * resolved/rejected state will be used to call the callback, rather than simply + * the synchronous return value. + * + * This also means you can asyncify ES2017 `async` functions. + * + * @name asyncify + * @static + * @memberOf module:Utils + * @method + * @alias wrapSync + * @category Util + * @param {Function} func - The synchronous function, or Promise-returning + * function to convert to an {@link AsyncFunction}. + * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be + * invoked with `(args..., callback)`. + * @example + * + * // passing a regular synchronous function + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(JSON.parse), + * function (data, next) { + * // data is the result of parsing the text. + * // If there was a parsing error, it would have been caught. + * } + * ], callback); + * + * // passing a function returning a promise + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(function (contents) { + * return db.model.create(contents); + * }), + * function (model, next) { + * // `model` is the instantiated model object. + * // If there was an error, this function would be skipped. + * } + * ], callback); + * + * // es2017 example, though `asyncify` is not needed if your JS environment + * // supports async functions out of the box + * var q = async.queue(async.asyncify(async function(file) { + * var intermediateStep = await processFile(file); + * return await somePromise(intermediateStep) + * })); + * + * q.push(files); + */ +function asyncify(func) { + if ((0, _wrapAsync.isAsync)(func)) { + return function (...args /*, callback*/) { + const callback = args.pop(); + const promise = func.apply(this, args); + return handlePromise(promise, callback); + }; + } + + return (0, _initialParams2.default)(function (args, callback) { + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (result && typeof result.then === 'function') { + return handlePromise(result, callback); + } else { + callback(null, result); + } + }); +} + +function handlePromise(promise, callback) { + return promise.then(value => { + invokeCallback(callback, null, value); + }, err => { + invokeCallback(callback, err && err.message ? err : new Error(err)); + }); +} + +function invokeCallback(callback, error, value) { + try { + callback(error, value); + } catch (err) { + (0, _setImmediate2.default)(e => { + throw e; + }, err); + } +} +module.exports = exports['default']; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/.travis.yml b/Challenge/seokahi/010.star/node_modules/colors/.travis.yml new file mode 100644 index 0000000..ec43125 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.11" + - "0.10" + - "0.8" + - "0.6" \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/MIT-LICENSE.txt b/Challenge/seokahi/010.star/node_modules/colors/MIT-LICENSE.txt new file mode 100644 index 0000000..3de4e33 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/MIT-LICENSE.txt @@ -0,0 +1,23 @@ +Original Library + - Copyright (c) Marak Squires + +Additional Functionality + - Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/ReadMe.md b/Challenge/seokahi/010.star/node_modules/colors/ReadMe.md new file mode 100644 index 0000000..beb5b14 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/ReadMe.md @@ -0,0 +1,167 @@ +# colors.js + +## get color and style in your node.js console + + + +## Installation + + npm install colors + +## colors and styles! + +### text colors + + - black + - red + - green + - yellow + - blue + - magenta + - cyan + - white + - gray + - grey + +### background colors + + + + - bgBlack + - bgRed + - bgGreen + - bgYellow + - bgBlue + - bgMagenta + - bgCyan + - bgWhite + +### styles + + - reset + - bold + - dim + - italic + - underline + - inverse + - hidden + - strikethrough + +### extras + + - rainbow + - zebra + - america + - trap + - random + + +## Usage + +By popular demand, `colors` now ships with two types of usages! + +The super nifty way + +```js +var colors = require('colors'); + +console.log('hello'.green); // outputs green text +console.log('i like cake and pies'.underline.red) // outputs red underlined text +console.log('inverse the color'.inverse); // inverses the color +console.log('OMG Rainbows!'.rainbow); // rainbow +console.log('Run the trap'.trap); // Drops the bass + +``` + +or a slightly less nifty way which doesn't extend `String.prototype` + +```js +var colors = require('colors/safe'); + +console.log(colors.green('hello')); // outputs green text +console.log(colors.red.underline('i like cake and pies')) // outputs red underlined text +console.log(colors.inverse('inverse the color')); // inverses the color +console.log(colors.rainbow('OMG Rainbows!')); // rainbow +console.log(colors.trap('Run the trap')); // Drops the bass + +``` + +I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. + +If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object. + +## Disabling Colors + +To disable colors you can pass the following arguments in the command line to your application: + +```bash +node myapp.js --no-color +``` + +## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data) + +```js +var name = 'Marak'; +console.log(colors.green('Hello %s'), name); +// outputs -> 'Hello Marak' +``` + +## Custom themes + +### Using standard API + +```js + +var colors = require('colors'); + +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); +``` + +### Using string safe API + +```js +var colors = require('colors/safe'); + +// set single property +var error = colors.red; +error('this is red'); + +// set theme +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log(colors.error("this is an error")); + +// outputs yellow text +console.log(colors.warn("this is a warning")); +``` + +*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.* \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/examples/normal-usage.js b/Challenge/seokahi/010.star/node_modules/colors/examples/normal-usage.js new file mode 100644 index 0000000..2818741 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/examples/normal-usage.js @@ -0,0 +1,74 @@ +var colors = require('../lib/index'); + +console.log("First some yellow text".yellow); + +console.log("Underline that text".yellow.underline); + +console.log("Make it bold and red".red.bold); + +console.log(("Double Raindows All Day Long").rainbow) + +console.log("Drop the bass".trap) + +console.log("DROP THE RAINBOW BASS".trap.rainbow) + + +console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported + +console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse + ' styles! '.yellow.bold); // styles not widely supported +console.log("Zebras are so fun!".zebra); + +// +// Remark: .strikethrough may not work with Mac OS Terminal App +// +console.log("This is " + "not".strikethrough + " fun."); + +console.log('Background color attack!'.black.bgWhite) +console.log('Use random styles on everything!'.random) +console.log('America, Heck Yeah!'.america) + + +console.log('Setting themes is useful') + +// +// Custom themes +// +console.log('Generic logging theme as JSON'.green.bold.underline); +// Load theme with JSON literal +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); + +// outputs grey text +console.log("this is an input".input); + +console.log('Generic logging theme as file'.green.bold.underline); + +// Load a theme from file +colors.setTheme(__dirname + '/../themes/generic-logging.js'); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); + +// outputs grey text +console.log("this is an input".input); + +//console.log("Don't summon".zalgo) \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/examples/safe-string.js b/Challenge/seokahi/010.star/node_modules/colors/examples/safe-string.js new file mode 100644 index 0000000..111b363 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/examples/safe-string.js @@ -0,0 +1,76 @@ +var colors = require('../safe'); + +console.log(colors.yellow("First some yellow text")); + +console.log(colors.yellow.underline("Underline that text")); + +console.log(colors.red.bold("Make it bold and red")); + +console.log(colors.rainbow("Double Raindows All Day Long")) + +console.log(colors.trap("Drop the bass")) + +console.log(colors.rainbow(colors.trap("DROP THE RAINBOW BASS"))); + +console.log(colors.bold.italic.underline.red('Chains are also cool.')); // styles not widely supported + + +console.log(colors.green('So ') + colors.underline('are') + ' ' + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); // styles not widely supported + +console.log(colors.zebra("Zebras are so fun!")); + +console.log("This is " + colors.strikethrough("not") + " fun."); + + +console.log(colors.black.bgWhite('Background color attack!')); +console.log(colors.random('Use random styles on everything!')) +console.log(colors.america('America, Heck Yeah!')); + +console.log('Setting themes is useful') + +// +// Custom themes +// +//console.log('Generic logging theme as JSON'.green.bold.underline); +// Load theme with JSON literal +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log(colors.error("this is an error")); + +// outputs yellow text +console.log(colors.warn("this is a warning")); + +// outputs grey text +console.log(colors.input("this is an input")); + + +// console.log('Generic logging theme as file'.green.bold.underline); + +// Load a theme from file +colors.setTheme(__dirname + '/../themes/generic-logging.js'); + +// outputs red text +console.log(colors.error("this is an error")); + +// outputs yellow text +console.log(colors.warn("this is a warning")); + +// outputs grey text +console.log(colors.input("this is an input")); + +// console.log(colors.zalgo("Don't summon him")) + + + diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/colors.js b/Challenge/seokahi/010.star/node_modules/colors/lib/colors.js new file mode 100644 index 0000000..59898de --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/colors.js @@ -0,0 +1,176 @@ +/* + +The MIT License (MIT) + +Original Library + - Copyright (c) Marak Squires + +Additional functionality + - Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +var colors = {}; +module['exports'] = colors; + +colors.themes = {}; + +var ansiStyles = colors.styles = require('./styles'); +var defineProps = Object.defineProperties; + +colors.supportsColor = require('./system/supports-colors'); + +if (typeof colors.enabled === "undefined") { + colors.enabled = colors.supportsColor; +} + +colors.stripColors = colors.strip = function(str){ + return ("" + str).replace(/\x1B\[\d+m/g, ''); +}; + + +var stylize = colors.stylize = function stylize (str, style) { + return ansiStyles[style].open + str + ansiStyles[style].close; +} + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; +var escapeStringRegexp = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + return str.replace(matchOperatorsRe, '\\$&'); +} + +function build(_styles) { + var builder = function builder() { + return applyStyle.apply(builder, arguments); + }; + builder._styles = _styles; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + builder.__proto__ = proto; + return builder; +} + +var styles = (function () { + var ret = {}; + ansiStyles.grey = ansiStyles.gray; + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + ret[key] = { + get: function () { + return build(this._styles.concat(key)); + } + }; + }); + return ret; +})(); + +var proto = defineProps(function colors() {}, styles); + +function applyStyle() { + var args = arguments; + var argsLen = args.length; + var str = argsLen !== 0 && String(arguments[0]); + if (argsLen > 1) { + for (var a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!colors.enabled || !str) { + return str; + } + + var nestedStyles = this._styles; + + var i = nestedStyles.length; + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + str = code.open + str.replace(code.closeRe, code.open) + code.close; + } + + return str; +} + +function applyTheme (theme) { + for (var style in theme) { + (function(style){ + colors[style] = function(str){ + return colors[theme[style]](str); + }; + })(style) + } +} + +colors.setTheme = function (theme) { + if (typeof theme === 'string') { + try { + colors.themes[theme] = require(theme); + applyTheme(colors.themes[theme]); + return colors.themes[theme]; + } catch (err) { + console.log(err); + return err; + } + } else { + applyTheme(theme); + } +}; + +function init() { + var ret = {}; + Object.keys(styles).forEach(function (name) { + ret[name] = { + get: function () { + return build([name]); + } + }; + }); + return ret; +} + +var sequencer = function sequencer (map, str) { + var exploded = str.split(""), i = 0; + exploded = exploded.map(map); + return exploded.join(""); +}; + +// custom formatter methods +colors.trap = require('./custom/trap'); +colors.zalgo = require('./custom/zalgo'); + +// maps +colors.maps = {}; +colors.maps.america = require('./maps/america'); +colors.maps.zebra = require('./maps/zebra'); +colors.maps.rainbow = require('./maps/rainbow'); +colors.maps.random = require('./maps/random') + +for (var map in colors.maps) { + (function(map){ + colors[map] = function (str) { + return sequencer(colors.maps[map], str); + } + })(map) +} + +defineProps(colors, init()); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/custom/trap.js b/Challenge/seokahi/010.star/node_modules/colors/lib/custom/trap.js new file mode 100644 index 0000000..3f09143 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/custom/trap.js @@ -0,0 +1,45 @@ +module['exports'] = function runTheTrap (text, options) { + var result = ""; + text = text || "Run the trap, drop the bass"; + text = text.split(''); + var trap = { + a: ["\u0040", "\u0104", "\u023a", "\u0245", "\u0394", "\u039b", "\u0414"], + b: ["\u00df", "\u0181", "\u0243", "\u026e", "\u03b2", "\u0e3f"], + c: ["\u00a9", "\u023b", "\u03fe"], + d: ["\u00d0", "\u018a", "\u0500" , "\u0501" ,"\u0502", "\u0503"], + e: ["\u00cb", "\u0115", "\u018e", "\u0258", "\u03a3", "\u03be", "\u04bc", "\u0a6c"], + f: ["\u04fa"], + g: ["\u0262"], + h: ["\u0126", "\u0195", "\u04a2", "\u04ba", "\u04c7", "\u050a"], + i: ["\u0f0f"], + j: ["\u0134"], + k: ["\u0138", "\u04a0", "\u04c3", "\u051e"], + l: ["\u0139"], + m: ["\u028d", "\u04cd", "\u04ce", "\u0520", "\u0521", "\u0d69"], + n: ["\u00d1", "\u014b", "\u019d", "\u0376", "\u03a0", "\u048a"], + o: ["\u00d8", "\u00f5", "\u00f8", "\u01fe", "\u0298", "\u047a", "\u05dd", "\u06dd", "\u0e4f"], + p: ["\u01f7", "\u048e"], + q: ["\u09cd"], + r: ["\u00ae", "\u01a6", "\u0210", "\u024c", "\u0280", "\u042f"], + s: ["\u00a7", "\u03de", "\u03df", "\u03e8"], + t: ["\u0141", "\u0166", "\u0373"], + u: ["\u01b1", "\u054d"], + v: ["\u05d8"], + w: ["\u0428", "\u0460", "\u047c", "\u0d70"], + x: ["\u04b2", "\u04fe", "\u04fc", "\u04fd"], + y: ["\u00a5", "\u04b0", "\u04cb"], + z: ["\u01b5", "\u0240"] + } + text.forEach(function(c){ + c = c.toLowerCase(); + var chars = trap[c] || [" "]; + var rand = Math.floor(Math.random() * chars.length); + if (typeof trap[c] !== "undefined") { + result += trap[c][rand]; + } else { + result += c; + } + }); + return result; + +} diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/custom/zalgo.js b/Challenge/seokahi/010.star/node_modules/colors/lib/custom/zalgo.js new file mode 100644 index 0000000..4dc20c8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/custom/zalgo.js @@ -0,0 +1,104 @@ +// please no +module['exports'] = function zalgo(text, options) { + text = text || " he is here "; + var soul = { + "up" : [ + '̍', '̎', '̄', '̅', + '̿', '̑', '̆', '̐', + '͒', '͗', '͑', '̇', + '̈', '̊', '͂', '̓', + '̈', '͊', '͋', '͌', + '̃', '̂', '̌', '͐', + '̀', '́', '̋', '̏', + '̒', '̓', '̔', '̽', + '̉', 'ͣ', 'ͤ', 'ͥ', + 'ͦ', 'ͧ', 'ͨ', 'ͩ', + 'ͪ', 'ͫ', 'ͬ', 'ͭ', + 'ͮ', 'ͯ', '̾', '͛', + '͆', '̚' + ], + "down" : [ + '̖', '̗', '̘', '̙', + '̜', '̝', '̞', '̟', + '̠', '̤', '̥', '̦', + '̩', '̪', '̫', '̬', + '̭', '̮', '̯', '̰', + '̱', '̲', '̳', '̹', + '̺', '̻', '̼', 'ͅ', + '͇', '͈', '͉', '͍', + '͎', '͓', '͔', '͕', + '͖', '͙', '͚', '̣' + ], + "mid" : [ + '̕', '̛', '̀', '́', + '͘', '̡', '̢', '̧', + '̨', '̴', '̵', '̶', + '͜', '͝', '͞', + '͟', '͠', '͢', '̸', + '̷', '͡', ' ҉' + ] + }, + all = [].concat(soul.up, soul.down, soul.mid), + zalgo = {}; + + function randomNumber(range) { + var r = Math.floor(Math.random() * range); + return r; + } + + function is_char(character) { + var bool = false; + all.filter(function (i) { + bool = (i === character); + }); + return bool; + } + + + function heComes(text, options) { + var result = '', counts, l; + options = options || {}; + options["up"] = options["up"] || true; + options["mid"] = options["mid"] || true; + options["down"] = options["down"] || true; + options["size"] = options["size"] || "maxi"; + text = text.split(''); + for (l in text) { + if (is_char(l)) { + continue; + } + result = result + text[l]; + counts = {"up" : 0, "down" : 0, "mid" : 0}; + switch (options.size) { + case 'mini': + counts.up = randomNumber(8); + counts.min = randomNumber(2); + counts.down = randomNumber(8); + break; + case 'maxi': + counts.up = randomNumber(16) + 3; + counts.min = randomNumber(4) + 1; + counts.down = randomNumber(64) + 3; + break; + default: + counts.up = randomNumber(8) + 1; + counts.mid = randomNumber(6) / 2; + counts.down = randomNumber(8) + 1; + break; + } + + var arr = ["up", "mid", "down"]; + for (var d in arr) { + var index = arr[d]; + for (var i = 0 ; i <= counts[index]; i++) { + if (options[index]) { + result = result + soul[index][randomNumber(soul[index].length)]; + } + } + } + } + return result; + } + // don't summon him + return heComes(text); +} diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/extendStringPrototype.js b/Challenge/seokahi/010.star/node_modules/colors/lib/extendStringPrototype.js new file mode 100644 index 0000000..b6b5b03 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/extendStringPrototype.js @@ -0,0 +1,118 @@ +var colors = require('./colors'), + styles = require('./styles'); + +module['exports'] = function () { + + // + // Extends prototype of native string object to allow for "foo".red syntax + // + var addProperty = function (color, func) { + String.prototype.__defineGetter__(color, func); + }; + + var sequencer = function sequencer (map, str) { + return function () { + var exploded = this.split(""), i = 0; + exploded = exploded.map(map); + return exploded.join(""); + } + }; + + var stylize = function stylize (str, style) { + return styles[style].open + str + styles[style].close; + } + + addProperty('strip', function () { + return colors.strip(this); + }); + + addProperty('stripColors', function () { + return colors.strip(this); + }); + + addProperty("trap", function(){ + return colors.trap(this); + }); + + addProperty("zalgo", function(){ + return colors.zalgo(this); + }); + + addProperty("zebra", function(){ + return colors.zebra(this); + }); + + addProperty("rainbow", function(){ + return colors.rainbow(this); + }); + + addProperty("random", function(){ + return colors.random(this); + }); + + addProperty("america", function(){ + return colors.america(this); + }); + + // + // Iterate through all default styles and colors + // + var x = Object.keys(colors.styles); + x.forEach(function (style) { + addProperty(style, function () { + return stylize(this, style); + }); + }); + + function applyTheme(theme) { + // + // Remark: This is a list of methods that exist + // on String that you should not overwrite. + // + var stringPrototypeBlacklist = [ + '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor', + 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt', + 'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring', + 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight' + ]; + + Object.keys(theme).forEach(function (prop) { + if (stringPrototypeBlacklist.indexOf(prop) !== -1) { + console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name'); + } + else { + if (typeof(theme[prop]) === 'string') { + colors[prop] = colors[theme[prop]]; + addProperty(prop, function () { + return colors[theme[prop]](this); + }); + } + else { + addProperty(prop, function () { + var ret = this; + for (var t = 0; t < theme[prop].length; t++) { + ret = exports[theme[prop][t]](ret); + } + return ret; + }); + } + } + }); + } + + colors.setTheme = function (theme) { + if (typeof theme === 'string') { + try { + colors.themes[theme] = require(theme); + applyTheme(colors.themes[theme]); + return colors.themes[theme]; + } catch (err) { + console.log(err); + return err; + } + } else { + applyTheme(theme); + } + }; + +}; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/index.js b/Challenge/seokahi/010.star/node_modules/colors/lib/index.js new file mode 100644 index 0000000..96d2b84 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/index.js @@ -0,0 +1,12 @@ +var colors = require('./colors'); +module['exports'] = colors; + +// Remark: By default, colors will add style properties to String.prototype +// +// If you don't wish to extend String.prototype you can do this instead and native String will not be touched +// +// var colors = require('colors/safe); +// colors.red("foo") +// +// +var extendStringPrototype = require('./extendStringPrototype')(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/maps/america.js b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/america.js new file mode 100644 index 0000000..a07d832 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/america.js @@ -0,0 +1,12 @@ +var colors = require('../colors'); + +module['exports'] = (function() { + return function (letter, i, exploded) { + if(letter === " ") return letter; + switch(i%3) { + case 0: return colors.red(letter); + case 1: return colors.white(letter) + case 2: return colors.blue(letter) + } + } +})(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/maps/rainbow.js b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/rainbow.js new file mode 100644 index 0000000..a7ce24e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/rainbow.js @@ -0,0 +1,13 @@ +var colors = require('../colors'); + +module['exports'] = (function () { + var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; //RoY G BiV + return function (letter, i, exploded) { + if (letter === " ") { + return letter; + } else { + return colors[rainbowColors[i++ % rainbowColors.length]](letter); + } + }; +})(); + diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/maps/random.js b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/random.js new file mode 100644 index 0000000..5cd101f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/random.js @@ -0,0 +1,8 @@ +var colors = require('../colors'); + +module['exports'] = (function () { + var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta']; + return function(letter, i, exploded) { + return letter === " " ? letter : colors[available[Math.round(Math.random() * (available.length - 1))]](letter); + }; +})(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/maps/zebra.js b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/zebra.js new file mode 100644 index 0000000..bf7dcde --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/maps/zebra.js @@ -0,0 +1,5 @@ +var colors = require('../colors'); + +module['exports'] = function (letter, i, exploded) { + return i % 2 === 0 ? letter : colors.inverse(letter); +}; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/styles.js b/Challenge/seokahi/010.star/node_modules/colors/lib/styles.js new file mode 100644 index 0000000..067d590 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/styles.js @@ -0,0 +1,77 @@ +/* +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +var styles = {}; +module['exports'] = styles; + +var codes = { + reset: [0, 0], + + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], + grey: [90, 39], + + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + + // legacy styles for colors pre v1.0.0 + blackBG: [40, 49], + redBG: [41, 49], + greenBG: [42, 49], + yellowBG: [43, 49], + blueBG: [44, 49], + magentaBG: [45, 49], + cyanBG: [46, 49], + whiteBG: [47, 49] + +}; + +Object.keys(codes).forEach(function (key) { + var val = codes[key]; + var style = styles[key] = []; + style.open = '\u001b[' + val[0] + 'm'; + style.close = '\u001b[' + val[1] + 'm'; +}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/lib/system/supports-colors.js b/Challenge/seokahi/010.star/node_modules/colors/lib/system/supports-colors.js new file mode 100644 index 0000000..3e008aa --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/lib/system/supports-colors.js @@ -0,0 +1,61 @@ +/* +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. + +*/ + +var argv = process.argv; + +module.exports = (function () { + if (argv.indexOf('--no-color') !== -1 || + argv.indexOf('--color=false') !== -1) { + return false; + } + + if (argv.indexOf('--color') !== -1 || + argv.indexOf('--color=true') !== -1 || + argv.indexOf('--color=always') !== -1) { + return true; + } + + if (process.stdout && !process.stdout.isTTY) { + return false; + } + + if (process.platform === 'win32') { + return true; + } + + if ('COLORTERM' in process.env) { + return true; + } + + if (process.env.TERM === 'dumb') { + return false; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return true; + } + + return false; +})(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/package.json b/Challenge/seokahi/010.star/node_modules/colors/package.json new file mode 100644 index 0000000..dc6ce6b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/package.json @@ -0,0 +1,21 @@ +{ + "name": "colors", + "description": "get colors in your node.js console", + "version": "1.0.3", + "author": "Marak Squires", + "homepage": "https://github.com/Marak/colors.js", + "bugs": "https://github.com/Marak/colors.js/issues", + "keywords": [ "ansi", "terminal", "colors" ], + "repository": { + "type": "git", + "url": "http://github.com/Marak/colors.js.git" + }, + "license": "MIT", + "scripts": { + "test": "node tests/basic-test.js && node tests/safe-test.js" + }, + "engines": { + "node": ">=0.1.90" + }, + "main": "./lib/index" +} diff --git a/Challenge/seokahi/010.star/node_modules/colors/safe.js b/Challenge/seokahi/010.star/node_modules/colors/safe.js new file mode 100644 index 0000000..a6a1f3a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/safe.js @@ -0,0 +1,9 @@ +// +// Remark: Requiring this file will use the "safe" colors API which will not touch String.prototype +// +// var colors = require('colors/safe); +// colors.red("foo") +// +// +var colors = require('./lib/colors'); +module['exports'] = colors; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/screenshots/colors.png b/Challenge/seokahi/010.star/node_modules/colors/screenshots/colors.png new file mode 100644 index 0000000000000000000000000000000000000000..7200a623590c35e8b4a8e74a8df49a42998ca9c5 GIT binary patch literal 79787 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

lt>d3ueR)29x+c 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' + s + ''; +} + +var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; +var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); + +colors.mode = 'console'; +assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m'); +assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m'); +assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m'); +assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m'); +assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[27m'); + +assert.ok(s.rainbow); + +aE(s, 'white', 37); +aE(s, 'grey', 90); +aE(s, 'black', 30); +aE(s, 'blue', 34); +aE(s, 'cyan', 36); +aE(s, 'green', 32); +aE(s, 'magenta', 35); +aE(s, 'red', 31); +aE(s, 'yellow', 33); + +assert.equal(s, 'string'); + +colors.setTheme({error:'red'}); + +assert.equal(typeof("astring".red),'string'); +assert.equal(typeof("astring".error),'string'); + diff --git a/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js b/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js new file mode 100644 index 0000000..daad4f9 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js @@ -0,0 +1,45 @@ +var assert = require('assert'), + colors = require('../safe'); + +var s = 'string'; + +function a(s, code) { + return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m'; +} + +function aE(s, color, code) { + assert.equal(colors[color](s), a(s, code)); + assert.equal(colors.strip(s), s); +} + +function h(s, color) { + return '' + s + ''; +} + +var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; +var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); + +colors.mode = 'console'; +assert.equal(colors.bold(s), '\x1B[1m' + s + '\x1B[22m'); +assert.equal(colors.italic(s), '\x1B[3m' + s + '\x1B[23m'); +assert.equal(colors.underline(s), '\x1B[4m' + s + '\x1B[24m'); +assert.equal(colors.strikethrough(s), '\x1B[9m' + s + '\x1B[29m'); +assert.equal(colors.inverse(s), '\x1B[7m' + s + '\x1B[27m'); + +assert.ok(colors.rainbow); + +aE(s, 'white', 37); +aE(s, 'grey', 90); +aE(s, 'black', 30); +aE(s, 'blue', 34); +aE(s, 'cyan', 36); +aE(s, 'green', 32); +aE(s, 'magenta', 35); +aE(s, 'red', 31); +aE(s, 'yellow', 33); + +assert.equal(s, 'string'); +colors.setTheme({error:'red'}); + +assert.equal(typeof(colors.red("astring")), 'string'); +assert.equal(typeof(colors.error("astring")), 'string'); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js b/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js new file mode 100644 index 0000000..571972c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js @@ -0,0 +1,12 @@ +module['exports'] = { + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/cycle/README.md b/Challenge/seokahi/010.star/node_modules/cycle/README.md new file mode 100644 index 0000000..de9a06d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/cycle/README.md @@ -0,0 +1,49 @@ +Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`. + +# Contributors + +* Douglas Crockford +* Nuno Job +* Justin Warkentin + +# JSON in JavaScript + +Douglas Crockford +douglas@crockford.com + +2010-11-18 + + +JSON is a light-weight, language independent, data interchange format. +See http://www.JSON.org/ + +The files in this collection implement JSON encoders/decoders in JavaScript. + +JSON became a built-in feature of JavaScript when the ECMAScript Programming +Language Standard - Fifth Edition was adopted by the ECMA General Assembly +in December 2009. Most of the files in this collection are for applications +that are expected to run in obsolete web browsers. For most purposes, json2.js +is the best choice. + + +json2.js: This file creates a JSON property in the global object, if there +isn't already one, setting its value to an object containing a stringify +method and a parse method. The parse method uses the eval method to do the +parsing, guarding it with several regular expressions to defend against +accidental code execution hazards. On current browsers, this file does nothing, +prefering the built-in JSON object. + +json.js: This file does everything that json2.js does. It also adds a +toJSONString method and a parseJSON method to Object.prototype. Use of this +file is not recommended. + +json_parse.js: This file contains an alternative JSON parse function that +uses recursive descent instead of eval. + +json_parse_state.js: This files contains an alternative JSON parse function that +uses a state machine instead of eval. + +cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, +which make it possible to encode cyclical structures and dags in JSON, and to +then recover them. JSONPath is used to represent the links. +http://GOESSNER.net/articles/JsonPath/ diff --git a/Challenge/seokahi/010.star/node_modules/cycle/cycle.js b/Challenge/seokahi/010.star/node_modules/cycle/cycle.js new file mode 100644 index 0000000..2e776ad --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/cycle/cycle.js @@ -0,0 +1,170 @@ +/* + cycle.js + 2013-02-19 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. +*/ + +/*jslint evil: true, regexp: true */ + +/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, + retrocycle, stringify, test, toString +*/ + +var cycle = exports; + +cycle.decycle = function decycle(object) { + 'use strict'; + +// Make a deep copy of an object or array, assuring that there is at most +// one instance of each object or array in the resulting structure. The +// duplicate references (which might be forming cycles) are replaced with +// an object of the form +// {$ref: PATH} +// where the PATH is a JSONPath string that locates the first occurance. +// So, +// var a = []; +// a[0] = a; +// return JSON.stringify(JSON.decycle(a)); +// produces the string '[{"$ref":"$"}]'. + +// JSONPath is used to locate the unique object. $ indicates the top level of +// the object or array. [NUMBER] or [STRING] indicates a child member or +// property. + + var objects = [], // Keep a reference to each unique object or array + paths = []; // Keep the path to each unique object or array + + return (function derez(value, path) { + +// The derez recurses through the object, producing the deep copy. + + var i, // The loop counter + name, // Property name + nu; // The new object or array + +// typeof null === 'object', so go on if this value is really an object but not +// one of the weird builtin objects. + + if (typeof value === 'object' && value !== null && + !(value instanceof Boolean) && + !(value instanceof Date) && + !(value instanceof Number) && + !(value instanceof RegExp) && + !(value instanceof String)) { + +// If the value is an object or array, look to see if we have already +// encountered it. If so, return a $ref/path object. This is a hard way, +// linear search that will get slower as the number of unique objects grows. + + for (i = 0; i < objects.length; i += 1) { + if (objects[i] === value) { + return {$ref: paths[i]}; + } + } + +// Otherwise, accumulate the unique value and its path. + + objects.push(value); + paths.push(path); + +// If it is an array, replicate the array. + + if (Object.prototype.toString.apply(value) === '[object Array]') { + nu = []; + for (i = 0; i < value.length; i += 1) { + nu[i] = derez(value[i], path + '[' + i + ']'); + } + } else { + +// If it is an object, replicate the object. + + nu = {}; + for (name in value) { + if (Object.prototype.hasOwnProperty.call(value, name)) { + nu[name] = derez(value[name], + path + '[' + JSON.stringify(name) + ']'); + } + } + } + return nu; + } + return value; + }(object, '$')); +}; + + +cycle.retrocycle = function retrocycle($) { + 'use strict'; + +// Restore an object that was reduced by decycle. Members whose values are +// objects of the form +// {$ref: PATH} +// are replaced with references to the value found by the PATH. This will +// restore cycles. The object will be mutated. + +// The eval function is used to locate the values described by a PATH. The +// root object is kept in a $ variable. A regular expression is used to +// assure that the PATH is extremely well formed. The regexp contains nested +// * quantifiers. That has been known to have extremely bad performance +// problems on some browsers for very long strings. A PATH is expected to be +// reasonably short. A PATH is allowed to belong to a very restricted subset of +// Goessner's JSONPath. + +// So, +// var s = '[{"$ref":"$"}]'; +// return JSON.retrocycle(JSON.parse(s)); +// produces an array containing a single element which is the array itself. + + var px = + /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; + + (function rez(value) { + +// The rez function walks recursively through the object looking for $ref +// properties. When it finds one that has a value that is a path, then it +// replaces the $ref object with a reference to the value that is found by +// the path. + + var i, item, name, path; + + if (value && typeof value === 'object') { + if (Object.prototype.toString.apply(value) === '[object Array]') { + for (i = 0; i < value.length; i += 1) { + item = value[i]; + if (item && typeof item === 'object') { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path); + } else { + rez(item); + } + } + } + } else { + for (name in value) { + if (typeof value[name] === 'object') { + item = value[name]; + if (item) { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path); + } else { + rez(item); + } + } + } + } + } + } + }($)); + return $; +}; diff --git a/Challenge/seokahi/010.star/node_modules/cycle/package.json b/Challenge/seokahi/010.star/node_modules/cycle/package.json new file mode 100644 index 0000000..6d85022 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/cycle/package.json @@ -0,0 +1,12 @@ +{ "name" : "cycle" +, "description" : "decycle your json" +, "author" : "" +, "version" : "1.0.3" +, "main" : "./cycle.js" +, "homepage" : "https://github.com/douglascrockford/JSON-js" +, "repository" : + { "type": "git", "url": "http://github.com/dscape/cycle.git" } +, "bugs" : "http://github.com/douglascrockford/JSON-js/issues" +, "keywords" : [ "json", "cycle", "stringify", "parse" ] +, "engines" : { "node" : ">=0.4.0" } +} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml b/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml new file mode 100644 index 0000000..ed05f88 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.11" + - "0.10" + - "0.8" + - "0.6" diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE b/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE new file mode 100644 index 0000000..a23e08a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Raynos. + +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. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/README.md b/Challenge/seokahi/010.star/node_modules/duplexer/README.md new file mode 100644 index 0000000..1dd3b89 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/README.md @@ -0,0 +1,49 @@ +# duplexer + +[![build status][1]][2] [![dependency status][3]][4] + +[![browser support][5]][6] + +Creates a duplex stream + +Taken from [event-stream][7] + +## duplex (writeStream, readStream) + +Takes a writable stream and a readable stream and makes them appear as a readable writable stream. + +It is assumed that the two streams are connected to each other in some way. + +## Example + +```js +var cp = require('child_process') + , duplex = require('duplexer') + , grep = cp.exec('grep Stream') + +duplex(grep.stdin, grep.stdout) +``` + +## Installation + +`npm install duplexer` + +## Tests + +`npm test` + +## Contributors + + - Dominictarr + - Raynos + - samccone + +## MIT Licenced + + [1]: https://secure.travis-ci.org/Raynos/duplexer.png + [2]: https://travis-ci.org/Raynos/duplexer + [3]: https://david-dm.org/Raynos/duplexer.png + [4]: https://david-dm.org/Raynos/duplexer + [5]: https://ci.testling.com/Raynos/duplexer.png + [6]: https://ci.testling.com/Raynos/duplexer + [7]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/index.js b/Challenge/seokahi/010.star/node_modules/duplexer/index.js new file mode 100644 index 0000000..a188a21 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/index.js @@ -0,0 +1,87 @@ +var Stream = require("stream") +var writeMethods = ["write", "end", "destroy"] +var readMethods = ["resume", "pause"] +var readEvents = ["data", "close"] +var slice = Array.prototype.slice + +module.exports = duplex + +function forEach (arr, fn) { + if (arr.forEach) { + return arr.forEach(fn) + } + + for (var i = 0; i < arr.length; i++) { + fn(arr[i], i) + } +} + +function duplex(writer, reader) { + var stream = new Stream() + var ended = false + + forEach(writeMethods, proxyWriter) + + forEach(readMethods, proxyReader) + + forEach(readEvents, proxyStream) + + reader.on("end", handleEnd) + + writer.on("drain", function() { + stream.emit("drain") + }) + + writer.on("error", reemit) + reader.on("error", reemit) + + stream.writable = writer.writable + stream.readable = reader.readable + + return stream + + function proxyWriter(methodName) { + stream[methodName] = method + + function method() { + return writer[methodName].apply(writer, arguments) + } + } + + function proxyReader(methodName) { + stream[methodName] = method + + function method() { + stream.emit(methodName) + var func = reader[methodName] + if (func) { + return func.apply(reader, arguments) + } + reader.emit(methodName) + } + } + + function proxyStream(methodName) { + reader.on(methodName, reemit) + + function reemit() { + var args = slice.call(arguments) + args.unshift(methodName) + stream.emit.apply(stream, args) + } + } + + function handleEnd() { + if (ended) { + return + } + ended = true + var args = slice.call(arguments) + args.unshift("end") + stream.emit.apply(stream, args) + } + + function reemit(err) { + stream.emit("error", err) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/package.json b/Challenge/seokahi/010.star/node_modules/duplexer/package.json new file mode 100644 index 0000000..015bd41 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/package.json @@ -0,0 +1,42 @@ +{ + "name": "duplexer", + "version": "0.1.2", + "description": "Creates a duplex stream", + "keywords": [], + "author": "Raynos ", + "repository": "git://github.com/Raynos/duplexer.git", + "main": "index", + "homepage": "https://github.com/Raynos/duplexer", + "contributors": [ + { + "name": "Jake Verbaten" + } + ], + "bugs": { + "url": "https://github.com/Raynos/duplexer/issues", + "email": "raynos2@gmail.com" + }, + "devDependencies": { + "tape": "0.3.3", + "through": "~0.1.4" + }, + "license": "MIT", + "scripts": { + "test": "node test" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "ie/8..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest" + ] + } +} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js b/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js new file mode 100644 index 0000000..a154567 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js @@ -0,0 +1,31 @@ +var through = require("through") +var test = require("tape") + +var duplex = require("../index") + +var readable = through() +var writable = through(write) +var written = 0 +var data = 0 + +var stream = duplex(writable, readable) + +function write() { + written++ +} + +stream.on("data", ondata) + +function ondata() { + data++ +} + +test("emit and write", function(t) { + t.plan(2) + + stream.write() + readable.emit("data") + + t.equal(written, 1, "should have written once") + t.equal(data, 1, "should have received once") +}) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml b/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE b/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE new file mode 100644 index 0000000..2af26fe --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2011 Dominic Tarr + +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/Challenge/seokahi/010.star/node_modules/event-stream/examples/data b/Challenge/seokahi/010.star/node_modules/event-stream/examples/data new file mode 100644 index 0000000..8c40730 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/examples/data @@ -0,0 +1,3 @@ +{"foo": 1} +{"foo": 2} +{"foo": 3, "bar": "test"} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js new file mode 100644 index 0000000..02eb840 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js @@ -0,0 +1,15 @@ +var es = require('..') + +process.stdin + .pipe(es.map(function (data, callback) { + for (var i = 0; i < data.length; i++) { + if (data[i] == 0x61) { + data[i] = 0x41 + } + } + callback(null, data) + })) + .pipe(process.stdout) + +// echo abcdabcd | node map.js +// AbcdAbcd \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js new file mode 100644 index 0000000..5ec88a4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js @@ -0,0 +1,18 @@ + +var inspect = require('util').inspect +var es = require('..') + +es.pipe( //pipe joins streams together + process.openStdin(), //open stdin + es.split(null, null, {trailing: false}), //split stream to break on newlines + es.map(function (data, callback) { //turn this async function into a stream + var obj = JSON.parse(data) //parse input into json + callback(null, inspect(obj) + '\n') //render it nicely + }), + process.stdout // pipe it to stdout ! +) + +// cat data | node pretty.js +// { foo: 1 } +// { foo: 2 } +// { foo: 3, bar: 'test' } \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js new file mode 100644 index 0000000..e21d579 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js @@ -0,0 +1,12 @@ +var es = require('..') + +process.stdin + .pipe(es.split(null, null, {trailing: false})) // ignore trailing empty line + .on('data', function (data) { + console.log('data: ' + data) + }) + +// cat data | node map.js +// data: {"foo": 1} +// data: {"foo": 2} +// data: {"foo": 3, "bar": "test"} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/index.js b/Challenge/seokahi/010.star/node_modules/event-stream/index.js new file mode 100644 index 0000000..adb0468 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/index.js @@ -0,0 +1,351 @@ +//filter will reemit the data if cb(err,pass) pass is truthy + +// reduce is more tricky +// maybe we want to group the reductions or emit progress updates occasionally +// the most basic reduce just emits one 'data' event after it has recieved 'end' + +var Stream = require('stream').Stream + , es = exports + , through = require('through') + , from = require('from') + , duplex = require('duplexer') + , map = require('map-stream') + , pause = require('pause-stream') + , split = require('split') + , pipeline = require('stream-combiner') + , immediately = global.setImmediate || process.nextTick; + +es.Stream = Stream //re-export Stream from core +es.through = through +es.from = from +es.duplex = duplex +es.map = map +es.pause = pause +es.split = split +es.pipeline = es.connect = es.pipe = pipeline +// merge / concat +// +// combine multiple streams into a single stream. +// will emit end only once + +es.concat = //actually this should be called concat +es.merge = function (/*streams...*/) { + var toMerge = [].slice.call(arguments) + if (toMerge.length === 1 && (toMerge[0] instanceof Array)) { + toMerge = toMerge[0] //handle array as arguments object + } + var stream = new Stream() + stream.setMaxListeners(0) // allow adding more than 11 streams + var endCount = 0 + stream.writable = stream.readable = true + + if (toMerge.length) { + toMerge.forEach(function (e) { + e.pipe(stream, {end: false}) + var ended = false + e.on('end', function () { + if(ended) return + ended = true + endCount ++ + if(endCount == toMerge.length) + stream.emit('end') + }) + }) + } else { + process.nextTick(function () { + stream.emit('end') + }) + } + + stream.write = function (data) { + this.emit('data', data) + } + stream.destroy = function () { + toMerge.forEach(function (e) { + if(e.destroy) e.destroy() + }) + } + return stream +} + + +// writable stream, collects all events into an array +// and calls back when 'end' occurs +// mainly I'm using this to test the other functions + +es.collect = +es.writeArray = function (done) { + if ('function' !== typeof done) + throw new Error('function writeArray (done): done must be function') + + var a = new Stream () + , array = [], isDone = false + a.write = function (l) { + array.push(l) + } + a.end = function () { + isDone = true + done(null, array) + } + a.writable = true + a.readable = false + a.destroy = function () { + a.writable = a.readable = false + if(isDone) return + done(new Error('destroyed before end'), array) + } + return a +} + +//return a Stream that reads the properties of an object +//respecting pause() and resume() + +es.readArray = function (array) { + var stream = new Stream() + , i = 0 + , paused = false + , ended = false + + stream.readable = true + stream.writable = false + + if(!Array.isArray(array)) + throw new Error('event-stream.read expects an array') + + stream.resume = function () { + if(ended) return + paused = false + var l = array.length + while(i < l && !paused && !ended) { + stream.emit('data', array[i++]) + } + if(i == l && !ended) + ended = true, stream.readable = false, stream.emit('end') + } + process.nextTick(stream.resume) + stream.pause = function () { + paused = true + } + stream.destroy = function () { + ended = true + stream.emit('close') + } + return stream +} + +// +// readable (asyncFunction) +// return a stream that calls an async function while the stream is not paused. +// +// the function must take: (count, callback) {... +// + +es.readable = +function (func, continueOnError) { + var stream = new Stream() + , i = 0 + , paused = false + , ended = false + , reading = false + + stream.readable = true + stream.writable = false + + if('function' !== typeof func) + throw new Error('event-stream.readable expects async function') + + stream.on('end', function () { ended = true }) + + function get (err, data) { + + if(err) { + stream.emit('error', err) + if(!continueOnError) stream.emit('end') + } else if (arguments.length > 1) + stream.emit('data', data) + + immediately(function () { + if(ended || paused || reading) return + try { + reading = true + func.call(stream, i++, function () { + reading = false + get.apply(null, arguments) + }) + } catch (err) { + stream.emit('error', err) + } + }) + } + stream.resume = function () { + paused = false + get() + } + process.nextTick(get) + stream.pause = function () { + paused = true + } + stream.destroy = function () { + stream.emit('end') + stream.emit('close') + ended = true + } + return stream +} + + +// +// map sync +// + +es.mapSync = function (sync) { + return es.through(function write(data) { + var mappedData + try { + mappedData = sync(data) + } catch (err) { + return this.emit('error', err) + } + if (mappedData !== undefined) + this.emit('data', mappedData) + }) +} + +// +// filterSync +// + +es.filterSync = function (test) { + return es.through(function(data){ + var s = this + if (test(data)) { + s.queue(data) + } + }); +} + +// +// flatmapSync +// + +es.flatmapSync = function (mapper) { + return es.through(function(data) { + var s = this + data.forEach(function(e) { + s.queue(mapper(e)) + }) + }) +} + +// +// log just print out what is coming through the stream, for debugging +// + +es.log = function (name) { + return es.through(function (data) { + var args = [].slice.call(arguments) + if(name) console.error(name, data) + else console.error(data) + this.emit('data', data) + }) +} + + +// +// child -- pipe through a child process +// + +es.child = function (child) { + + return es.duplex(child.stdin, child.stdout) + +} + +// +// parse +// +// must be used after es.split() to ensure that each chunk represents a line +// source.pipe(es.split()).pipe(es.parse()) + +es.parse = function (options) { + var emitError = !!(options ? options.error : false) + return es.through(function (data) { + var obj + try { + if(data) //ignore empty lines + obj = JSON.parse(data.toString()) + } catch (err) { + if (emitError) + return this.emit('error', err) + return console.error(err, 'attempting to parse:', data) + } + //ignore lines that where only whitespace. + if(obj !== undefined) + this.emit('data', obj) + }) +} +// +// stringify +// + +es.stringify = function () { + var Buffer = require('buffer').Buffer + return es.mapSync(function (e){ + return JSON.stringify(Buffer.isBuffer(e) ? e.toString() : e) + '\n' + }) +} + +// +// replace a string within a stream. +// +// warn: just concatenates the string and then does str.split().join(). +// probably not optimal. +// for smallish responses, who cares? +// I need this for shadow-npm so it's only relatively small json files. + +es.replace = function (from, to) { + return es.pipeline(es.split(from), es.join(to)) +} + +// +// join chunks with a joiner. just like Array#join +// also accepts a callback that is passed the chunks appended together +// this is still supported for legacy reasons. +// + +es.join = function (str) { + + //legacy api + if('function' === typeof str) + return es.wait(str) + + var first = true + return es.through(function (data) { + if(!first) + this.emit('data', str) + first = false + this.emit('data', data) + return true + }) +} + + +// +// wait. callback when 'end' is emitted, with all chunks appended as string. +// + +es.wait = function (callback) { + var arr = [] + return es.through(function (data) { arr.push(data) }, + function () { + var body = Buffer.isBuffer(arr[0]) ? Buffer.concat(arr) + : arr.join('') + this.emit('data', body) + this.emit('end') + if(callback) callback(null, body) + }) +} + +es.pipeable = function () { + throw new Error('[EVENT-STREAM] es.pipeable is deprecated') +} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/package.json b/Challenge/seokahi/010.star/node_modules/event-stream/package.json new file mode 100644 index 0000000..a2a487d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/package.json @@ -0,0 +1,36 @@ +{ + "name": "event-stream", + "version": "4.0.1", + "description": "construct pipes of streams of events", + "homepage": "http://github.com/dominictarr/event-stream", + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/event-stream.git" + }, + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + }, + "devDependencies": { + "asynct": "^1.1.0", + "it-is": "^1.0.3", + "stream-spec": "^0.3.6", + "tape": "^4.9.1", + "ubelt": "^3.2.2" + }, + "scripts": { + "prepublish": "npm ls && npm test", + "test": "asynct test/", + "test_tap": "set -e; for t in test/*.js; do node $t; done" + }, + "keywords": [ + "stream", "map", "flatmap", "filter", "split", "join", "merge", "replace" + ], + "license": "MIT", + "author": "Dominic Tarr (http://bit.ly/dominictarr)" +} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown new file mode 100644 index 0000000..4ce5177 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown @@ -0,0 +1,345 @@ +# EventStream + +[Streams](http://nodejs.org/api/stream.html "Stream") are node's best and most misunderstood idea, and EventStream is a toolkit to make creating and working with streams easy. + +Normally, streams are only used for IO, but in event stream we send all kinds of objects down the pipe. If your application's input and output are streams, shouldn't the throughput be a stream too? + +The *EventStream* functions resemble the array functions, because Streams are like Arrays, but laid out in time, rather than in memory. + +All the `event-stream` functions return instances of `Stream`. + +`event-stream` creates [0.8 streams](https://github.com/joyent/node/blob/v0.8/doc/api/stream.markdown), which are compatible with [0.10 streams](http://nodejs.org/api/stream.html "Stream"). + +>NOTE: I shall use the term "through stream" to refer to a stream that is writable and readable. + +>NOTE for Gulp users: Merge will not work for gulp 4. [merge-stream](https://npmjs.com/merge-stream) should be used. + +### [simple example](https://github.com/dominictarr/event-stream/blob/master/examples/pretty.js): + +``` js +//pretty.js + +if(!module.parent) { + var es = require('event-stream') + var inspect = require('util').inspect + + process.stdin //connect streams together with `pipe` + .pipe(es.split()) //split stream to break on newlines + .pipe(es.map(function (data, cb) { //turn this async function into a stream + cb(null + , inspect(JSON.parse(data))) //render it nicely + })) + .pipe(process.stdout) // pipe it to stdout ! +} +``` +run it ... + +``` bash +curl -sS registry.npmjs.org/event-stream | node pretty.js +``` + +[node Stream documentation](http://nodejs.org/api/stream.html) + +## through (write?, end?) + +Re-emits data synchronously. Easy way to create synchronous through streams. +Pass in optional `write` and `end` methods. They will be called in the +context of the stream. Use `this.pause()` and `this.resume()` to manage flow. +Check `this.paused` to see current flow state. (write always returns `!this.paused`) + +this function is the basis for most of the synchronous streams in `event-stream`. + +``` js + +es.through(function write(data) { + this.emit('data', data) + //this.pause() + }, + function end () { //optional + this.emit('end') + }) + +``` + +## map (asyncFunction) + +Create a through stream from an asynchronous function. + +``` js +var es = require('event-stream') + +es.map(function (data, callback) { + //transform data + // ... + callback(null, data) +}) + +``` + +Each map MUST call the callback. It may callback with data, with an error or with no arguments, + + * `callback()` drop this data. + this makes the map work like `filter`, + note:`callback(null,null)` is not the same, and will emit `null` + + * `callback(null, newData)` turn data into newData + + * `callback(error)` emit an error for this item. + +>Note: if a callback is not called, `map` will think that it is still being processed, +>every call must be answered or the stream will not know when to end. +> +>Also, if the callback is called more than once, every call but the first will be ignored. + +## mapSync (syncFunction) + +Same as `map`, but the callback is called synchronously. Based on `es.through` + +## flatmapSync (syncFunction) + +Map elements nested. + +``` js +var es = require('event-stream') + +es.flatmapSync(function (data) { + //transform data + // ... + return data +}) + +``` + +## filterSync (syncFunction) + +Filter elements. + +``` js +var es = require('event-stream') + +es.filterSync(function (data) { + return data > 0 +}) + +``` + +## split (matcher) + +Break up a stream and reassemble it so that each line is a chunk. matcher may be a `String`, or a `RegExp` + +Example, read every line in a file ... + +``` js +fs.createReadStream(file, {flags: 'r'}) + .pipe(es.split()) + .pipe(es.map(function (line, cb) { + //do something with the line + cb(null, line) + })) +``` + +`split` takes the same arguments as `string.split` except it defaults to '\n' instead of ',', and the optional `limit` parameter is ignored. +[String#split](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split) + +**NOTE** - Maintaining Line Breaks +If you want to process each line of the stream, transform the data, reassemble, and **KEEP** the line breaks the example will look like this: + +```javascript +fs.createReadStream(file, {flags: 'r'}) + .pipe(es.split(/(\r?\n)/)) + .pipe(es.map(function (line, cb) { + //do something with the line + cb(null, line) + })) +``` + +This technique is mentioned in the [underlying documentation](https://www.npmjs.com/package/split#keep-matched-splitter) for the split npm package. + +## join (separator) + +Create a through stream that emits `separator` between each chunk, just like Array#join. + +(for legacy reasons, if you pass a callback instead of a string, join is a synonym for `es.wait`) + +## merge (stream1,...,streamN) or merge (streamArray) +> concat → merge + +Merges streams into one and returns it. +Incoming data will be emitted as soon it comes into - no ordering will be applied (for example: `data1 data1 data2 data1 data2` - where `data1` and `data2` is data from two streams). +Counts how many streams were passed to it and emits end only when all streams emitted end. + +```js +es.merge( + process.stdout, + process.stderr +).pipe(fs.createWriteStream('output.log')); +``` + +It can also take an Array of streams as input like this: +```js +es.merge([ + fs.createReadStream('input1.txt'), + fs.createReadStream('input2.txt') +]).pipe(fs.createWriteStream('output.log')); +``` + +## replace (from, to) + +Replace all occurrences of `from` with `to`. `from` may be a `String` or a `RegExp`. +Works just like `string.split(from).join(to)`, but streaming. + + +## parse + +Convenience function for parsing JSON chunks. For newline separated JSON, +use with `es.split`. By default it logs parsing errors by `console.error`; +for another behaviour, transforms created by `es.parse({error: true})` will +emit error events for exceptions thrown from `JSON.parse`, unmodified. + +``` js +fs.createReadStream(filename) + .pipe(es.split()) //defaults to lines. + .pipe(es.parse()) +``` + +## stringify + +convert javascript objects into lines of text. The text will have whitespace escaped and have a `\n` appended, so it will be compatible with `es.parse` + +``` js +objectStream + .pipe(es.stringify()) + .pipe(fs.createWriteStream(filename)) +``` + +## readable (asyncFunction) + +create a readable stream (that respects pause) from an async function. +while the stream is not paused, +the function will be polled with `(count, callback)`, +and `this` will be the readable stream. + +``` js + +es.readable(function (count, callback) { + if(streamHasEnded) + return this.emit('end') + + //... + + this.emit('data', data) //use this way to emit multiple chunks per call. + + callback() // you MUST always call the callback eventually. + // the function will not be called again until you do this. +}) +``` +you can also pass the data and the error to the callback. +you may only call the callback once. +calling the same callback more than once will have no effect. + +## readArray (array) + +Create a readable stream from an Array. + +Just emit each item as a data event, respecting `pause` and `resume`. + +``` js + var es = require('event-stream') + , reader = es.readArray([1,2,3]) + + reader.pipe(...) +``` + +If you want the stream behave like a 0.10 stream you will need to wrap it using [`Readable.wrap()`](http://nodejs.org/api/stream.html#stream_readable_wrap_stream) function. Example: + +``` js + var s = new stream.Readable({objectMode: true}).wrap(es.readArray([1,2,3])); +``` + +## writeArray (callback) + +create a writeable stream from a callback, +all `data` events are stored in an array, which is passed to the callback when the stream ends. + +``` js + var es = require('event-stream') + , reader = es.readArray([1, 2, 3]) + , writer = es.writeArray(function (err, array){ + //array deepEqual [1, 2, 3] + }) + + reader.pipe(writer) +``` + +## pause () + +A stream that buffers all chunks when paused. + + +``` js + var ps = es.pause() + ps.pause() //buffer the stream, also do not allow 'end' + ps.resume() //allow chunks through +``` + +## duplex (writeStream, readStream) + +Takes a writable stream and a readable stream and makes them appear as a readable writable stream. + +It is assumed that the two streams are connected to each other in some way. + +(This is used by `pipeline` and `child`.) + +``` js + var grep = cp.exec('grep Stream') + + es.duplex(grep.stdin, grep.stdout) +``` + +## child (child_process) + +Create a through stream from a child process ... + +``` js + var cp = require('child_process') + + es.child(cp.exec('grep Stream')) // a through stream + +``` + +## wait (callback) + +waits for stream to emit 'end'. +joins chunks of a stream into a single string or buffer. +takes an optional callback, which will be passed the +complete string/buffer when it receives the 'end' event. + +also, emits a single 'data' event. + +``` js + +readStream.pipe(es.wait(function (err, body) { + // have complete text here. +})) + +``` + +# Other Stream Modules + +These modules are not included as a part of *EventStream* but may be +useful when working with streams. + +## [reduce (syncFunction, initial)](https://github.com/parshap/node-stream-reduce) + +Like `Array.prototype.reduce` but for streams. Given a sync reduce +function and an initial value it will return a through stream that emits +a single data event with the reduced value once the input stream ends. + +``` js +var reduce = require("stream-reduce"); +process.stdin.pipe(reduce(function(acc, data) { + return acc + data.length; +}, 0)).on("data", function(length) { + console.log("stdin size:", length); +}); +``` diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js new file mode 100644 index 0000000..e6a442b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js @@ -0,0 +1,86 @@ +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + +function makeExamplePipe() { + + return es.connect( + es.map(function (data, callback) { + callback(null, data * 2) + }), + es.map(function (data, callback) { + d.delay(callback)(null, data) + }), + es.map(function (data, callback) { + callback(null, data + 2) + })) +} + +exports['simple pipe'] = function (test) { + + var pipe = makeExamplePipe() + + pipe.on('data', function (data) { + it(data).equal(18) + test.done() + }) + + pipe.write(8) + +} + +exports['read array then map'] = function (test) { + + var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 + , first = es.readArray(readThis) + , read = [] + , pipe = + es.connect( + first, + es.map(function (data, callback) { + callback(null, {data: data}) + }), + es.map(function (data, callback) { + callback(null, {data: data}) + }), + es.writeArray(function (err, array) { + it(array).deepEqual(d.map(readThis, function (data) { + return {data: {data: data}} + })) + test.done() + }) + ) +} + +exports ['connect returns a stream'] = function (test) { + + var rw = + es.connect( + es.map(function (data, callback) { + callback(null, data * 2) + }), + es.map(function (data, callback) { + callback(null, data * 5) + }) + ) + + it(rw).has({readable: true, writable: true}) + + var array = [190, 24, 6, 7, 40, 57, 4, 6] + , _array = [] + , c = + es.connect( + es.readArray(array), + rw, + es.log('after rw:'), + es.writeArray(function (err, _array) { + it(_array).deepEqual(array.map(function (e) { return e * 10 })) + test.done() + }) + ) + +} + + +require('./helper')(module) + diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js new file mode 100644 index 0000000..1d2e4f9 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js @@ -0,0 +1,17 @@ +'use strict'; + +var es = require('../') + , it = require('it-is') + +exports ['filter'] = function (test) { + es.readArray([1, 2, 3, 4]) + .pipe(es.filterSync(function(e) { + return e > 2 + })) + .pipe(es.writeArray(function(error, array) { + test.deepEqual([3, 4], array) + test.end() + })) +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js new file mode 100644 index 0000000..ae6a9a0 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js @@ -0,0 +1,17 @@ +'use strict'; + +var es = require('../') + , it = require('it-is') + +exports ['flatmap'] = function (test) { + es.readArray([[1], [1, 2], [1, 2, 3]]) + .pipe(es.flatmapSync(function(e) { + return e + 1 + })) + .pipe(es.writeArray(function(error, array) { + test.deepEqual([2, 2, 3, 2, 3, 4], array) + test.end() + })) +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js new file mode 100644 index 0000000..96abaeb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js @@ -0,0 +1,12 @@ +var tape = require('tape') + +module.exports = function (m) { + if(m.parent) return + for(var name in m.exports) { + tape(name, function (t) { + console.log('start', name) + t.done = t.end + m.exports[name](t) + }) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js new file mode 100644 index 0000000..68f38ba --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js @@ -0,0 +1,29 @@ +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + +exports.merge = function (t) { + var odd = d.map(1, 3, 100, d.id) //array of multiples of 3 < 100 + var even = d.map(2, 4, 100, d.id) //array of multiples of 3 < 100 + + var r1 = es.readArray(even) + var r2 = es.readArray(odd) + var endCount = 0 + + var writer = es.writeArray(function (err, array){ + if(err) throw err //unpossible + it(array.sort()).deepEqual(even.concat(odd).sort()) + if (++endCount === 2) t.done() + }) + + var writer2 = es.writeArray(function (err, array){ + if(err) throw err //unpossible + it(array.sort()).deepEqual(even.concat(odd).sort()) + if (++endCount === 2) t.done() + }) + + es.merge(r1, r2).pipe(writer) + es.merge([r1, r2]).pipe(writer2) + +} +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js new file mode 100644 index 0000000..a5fefcf --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js @@ -0,0 +1,32 @@ +var es = require('../') + , it = require('it-is').style('colour') + +exports ['es.parse() writes parsing errors with console.error'] = function (test) { + var parseStream = es.parse() + var oldConsoleError = console.error + console.error = function () { + console.error = oldConsoleError + it(arguments.length > 0).ok() + test.done() + } + + // bare word is not valid JSON + parseStream.write('A') +} + +exports ['es.parse({error: true(thy)}) emits error events from parsing'] = function (test) { + var parseStream = es.parse({error: 1}) + var expectedError + try { + JSON.parse('A') + } catch(e) { + expectedError = e + } + + parseStream.on('error', function (e) { + it(e).deepEqual(expectedError) + process.nextTick(function () { + test.done() + }) + }).write('A') +} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js new file mode 100644 index 0000000..b073604 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js @@ -0,0 +1,39 @@ + +var es = require('../') + , it = require('it-is') + , d = require('ubelt') + +exports ['gate buffers when shut'] = function (test) { + + var hundy = d.map(1,100, d.id) + , gate = es.pause() + , ten = 10 + es.connect( + es.readArray(hundy), + es.log('after readArray'), + gate, + //es.log('after gate'), + es.map(function (num, next) { + //stick a map in here to check that gate never emits when open + it(gate.paused).equal(false) + console.log('data', num) + if(!--ten) { + console.log('PAUSE') + gate.pause()//.resume() + d.delay(gate.resume.bind(gate), 10)() + ten = 10 + } + + next(null, num) + }), + es.writeArray(function (err, array) { //just realized that I should remove the error param. errors will be emitted + console.log('eonuhoenuoecbulc') + it(array).deepEqual(hundy) + test.done() + }) + ) + + gate.resume() + +} +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js new file mode 100644 index 0000000..f07c6fa --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js @@ -0,0 +1,52 @@ +var es = require('..') + +exports['do not duplicate errors'] = function (test) { + + var errors = 0; + var pipe = es.pipeline( + es.through(function(data) { + return this.emit('data', data); + }), + es.through(function(data) { + return this.emit('error', new Error(data)); + }) + ) + + pipe.on('error', function(err) { + errors++ + console.log('error count', errors) + process.nextTick(function () { + return test.done(); + }) + }) + + return pipe.write('meh'); + +} + +exports['3 pipe do not duplicate errors'] = function (test) { + + var errors = 0; + var pipe = es.pipeline( + es.through(function(data) { + return this.emit('data', data); + }), + es.through(function(data) { + return this.emit('error', new Error(data)); + }), + es.through() + ) + + pipe.on('error', function(err) { + errors++ + console.log('error count', errors) + process.nextTick(function () { + return test.done(); + }) + }) + + return pipe.write('meh'); + +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js new file mode 100644 index 0000000..3eeb90a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js @@ -0,0 +1,89 @@ + +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + +function readStream(stream, pauseAt, done) { + if(!done) done = pauseAt, pauseAt = -1 + var array = [] + stream.on('data', function (data) { + array.push(data) + if(!--pauseAt ) + stream.pause(), done(null, array) + }) + stream.on('error', done) + stream.on('end', function (data) { + done(null, array) + }) + +} + +exports ['read an array'] = function (test) { + + var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 + + var reader = es.readArray(readThis) + + var writer = es.writeArray(function (err, array){ + if(err) throw err //unpossible + it(array).deepEqual(readThis) + test.done() + }) + + reader.pipe(writer) +} + +exports ['read an array and pause it.'] = function (test) { + + var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 + + var reader = es.readArray(readThis) + + readStream(reader, 10, function (err, data) { + if(err) throw err + it(data).deepEqual([3, 6, 9, 12, 15, 18, 21, 24, 27, 30]) + readStream(reader, 10, function (err, data) { + it(data).deepEqual([33, 36, 39, 42, 45, 48, 51, 54, 57, 60]) + test.done() + }) + reader.resume() + }) + +} + +exports ['reader is readable, but not writeable'] = function (test) { + var reader = es.readArray([1]) + it(reader).has({ + readable: true, + writable: false + }) + + test.done() +} + + +exports ['read one item per tick'] = function (test) { + var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 + var drains = 0 + var reader = es.readArray(readThis) + var tickMapper = es.map(function (data,callback) { + process.nextTick(function () { + callback(null, data) + }) + //since tickMapper is returning false + //pipe should pause the writer until a drain occurs + return false + }) + reader.pipe(tickMapper) + readStream(tickMapper, function (err, array) { + it(array).deepEqual(readThis) + it(array.length).deepEqual(readThis.length) + it(drains).equal(readThis.length) + test.done() + }) + tickMapper.on('drain', function () { + drains ++ + }) + +} +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js new file mode 100644 index 0000000..6ea2fdb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js @@ -0,0 +1,197 @@ + +var es = require('../') + , it = require('it-is').style('colour') + , u = require('ubelt') + +exports ['read an array'] = function (test) { + + + console.log('readable') + return test.end() + var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 + + console.log('readable') + + var reader = + es.readable(function (i, callback) { + if(i >= readThis.length) + return this.emit('end') + console.log('readable') + callback(null, readThis[i]) + }) + + var writer = es.writeArray(function (err, array){ + if(err) throw err + it(array).deepEqual(readThis) + test.done() + }) + + reader.pipe(writer) +} + +exports ['read an array - async'] = function (test) { + + var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 + + var reader = + es.readable(function (i, callback) { + if(i >= readThis.length) + return this.emit('end') + u.delay(callback)(null, readThis[i]) + }) + + var writer = es.writeArray(function (err, array){ + if(err) throw err + it(array).deepEqual(readThis) + test.done() + }) + + reader.pipe(writer) +} + + +exports ['emit data then call next() also works'] = function (test) { + + var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 + + var reader = + es.readable(function (i, next) { + if(i >= readThis.length) + return this.emit('end') + this.emit('data', readThis[i]) + next() + }) + + var writer = es.writeArray(function (err, array){ + if(err) throw err + it(array).deepEqual(readThis) + test.done() + }) + + reader.pipe(writer) +} + + +exports ['callback emits error, then stops'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , called = 0 + + var reader = + es.readable(function (i, callback) { + if(called++) + return + callback(err) + }) + + reader.on('error', function (_err){ + it(_err).deepEqual(err) + u.delay(function() { + it(called).equal(1) + test.done() + }, 50)() + }) +} + +exports['readable does not call read concurrently'] = function (test) { + + var current = 0 + var source = es.readable(function(count, cb){ + current ++ + if(count > 100) + return this.emit('end') + u.delay(function(){ + current -- + it(current).equal(0) + cb(null, {ok: true, n: count}); + })(); + }); + + var destination = es.map(function(data, cb){ + //console.info(data); + cb(); + }); + + var all = es.connect(source, destination); + + destination.on('end', test.done) +} + +exports ['does not raise a warning: Recursive process.nextTick detected'] = function (test) { + var readThisDelayed; + + u.delay(function () { + readThisDelayed = [1, 3, 5]; + })(); + + es.readable(function (count, callback) { + + if (readThisDelayed) { + var that = this; + readThisDelayed.forEach(function (item) { + that.emit('data', item); + }); + + this.emit('end'); + test.done(); + } + + callback(); + }); +}; + +// +// emitting multiple errors is not supported by stream. +// +// I do not think that this is a good idea, at least, there should be an option to pipe to +// continue on error. it makes alot ef sense, if you are using Stream like I am, to be able to emit multiple errors. +// an error might not necessarily mean the end of the stream. it depends on the error, at least. +// +// I will start a thread on the mailing list. I'd rather that than use a custom `pipe` implementation. +// +// basically, I want to be able use pipe to transform objects, and if one object is invalid, +// the next might still be good, so I should get to choose if it's gonna stop. +// re-enstate this test when this issue progresses. +// +// hmm. I could add this to es.connect by deregistering the error listener, +// but I would rather it be an option in core. + +/* +exports ['emit multiple errors, with 2nd parameter (continueOnError)'] = function (test) { + + var readThis = d.map(1, 100, d.id) + , errors = 0 + var reader = + es.readable(function (i, callback) { + console.log(i, readThis.length) + if(i >= readThis.length) + return this.emit('end') + if(!(readThis[i] % 7)) + return callback(readThis[i]) + callback(null, readThis[i]) + }, true) + + var writer = es.writeArray(function (err, array) { + if(err) throw err + it(array).every(function (u){ + it(u % 7).notEqual(0) + }).property('length', 80) + it(errors).equal(14) + test.done() + }) + + reader.on('error', function (u) { + errors ++ + console.log(u) + if('number' !== typeof u) + throw u + + it(u % 7).equal(0) + + }) + + reader.pipe(writer) +} +*/ + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js new file mode 100644 index 0000000..1c8735b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js @@ -0,0 +1,76 @@ +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + , spec = require('stream-spec') + +var next = process.nextTick + +var fizzbuzz = '12F4BF78FB11F1314FB1617F19BF2223FB26F2829FB3132F34BF3738FB41F4344FB4647F49BF5253FB56F5859FB6162F64BF6768FB71F7374FB7677F79BF8283FB86F8889FB9192F94BF9798FB' + , fizz7buzz = '12F4BFseven8FB11F1314FB161sevenF19BF2223FB26F2829FB3132F34BF3seven38FB41F4344FB464sevenF49BF5253FB56F5859FB6162F64BF6seven68FBseven1Fseven3seven4FBseven6sevensevenFseven9BF8283FB86F8889FB9192F94BF9seven98FB' + , fizzbuzzwhitespce = ' 12F4BF78FB11F1314FB1617F19BF2223FB26F2829FB3132F34BF3738FB41F4344FB4647F49BF5253FB56F5859FB6162F64BF6768FB71F7374FB7677F79BF8283FB86F8889FB9192F94BF9798FB ' + +exports ['fizz buzz'] = function (test) { + + var readThis = d.map(1, 100, function (i) { + return ( + ! (i % 3 || i % 5) ? "FB" : + !(i % 3) ? "F" : + !(i % 5) ? "B" : + ''+i + ) + }) //array of multiples of 3 < 100 + + var reader = es.readArray(readThis) + var join = es.wait(function (err, string){ + it(string).equal(fizzbuzz) + test.done() + }) + reader.pipe(join) + +} + + +exports ['fizz buzz replace'] = function (test) { + var split = es.split(/(1)/) + var replace = es.replace('7', 'seven') +// var x = spec(replace).through() + split + .pipe(replace) + .pipe(es.join(function (err, string) { + it(string).equal(fizz7buzz) + })) + + replace.on('close', function () { +// x.validate() + test.done() + }) + + split.write(fizzbuzz) + split.end() + +} + + +exports ['fizz buzz replace whitespace using regexp'] = function (test) { + var split = es.split(/(1)/) + var replaceLeading = es.replace(/^[\s]*/, '') + var replaceTrailing = es.replace(/[\s]*$/, '') +// var x = spec(replace).through() + split + .pipe(replaceLeading) + .pipe(replaceTrailing) + .pipe(es.join(function (err, string) { + it(string).equal(fizzbuzz) + })) + + replaceTrailing.on('close', function () { +// x.validate() + test.done() + }) + + split.write(fizzbuzz) + split.end() + +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js new file mode 100644 index 0000000..25121f9 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js @@ -0,0 +1,343 @@ +'use strict'; + +var es = require('../') + , it = require('it-is') + , u = require('ubelt') + , spec = require('stream-spec') + , Stream = require('stream') + , from = require('from') + , through = require('through') + +//REFACTOR THIS TEST TO USE es.readArray and es.writeArray + +function writeArray(array, stream) { + + array.forEach( function (j) { + stream.write(j) + }) + stream.end() + +} + +function readStream(stream, done) { + + var array = [] + stream.on('data', function (data) { + array.push(data) + }) + stream.on('error', done) + stream.on('end', function (data) { + done(null, array) + }) + +} + +//call sink on each write, +//and complete when finished. + +function pauseStream (prob, delay) { + var pauseIf = ( + 'number' == typeof prob + ? function () { + return Math.random() < prob + } + : 'function' == typeof prob + ? prob + : 0.1 + ) + var delayer = ( + !delay + ? process.nextTick + : 'number' == typeof delay + ? function (next) { setTimeout(next, delay) } + : delay + ) + + return es.through(function (data) { + if(!this.paused && pauseIf()) { + console.log('PAUSE STREAM PAUSING') + this.pause() + var self = this + delayer(function () { + console.log('PAUSE STREAM RESUMING') + self.resume() + }) + } + console.log("emit ('data', " + data + ')') + this.emit('data', data) + }) +} + +exports ['simple map'] = function (test) { + + var input = u.map(1, 1000, function () { + return Math.random() + }) + var expected = input.map(function (v) { + return v * 2 + }) + + var pause = pauseStream(0.1) + var fs = from(input) + var ts = es.writeArray(function (err, ar) { + it(ar).deepEqual(expected) + test.done() + }) + var map = es.through(function (data) { + this.emit('data', data * 2) + }) + + spec(map).through().validateOnExit() + spec(pause).through().validateOnExit() + + fs.pipe(map).pipe(pause).pipe(ts) +} + +exports ['simple map applied to a stream'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + //create event stream from + + var doubler = es.map(function (data, cb) { + cb(null, data * 2) + }) + + spec(doubler).through().validateOnExit() + + //a map is only a middle man, so it is both readable and writable + + it(doubler).has({ + readable: true, + writable: true, + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.map(function (j) { + return j * 2 + })) +// process.nextTick(x.validate) + test.done() + }) + + writeArray(input, doubler) + +} + +exports['pipe two maps together'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + //create event stream from + function dd (data, cb) { + cb(null, data * 2) + } + var doubler1 = es.map(dd), doubler2 = es.map(dd) + + doubler1.pipe(doubler2) + + spec(doubler1).through().validateOnExit() + spec(doubler2).through().validateOnExit() + + readStream(doubler2, function (err, output) { + it(output).deepEqual(input.map(function (j) { + return j * 4 + })) + test.done() + }) + + writeArray(input, doubler1) + +} + +//next: +// +// test pause, resume and drian. +// + +// then make a pipe joiner: +// +// plumber (evStr1, evStr2, evStr3, evStr4, evStr5) +// +// will return a single stream that write goes to the first + +exports ['map will not call end until the callback'] = function (test) { + + var ticker = es.map(function (data, cb) { + process.nextTick(function () { + cb(null, data * 2) + }) + }) + + spec(ticker).through().validateOnExit() + + ticker.write('x') + ticker.end() + + ticker.on('end', function () { + test.done() + }) +} + + +exports ['emit error thrown'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , mapper = + es.map(function () { + throw err + }) + + mapper.on('error', function (_err) { + it(_err).equal(err) + test.done() + }) + +// onExit(spec(mapper).basic().validate) +//need spec that says stream may error. + + mapper.write('hello') + +} + +exports ['emit error calledback'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , mapper = + es.map(function (data, callback) { + callback(err) + }) + + mapper.on('error', function (_err) { + it(_err).equal(err) + test.done() + }) + + mapper.write('hello') + +} + +exports ['do not emit drain if not paused'] = function (test) { + + var map = es.map(function (data, callback) { + u.delay(callback)(null, 1) + return true + }) + + spec(map).through().pausable().validateOnExit() + + map.on('drain', function () { + it(false).ok('should not emit drain unless the stream is paused') + }) + + it(map.write('hello')).equal(true) + it(map.write('hello')).equal(true) + it(map.write('hello')).equal(true) + setTimeout(function () {map.end()},10) + map.on('end', test.done) +} + +exports ['emits drain if paused, when all '] = function (test) { + var active = 0 + var drained = false + var map = es.map(function (data, callback) { + active ++ + u.delay(function () { + active -- + callback(null, 1) + })() + console.log('WRITE', false) + return false + }) + + spec(map).through().validateOnExit() + + map.on('drain', function () { + drained = true + it(active).equal(0, 'should emit drain when all maps are done') + }) + + it(map.write('hello')).equal(false) + it(map.write('hello')).equal(false) + it(map.write('hello')).equal(false) + + process.nextTick(function () {map.end()},10) + + map.on('end', function () { + console.log('end') + it(drained).ok('shoud have emitted drain before end') + test.done() + }) + +} + +exports ['map applied to a stream with filtering'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + + var doubler = es.map(function (data, callback) { + if (data % 2) + callback(null, data * 2) + else + callback() + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.filter(function (j) { + return j % 2 + }).map(function (j) { + return j * 2 + })) + test.done() + }) + + spec(doubler).through().validateOnExit() + + writeArray(input, doubler) + +} + +exports ['simple mapSync applied to a stream'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + + var doubler = es.mapSync(function (data) { + return data * 2 + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.map(function (j) { + return j * 2 + })) + test.done() + }) + + spec(doubler).through().validateOnExit() + + writeArray(input, doubler) + +} + +exports ['mapSync applied to a stream with filtering'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + + var doubler = es.mapSync(function (data) { + if (data % 2) + return data * 2 + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.filter(function (j) { + return j % 2 + }).map(function (j) { + return j * 2 + })) + test.done() + }) + + spec(doubler).through().validateOnExit() + + writeArray(input, doubler) + +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js new file mode 100644 index 0000000..6d5fb6b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js @@ -0,0 +1,86 @@ +/* + assert that data is called many times + assert that end is called eventually + + assert that when stream enters pause state, + on drain is emitted eventually. +*/ + +var es = require('..') +var it = require('it-is').style('colour') +var spec = require('stream-spec') + +exports['simple stream'] = function (test) { + + var stream = es.through() + var x = spec(stream).basic().pausable() + + stream.write(1) + stream.write(1) + stream.pause() + stream.write(1) + stream.resume() + stream.write(1) + stream.end(2) //this will call write() + + process.nextTick(function (){ + x.validate() + test.done() + }) +} + +exports['throw on write when !writable'] = function (test) { + + var stream = es.through() + var x = spec(stream).basic().pausable() + + stream.write(1) + stream.write(1) + stream.end(2) //this will call write() + stream.write(1) //this will be throwing..., but the spec will catch it. + + process.nextTick(function () { + x.validate() + test.done() + }) + +} + +exports['end fast'] = function (test) { + + var stream = es.through() + var x = spec(stream).basic().pausable() + + stream.end() //this will call write() + + process.nextTick(function () { + x.validate() + test.done() + }) + +} + + +/* + okay, that was easy enough, whats next? + + say, after you call paused(), write should return false + until resume is called. + + simple way to implement this: + write must return !paused + after pause() paused = true + after resume() paused = false + + on resume, if !paused drain is emitted again. + after drain, !paused + + there are lots of subtle ordering bugs in streams. + + example, set !paused before emitting drain. + + the stream api is stateful. +*/ + + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js new file mode 100644 index 0000000..7d44bac --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js @@ -0,0 +1,47 @@ +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + , join = require('path').join + , fs = require('fs') + , Stream = require('stream').Stream + , spec = require('stream-spec') + +exports ['es.split() works like String#split'] = function (test) { + var readme = join(__filename) + , expected = fs.readFileSync(readme, 'utf-8').split('\n') + , cs = es.split() + , actual = [] + , ended = false + , x = spec(cs).through() + + var a = new Stream () + + a.write = function (l) { + actual.push(l.trim()) + } + a.end = function () { + + ended = true + expected.forEach(function (v,k) { + //String.split will append an empty string '' + //if the string ends in a split pattern. + //es.split doesn't which was breaking this test. + //clearly, appending the empty string is correct. + //tests are passing though. which is the current job. + if(v) + it(actual[k]).like(v) + }) + //give the stream time to close + process.nextTick(function () { + test.done() + x.validate() + }) + } + a.writable = true + + fs.createReadStream(readme, {flags: 'r'}).pipe(cs) + cs.pipe(a) + +} + +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js new file mode 100644 index 0000000..d158185 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js @@ -0,0 +1,15 @@ + + + +var es = require('../') + +exports['handle buffer'] = function (t) { + + + es.stringify().on('data', function (d) { + t.equal(d.trim(), JSON.stringify('HELLO')) + t.end() + }).write(new Buffer('HELLO')) + +} +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js new file mode 100644 index 0000000..5d705de --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js @@ -0,0 +1,31 @@ + +var es = require('../') + , it = require('it-is').style('colour') + , d = require('ubelt') + +exports ['write an array'] = function (test) { + + var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 + + var writer = es.writeArray(function (err, array){ + if(err) throw err //unpossible + it(array).deepEqual(readThis) + test.done() + }) + + d.each(readThis, writer.write.bind(writer)) + writer.end() + +} + + +exports ['writer is writable, but not readable'] = function (test) { + var reader = es.writeArray(function () {}) + it(reader).has({ + readable: false, + writable: true + }) + + test.done() +} +require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/eyes/LICENSE b/Challenge/seokahi/010.star/node_modules/eyes/LICENSE new file mode 100644 index 0000000..a1edd93 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 cloudhead + +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/Challenge/seokahi/010.star/node_modules/eyes/Makefile b/Challenge/seokahi/010.star/node_modules/eyes/Makefile new file mode 100644 index 0000000..a121dea --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/Makefile @@ -0,0 +1,4 @@ +test: + @@node test/eyes-test.js + +.PHONY: test diff --git a/Challenge/seokahi/010.star/node_modules/eyes/README.md b/Challenge/seokahi/010.star/node_modules/eyes/README.md new file mode 100644 index 0000000..c4f6f76 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/README.md @@ -0,0 +1,73 @@ +eyes +==== + +a customizable value inspector for Node.js + +synopsis +-------- + +I was tired of looking at cluttered output in the console -- something needed to be done, +`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. +So I decided to have some fun. _eyes_ were born. + +![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif) + +_example of the output of a user-customized eyes.js inspector_ + +*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals. + +usage +----- + + var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); + + inspect(something); // inspect with the settings passed to `inspector` + +or + + var eyes = require('eyes'); + + eyes.inspect(something); // inspect with the default settings + +you can pass a _label_ to `inspect()`, to keep track of your inspections: + + eyes.inspect(something, "a random value"); + +If you want to return the output of eyes without printing it, you can set it up this way: + + var inspect = require('eyes').inspector({ stream: null }); + + sys.puts(inspect({ something: 42 })); + +customization +------------- + +These are the default styles and settings used by _eyes_. + + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + + pretty: true, // Indent object literals + hideFunctions: false, // Don't output functions at all + stream: process.stdout, // Stream to write to, or null + maxLength: 2048 // Truncate output if longer + +You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`. + + var inspect = require('eyes').inspector({ + styles: { + all: 'magenta', + special: 'bold' + }, + maxLength: 512 + }); + diff --git a/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js b/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js new file mode 100644 index 0000000..10d964b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js @@ -0,0 +1,236 @@ +// +// Eyes.js - a customizable value inspector for Node.js +// +// usage: +// +// var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); +// inspect(something); // inspect with the settings passed to `inspector` +// +// or +// +// var eyes = require('eyes'); +// eyes.inspect(something); // inspect with the default settings +// +var eyes = exports, + stack = []; + +eyes.defaults = { + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + pretty: true, // Indent object literals + hideFunctions: false, + showHidden: false, + stream: process.stdout, + maxLength: 2048 // Truncate output if longer +}; + +// Return a curried inspect() function, with the `options` argument filled in. +eyes.inspector = function (options) { + var that = this; + return function (obj, label, opts) { + return that.inspect.call(that, obj, label, + merge(options || {}, opts || {})); + }; +}; + +// If we have a `stream` defined, use it to print a styled string, +// if not, we just return the stringified object. +eyes.inspect = function (obj, label, options) { + options = merge(this.defaults, options || {}); + + if (options.stream) { + return this.print(stringify(obj, options), label, options); + } else { + return stringify(obj, options) + (options.styles ? '\033[39m' : ''); + } +}; + +// Output using the 'stream', and an optional label +// Loop through `str`, and truncate it after `options.maxLength` has been reached. +// Because escape sequences are, at this point embeded within +// the output string, we can't measure the length of the string +// in a useful way, without separating what is an escape sequence, +// versus a printable character (`c`). So we resort to counting the +// length manually. +eyes.print = function (str, label, options) { + for (var c = 0, i = 0; i < str.length; i++) { + if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5 + else if (c === options.maxLength) { + str = str.slice(0, i - 1) + '…'; + break; + } else { c++ } + } + return options.stream.write.call(options.stream, (label ? + this.stylize(label, options.styles.label, options.styles) + ': ' : '') + + this.stylize(str, options.styles.all, options.styles) + '\033[0m' + "\n"); +}; + +// Apply a style to a string, eventually, +// I'd like this to support passing multiple +// styles. +eyes.stylize = function (str, style, styles) { + var codes = { + 'bold' : [1, 22], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'cyan' : [36, 39], + 'magenta' : [35, 39], + 'blue' : [34, 39], + 'yellow' : [33, 39], + 'green' : [32, 39], + 'red' : [31, 39], + 'grey' : [90, 39] + }, endCode; + + if (style && codes[style]) { + endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0] + : codes[style][1]; + return '\033[' + codes[style][0] + 'm' + str + + '\033[' + endCode + 'm'; + } else { return str } +}; + +// Convert any object to a string, ready for output. +// When an 'array' or an 'object' are encountered, they are +// passed to specialized functions, which can then recursively call +// stringify(). +function stringify(obj, options) { + var that = this, stylize = function (str, style) { + return eyes.stylize(str, options.styles[style], options.styles) + }, index, result; + + if ((index = stack.indexOf(obj)) !== -1) { + return stylize(new(Array)(stack.length - index + 1).join('.'), 'special'); + } + stack.push(obj); + + result = (function (obj) { + switch (typeOf(obj)) { + case "string" : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'" + : '"' + obj + '"'); + return stylize(obj, 'string'); + case "regexp" : return stylize('/' + obj.source + '/', 'regexp'); + case "number" : return stylize(obj + '', 'number'); + case "function" : return options.stream ? stylize("Function", 'other') : '[Function]'; + case "null" : return stylize("null", 'special'); + case "undefined": return stylize("undefined", 'special'); + case "boolean" : return stylize(obj + '', 'bool'); + case "date" : return stylize(obj.toUTCString()); + case "array" : return stringifyArray(obj, options, stack.length); + case "object" : return stringifyObject(obj, options, stack.length); + } + })(obj); + + stack.pop(); + return result; +}; + +// Escape invisible characters in a string +function stringifyString (str, options) { + return str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/[\u0001-\u001F]/g, function (match) { + return '\\0' + match[0].charCodeAt(0).toString(8); + }); +} + +// Convert an array to a string, such as [1, 2, 3]. +// This function calls stringify() for each of the elements +// in the array. +function stringifyArray(ary, options, level) { + var out = []; + var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) { + return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) || + (Array.isArray(o) && o.length > 0); + })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + for (var i = 0; i < ary.length; i++) { + out.push(stringify(ary[i], options)); + } + + if (out.length === 0) { + return '[]'; + } else { + return '[' + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + ']'; + } +}; + +// Convert an object to a string, such as {a: 1}. +// This function calls stringify() for each of its values, +// and does not output functions or prototype values. +function stringifyObject(obj, options, level) { + var out = []; + var pretty = options.pretty && (Object.keys(obj).length > 2 || + Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj); + keys.forEach(function (k) { + if (Object.prototype.hasOwnProperty.call(obj, k) + && !(obj[k] instanceof Function && options.hideFunctions)) { + out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' + + stringify(obj[k], options)); + } + }); + + if (out.length === 0) { + return '{}'; + } else { + return "{" + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + "}"; + } +}; + +// A better `typeof` +function typeOf(value) { + var s = typeof(value), + types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; + + if (s === 'object' || s === 'function') { + if (value) { + types.forEach(function (t) { + if (value instanceof t) { s = t.name.toLowerCase() } + }); + } else { s = 'null' } + } + return s; +} + +function merge(/* variable args */) { + var objs = Array.prototype.slice.call(arguments); + var target = {}; + + objs.forEach(function (o) { + Object.keys(o).forEach(function (k) { + if (k === 'styles') { + if (! o.styles) { + target.styles = false; + } else { + target.styles = {} + for (var s in o.styles) { + target.styles[s] = o.styles[s]; + } + } + } else { + target[k] = o[k]; + } + }); + }); + return target; +} + diff --git a/Challenge/seokahi/010.star/node_modules/eyes/package.json b/Challenge/seokahi/010.star/node_modules/eyes/package.json new file mode 100644 index 0000000..bc40240 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/package.json @@ -0,0 +1,14 @@ +{ + "name" : "eyes", + "description" : "a customizable value inspector", + "url" : "http://github.com/cloudhead/eyes.js", + "keywords" : ["inspector", "debug", "inspect", "print"], + "author" : "Alexis Sellier ", + "contributors" : [{ "name": "Charlie Robbins", "email": "charlie@nodejitsu.com" }], + "licenses" : ["MIT"], + "main" : "./lib/eyes", + "version" : "0.1.8", + "scripts" : { "test": "node test/*-test.js" }, + "directories" : { "lib": "./lib", "test": "./test" }, + "engines" : { "node": "> 0.1.90" } +} diff --git a/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js b/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js new file mode 100644 index 0000000..1f9606a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js @@ -0,0 +1,56 @@ +var util = require('util'); +var eyes = require('../lib/eyes'); + +eyes.inspect({ + number: 42, + string: "John Galt", + regexp: /[a-z]+/, + array: [99, 168, 'x', {}], + func: function () {}, + bool: false, + nil: null, + undef: undefined, + object: {attr: []} +}, "native types"); + +eyes.inspect({ + number: new(Number)(42), + string: new(String)("John Galt"), + regexp: new(RegExp)(/[a-z]+/), + array: new(Array)(99, 168, 'x', {}), + bool: new(Boolean)(false), + object: new(Object)({attr: []}), + date: new(Date) +}, "wrapped types"); + +var obj = {}; +obj.that = { self: obj }; +obj.self = obj; + +eyes.inspect(obj, "circular object"); +eyes.inspect({hello: 'moto'}, "small object"); +eyes.inspect({hello: new(Array)(6) }, "big object"); +eyes.inspect(["hello 'world'", 'hello "world"'], "quotes"); +eyes.inspect({ + recommendations: [{ + id: 'a7a6576c2c822c8e2bd81a27e41437d8', + key: [ 'spree', 3.764316258020699 ], + value: { + _id: 'a7a6576c2c822c8e2bd81a27e41437d8', + _rev: '1-2e2d2f7fd858c4a5984bcf809d22ed98', + type: 'domain', + domain: 'spree', + weight: 3.764316258020699, + product_id: 30 + } + }] +}, 'complex'); + +eyes.inspect([null], "null in array"); + +var inspect = eyes.inspector({ stream: null }); + +util.puts(inspect('something', "something")); +util.puts(inspect("something else")); + +util.puts(inspect(["no color"], null, { styles: false })); diff --git a/Challenge/seokahi/010.star/node_modules/from/.npmignore b/Challenge/seokahi/010.star/node_modules/from/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/Challenge/seokahi/010.star/node_modules/from/.travis.yml b/Challenge/seokahi/010.star/node_modules/from/.travis.yml new file mode 100644 index 0000000..76db03f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "node" + - "6" + - "5" + - "4" diff --git a/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 b/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 new file mode 100644 index 0000000..6366c04 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 @@ -0,0 +1,15 @@ +Apache License, Version 2.0 + +Copyright (c) 2011 Dominic Tarr + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT b/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT new file mode 100644 index 0000000..6eafbd7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2011 Dominic Tarr + +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/Challenge/seokahi/010.star/node_modules/from/index.js b/Challenge/seokahi/010.star/node_modules/from/index.js new file mode 100644 index 0000000..e3e7bfd --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/index.js @@ -0,0 +1,68 @@ + +'use strict'; + +var Stream = require('stream') + +// from +// +// a stream that reads from an source. +// source may be an array, or a function. +// from handles pause behaviour for you. + +module.exports = +function from (source) { + if(Array.isArray(source)) { + var source_index = 0, source_len = source.length; + return from (function (i) { + if(source_index < source_len) + this.emit('data', source[source_index++]) + else + this.emit('end') + return true + }) + } + var s = new Stream(), i = 0 + s.ended = false + s.started = false + s.readable = true + s.writable = false + s.paused = false + s.ended = false + s.pause = function () { + s.started = true + s.paused = true + } + function next () { + s.started = true + if(s.ended) return + while(!s.ended && !s.paused && source.call(s, i++, function () { + if(!s.ended && !s.paused) + process.nextTick(next); + })) + ; + } + s.resume = function () { + s.started = true + s.paused = false + next() + } + s.on('end', function () { + s.ended = true + s.readable = false + process.nextTick(s.destroy) + }) + s.destroy = function () { + s.ended = true + s.emit('close') + } + /* + by default, the stream will start emitting at nextTick + if you want, you can pause it, after pipeing. + you can also resume before next tick, and that will also + work. + */ + process.nextTick(function () { + if(!s.started) s.resume() + }) + return s +} diff --git a/Challenge/seokahi/010.star/node_modules/from/package.json b/Challenge/seokahi/010.star/node_modules/from/package.json new file mode 100644 index 0000000..a265d84 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/package.json @@ -0,0 +1,26 @@ +{ + "name": "from", + "version": "0.1.7", + "description": "Easy way to make a Readable Stream", + "main": "index.js", + "scripts": { + "test": "asynct test/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/from.git" + }, + "keywords": [ + "stream", + "streams", + "readable", + "easy" + ], + "devDependencies": { + "asynct": "1", + "stream-spec": "0", + "assertions": "~2.3.0" + }, + "author": "Dominic Tarr (dominictarr.com)", + "license": "MIT" +} diff --git a/Challenge/seokahi/010.star/node_modules/from/readme.markdown b/Challenge/seokahi/010.star/node_modules/from/readme.markdown new file mode 100644 index 0000000..c84fc9b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/readme.markdown @@ -0,0 +1,40 @@ +[![TravisCI Build Status](https://travis-ci.org/nmhnmh/from.svg?branch=master)](https://travis-ci.org/nmhnmh/from) + +# from + +An easy way to create a `readable Stream`. + +## from(function getChunk(count, next)) + +from takes a `getChunk` function and returns a stream. + +`getChunk` is called again and again, after each time the user calls `next()`, +until the user emits `'end'` + +if `pause()` is called, the `getChunk` won't be called again untill `resume()` is called. + + +```js +var from = require('from') + +var stream = + from(function getChunk(count, next) { + //do some sort of data + this.emit('data', whatever) + + if(itsOver) + this.emit('end') + + //ready to handle the next chunk + next() + //or, if it's sync: + return true + }) +``` + +## from(array) + +from also takes an `Array` whose elements it emits one after another. + +## License +MIT / Apache2 diff --git a/Challenge/seokahi/010.star/node_modules/from/test/index.js b/Challenge/seokahi/010.star/node_modules/from/test/index.js new file mode 100644 index 0000000..5e2f161 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/from/test/index.js @@ -0,0 +1,210 @@ +var from = require('..') +var spec = require('stream-spec') +var a = require('assertions') + +function read(stream, callback) { + var actual = [] + stream.on('data', function (data) { + actual.push(data) + }) + stream.once('end', function () { + callback(null, actual) + }) + stream.once('error', function (err) { + callback(err) + }) +} + +function pause(stream) { + stream.on('data', function () { + if(Math.random() > 0.1) return + stream.pause() + process.nextTick(function () { + stream.resume() + }) + }) +} + +exports['inc'] = function (test) { + + var fs = from(function (i) { + this.emit('data', i) + if(i >= 99) + return this.emit('end') + return true + }) + + spec(fs).readable().validateOnExit() + + read(fs, function (err, arr) { + test.equal(arr.length, 100) + test.done() + }) +} + +exports['inc - async'] = function (test) { + + var fs = from(function (i, next) { + this.emit('data', i) + if(i >= 99) + return this.emit('end') + next(); + }) + + spec(fs).readable().validateOnExit() + + read(fs, function (err, arr) { + test.equal(arr.length, 100) + test.done() + }) +} + +exports['large stream - from an array'] = function (test) { + + var l = 100000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var fs = from(expected.slice()) + + spec(fs).readable().validateOnExit() + + read(fs, function (err, arr) { + a.deepEqual(arr, expected) + test.done() + }) +} + +exports['large stream - callback return true'] = function (test) { + + var fs = from(function (i, next) { + this.emit('data', i) + if(i >= 99999) + return this.emit('end') + return true; + }) + + spec(fs).readable().validateOnExit() + + read(fs, function (err, arr) { + test.equal(arr.length, 100000) + test.done() + }) +} + +exports['large stream - callback call next()'] = function (test) { + + var fs = from(function (i, next) { + this.emit('data', i) + if(i >= 99999) + return this.emit('end') + next(); + }) + + spec(fs).readable().validateOnExit() + + read(fs, function (err, arr) { + test.equal(arr.length, 100000) + test.done() + }) +} + +exports['simple'] = function (test) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = from(expected.slice()) + + spec(t) + .readable() + .pausable({strict: true}) + .validateOnExit() + + read(t, function (err, actual) { + if(err) test.error(err) //fail + a.deepEqual(actual, expected) + test.done() + }) + +} + +exports['simple pausable'] = function (test) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = from(expected.slice()) + + spec(t) + .readable() + .pausable({strict: true}) + .validateOnExit() + + pause(t) + + read(t, function (err, actual) { + if(err) test.error(err) //fail + a.deepEqual(actual, expected) + test.done() + }) + +} + +exports['simple (not strictly pausable) setTimeout'] = function (test) { + + var l = 10 + , expected = [] + while(l--) expected.push(l * Math.random()) + + + var _expected = expected.slice() + var t = from(function (i, n) { + var self = this + setTimeout(function () { + if(_expected.length) + self.emit('data', _expected.shift()) + else + if(!self.ended) + self.emit('end') + n() + }, 3) + }) + + /* + using from in this way will not be strictly pausable. + it could be extended to buffer outputs, but I think a better + way would be to use a PauseStream that implements strict pause. + */ + + spec(t) + .readable() + .pausable({strict: false }) + .validateOnExit() + + //pause(t) + var paused = false + var i = setInterval(function () { + if(!paused) t.pause() + else t.resume() + paused = !paused + }, 2) + + t.on('end', function () { + clearInterval(i) + }) + + read(t, function (err, actual) { + if(err) test.error(err) //fail + a.deepEqual(actual, expected) + test.done() + }) + +} + + diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc b/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc new file mode 100644 index 0000000..c8ef3ca --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.npmignore b/Challenge/seokahi/010.star/node_modules/isstream/.npmignore new file mode 100644 index 0000000..aa1ec1e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/.npmignore @@ -0,0 +1 @@ +*.tgz diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml b/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml new file mode 100644 index 0000000..1fec2ab --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" +branches: + only: + - master +notifications: + email: + - rod@vagg.org +script: npm test diff --git a/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md b/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md new file mode 100644 index 0000000..43f7153 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) +===================== + +Copyright (c) 2015 Rod Vagg +--------------------------- + +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/Challenge/seokahi/010.star/node_modules/isstream/README.md b/Challenge/seokahi/010.star/node_modules/isstream/README.md new file mode 100644 index 0000000..06770e8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/README.md @@ -0,0 +1,66 @@ +# isStream + +[![Build Status](https://secure.travis-ci.org/rvagg/isstream.png)](http://travis-ci.org/rvagg/isstream) + +**Test if an object is a `Stream`** + +[![NPM](https://nodei.co/npm/isstream.svg)](https://nodei.co/npm/isstream/) + +The missing `Stream.isStream(obj)`: determine if an object is standard Node.js `Stream`. Works for Node-core `Stream` objects (for 0.8, 0.10, 0.11, and in theory, older and newer versions) and all versions of **[readable-stream](https://github.com/isaacs/readable-stream)**. + +## Usage: + +```js +var isStream = require('isstream') +var Stream = require('stream') + +isStream(new Stream()) // true + +isStream({}) // false + +isStream(new Stream.Readable()) // true +isStream(new Stream.Writable()) // true +isStream(new Stream.Duplex()) // true +isStream(new Stream.Transform()) // true +isStream(new Stream.PassThrough()) // true +``` + +## But wait! There's more! + +You can also test for `isReadable(obj)`, `isWritable(obj)` and `isDuplex(obj)` to test for implementations of Streams2 (and Streams3) base classes. + +```js +var isReadable = require('isstream').isReadable +var isWritable = require('isstream').isWritable +var isDuplex = require('isstream').isDuplex +var Stream = require('stream') + +isReadable(new Stream()) // false +isWritable(new Stream()) // false +isDuplex(new Stream()) // false + +isReadable(new Stream.Readable()) // true +isReadable(new Stream.Writable()) // false +isReadable(new Stream.Duplex()) // true +isReadable(new Stream.Transform()) // true +isReadable(new Stream.PassThrough()) // true + +isWritable(new Stream.Readable()) // false +isWritable(new Stream.Writable()) // true +isWritable(new Stream.Duplex()) // true +isWritable(new Stream.Transform()) // true +isWritable(new Stream.PassThrough()) // true + +isDuplex(new Stream.Readable()) // false +isDuplex(new Stream.Writable()) // false +isDuplex(new Stream.Duplex()) // true +isDuplex(new Stream.Transform()) // true +isDuplex(new Stream.PassThrough()) // true +``` + +*Reminder: when implementing your own streams, please [use **readable-stream** rather than core streams](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).* + + +## License + +**isStream** is Copyright (c) 2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details. diff --git a/Challenge/seokahi/010.star/node_modules/isstream/isstream.js b/Challenge/seokahi/010.star/node_modules/isstream/isstream.js new file mode 100644 index 0000000..a1d104a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/isstream.js @@ -0,0 +1,27 @@ +var stream = require('stream') + + +function isStream (obj) { + return obj instanceof stream.Stream +} + + +function isReadable (obj) { + return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' +} + + +function isWritable (obj) { + return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' +} + + +function isDuplex (obj) { + return isReadable(obj) && isWritable(obj) +} + + +module.exports = isStream +module.exports.isReadable = isReadable +module.exports.isWritable = isWritable +module.exports.isDuplex = isDuplex diff --git a/Challenge/seokahi/010.star/node_modules/isstream/package.json b/Challenge/seokahi/010.star/node_modules/isstream/package.json new file mode 100644 index 0000000..9ee8bf8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/package.json @@ -0,0 +1,33 @@ +{ + "name": "isstream", + "version": "0.1.2", + "description": "Determine if an object is a Stream", + "main": "isstream.js", + "scripts": { + "test": "tar --xform 's/^package/readable-stream-1.0/' -zxf readable-stream-1.0.*.tgz && tar --xform 's/^package/readable-stream-1.1/' -zxf readable-stream-1.1.*.tgz && node test.js; rm -rf readable-stream-1.?/" + }, + "repository": { + "type": "git", + "url": "https://github.com/rvagg/isstream.git" + }, + "keywords": [ + "stream", + "type", + "streams", + "readable-stream", + "hippo" + ], + "devDependencies": { + "tape": "~2.12.3", + "core-util-is": "~1.0.0", + "isarray": "0.0.1", + "string_decoder": "~0.10.x", + "inherits": "~2.0.1" + }, + "author": "Rod Vagg ", + "license": "MIT", + "bugs": { + "url": "https://github.com/rvagg/isstream/issues" + }, + "homepage": "https://github.com/rvagg/isstream" +} diff --git a/Challenge/seokahi/010.star/node_modules/isstream/test.js b/Challenge/seokahi/010.star/node_modules/isstream/test.js new file mode 100644 index 0000000..8c950c5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/isstream/test.js @@ -0,0 +1,168 @@ +var tape = require('tape') + , EE = require('events').EventEmitter + , util = require('util') + + + , isStream = require('./') + , isReadable = require('./').isReadable + , isWritable = require('./').isWritable + , isDuplex = require('./').isDuplex + + , CoreStreams = require('stream') + , ReadableStream10 = require('./readable-stream-1.0/') + , ReadableStream11 = require('./readable-stream-1.1/') + + +function test (pass, type, stream) { + tape('isStream(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isStream(stream), type) + }) +} + + +function testReadable (pass, type, stream) { + tape('isReadable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isReadable(stream), type) + }) +} + + +function testWritable (pass, type, stream) { + tape('isWritable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isWritable(stream), type) + }) +} + + +function testDuplex (pass, type, stream) { + tape('isDuplex(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isDuplex(stream), type) + }) +} + + +[ undefined, null, '', true, false, 0, 1, 1.0, 'string', {}, function foo () {} ].forEach(function (o) { + test(false, 'non-stream / primitive: ' + (JSON.stringify(o) || (o && o.toString()) || o), o) +}) + + +test(false, 'fake stream obj', { pipe: function () {} }) + + +;(function () { + + // looks like a stream! + + function Stream () { + EE.call(this) + } + util.inherits(Stream, EE) + Stream.prototype.pipe = function () {} + Stream.Stream = Stream + + test(false, 'fake stream "new Stream()"', new Stream()) + +}()) + + +test(true, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +test(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +test(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +test(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +test(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +test(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +test(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +test(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +test(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +test(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +test(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +test(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +test(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +test(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +test(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +test(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testReadable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testReadable(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testReadable(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testReadable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testReadable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testReadable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testReadable(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testReadable(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testReadable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testReadable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testReadable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testReadable(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testReadable(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testReadable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testReadable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testReadable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testWritable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testWritable(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testWritable(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testWritable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testWritable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testWritable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testWritable(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testWritable(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testWritable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testWritable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testWritable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testWritable(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testWritable(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testWritable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testWritable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testWritable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testDuplex(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testDuplex(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testDuplex(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testDuplex(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testDuplex(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testDuplex(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testDuplex(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testDuplex(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testDuplex(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testDuplex(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testDuplex(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testDuplex(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testDuplex(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testDuplex(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testDuplex(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testDuplex(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +;[ CoreStreams, ReadableStream10, ReadableStream11 ].forEach(function (p) { + [ 'Stream', 'Readable', 'Writable', 'Duplex', 'Transform', 'PassThrough' ].forEach(function (k) { + if (!p[k]) + return + + function SubStream () { + p[k].call(this) + } + util.inherits(SubStream, p[k]) + + test(true, 'Stream subclass: ' + p.name + '.' + k, new SubStream()) + + }) +}) + + + diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE b/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md b/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md new file mode 100644 index 0000000..6bce2d6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md @@ -0,0 +1,18 @@ +# lodash.assign v4.2.0 + +The [lodash](https://lodash.com/) method `_.assign` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.assign +``` + +In Node.js: +```js +var assign = require('lodash.assign'); +``` + +See the [documentation](https://lodash.com/docs#assign) or [package source](https://github.com/lodash/lodash/blob/4.2.0-npm-packages/lodash.assign) for more details. diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js b/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js new file mode 100644 index 0000000..8b007bc --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js @@ -0,0 +1,637 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ +var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } +}); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = assign; diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json b/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json new file mode 100644 index 0000000..78672ea --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json @@ -0,0 +1,17 @@ +{ + "name": "lodash.assign", + "version": "4.2.0", + "description": "The lodash method `_.assign` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "keywords": "lodash-modularized, assign", + "author": "John-David Dalton (http://allyoucanleet.com/)", + "contributors": [ + "John-David Dalton (http://allyoucanleet.com/)", + "Blaine Bublitz (https://github.com/phated)", + "Mathias Bynens (https://mathiasbynens.be/)" + ], + "repository": "lodash/lodash", + "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" } +} diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore b/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore new file mode 100644 index 0000000..13abef4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore @@ -0,0 +1,3 @@ +node_modules +node_modules/* +npm_debug.log diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml b/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml new file mode 100644 index 0000000..895dbd3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE b/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE new file mode 100644 index 0000000..2af26fe --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2011 Dominic Tarr + +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/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js b/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js new file mode 100644 index 0000000..ab07398 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js @@ -0,0 +1,26 @@ + +var inspect = require('util').inspect + +if(!module.parent) { + var map = require('..') //load map-stream + var es = require('event-stream') //load event-stream + es.pipe( //pipe joins streams together + process.openStdin(), //open stdin + es.split(), //split stream to break on newlines + map(function (data, callback) { //turn this async function into a stream + var j + try { + j = JSON.parse(data) //try to parse input into json + } catch (err) { + return callback(null, data) //if it fails just pass it anyway + } + callback(null, inspect(j)) //render it nicely + }), + process.stdout // pipe it to stdout ! + ) + } + +// run this +// +// curl -sS registry.npmjs.org/event-stream | node pretty.js +// diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/index.js b/Challenge/seokahi/010.star/node_modules/map-stream/index.js new file mode 100644 index 0000000..cbf3970 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/index.js @@ -0,0 +1,144 @@ +//filter will reemit the data if cb(err,pass) pass is truthy + +// reduce is more tricky +// maybe we want to group the reductions or emit progress updates occasionally +// the most basic reduce just emits one 'data' event after it has recieved 'end' + + +var Stream = require('stream').Stream + + +//create an event stream and apply function to each .write +//emitting each response as data +//unless it's an empty callback + +module.exports = function (mapper, opts) { + + var stream = new Stream() + , inputs = 0 + , outputs = 0 + , ended = false + , paused = false + , destroyed = false + , lastWritten = 0 + , inNext = false + + opts = opts || {}; + var errorEventName = opts.failures ? 'failure' : 'error'; + + // Items that are not ready to be written yet (because they would come out of + // order) get stuck in a queue for later. + var writeQueue = {} + + stream.writable = true + stream.readable = true + + function queueData (data, number) { + var nextToWrite = lastWritten + 1 + + if (number === nextToWrite) { + // If it's next, and its not undefined write it + if (data !== undefined) { + stream.emit.apply(stream, ['data', data]) + } + lastWritten ++ + nextToWrite ++ + } else { + // Otherwise queue it for later. + writeQueue[number] = data + } + + // If the next value is in the queue, write it + if (writeQueue.hasOwnProperty(nextToWrite)) { + var dataToWrite = writeQueue[nextToWrite] + delete writeQueue[nextToWrite] + return queueData(dataToWrite, nextToWrite) + } + + outputs ++ + if(inputs === outputs) { + if(paused) paused = false, stream.emit('drain') //written all the incoming events + if(ended) end() + } + } + + function next (err, data, number) { + if(destroyed) return + inNext = true + + if (!err || opts.failures) { + queueData(data, number) + } + + if (err) { + stream.emit.apply(stream, [ errorEventName, err ]); + } + + inNext = false; + } + + // Wrap the mapper function by calling its callback with the order number of + // the item in the stream. + function wrappedMapper (input, number, callback) { + return mapper.call(null, input, function(err, data){ + callback(err, data, number) + }) + } + + stream.write = function (data) { + if(ended) throw new Error('map stream is not writable') + inNext = false + inputs ++ + + try { + //catch sync errors and handle them like async errors + var written = wrappedMapper(data, inputs, next) + paused = (written === false) + return !paused + } catch (err) { + //if the callback has been called syncronously, and the error + //has occured in an listener, throw it again. + if(inNext) + throw err + next(err) + return !paused + } + } + + function end (data) { + //if end was called with args, write it, + ended = true //write will emit 'end' if ended is true + stream.writable = false + if(data !== undefined) { + return queueData(data, inputs) + } else if (inputs == outputs) { //wait for processing + stream.readable = false, stream.emit('end'), stream.destroy() + } + } + + stream.end = function (data) { + if(ended) return + end(data) + } + + stream.destroy = function () { + ended = destroyed = true + stream.writable = stream.readable = paused = false + process.nextTick(function () { + stream.emit('close') + }) + } + stream.pause = function () { + paused = true + } + + stream.resume = function () { + paused = false + } + + return stream +} + + + + diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/package.json b/Challenge/seokahi/010.star/node_modules/map-stream/package.json new file mode 100644 index 0000000..91f46d7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/package.json @@ -0,0 +1,24 @@ +{ + "name": "map-stream", + "version": "0.0.7", + "license": "MIT", + "description": "construct pipes of streams of events", + "homepage": "http://github.com/dominictarr/map-stream", + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/map-stream.git" + }, + "dependencies": {}, + "devDependencies": { + "asynct": "*", + "it-is": "1", + "ubelt": "~2.9", + "stream-spec": "~0.2", + "event-stream": "~2.1", + "from": "0.0.2" + }, + "scripts": { + "test": "asynct test/" + }, + "author": "Dominic Tarr (http://dominictarr.com)" +} diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown new file mode 100644 index 0000000..1897158 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown @@ -0,0 +1,37 @@ +# MapStream + +Refactored out of [event-stream](https://github.com/dominictarr/event-stream) + +##map (asyncFunction[, options]) + +Create a through stream from an asyncronous function. + +``` js +var map = require('map-stream') + +map(function (data, callback) { + //transform data + // ... + callback(null, data) +}) + +``` + +Each map MUST call the callback. It may callback with data, with an error or with no arguments, + + * `callback()` drop this data. + this makes the map work like `filter`, + note:`callback(null,null)` is not the same, and will emit `null` + + * `callback(null, newData)` turn data into newData + + * `callback(error)` emit an error for this item. + +>Note: if a callback is not called, `map` will think that it is still being processed, +>every call must be answered or the stream will not know when to end. +> +>Also, if the callback is called more than once, every call but the first will be ignored. + +##Options + + * `failures` - `boolean` continue mapping even if error occured. On error `map-stream` will emit `failure` event. (default: `false`) diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js b/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js new file mode 100644 index 0000000..2b9a292 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js @@ -0,0 +1,318 @@ +'use strict'; + +var map = require('../') + , it = require('it-is') + , u = require('ubelt') + , spec = require('stream-spec') + , from = require('from') + , Stream = require('stream') + , es = require('event-stream') + +//REFACTOR THIS TEST TO USE es.readArray and es.writeArray + +function writeArray(array, stream) { + + array.forEach( function (j) { + stream.write(j) + }) + stream.end() + +} + +function readStream(stream, done) { + + var array = [] + stream.on('data', function (data) { + array.push(data) + }) + stream.on('error', done) + stream.on('end', function (data) { + done(null, array) + }) + +} + +//call sink on each write, +//and complete when finished. + +function pauseStream (prob, delay) { + var pauseIf = ( + 'number' == typeof prob + ? function () { + return Math.random() < prob + } + : 'function' == typeof prob + ? prob + : 0.1 + ) + var delayer = ( + !delay + ? process.nextTick + : 'number' == typeof delay + ? function (next) { setTimeout(next, delay) } + : delay + ) + + return es.through(function (data) { + if(!this.paused && pauseIf()) { + console.log('PAUSE STREAM PAUSING') + this.pause() + var self = this + delayer(function () { + console.log('PAUSE STREAM RESUMING') + self.resume() + }) + } + console.log("emit ('data', " + data + ')') + this.emit('data', data) + }) +} + +exports ['simple map applied to a stream'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + //create event stream from + + var doubler = map(function (data, cb) { + cb(null, data * 2) + }) + + spec(doubler).through().validateOnExit() + + //a map is only a middle man, so it is both readable and writable + + it(doubler).has({ + readable: true, + writable: true, + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.map(function (j) { + return j * 2 + })) +// process.nextTick(x.validate) + test.done() + }) + + writeArray(input, doubler) + +} + +exports ['stream comes back in the correct order'] = function (test) { + var input = [3, 2, 1] + + var delayer = map(function(data, cb){ + setTimeout(function () { + cb(null, data) + }, 100 * data) + }) + + readStream(delayer, function (err, output) { + it(output).deepEqual(input) + test.done() + }) + + writeArray(input, delayer) +} + +exports ['continues on error event with failures `true`'] = function (test) { + var input = [1, 2, 3] + + var delayer = map(function(data, cb){ + cb(new Error('Something gone wrong'), data) + }, { failures: true }) + + readStream(delayer, function (err, output) { + it(output).deepEqual(input) + test.done() + }) + + writeArray(input, delayer) +} + +exports['pipe two maps together'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + //create event stream from + function dd (data, cb) { + cb(null, data * 2) + } + var doubler1 = map(dd), doubler2 = map(dd) + + doubler1.pipe(doubler2) + + spec(doubler1).through().validateOnExit() + spec(doubler2).through().validateOnExit() + + readStream(doubler2, function (err, output) { + it(output).deepEqual(input.map(function (j) { + return j * 4 + })) + test.done() + }) + + writeArray(input, doubler1) + +} + +//next: +// +// test pause, resume and drian. +// + +// then make a pipe joiner: +// +// plumber (evStr1, evStr2, evStr3, evStr4, evStr5) +// +// will return a single stream that write goes to the first + +exports ['map will not call end until the callback'] = function (test) { + + var ticker = map(function (data, cb) { + process.nextTick(function () { + cb(null, data * 2) + }) + }) + + spec(ticker).through().validateOnExit() + + ticker.write('x') + ticker.end() + + ticker.on('end', function () { + test.done() + }) +} + +exports ['emit failures with opts.failures === `ture`'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , mapper = + map(function () { + throw err + }, { failures: true }) + + mapper.on('failure', function (_err) { + it(_err).equal(err) + test.done() + }) + + mapper.write('hello') + +} + +exports ['emit error thrown'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , mapper = + map(function () { + throw err + }) + + mapper.on('error', function (_err) { + it(_err).equal(err) + test.done() + }) + + mapper.write('hello') + +} + +exports ['emit error calledback'] = function (test) { + + var err = new Error('INTENSIONAL ERROR') + , mapper = + map(function (data, callback) { + callback(err) + }) + + mapper.on('error', function (_err) { + it(_err).equal(err) + test.done() + }) + + mapper.write('hello') + +} + +exports ['do not emit drain if not paused'] = function (test) { + + var maps = map(function (data, callback) { + u.delay(callback)(null, 1) + return true + }) + + spec(maps).through().pausable().validateOnExit() + + maps.on('drain', function () { + it(false).ok('should not emit drain unless the stream is paused') + }) + + it(maps.write('hello')).equal(true) + it(maps.write('hello')).equal(true) + it(maps.write('hello')).equal(true) + setTimeout(function () {maps.end()},10) + maps.on('end', test.done) +} + +exports ['emits drain if paused, when all '] = function (test) { + var active = 0 + var drained = false + var maps = map(function (data, callback) { + active ++ + u.delay(function () { + active -- + callback(null, 1) + })() + console.log('WRITE', false) + return false + }) + + spec(maps).through().validateOnExit() + + maps.on('drain', function () { + drained = true + it(active).equal(0, 'should emit drain when all maps are done') + }) + + it(maps.write('hello')).equal(false) + it(maps.write('hello')).equal(false) + it(maps.write('hello')).equal(false) + + process.nextTick(function () {maps.end()},10) + + maps.on('end', function () { + console.log('end') + it(drained).ok('shoud have emitted drain before end') + test.done() + }) + +} + +exports ['map applied to a stream with filtering'] = function (test) { + + var input = [1,2,3,7,5,3,1,9,0,2,4,6] + + var doubler = map(function (data, callback) { + if (data % 2) + callback(null, data * 2) + else + callback() + }) + + readStream(doubler, function (err, output) { + it(output).deepEqual(input.filter(function (j) { + return j % 2 + }).map(function (j) { + return j * 2 + })) + test.done() + }) + + spec(doubler).through().validateOnExit() + + writeArray(input, doubler) + +} + + diff --git a/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md b/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md new file mode 100644 index 0000000..468b0b7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md @@ -0,0 +1,98 @@ +Changelog +========= +## 1.3.3 / 2017-08-02 +- Fix `computeValue` not overriding group operator keys after resolving expression +- Added `$in`, `$objectToArray`, and `$arrayToObject` array aggregation operators +- Minor refactoring + +## 1.3.2 / 2017-07-28 +- Restore `setup` function. https://github.com/kofrasa/mingo/issues/56 + +## 1.3.1 / 2017-07-24 +- Replaced core-js because it bloats compiled library by 10K i.e. ~24% +- Fix #55 + +## 1.3.0 / 2017-07-23 +- Support ES6 modules +- Fix matching null and missing values. https://github.com/kofrasa/mingo/issues/54 +- Improve comparing user-defined types + +## v1.2.0 / 2017-07-17 +- Fix `$where` operator not executed last. https://github.com/kofrasa/mingo/pull/50 +- Fix matching nested arrays. https://github.com/kofrasa/mingo/issues/51 +- Added `$facet` and `$bucket` operators +- Added `$bucketAuto` operator without granularity support +- Added string keys for `$type` operator +- Added Cursor support for [ES2015 Iterator Protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) +- Sort null/undefined values to front of sorted result +- Revert to operator names with format `Mingo.OP_` + +## v1.1.2 / 2017-03-30 +- Optimize `$lookup` implementation +- Avoid reversing original input to `$reverseArray` +- Refactor some methods + +## v1.1.1 / 2017-03-12 +- Fix incorrect method call for ObjectProto +- Limit exposed util methods to type checking + +## v1.1.0 / 2017-03-11 +- Renamed `Mingo.OP_` functions to `Mingo.KEY_` +- Added pipeline stage operator (`$lookup`) + +## v1.0.1 / 2017-03-01 +- Updated polyfills to fix failing build on older node versions + +## v1.0.0 / 2017-02-28 +- Added array aggregation operators + (`$arrayElemAt`,`$concatArrays`,`$filter`,`$indexOfArray`,`$isArray`,`$range`,`$reverseArray`,`$reduce`,`$slice`,`$zip`) +- Added string aggregation operators (`$indexOfBytes`,`$split`) +- Added arithmetic aggregation operators (`$ceil`,`$exp`,`$floor`,`$ln`,`$log`,`$log10`,`$pow`,`$sqrt`,`$trunc`) +- Added .editorconfig +- Pass utility functions to custom operator implementation +- Rename function to retrieve collection id to `idKey` in custom operators +- Moved support for query projection streaming to a new package [mingo-stream](https://github.com/kofrasa/mingo-stream) + +## v0.9.1 / 2017-02-08 +- Fix resolving system variables with subpaths. See [issue#41](https://github.com/kofrasa/mingo/issues/41) + +## v0.9.0 / 2017-02-06 +- Added support for system variables (`$$ROOT`,`$$CURRENT`) +- Implemented more pipeline operators (`$redact`,`$addFields`,`$sample`,`$sortByCount`,`$count`,`$replaceRoot`) +- Added `$switch` conditional operator +- Fixed `$ifNull` conditional operator +- Allow use of `$in` and `$nin` as aggregation comparison operators + +## v0.8.1 / 2016-12-08 +- Fix querying deeply nested nested arrays and object equality matching. See [issue#36](https://github.com/kofrasa/mingo/issues/36) + +## v0.8.0 / 2016-09-26 +- Make this library zero-dependent + +## v0.7.0 / 2016-09-10 +- Fix nested projections for objects and arrays. See [issue#25](https://github.com/kofrasa/mingo/issues/25) + +## v0.6.5 / 2016-07-04 +- Fix incorrect de-duping of Date types in $sort aggregate operator. See [issue#23](https://github.com/kofrasa/mingo/pull/23) + +## v0.6.4 / 2016-05-19 +- Support matching against user-defined types. See [issue#22](https://github.com/kofrasa/mingo/issues/22) + +## v0.6.3 / 2015-12-27 +- Fixed numeric aggregation over undefined values. See [issues#21](https://github.com/kofrasa/mingo/issues/21) + +## v0.6.2 / 2015-11-17 +- Fixed erroneous cloning of objects. See [issue#20](https://github.com/kofrasa/mingo/pull/20) + +## v0.6.1 / 2015-09-20 +- Fixed matching nested array fields without specifying index. See [issue#19](https://github.com/kofrasa/mingo/issues/19) +- Added `VERSION` global field + +## v0.6.0 / 2015-05-28 +- Added `$dateToString` aggregation operator + +## v0.5.0 / 2015-04-29 +- Added support for extending operators via `Mingo.addOperators` +- Added `bower.json` +- Fixed grouping documents by an object key +- Fixed exclusive select projection not returning correct fields diff --git a/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md b/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md new file mode 100644 index 0000000..9b0ae59 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +Francis Asante +Shane Holloway diff --git a/Challenge/seokahi/010.star/node_modules/mingo/LICENSE b/Challenge/seokahi/010.star/node_modules/mingo/LICENSE new file mode 100644 index 0000000..9613755 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Francis Asante + +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/Challenge/seokahi/010.star/node_modules/mingo/README.md b/Challenge/seokahi/010.star/node_modules/mingo/README.md new file mode 100644 index 0000000..5a908b8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/README.md @@ -0,0 +1,172 @@ +# mingo +JavaScript implementation of MongoDB query language + +[![version](https://img.shields.io/npm/v/mingo.svg)](https://www.npmjs.org/package/mingo) +[![build status](https://secure.travis-ci.org/kofrasa/mingo.png)](http://travis-ci.org/kofrasa/mingo) + +## Install +```$ npm install mingo``` + +## Features +- Supports Dot Notation for both '_<array>.<index>_' and '_<document>.<field>_' selectors +- Query and Projection Operators + - [Array Operators](https://docs.mongodb.com/manual/reference/operator/query-array/) + - [Comparisons Operators](https://docs.mongodb.com/manual/reference/operator/query-comparison/) + - [Element Operators](https://docs.mongodb.com/manual/reference/operator/query-element/) + - [Evaluation Operators](https://docs.mongodb.com/manual/reference/operator/query-evaluation/) + - [Logical Operators](https://docs.mongodb.com/manual/reference/operator/query-logical/) +- Aggregation Framework Operators + - [Pipeline Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/) + - [Group Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-group/) + - [Projection Operators](https://docs.mongodb.com/manual/reference/operator/projection/) + - [Arithmetic Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-arithmetic/) + - [Array Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-array/) + - [Boolean Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-boolean/) + - [Comparisons Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-comparison/) + - [Conditional Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-conditional/) + - [Date Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-date/) + - [Literal Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-literal/) + - [Set Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-set/) + - [String Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-string/) + - [Variable Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-projection/) +- Support for adding custom operators +- Match against user-defined types +- Support for aggregaion variables + - [`$$ROOT`,`$$CURRENT`,`$$DESCEND`,`$$PRUNE`,`$$KEEP`](https://docs.mongodb.com/manual/reference/aggregation-variables/) +- Fully ES6 module compatible +- Support integrating with custom collections via mixin +- Query filter and projection streaming. See [mingo-stream](https://github.com/kofrasa/mingo-stream) + +For documentation on using query operators see [mongodb](http://docs.mongodb.org/manual/reference/operator/query/) + + +## Usage +On the server side +```js +// Use as es6 module +import mingo from 'mingo' + +// or vanilla nodeJS +var mingo = require('mingo') +``` + +For the browser +``` +// minified UMD module + + +// or gzipped UMD module + +``` + +Tiny configuration if needed +```js +// setup the key field for your collection +mingo.setup({ + key: '_id' // default +}); + + +## Using query object to test objects +// create a query with criteria +// find all grades for homework with score >= 50 +let query = new mingo.Query({ + type: "homework", + score: { $gte: 50 } +}); + +query.test(someObject) +``` + +## Searching and Filtering +```js +// `collection` is an Array of objects you want to query + +// filter collection with find() +let cursor = query.find(collection); + +// shorthand with query criteria +// cursor = mingo.find(collection, criteria); + +// sort, skip and limit by chaining +cursor.sort({student_id: 1, score: -1}) + .skip(100) + .limit(100); + +// count matches +cursor.count(); + +// iterate cursor +// iteration is forward only +while (cursor.hasNext()) { + console.log(cursor.next()); +} + +// use first(), last() and all() to retrieve matched objects +cursor.first(); +cursor.last(); +cursor.all(); + +// Filter non-matched objects ( +console.log(query.remove(collection)); +``` + +## Aggregation Pipeline +```js +let agg = new mingo.Aggregator([ + {'$match': { "type": "homework"}}, + {'$group':{'_id':'$student_id', 'score':{$min:'$score'}}}, + {'$sort':{'_id': 1, 'score': 1}} +]); + +let result = agg.run(collection); + +// shorthand +result = mingo.aggregate( + collection, + [ + {'$match': { "type": "homework"}}, + {'$group':{'_id':'$student_id', 'score':{$min:'$score'}}}, + {'$sort':{'_id': 1, 'score': 1}} + ] +); +``` + +## Integration with custom collection +```js +// using Backbone.Collection as an example (any user-defined object will do) +let Grades = Backbone.Collection.extend(mingo.CollectionMixin); + +// `collection` is an array of objects +let grades = new Grades(collection); + +// find students with grades less than 50 in homework or quiz +// sort by score ascending and type descending +cursor = grades.query({ + $or: [{type: "quiz", score: {$lt: 50}}, {type: "homework", score: {$lt: 50}}] +}).sort({score: 1, type: -1}).limit(10); + +// return grade with the lowest score +cursor.first(); +``` + +The collection to mixin needs to provide a method with signature `toJSON() -> Array[Object]`. + +## Documentation +- [API](https://github.com/kofrasa/mingo/wiki/API) +- [Custom Operators](https://github.com/kofrasa/mingo/wiki/Custom-Operators) + +## Why? + - Born out of a real need + - Alternative to writing a lot of custom code for transforming collections of JSON objects + - Quick validation of MongoDB queries without the need for a database + - MongoDB query language is among the best in the market and is well documented + - Finally, because queries are better than me and perhaps you too :) + +## Contributing +* Submit pull requests to the [development](https://github.com/kofrasa/mingo/tree/development) branch +* Squash changes into one commit +* Run `make` to ensure build and tests pass + +## License +MIT diff --git a/Challenge/seokahi/010.star/node_modules/mingo/VERSION b/Challenge/seokahi/010.star/node_modules/mingo/VERSION new file mode 100644 index 0000000..785cda8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/VERSION @@ -0,0 +1 @@ +1.3.3 \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js new file mode 100644 index 0000000..3af3184 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js @@ -0,0 +1,3866 @@ +// mingo.js 1.3.3 +// Copyright (c) 2017 Francis Asante +// https://github.com/kofrasa/mingo +// MIT + +/** + * Polyfill to add native methods for non-supported environments. + */ + +// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new Error('Function.prototype.bind - what is trying to be bound is not callable') + } + + var aArgs = Array.prototype.slice.call(arguments, 1); + var fToBind = this; + var fNOP = function () {}; + var fBound = function () { + return fToBind.apply( + (this instanceof fNOP) ? this : oThis, + aArgs.concat(Array.prototype.slice.call(arguments)) + ) + }; + + if (this.prototype) { + // Function.prototype doesn't have a prototype property + fNOP.prototype = this.prototype; + } + fBound.prototype = new fNOP(); + + return fBound + }; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this); + var len = o.length >>> 0; + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function') + } + + var thisArg = arguments[1]; + var k = 0; + + while (k < len) { + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return kValue + } + k++; + } + return undefined + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + value: function(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this); + var len = o.length >>> 0; + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function') + } + + var thisArg = arguments[1]; + var k = 0; + while (k < len) { + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return k + } + k++; + } + return -1 + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes +if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + value: function(searchElement, fromIndex) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this); + var len = o.length >>> 0; + + if (len === 0) { + return false + } + var n = fromIndex | 0; + var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); + + function sameValueZero(x, y) { + return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) + } + + while (k < len) { + if (sameValueZero(o[k], searchElement)) { + return true + } + k++; + } + return false + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign +if (typeof Object.assign != 'function') { + Object.assign = function(target, varArgs) { // .length of function is 2 + + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object') + } + + var to = Object(target); + var args = Array.prototype.slice.call(arguments); + + for (var index = 1; index < args.length; index++) { + var nextSource = args[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (nextSource.hasOwnProperty(nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to + }; +} + +// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html +if (!Object.keys) { + Object.keys = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.keys called on a non-object') + } + + var result = []; + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(k); + } + } + return result + }; +} + +// https://github.com/es-shims/Object.values/blob/master/implementation.js +if (!Object.values) { + Object.values = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.values called on a non-object') + } + var result = []; + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(o[k]); + } + } + return result + }; +} + +// Javascript native types +const T_NULL = 'null'; +const T_UNDEFINED = 'undefined'; +const T_BOOL = 'bool'; +const T_BOOLEAN = 'boolean'; +const T_NUMBER = 'number'; +const T_STRING = 'string'; +const T_DATE = 'date'; +const T_REGEX = 'regex'; +const T_REGEXP = 'regexp'; +const T_ARRAY = 'array'; +const T_OBJECT = 'object'; +const T_FUNCTION = 'function'; + +// no array, object, or function types +const JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP]; + +// operator classes +const OP_AGGREGATE = 'aggregate'; +const OP_GROUP = 'group'; +const OP_PIPELINE = 'pipeline'; +const OP_PROJECTION = 'projection'; +const OP_QUERY = 'query'; + +/** + * Utility functions + */ + +function assert (condition, message) { + if (falsey(condition)) err(message); +} + +/** + * Deep clone an object + * @param obj + * @returns {*} + */ +function clone (obj) { + switch (jsType(obj)) { + case T_ARRAY: + return obj.map(clone) + case T_OBJECT: + return map(obj, clone) + default: + return obj + } +} + +function getType (v) { + if (v === null) return 'Null' + if (v === undefined) return 'Undefined' + return v.constructor.name +} +function jsType (v) { return getType(v).toLowerCase() } +function isBoolean (v) { return jsType(v) === T_BOOLEAN } +function isString (v) { return jsType(v) === T_STRING } +function isNumber (v) { return jsType(v) === T_NUMBER } +function isArray (v) { return jsType(v) === T_ARRAY } +function isArrayLike (v) { return !isNil(v) && has(v, 'length') } +function isObject (v) { return jsType(v) === T_OBJECT } +function isObjectLike (v) { return v === Object(v) } // objects, arrays, functions, date, custom object +function isDate (v) { return jsType(v) === T_DATE } +function isRegExp (v) { return jsType(v) === T_REGEXP } +function isFunction (v) { return jsType(v) === T_FUNCTION } +function isNil (v) { return isNull(v) || isUndefined(v) } +function isNull (v) { return jsType(v) === T_NULL } +function isUndefined (v) { return jsType(v) === T_UNDEFINED } +function inArray (arr, item) { return arr.includes(item) } +function notInArray (arr, item) { return !arr.includes(item) } +function truthy (arg) { return !!arg } +function falsey (arg) { return !arg } +function isEmpty (x) { + return isNil(x) || + isArray(x) && x.length === 0 || + isObject(x) && keys(x).length === 0 || !x +} +// ensure a value is an array +function array (x) { return isArray(x) ? x : [x] } +function has (obj, prop) { return obj.hasOwnProperty(prop) } +function err (s) { throw new Error(s) } +function keys (o) { return Object.keys(o) } + +// ////////////////// UTILS //////////////////// + +// internal constants +const __MINGO_META = '__mingo__'; + +function addMeta (obj, value) { + obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value); +} + +function hasMeta (obj, value) { + return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]) +} + +function dropMeta (obj) { + if (has(obj, __MINGO_META)) delete obj[__MINGO_META]; +} + +/** + * Iterate over an array or object + * @param {Array|Object} obj An object-like value + * @param {Function} fn The callback to run per item + * @param {*} ctx The object to use a context + * @return {void} + */ +function each (obj, fn, ctx = null) { + assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'"); + + if (isArrayLike(obj)) { + for (let i = 0, len = obj.length; i < len; i++) { + if (fn.call(ctx, obj[i], i, obj) === false) break + } + } else { + for (let k in obj) { + if (has(obj, k)) { + if (fn.call(ctx, obj[k], k, obj) === false) break + } + } + } +} + +/** + * Transform values in a collection + * + * @param {Array|Object} obj An array/object whose values to transform + * @param {Function} fn The transform function + * @param {*} ctx The value to use as the "this" context for the transform + * @return {Array|Object} Result object after applying the transform + */ +function map (obj, fn, ctx = null) { + if (isArray(obj)) { + return obj.map(fn, ctx) + } else if (isObject(obj)) { + let o = {}; + each(obj, (v, k) => o[k] = fn.call(ctx, v, k), obj); + return o + } +} + +/** + * Reduce any array-like object + * @param collection + * @param fn + * @param accumulator + * @returns {*} + */ +function reduce (collection, fn, accumulator) { + if (isArray(collection)) return collection.reduce(fn, accumulator) + // array-like objects + each(collection, (v, k) => accumulator = fn(accumulator, v, k, collection)); + return accumulator +} + +/** + * Returns the intersection between two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} Result array + */ +function intersection (xs, ys) { + return xs.filter(inArray.bind(null, ys)) +} + +/** + * Returns the union of two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} The result array + */ +function union (xs, ys) { + return into(into([], xs), ys.filter(notInArray.bind(null, xs))) +} + +/** + * Flatten the array + * + * @param {Array} xs The array to flatten + * @param {Number} depth The number of nested lists to iterate + */ + + +/** + * Determine whether two values are the same or strictly equivalent + * + * @param {*} a The first value + * @param {*} b The second value + * @return {Boolean} Result of comparison + */ +function isEqual (a, b) { + // strictly equal must be equal. + if (a === b) return true + + // unequal types and functions cannot be equal. + let type = jsType(a); + if (type !== jsType(b) || type === T_FUNCTION) return false + + // we treat NaN as the same + if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true + + // leverage toString for Date and RegExp types + if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString() + + if (type === T_ARRAY) { + if (a.length === b.length && a.length === 0) return true + if (a.length !== b.length) return false + for (let i = 0, len = a.length; i < len; i++) { + if (!isEqual(a[i], b[i])) return false + } + } else if (type === T_OBJECT) { + // deep compare objects + let ka = keys(a); + let kb = keys(b); + + // check length of keys early + if (ka.length !== kb.length) return false + + // we know keys are strings so we sort before comparing + ka.sort(); + kb.sort(); + + // compare keys + if (!isEqual(ka, kb)) return false + + // back to the drawing board + for (let i = 0, len = ka.length; i < len; i++) { + let temp = ka[i]; + if (!isEqual(a[temp], b[temp])) return false + } + } else { + // we do not know how to compare custom types so we guess + return getHash(a) === getHash(b) + } + // best effort says values are equal :) + return true +} + +/** + * Return a new unique version of the collection + * @param {Array} xs The input collection + * @return {Array} A new collection with unique values + */ +function unique (xs) { + let h = {}; + let arr = []; + each(xs, (item) => { + let k = getHash(item); + if (!has(h, k)) { + arr.push(item); + h[k] = 0; + } + }); + return arr +} + +/** + * Generates a random string of max length range [24,27] + * @param n Size of string to return + * @returns {*} + */ +function randomString(n) { + return (Math.E + Math.random()).toString(36).slice(2, n+2) +} + +/** + * Encode value using a simple optimistic stable scheme. + * @param value + * @returns {*} + */ +function encode (value) { + let type = jsType(value); + switch (type) { + case T_FUNCTION: + return randomString(7) + case T_BOOLEAN: + case T_NUMBER: + case T_REGEXP: + return value.toString() + case T_STRING: + return JSON.stringify(value) + case T_DATE: + return value.toISOString() + case T_NULL: + case T_UNDEFINED: + return type + case T_ARRAY: + return '[' + map(value, (v) => `${encode(v)}`) + ']' + default: + let prefix = (type === T_OBJECT)? '' : `${getType(value)}|`; + let objKeys = keys(value); + objKeys.sort(); + return `${prefix}{` + map(objKeys, (k) => `${encode(k)}:${encode(value[k])}`) + '}' + } +} + +/** + * Generate hash code + * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery + * + * @param value + * @returns {*} + */ +function getHash (value) { + let hash = 0, i, chr, len, s = encode(value); + if (s.length === 0) return hash + for (i = 0, len = s.length; i < len; i++) { + chr = s.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash.toString() +} + +/** + * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee + * + * This implementation treats null/undefined sort keys as less than every other type + * + * @param {Array} collection + * @param {Function} fn The function used to resolve sort keys + * @param {Object} ctx The context to use for calling `fn` + * @return {Array} Returns a new sorted array by the given iteratee + */ +function sortBy (collection, fn, ctx = null) { + let sortKeys = {}; + let sorted = []; + let len = collection.length; + let result = []; + + for (let i = 0; i < len; i++) { + let obj = collection[i]; + let key = fn.call(ctx, obj, i); + if (isNil(key)) { + // objects with null keys will go in first + result.push(obj); + } else { + let hash = getHash(obj); + if (!has(sortKeys, hash)) { + sortKeys[hash] = [key, i]; + } + sorted.push(obj); + } + } + // use native array sorting but enforce stableness + sorted.sort((a, b) => { + let A = sortKeys[getHash(a)]; + let B = sortKeys[getHash(b)]; + if (A[0] < B[0]) return -1 + if (A[0] > B[0]) return 1 + if (A[1] < B[1]) return -1 + if (A[1] > B[1]) return 1 + return 0 + }); + return into(result, sorted) +} + +/** + * Groups the collection into sets by the returned key + * + * @param collection + * @param fn {Function} to compute the group key of an item in the collection + * @param ctx {Object} The context to use for calling `fn` + * @returns {{keys: Array, groups: Array}} + */ +function groupBy (collection, fn, ctx) { + let result = { + 'keys': [], + 'groups': [] + }; + let lookup = {}; + each(collection, (obj) => { + let key = fn.call(ctx, obj); + let hash = getHash(key); + let index = -1; + + if (isUndefined(lookup[hash])) { + index = result.keys.length; + lookup[hash] = index; + result.keys.push(key); + result.groups.push([]); + } + index = lookup[hash]; + result.groups[index].push(obj); + }); + return result +} + +/** + * Push elements in given array into target array + * + * @param {*} target The array to push into + * @param {*} xs The array of elements to push + */ +function into (target, xs) { + Array.prototype.push.apply(target, xs); + return target +} + +/** + * Find the insert index for the given key in a sorted array. + * + * @param {*} array The sorted array to search + * @param {*} key The search key + */ +function findInsertIndex (array, key) { + // uses binary search + let lo = 0; + let hi = array.length - 1; + while (lo <= hi) { + let mid = Math.round(lo + (hi - lo) / 2); + if (key < array[mid]) { + hi = mid - 1; + } else if (key > array[mid]) { + lo = mid + 1; + } else { + return mid + } + } + return lo +} + +/** + * This is a generic memoization function + * + * This implementation uses a cache independent of the function being memoized + * to allow old values to be garbage collected when the memoized function goes out of scope. + * + * @param {*} fn The function object to memoize + */ +function memoize (fn) { + return ((cache) => { + return (...args) => { + let key = getHash(args); + if (!has(cache, key)) { + cache[key] = fn.apply(this, args); + } + return cache[key] + } + })({/* storage */}) +} + +/** + * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ + */ + +const groupOperators = { + + /** + * Returns an array of all the unique values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {*} + */ + $addToSet (collection, expr) { + return unique(this.$push(collection, expr)) + }, + + /** + * Returns the sum of all the values in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $sum (collection, expr) { + if (!isArray(collection)) return 0 + + if (isNumber(expr)) { + // take a short cut if expr is number literal + return collection.length * expr + } + return reduce(this.$push(collection, expr).filter(isNumber), (acc, n) => acc + n, 0) + }, + + /** + * Returns the highest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $max (collection, expr) { + let mapped = this.$push(collection, expr); + return reduce(mapped, (acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) + }, + + /** + * Returns the lowest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $min (collection, expr) { + let mapped = this.$push(collection, expr); + return reduce(mapped, (acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) + }, + + /** + * Returns an average of all the values in a group. + * + * @param collection + * @param expr + * @returns {number} + */ + $avg (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber); + let sum = reduce(data, (acc, n) => acc + n, 0); + return sum / (data.length || 1) + }, + + /** + * Returns an array of all values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $push (collection, expr) { + if (isNil(expr)) return collection + return map(collection, (obj) => computeValue(obj, expr)) + }, + + /** + * Returns the first value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $first (collection, expr) { + return (collection.length > 0) ? computeValue(collection[0], expr) : undefined + }, + + /** + * Returns the last value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $last (collection, expr) { + return (collection.length > 0) ? computeValue(collection[collection.length - 1], expr) : undefined + }, + + /** + * Returns the population standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number} + */ + $stdDevPop (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber); + return stddev({ data: data, sampled: false }) + }, + + /** + * Returns the sample standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number|null} + */ + $stdDevSamp (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber); + return stddev({ data: data, sampled: true }) + } +}; + +/** + * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ + */ +const projectionOperators = { + + /** + * Projects the first element in an array that matches the query condition. + * + * @param obj + * @param field + * @param expr + */ + $ (obj, expr, field) { + err('$ not implemented'); + }, + + /** + * Projects only the first element from an array that matches the specified $elemMatch condition. + * + * @param obj + * @param field + * @param expr + * @returns {*} + */ + $elemMatch (obj, expr, field) { + let arr = resolve(obj, field); + let query = new Query(expr); + + if (isNil(arr) || !isArray(arr)) { + return undefined + } + + for (let i = 0; i < arr.length; i++) { + if (query.test(arr[i])) { + return [arr[i]] + } + } + + return undefined + }, + + /** + * Limits the number of elements projected from an array. Supports skip and limit slices. + * + * @param obj + * @param field + * @param expr + */ + $slice (obj, expr, field) { + let xs = resolve(obj, field); + + if (!isArray(xs)) return xs + + if (isArray(expr)) { + return slice(xs, expr[0], expr[1]) + } else if (isNumber(expr)) { + return slice(xs, expr) + } else { + err('Invalid argument type for $slice projection operator'); + } + }, + + /** + * Returns the population standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number} + */ + $stdDevPop (obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: false + }) + }, + + /** + * Returns the sample standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number|null} + */ + $stdDevSamp (obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: true + }) + } +}; + +/** + * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ + */ +const pipelineOperators = { + + /** + * Adds new fields to documents. + * Outputs documents that contain all existing fields from the input documents and newly added fields. + * + * @param {Array} collection + * @param {*} expr + */ + $addFields (collection, expr) { + let newFields = keys(expr); + + return collection.map((obj) => { + obj = clone(obj); + each(newFields, (field) => { + let subExpr = expr[field]; + let newValue = computeValue(obj, subExpr); + traverse(obj, field, (o, key) => { + o[key] = newValue; + }, true); + }); + return obj + }) + }, + + /** + * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $group (collection, expr) { + // lookup key for grouping + const ID_KEY = idKey(); + let objectId = expr[ID_KEY]; + + let partitions = groupBy(collection, (obj) => { + return computeValue(obj, objectId, objectId) + }); + + let result = []; + + // remove the group key + delete expr[ID_KEY]; + + each(partitions.keys, (value, i) => { + let obj = {}; + + // exclude undefined key value + if (!isUndefined(value)) { + obj[ID_KEY] = value; + } + + // compute remaining keys in expression + each(expr, (val, key) => { + obj[key] = accumulate(partitions.groups[i], key, val); + }); + result.push(obj); + }); + + return result + }, + + /** + * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. + * + * @param collection + * @param expr + */ + $lookup (collection, expr) { + let joinColl = expr.from; + let localField = expr.localField; + let foreignField = expr.foreignField; + let asField = expr.as; + + let errorMsg = "Invalid $lookup expression. "; + assert(isArray(joinColl), errorMsg + "'from' must be an array"); + assert(isString(foreignField), errorMsg + "'foreignField' must be a string"); + assert(isString(localField), errorMsg + "'localField' must be a string"); + assert(isString(asField), errorMsg + "'as' must be a string"); + + let result = []; + let hash = {}; + + function hashCode (v) { + return getHash(isNil(v) ? null : v) + } + + if (joinColl.length <= collection.length) { + each(joinColl, (obj, i) => { + let k = hashCode(obj[foreignField]); + hash[k] = hash[k] || []; + hash[k].push(i); + }); + + each(collection, (obj) => { + let k = hashCode(obj[localField]); + let indexes = hash[k] || []; + let newObj = clone(obj); + newObj[asField] = indexes.map((i) => clone(joinColl[i])); + result.push(newObj); + }); + + } else { + + each(collection, (obj, i) => { + let k = hashCode(obj[localField]); + hash[k] = hash[k] || []; + hash[k].push(i); + }); + + let tempResult = {}; + each(joinColl, (obj) => { + let k = hashCode(obj[foreignField]); + let indexes = hash[k] || []; + each(indexes, (i) => { + let newObj = tempResult[i] || clone(collection[i]); + newObj[asField] = newObj[asField] || []; + newObj[asField].push(clone(obj)); + tempResult[i] = newObj; + }); + }); + for (let i = 0, len = keys(tempResult).length; i < len; i++) { + result.push(tempResult[i]); + } + } + + return result + }, + + /** + * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. + * $match uses standard MongoDB queries. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $match (collection, expr) { + return (new Query(expr)).find(collection).all() + }, + + /** + * Reshapes a document stream. + * $project can rename, add, or remove fields as well as create computed values and sub-documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $project (collection, expr) { + if (isEmpty(expr)) { + return collection + } + + // result collection + let projected = []; + let objKeys = keys(expr); + let idOnlyExcludedExpression = false; + const ID_KEY = idKey(); + + // validate inclusion and exclusion + let check = [false, false]; + each(expr, (v, k) => { + if (k === ID_KEY) return + if (v === 0 || v === false) { + check[0] = true; + } else { + check[1] = true; + } + assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.'); + }); + + if (inArray(objKeys, ID_KEY)) { + let id = expr[ID_KEY]; + if (id === 0 || id === false) { + objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])); + assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key'); + idOnlyExcludedExpression = isEmpty(objKeys); + } + } else { + // if not specified the add the ID field + objKeys.push(ID_KEY); + } + + each(collection, (obj) => { + let cloneObj = {}; + let foundSlice = false; + let foundExclusion = false; + let dropKeys = []; + + if (idOnlyExcludedExpression) { + dropKeys.push(ID_KEY); + } + + each(objKeys, (key) => { + let subExpr = expr[key]; + let value; // final computed value of the key + + if (key !== ID_KEY && subExpr === 0) { + foundExclusion = true; + } + + if (key === ID_KEY && isEmpty(subExpr)) { + // tiny optimization here to skip over id + value = obj[key]; + } else if (isString(subExpr)) { + value = computeValue(obj, subExpr, key); + } else if (subExpr === 1 || subExpr === true) { + // For direct projections, we use the resolved object value + } else if (isObject(subExpr)) { + let operator = keys(subExpr); + operator = operator.length > 1 ? false : operator[0]; + + if (inArray(ops(OP_PROJECTION), operator)) { + // apply the projection operator on the operator expression for the key + if (operator === '$slice') { + // $slice is handled differently for aggregation and projection operations + if (array(subExpr[operator]).every(isNumber)) { + // $slice for projection operation + value = projectionOperators[operator](obj, subExpr[operator], key); + foundSlice = true; + } else { + // $slice for aggregation operation + value = computeValue(obj, subExpr, key); + } + } else { + value = projectionOperators[operator](obj, subExpr[operator], key); + } + } else { + // compute the value for the sub expression for the key + value = computeValue(obj, subExpr, key); + } + } else { + dropKeys.push(key); + return + } + + // clone resolved values + let objValue = clone(resolveObj(obj, key)); + + if (!isUndefined(objValue)) { + Object.assign(cloneObj, objValue); + } + if (!isUndefined(value)) { + setValue(cloneObj, key, clone(value)); + } + + }); + // if projection included $slice operator + // Also if exclusion fields are found or we want to exclude only the id field + // include keys that were not explicitly excluded + if (foundSlice || foundExclusion || idOnlyExcludedExpression) { + cloneObj = Object.assign(clone(obj), cloneObj); + each(dropKeys, (key) => removeValue(cloneObj, key)); + } + projected.push(cloneObj); + }); + + return projected + }, + + /** + * Restricts the number of documents in an aggregation pipeline. + * + * @param collection + * @param value + * @returns {Object|*} + */ + $limit (collection, value) { + return collection.slice(0, value) + }, + + /** + * Skips over a specified number of documents from the pipeline and returns the rest. + * + * @param collection + * @param value + * @returns {*} + */ + $skip (collection, value) { + return collection.slice(value) + }, + + /** + * Takes an array of documents and returns them as a stream of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $unwind (collection, expr) { + let result = []; + let field = expr.substr(1); + each(collection, (obj) => { + // must throw an error if value is not an array + let value = getValue(obj, field); + + assert(isArray(value), "Target field '" + field + "' is not of type Array."); + + each(value, (item) => { + let tmp = clone(obj); + tmp[field] = item; + result.push(tmp); + }); + }); + return result + }, + + /** + * Takes all input documents and returns them in a stream of sorted documents. + * + * @param collection + * @param sortKeys + * @returns {*} + */ + $sort (collection, sortKeys) { + if (!isEmpty(sortKeys) && isObject(sortKeys)) { + let modifiers = keys(sortKeys); + each(modifiers.reverse(), (key) => { + let grouped = groupBy(collection, (obj) => resolve(obj, key)); + let sortedIndex = {}; + let getIndex = (k) => sortedIndex[getHash(k)]; + + let indexKeys = sortBy(grouped.keys, (item, i) => { + sortedIndex[getHash(item)] = i; + return item + }); + + if (sortKeys[key] === -1) { + indexKeys.reverse(); + } + collection = []; + each(indexKeys, (item) => into(collection, grouped.groups[getIndex(item)])); + }); + } + return collection + }, + + /** + * Groups incoming documents based on the value of a specified expression, + * then computes the count of documents in each distinct group. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sortByCount (collection, expr) { + let newExpr = { count: { $sum: 1 } }; + newExpr[idKey()] = expr; + + return this.$sort( + this.$group(collection, newExpr), + { count: -1 } + ) + }, + + /** + * Randomly selects the specified number of documents from its input. + * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sample (collection, expr) { + let size = expr.size; + assert(isNumber(size), '$sample size must be a positive integer'); + + let result = []; + let len = collection.length; + for (let i = 0; i < size; i++) { + let n = Math.floor(Math.random() * len); + result.push(collection[n]); + } + return result + }, + + /** + * Returns a document that contains a count of the number of documents input to the stage. + * @param {Array} collection + * @param {String} expr + * @return {Object} + */ + $count (collection, expr) { + assert( + isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', + 'Invalid expression value for $count' + ); + + let result = {}; + result[expr] = collection.length; + return result + }, + + /** + * Replaces a document with the specified embedded document or new one. + * The replacement document can be any valid expression that resolves to a document. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $replaceRoot (collection, expr) { + let newRoot = expr.newRoot; + let result = []; + each(collection, (obj) => { + obj = computeValue(obj, newRoot); + assert(isObject(obj), '$replaceRoot expression must return a valid JS object'); + result.push(obj); + }); + return result + }, + + /** + * Restricts the contents of the documents based on information stored in the documents themselves. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ + */ + $redact (collection, expr) { + return collection.map((obj) => { + return redactObj(clone(obj), expr) + }) + }, + + /** + * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ + */ + $bucket (collection, expr) { + let boundaries = expr.boundaries; + let defaultKey = expr.default; + let lower = boundaries[0]; // inclusive + let upper = boundaries[boundaries.length - 1]; // exclusive + let outputExpr = expr.output || { 'count': { '$sum': 1 } }; + + assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements"); + let boundType = getType(lower); + + for (let i = 0, len = boundaries.length - 1; i < len; i++) { + assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type"); + assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order"); + } + + if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { + assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range"); + } + + let grouped = {}; + each(boundaries, (k) => grouped[k] = []); + + // add default key if provided + if (!isNil(defaultKey)) grouped[defaultKey] = []; + + each(collection, (obj) => { + let key = computeValue(obj, expr.groupBy); + + if (isNil(key) || key < lower || key >= upper) { + assert(!isNil(defaultKey), '$bucket require a default for out of range values'); + grouped[defaultKey].push(obj); + } else if (key >= lower && key < upper) { + let index = findInsertIndex(boundaries, key); + let boundKey = boundaries[Math.max(0, index - 1)]; + grouped[boundKey].push(obj); + } else { + err("$bucket 'groupBy' expression must resolve to a value in range of boundaries"); + } + }); + + // upper bound is exclusive so we remove it + boundaries.pop(); + if (!isNil(defaultKey)) boundaries.push(defaultKey); + + return map(boundaries, (key) => { + let acc = accumulate(grouped[key], null, outputExpr); + return Object.assign(acc, { '_id': key }) + }) + }, + + $bucketAuto (collection, expr) { + let outputExpr = expr.output || { 'count': { '$sum': 1 } }; + let groupByExpr = expr.groupBy; + let bucketCount = expr.buckets; + + assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount); + + let approxBucketSize = Math.round(collection.length / bucketCount); + if (approxBucketSize < 1) { + approxBucketSize = 1; + } + + let computeValueOptimized = memoize(computeValue); + let grouped = {}; + let remaining = []; + let sorted = sortBy(collection, (o) => { + let key = computeValueOptimized(o, groupByExpr); + if (isNil(key)) { + remaining.push(o); + } else { + grouped[key] || (grouped[key] = []); + grouped[key].push(o); + } + return key + }); + + const ID_KEY = idKey(); + let result = []; + let index = 0; // counter for sorted collection + + for (let i = 0, len = sorted.length; i < bucketCount && index < len; i++) { + let boundaries = {}; + let bucketItems = []; + + for (let j = 0; j < approxBucketSize && index < len; j++) { + let key = computeValueOptimized(sorted[index], groupByExpr); + + if (isNil(key)) key = null; + + // populate current bucket with all values for current key + into(bucketItems, isNil(key) ? remaining : grouped[key]); + + // increase sort index by number of items added + index += (isNil(key) ? remaining.length : grouped[key].length); + + // set the min key boundary if not already present + if (!has(boundaries, 'min')) boundaries.min = key; + + if (result.length > 0) { + let lastBucket = result[result.length - 1]; + lastBucket[ID_KEY].max = boundaries.min; + } + } + + // if is last bucket add remaining items + if (i == bucketCount - 1) { + into(bucketItems, sorted.slice(index)); + } + + result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })); + } + + if (result.length > 0) { + result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr); + } + + return result + }, + + /** + * Processes multiple aggregation pipelines within a single stage on the same set of input documents. + * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + */ + $facet (collection, expr) { + return map(expr, (pipeline) => aggregate(collection, pipeline)) + } +}; + +/** + * Returns the result of evaluating a $group operation over a collection + * + * @param collection + * @param field the name of the aggregate operator or field + * @param expr the expression of the aggregate operator for the field + * @returns {*} + */ +function accumulate (collection, field, expr) { + if (inArray(ops(OP_GROUP), field)) { + return groupOperators[field](collection, expr) + } + + if (isObject(expr)) { + let result = {}; + each(expr, (val, key) => { + result[key] = accumulate(collection, key, expr[key]); + // must run ONLY one group operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_GROUP), key)) { + result = result[key]; + // if there are more keys in expression this is bad + assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'"); + return false // break + } + }); + return result + } + + return undefined +} + +/** + * Aggregator for defining filter using mongoDB aggregation pipeline syntax + * + * @param operators an Array of pipeline operators + * @constructor + */ +class Aggregator { + + constructor (operators) { + this.__operators = operators; + } + + /** + * Apply the pipeline operations over the collection by order of the sequence added + * + * @param collection an array of objects to process + * @param query the `Query` object to use as context + * @returns {Array} + */ + run (collection, query) { + if (!isEmpty(this.__operators)) { + // run aggregation pipeline + each(this.__operators, (operator) => { + let key = keys(operator); + assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), `Invalid aggregation operator ${key}`); + key = key[0]; + if (query && query instanceof Query) { + collection = pipelineOperators[key].call(query, collection, operator[key]); + } else { + collection = pipelineOperators[key](collection, operator[key]); + } + }); + } + return collection + } +} + +/** + * Return the result collection after running the aggregation pipeline for the given collection + * + * @param collection + * @param pipeline + * @returns {Array} + */ +function aggregate (collection, pipeline) { + assert(isArray(pipeline), 'Aggregation pipeline must be an array'); + return (new Aggregator(pipeline)).run(collection) +} + +/** + * Cursor to iterate and perform filtering on matched objects + * @param collection + * @param query + * @param projection + * @constructor + */ +class Cursor { + + constructor (collection, query, projection) { + this.__query = query; + this.__collection = collection; + this.__projection = projection || query.__projection; + this.__operators = {}; + this.__result = false; + this.__position = 0; + } + + _fetch () { + + if (this.__result !== false) { + return this.__result + } + + // inject projection operator + if (isObject(this.__projection)) { + Object.assign(this.__operators, { '$project': this.__projection }); + } + + assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); + + // filter collection + this.__result = this.__collection.filter(this.__query.test, this.__query); + let pipeline = []; + + each(['$sort', '$skip', '$limit', '$project'], (op) => { + if (has(this.__operators, op)) { + let selected = {}; + selected[op] = this.__operators[op]; + pipeline.push(selected); + } + }); + + if (pipeline.length > 0) { + let aggregator = new Aggregator(pipeline); + this.__result = aggregator.run(this.__result, this.__query); + } + return this.__result + } + + /** + * Fetch and return all matched results + * @returns {Array} + */ + all () { + return this._fetch() + } + + /** + * Fetch and return the first matching result + * @returns {Object} + */ + first () { + return this.count() > 0 ? this._fetch()[0] : null + } + + /** + * Fetch and return the last matching object from the result + * @returns {Object} + */ + last () { + return this.count() > 0 ? this._fetch()[this.count() - 1] : null + } + + /** + * Counts the number of matched objects found + * @returns {Number} + */ + count () { + return this._fetch().length + } + + /** + * Returns a cursor that begins returning results only after passing or skipping a number of documents. + * @param {Number} n the number of results to skip. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + skip (n) { + Object.assign(this.__operators, { '$skip': n }); + return this + } + + /** + * Constrains the size of a cursor's result set. + * @param {Number} n the number of results to limit to. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + limit (n) { + Object.assign(this.__operators, { '$limit': n }); + return this + } + + /** + * Returns results ordered according to a sort specification. + * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + sort (modifier) { + Object.assign(this.__operators, { '$sort': modifier }); + return this + } + + /** + * Returns the next document in a cursor. + * @returns {Object | Boolean} + */ + next () { + if (this.hasNext()) { + return this._fetch()[this.__position++] + } + return null + } + + /** + * Returns true if the cursor has documents and can be iterated. + * @returns {boolean} + */ + hasNext () { + return this.count() > this.__position + } + + /** + * Specifies the exclusive upper bound for a specific field + * @param expr + * @returns {Number} + */ + max (expr) { + return groupOperators.$max(this._fetch(), expr) + } + + /** + * Specifies the inclusive lower bound for a specific field + * @param expr + * @returns {Number} + */ + min (expr) { + return groupOperators.$min(this._fetch(), expr) + } + + /** + * Applies a function to each document in a cursor and collects the return values in an array. + * @param callback + * @returns {Array} + */ + map (callback) { + return this._fetch().map(callback) + } + + /** + * Applies a JavaScript function for every document in a cursor. + * @param callback + */ + forEach (callback) { + each(this._fetch(), callback); + } + + /** + * Applies an [ES2015 Iteration protocol][] compatible implementation + * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + * @returns {Object} + */ + [Symbol.iterator] () { + let self = this; + return { + next () { + if (!self.hasNext()) { + return { done: true } + } + return { + done: false, + value: self.next() + } + } + } + } +} + +/** + * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ + */ +const simpleOperators = { + + /** + * Checks that two values are equal. + * + * @param a The lhs operand as resolved from the object by the given selector + * @param b The rhs operand provided by the user + * @returns {*} + */ + $eq (a, b) { + // start with simple equality check + if (isEqual(a, b)) return true + + // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ + if (isNil(a) && isNil(b)) return true + + if (isArray(a)) { + // is multi-valued lhs so we check each separately + if (hasMeta(a, { isMulti: true })) { + try { + for (let i = 0; i < a.length; i++) { + if (this.$eq(a[i], b)) { + return true; + } + } + } finally { + dropMeta(a); + } + } else { + // check one level deep + return a.findIndex(isEqual.bind(null, b)) !== -1 + } + } + return false; + }, + + /** + * Matches all values that are not equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $ne (a, b) { + return !this.$eq(a, b) + }, + + /** + * Matches any of the values that exist in an array specified in the query. + * + * @param a + * @param b + * @returns {*} + */ + $in (a, b) { + a = array(a); + return intersection(a, b).length > 0 + }, + + /** + * Matches values that do not exist in an array specified to the query. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $nin (a, b) { + return isNil(a) || !this.$in(a, b) + }, + + /** + * Matches values that are less than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lt (a, b) { + a = array(a).find((val) => val < b); + return a !== undefined + }, + + /** + * Matches values that are less than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lte (a, b) { + a = array(a).find((val) => val <= b); + return a !== undefined + }, + + /** + * Matches values that are greater than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gt (a, b) { + a = array(a).find((val) => val > b); + return a !== undefined + }, + + /** + * Matches values that are greater than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gte (a, b) { + a = array(a).find((val) => val >= b); + return a !== undefined + }, + + /** + * Performs a modulo operation on the value of a field and selects documents with a specified result. + * + * @param a + * @param b + * @returns {boolean} + */ + $mod (a, b) { + a = array(a).find((val) => isNumber(val) && isArray(b) && b.length === 2 && (val % b[0]) === b[1]); + return a !== undefined + }, + + /** + * Selects documents where values match a specified regular expression. + * + * @param a + * @param b + * @returns {boolean} + */ + $regex (a, b) { + a = array(a).find((val) => isString(val) && isRegExp(b) && (!!val.match(b))); + return a !== undefined + }, + + /** + * Matches documents that have the specified field. + * + * @param a + * @param b + * @returns {boolean} + */ + $exists (a, b) { + return ((b === false || b === 0) && isNil(a)) || ((b === true || b === 1) && !isNil(a)) + }, + + /** + * Matches arrays that contain all elements specified in the query. + * + * @param a + * @param b + * @returns boolean + */ + $all (a, b) { + let matched = false; + if (isArray(a) && isArray(b)) { + for (let i = 0, len = b.length; i < len; i++) { + if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { + matched = matched || this.$elemMatch(a, b[i].$elemMatch); + } else { + // order of arguments matter + return intersection(b, a).length === len + } + } + } + return matched + }, + + /** + * Selects documents if the array field is a specified size. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $size (a, b) { + return isArray(a) && isNumber(b) && (a.length === b) + }, + + /** + * Selects documents if element in the array field matches all the specified $elemMatch condition. + * + * @param a + * @param b + */ + $elemMatch (a, b) { + if (isArray(a) && !isEmpty(a)) { + let query = new Query(b); + for (let i = 0, len = a.length; i < len; i++) { + if (query.test(a[i])) { + return true + } + } + } + return false + }, + + /** + * Selects documents if a field is of the specified type. + * + * @param a + * @param b + * @returns {boolean} + */ + $type (a, b) { + switch (b) { + case 1: + case 'double': + return isNumber(a) && (a + '').indexOf('.') !== -1 + case 2: + case T_STRING: + return isString(a) + case 3: + case T_OBJECT: + return isObject(a) + case 4: + case T_ARRAY: + return isArray(a) + case 6: + case T_UNDEFINED: + return isNil(a) + case 8: + case T_BOOL: + return isBoolean(a) + case 9: + case T_DATE: + return isDate(a) + case 10: + case T_NULL: + return isNull(a) + case 11: + case T_REGEX: + return isRegExp(a) + case 16: + case 'int': + return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1 + case 18: + case 'long': + return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1 + case 19: + case 'decimal': + return isNumber(a) + default: + return false + } + } +}; + +const queryOperators = { + + /** + * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $and (selector, value) { + assert(isArray(value), 'Invalid expression: $and expects value to be an Array'); + + let queries = []; + each(value, (expr) => queries.push(new Query(expr))); + + return { + test (obj) { + for (let i = 0; i < queries.length; i++) { + if (!queries[i].test(obj)) { + return false + } + } + return true + } + } + }, + + /** + * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $or (selector, value) { + assert(isArray(value),'Invalid expression. $or expects value to be an Array'); + + let queries = []; + each(value, (expr) => queries.push(new Query(expr))); + + return { + test (obj) { + for (let i = 0; i < queries.length; i++) { + if (queries[i].test(obj)) { + return true + } + } + return false + } + } + }, + + /** + * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $nor (selector, value) { + assert(isArray(value),'Invalid expression. $nor expects value to be an Array'); + let query = this.$or('$or', value); + return { + test (obj) { + return !query.test(obj) + } + } + }, + + /** + * Inverts the effect of a query expression and returns documents that do not match the query expression. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $not (selector, value) { + let criteria = {}; + criteria[selector] = normalize(value); + let query = new Query(criteria); + return { + test (obj) { + return !query.test(obj) + } + } + }, + + /** + * Matches documents that satisfy a JavaScript expression. + * + * @param selector + * @param value + * @returns {{test: test}} + */ + $where (selector, value) { + if (!isFunction(value)) { + value = new Function('return ' + value + ';'); + } + return { + test (obj) { + return value.call(obj) === true + } + } + } +}; + +// add simple query operators +each(simpleOperators, (fn, op) => { + queryOperators[op] = ((f, ctx) => { + return (selector, value) => { + return { + test (obj) { + // value of field must be fully resolved. + let lhs = resolve(obj, selector); + return f.call(ctx, lhs, value) + } + } + } + })(fn, simpleOperators); +}); + +/** + * Query object to test collection elements with + * @param criteria the pass criteria for the query + * @param projection optional projection specifiers + * @constructor + */ +class Query { + + constructor (criteria, projection = {}) { + this.__criteria = criteria; + this.__projection = projection; + this.__compiled = []; + this._compile(); + } + + _compile () { + if (isEmpty(this.__criteria)) return + + assert(isObject(this.__criteria), 'Criteria must be of type Object'); + + let whereOperator; + + each(this.__criteria, (expr, field) => { + // save $where operators to be executed after other operators + if ('$where' === field) { + whereOperator = { field: field, expr: expr }; + } else if (inArray(['$and', '$or', '$nor'], field)) { + this._processOperator(field, field, expr); + } else { + // normalize expression + expr = normalize(expr); + each(expr, (val, op) => { + this._processOperator(field, op, val); + }); + } + + if (isObject(whereOperator)) { + this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); + } + }); + } + + _processOperator (field, operator, value) { + if (inArray(ops(OP_QUERY), operator)) { + this.__compiled.push(queryOperators[operator](field, value)); + } else { + err("Invalid query operator '" + operator + "' detected"); + } + } + + /** + * Checks if the object passes the query criteria. Returns true if so, false otherwise. + * @param obj + * @returns {boolean} + */ + test (obj) { + for (let i = 0, len = this.__compiled.length; i < len; i++) { + if (!this.__compiled[i].test(obj)) { + return false + } + } + return true + } + + /** + * Performs a query on a collection and returns a cursor object. + * @param collection + * @param projection + * @returns {Cursor} + */ + find (collection, projection) { + return new Cursor(collection, this, projection) + } + + /** + * Remove matched documents from the collection returning the remainder + * @param collection + * @returns {Array} + */ + remove (collection) { + return reduce(collection, (acc, obj) => { + if (!this.test(obj)) acc.push(obj); + return acc + }, []) + } +} + +/** + * Performs a query on a collection and returns a cursor object. + * + * @param collection + * @param criteria + * @param projection + * @returns {Cursor} + */ +function find (collection, criteria, projection) { + return new Query(criteria).find(collection, projection) +} + +/** + * Returns a new array without objects which match the criteria + * + * @param collection + * @param criteria + * @returns {Array} + */ +function remove (collection, criteria) { + return new Query(criteria).remove(collection) +} + +const arithmeticOperators = { + + /** + * Returns the absolute value of a number. + * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs + * @param obj + * @param expr + * @return {Number|null|NaN} + */ + $abs (obj, expr) { + let val = computeValue(obj, expr); + return (val === null || val === undefined) ? null : Math.abs(val) + }, + + /** + * Computes the sum of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $add (obj, expr) { + let args = computeValue(obj, expr); + return reduce(args, (acc, num) => acc + num, 0) + }, + + /** + * Returns the smallest integer greater than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $ceil (obj, expr) { + let arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.'); + return Math.ceil(arg) + }, + + /** + * Takes two numbers and divides the first number by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $divide (obj, expr) { + let args = computeValue(obj, expr); + return args[0] / args[1] + }, + + /** + * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {number} + */ + $exp (obj, expr) { + let arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.'); + return Math.exp(arg) + }, + + /** + * Returns the largest integer less than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $floor (obj, expr) { + let arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.'); + return Math.floor(arg) + }, + + /** + * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $ln (obj, expr) { + let arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.'); + return Math.log(arg) + }, + + /** + * Calculates the log of a number in the specified base and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log (obj, expr) { + let args = computeValue(obj, expr); + assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items'); + if (args.some(isNaN)) return NaN + if (args.some(isNil)) return null + assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers'); + return Math.log10(args[0]) / Math.log10(args[1]) + }, + + /** + * Calculates the log base 10 of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log10 (obj, expr) { + let arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.'); + return Math.log10(arg) + }, + + /** + * Takes two numbers and calculates the modulo of the first number divided by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $mod (obj, expr) { + let args = computeValue(obj, expr); + return args[0] % args[1] + }, + + /** + * Computes the product of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $multiply (obj, expr) { + let args = computeValue(obj, expr); + return reduce(args, (acc, num) => acc * num, 1) + }, + + /** + * Raises a number to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {Object} + */ + $pow (obj, expr) { + let args = computeValue(obj, expr); + + assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers'); + assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent'); + + return Math.pow(args[0], args[1]) + }, + + /** + * Calculates the square root of a positive number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $sqrt (obj, expr) { + let n = computeValue(obj, expr); + if (isNaN(n)) return NaN + if (isNil(n)) return null + assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.'); + return Math.sqrt(n) + }, + + /** + * Takes an array that contains two numbers or two dates and subtracts the second value from the first. + * + * @param obj + * @param expr + * @returns {number} + */ + $subtract (obj, expr) { + let args = computeValue(obj, expr); + return args[0] - args[1] + }, + + /** + * Truncates a number to its integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $trunc (obj, expr) { + let n = computeValue(obj, expr); + if (isNaN(n)) return NaN + if (isNil(n)) return null + assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.'); + return Math.trunc(n) + } +}; + +const arrayOperators = { + /** + * Returns the element at the specified array index. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $arrayElemAt (obj, expr) { + let arr = computeValue(obj, expr); + assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements'); + assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array'); + assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer'); + let idx = arr[1]; + arr = arr[0]; + if (idx < 0 && Math.abs(idx) <= arr.length) { + return arr[idx + arr.length] + } else if (idx >= 0 && idx < arr.length) { + return arr[idx] + } + return undefined + }, + + /** + * Converts an array of key value pairs to a document. + */ + $arrayToObject (obj, expr) { + let arr = computeValue(obj, expr); + assert(isArray(arr), '$arrayToObject expression must resolve to an array'); + return reduce(arr, (newObj, val) => { + if (isArray(val) && val.length == 2) newObj[val[0]] = val[1]; + else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v; + else err('$arrayToObject expression is invalid.'); + return newObj + }, {}) + }, + + /** + * Concatenates arrays to return the concatenated array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $concatArrays (obj, expr) { + let arr = computeValue(obj, expr, null); + assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements'); + + if (arr.some(isNil)) return null + + return arr[0].concat(arr[1]) + }, + + /** + * Selects a subset of the array to return an array with only the elements that match the filter condition. + * + * @param {Object} obj [description] + * @param {*} expr [description] + * @return {*} [description] + */ + $filter (obj, expr) { + let input = computeValue(obj, expr.input); + let asVar = expr['as']; + let condExpr = expr['cond']; + + assert(isArray(input), "$filter 'input' expression must resolve to an array"); + + return input.filter((o) => { + // inject variable + let tempObj = {}; + tempObj['$' + asVar] = o; + return computeValue(tempObj, condExpr) === true + }) + }, + + /** + * Returns a boolean indicating whether a specified value is in an array. + * + * @param {Object} obj + * @param {Array} expr + */ + $in (obj, expr) { + let val = computeValue(obj, expr[0]); + let arr = computeValue(obj, expr[1]); + assert(isArray(arr), '$in second argument must be an array'); + return inArray(arr, val) + }, + + /** + * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfArray (obj, expr) { + let args = computeValue(obj, expr); + if (isNil(args)) return null + + let arr = args[0]; + if (isNil(arr)) return null + + assert(isArray(arr), '$indexOfArray expression must resolve to an array.'); + + let searchValue = args[1]; + if (isNil(searchValue)) return null + + let start = args[2] || 0; + let end = args[3] || arr.length; + + if (end < arr.length) { + arr = arr.slice(start, end); + } + + return arr.indexOf(searchValue, start) + }, + + /** + * Determines if the operand is an array. Returns a boolean. + * + * @param {Object} obj + * @param {*} expr + * @return {Boolean} + */ + $isArray (obj, expr) { + return isArray(computeValue(obj, expr)) + }, + + /** + * Applies a sub-expression to each element of an array and returns the array of resulting values in order. + * + * @param obj + * @param expr + * @returns {Array|*} + */ + $map (obj, expr) { + let inputExpr = computeValue(obj, expr.input); + assert(isArray(inputExpr), `$map 'input' expression must resolve to an array`); + + let asExpr = expr['as']; + let inExpr = expr['in']; + + // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" + // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". + // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. + let tempKey = '$' + asExpr; + // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) + let original = obj[tempKey]; + return map(inputExpr, (item) => { + obj[tempKey] = item; + let value = computeValue(obj, inExpr); + // cleanup and restore + if (isUndefined(original)) { + delete obj[tempKey]; + } else { + obj[tempKey] = original; + } + return value + }) + }, + + /** + * Converts a document to an array of documents representing key-value pairs. + */ + $objectToArray (obj, expr) { + let val = computeValue(obj, expr); + assert(isObject(val), '$objectToArray expression must resolve to an object'); + let arr = []; + each(val, (v,k) => arr.push({k,v})); + return arr + }, + + /** + * Returns an array whose elements are a generated sequence of numbers. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $range (obj, expr) { + let arr = computeValue(obj, expr); + let start = arr[0]; + let end = arr[1]; + let step = arr[2] || 1; + + let result = []; + + while ((start < end && step > 0) || (start > end && step < 0)) { + result.push(start); + start += step; + } + + return result + }, + + /** + * Applies an expression to each element in an array and combines them into a single value. + * + * @param {Object} obj + * @param {*} expr + */ + $reduce (obj, expr) { + let input = computeValue(obj, expr.input); + let initialValue = computeValue(obj, expr.initialValue); + let inExpr = expr['in']; + + if (isNil(input)) return null + assert(isArray(input), "$reduce 'input' expression must resolve to an array"); + return reduce(input, (acc, n) => computeValue({ '$value': acc, '$this': n }, inExpr), initialValue) + }, + + /** + * Returns an array with the elements in reverse order. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $reverseArray (obj, expr) { + let arr = computeValue(obj, expr); + + if (isNil(arr)) return null + assert(isArray(arr), '$reverseArray expression must resolve to an array'); + + let result = []; + into(result, arr); + result.reverse(); + return result + }, + + /** + * Counts and returns the total the number of items in an array. + * + * @param obj + * @param expr + */ + $size (obj, expr) { + let value = computeValue(obj, expr); + return isArray(value) ? value.length : undefined + }, + + /** + * Returns a subset of an array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $slice (obj, expr) { + let arr = computeValue(obj, expr); + return slice(arr[0], arr[1], arr[2]) + }, + + /** + * Merge two lists together. + * + * Transposes an array of input arrays so that the first element of the output array would be an array containing, + * the first element of the first input array, the first element of the second input array, etc. + * + * @param {Obj} obj + * @param {*} expr + * @return {*} + */ + $zip (obj, expr) { + let inputs = computeValue(obj, expr.inputs); + let useLongestLength = expr.useLongestLength || false; + + assert(isArray(inputs), "'inputs' expression must resolve to an array"); + assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean"); + + if (isArray(expr.defaults)) { + assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'"); + } + + let zipCount = 0; + + for (let i = 0, len = inputs.length; i < len; i++) { + let arr = inputs[i]; + + if (isNil(arr)) return null + + assert(isArray(arr), "'inputs' expression values must resolve to an array or null"); + + zipCount = useLongestLength + ? Math.max(zipCount, arr.length) + : Math.min(zipCount || arr.length, arr.length); + } + + let result = []; + let defaults = expr.defaults || []; + + for (let i = 0; i < zipCount; i++) { + let temp = inputs.map((val, index) => { + return isNil(val[i]) ? (defaults[index] || null) : val[i] + }); + result.push(temp); + } + + return result + } +}; + +const booleanOperators = { + /** + * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $and: (obj, expr) => { + let value = computeValue(obj, expr); + return truthy(value) && value.every(truthy) + }, + + /** + * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $or: (obj, expr) => { + let value = computeValue(obj, expr); + return truthy(value) && value.some(truthy) + }, + + /** + * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $not: (obj, expr) => { + return !computeValue(obj, expr[0]) + } +}; + +const comparisonOperators = { + /** + * Compares two values and returns the result of the comparison as an integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $cmp (obj, expr) { + let args = computeValue(obj, expr); + if (args[0] > args[1]) return 1 + if (args[0] < args[1]) return -1 + return 0 + } +}; +// mixin comparison operators +each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], (op) => { + comparisonOperators[op] = (obj, expr) => { + let args = computeValue(obj, expr); + return simpleOperators[op](args[0], args[1]) + }; +}); + +/** + * Conditional operators + */ + +const conditionalOperators = { + + /** + * A ternary operator that evaluates one expression, + * and depending on the result returns the value of one following expressions. + * + * @param obj + * @param expr + */ + $cond (obj, expr) { + let ifExpr, thenExpr, elseExpr; + if (isArray(expr)) { + assert(expr.length === 3, 'Invalid arguments for $cond operator'); + ifExpr = expr[0]; + thenExpr = expr[1]; + elseExpr = expr[2]; + } else if (isObject(expr)) { + ifExpr = expr['if']; + thenExpr = expr['then']; + elseExpr = expr['else']; + } + let condition = computeValue(obj, ifExpr); + return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr) + }, + + /** + * An operator that evaluates a series of case expressions. When it finds an expression which + * evaluates to true, it returns the resulting expression for that case. If none of the cases + * evaluate to true, it returns the default expression. + * + * @param obj + * @param expr + */ + $switch (obj, expr) { + assert(expr.branches, 'Invalid arguments for $switch operator'); + + let validBranch = expr.branches.find((branch) => { + assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator'); + return computeValue(obj, branch['case']) + }); + + if (validBranch) { + return computeValue(obj, validBranch.then) + } else if (!expr.default) { + err('Invalid arguments for $switch operator'); + } else { + return computeValue(obj, expr.default) + } + }, + + /** + * Evaluates an expression and returns the first expression if it evaluates to a non-null value. + * Otherwise, $ifNull returns the second expression's value. + * + * @param obj + * @param expr + * @returns {*} + */ + $ifNull (obj, expr) { + assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator'); + let args = computeValue(obj, expr); + return (args[0] === null || args[0] === undefined) ? args[1] : args[0] + } +}; + +// used for formatting dates in $dateToString operator +let DATE_SYM_TABLE = { + '%Y': ['$year', 4], + '%m': ['$month', 2], + '%d': ['$dayOfMonth', 2], + '%H': ['$hour', 2], + '%M': ['$minute', 2], + '%S': ['$second', 2], + '%L': ['$millisecond', 3], + '%j': ['$dayOfYear', 3], + '%w': ['$dayOfWeek', 1], + '%U': ['$week', 2], + '%%': '%' +}; + +const dateOperators = { + /** + * Returns the day of the year for a date as a number between 1 and 366 (leap year). + * @param obj + * @param expr + */ + $dayOfYear (obj, expr) { + let d = computeValue(obj, expr); + if (isDate(d)) { + let start = new Date(d.getFullYear(), 0, 0); + let diff = d - start; + let oneDay = 1000 * 60 * 60 * 24; + return Math.round(diff / oneDay) + } + return undefined + }, + + /** + * Returns the day of the month for a date as a number between 1 and 31. + * @param obj + * @param expr + */ + $dayOfMonth (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getDate() : undefined + }, + + /** + * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). + * @param obj + * @param expr + */ + $dayOfWeek (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getDay() + 1 : undefined + }, + + /** + * Returns the year for a date as a number (e.g. 2014). + * @param obj + * @param expr + */ + $year (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getFullYear() : undefined + }, + + /** + * Returns the month for a date as a number between 1 (January) and 12 (December). + * @param obj + * @param expr + */ + $month (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getMonth() + 1 : undefined + }, + + /** + * Returns the week number for a date as a number between 0 + * (the partial week that precedes the first Sunday of the year) and 53 (leap year). + * @param obj + * @param expr + */ + $week (obj, expr) { + // source: http://stackoverflow.com/a/6117889/1370481 + let d = computeValue(obj, expr); + + // Copy date so don't modify original + d = new Date(+d); + d.setHours(0, 0, 0); + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + d.setDate(d.getDate() + 4 - (d.getDay() || 7)); + // Get first day of year + let yearStart = new Date(d.getFullYear(), 0, 1); + // Calculate full weeks to nearest Thursday + return Math.floor((((d - yearStart) / 8.64e7) + 1) / 7) + }, + + /** + * Returns the hour for a date as a number between 0 and 23. + * @param obj + * @param expr + */ + $hour (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getUTCHours() : undefined + }, + + /** + * Returns the minute for a date as a number between 0 and 59. + * @param obj + * @param expr + */ + $minute (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getMinutes() : undefined + }, + + /** + * Returns the seconds for a date as a number between 0 and 60 (leap seconds). + * @param obj + * @param expr + */ + $second (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getSeconds() : undefined + }, + + /** + * Returns the milliseconds of a date as a number between 0 and 999. + * @param obj + * @param expr + */ + $millisecond (obj, expr) { + let d = computeValue(obj, expr); + return isDate(d) ? d.getMilliseconds() : undefined + }, + + /** + * Returns the date as a formatted string. + * + * %Y Year (4 digits, zero padded) 0000-9999 + * %m Month (2 digits, zero padded) 01-12 + * %d Day of Month (2 digits, zero padded) 01-31 + * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 + * %M Minute (2 digits, zero padded) 00-59 + * %S Second (2 digits, zero padded) 00-60 + * %L Millisecond (3 digits, zero padded) 000-999 + * %j Day of year (3 digits, zero padded) 001-366 + * %w Day of week (1-Sunday, 7-Saturday) 1-7 + * %U Week of year (2 digits, zero padded) 00-53 + * %% Percent Character as a Literal % + * + * @param obj current object + * @param expr operator expression + */ + $dateToString (obj, expr) { + let fmt = expr['format']; + let date = computeValue(obj, expr['date']); + let matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g); + + for (let i = 0, len = matches.length; i < len; i++) { + let hdlr = DATE_SYM_TABLE[matches[i]]; + let value = hdlr; + + if (isArray(hdlr)) { + // reuse date operators + let fn = this[hdlr[0]]; + let pad = hdlr[1]; + value = padDigits(fn.call(this, obj, date), pad); + } + // replace the match with resolved value + fmt = fmt.replace(matches[i], value); + } + + return fmt + } +}; + +function padDigits (number, digits) { + return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number +} + +const literalOperators = { + /** + * Return a value without parsing. + * @param obj + * @param expr + */ + $literal (obj, expr) { + return expr + } +}; + +const setOperators = { + /** + * Returns true if two sets have the same elements. + * @param obj + * @param expr + */ + $setEquals (obj, expr) { + let args = computeValue(obj, expr); + let xs = unique(args[0]); + let ys = unique(args[1]); + return xs.length === ys.length && xs.length === intersection(xs, ys).length + }, + + /** + * Returns the common elements of the input sets. + * @param obj + * @param expr + */ + $setIntersection (obj, expr) { + let args = computeValue(obj, expr); + return intersection(args[0], args[1]) + }, + + /** + * Returns elements of a set that do not appear in a second set. + * @param obj + * @param expr + */ + $setDifference (obj, expr) { + let args = computeValue(obj, expr); + return args[0].filter(notInArray.bind(null, args[1])) + }, + + /** + * Returns a set that holds all elements of the input sets. + * @param obj + * @param expr + */ + $setUnion (obj, expr) { + let args = computeValue(obj, expr); + return union(args[0], args[1]) + }, + + /** + * Returns true if all elements of a set appear in a second set. + * @param obj + * @param expr + */ + $setIsSubset (obj, expr) { + let args = computeValue(obj, expr); + return intersection(args[0], args[1]).length === args[0].length + }, + + /** + * Returns true if any elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $anyElementTrue (obj, expr) { + // mongodb nests the array expression in another + let args = computeValue(obj, expr)[0]; + return args.some(truthy) + }, + + /** + * Returns true if all elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $allElementsTrue (obj, expr) { + // mongodb nests the array expression in another + let args = computeValue(obj, expr)[0]; + return args.every(truthy) + } +}; + +const stringOperators = { + + /** + * Concatenates two strings. + * + * @param obj + * @param expr + * @returns {string|*} + */ + $concat (obj, expr) { + let args = computeValue(obj, expr); + // does not allow concatenation with nulls + if ([null, undefined].some(inArray.bind(null, args))) { + return null + } + return args.join('') + }, + + /** + * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfBytes (obj, expr) { + let arr = computeValue(obj, expr); + + if (isNil(arr[0])) return null + + assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string'); + assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string'); + + let str = arr[0]; + let searchStr = arr[1]; + let start = arr[2]; + let end = arr[3]; + + assert( + isNil(start) || (isNumber(start) && start >= 0 && Math.round(start) === start), + '$indexOfBytes third operand must resolve to a non-negative integer' + ); + start = start || 0; + + assert( + isNil(end) || (isNumber(end) && end >= 0 && Math.round(end) === end), + '$indexOfBytes fourth operand must resolve to a non-negative integer' + ); + end = end || str.length; + + if (start > end) return -1 + + let index = str.substring(start, end).indexOf(searchStr); + return (index > -1) + ? index + start + : index + }, + + /** + * Splits a string into substrings based on a delimiter. + * If the delimiter is not found within the string, returns an array containing the original string. + * + * @param {Object} obj + * @param {Array} expr + * @return {Array} Returns an array of substrings. + */ + $split (obj, expr) { + let args = computeValue(obj, expr); + assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])); + assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])); + return args[0].split(args[1]) + }, + + /** + * Compares two strings and returns an integer that reflects the comparison. + * + * @param obj + * @param expr + * @returns {number} + */ + $strcasecmp (obj, expr) { + let args = computeValue(obj, expr); + args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase(); + args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase(); + if (args[0] > args[1]) { + return 1 + } + return (args[0] < args[1]) ? -1 : 0 + }, + + /** + * Returns a substring of a string, starting at a specified index position and including the specified number of characters. + * The index is zero-based. + * + * @param obj + * @param expr + * @returns {string} + */ + $substr (obj, expr) { + let args = computeValue(obj, expr); + if (isString(args[0])) { + if (args[1] < 0) { + return '' + } else if (args[2] < 0) { + return args[0].substr(args[1]) + } else { + return args[0].substr(args[1], args[2]) + } + } + return '' + }, + + /** + * Converts a string to lowercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toLower (obj, expr) { + let value = computeValue(obj, expr); + return isEmpty(value) ? '' : value.toLowerCase() + }, + + /** + * Converts a string to uppercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toUpper (obj, expr) { + let value = computeValue(obj, expr); + return isEmpty(value) ? '' : value.toUpperCase() + } +}; + +/** + * Aggregation framework variable operators + */ + +const variableOperators = { + /** + * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. + * + * @param obj + * @param expr + * @returns {*} + */ + $let (obj, expr) { + let varsExpr = expr['vars']; + let inExpr = expr['in']; + + // resolve vars + let originals = {}; + let varsKeys = keys(varsExpr); + each(varsKeys, (key) => { + let val = computeValue(obj, varsExpr[key]); + let tempKey = '$' + key; + // set value on object using same technique as in "$map" + originals[tempKey] = obj[tempKey]; + obj[tempKey] = val; + }); + + let value = computeValue(obj, inExpr); + + // cleanup and restore + each(varsKeys, (key) => { + let tempKey = '$' + key; + if (isUndefined(originals[tempKey])) { + delete obj[tempKey]; + } else { + obj[tempKey] = originals[tempKey]; + } + }); + + return value + } +}; + +// combine aggregate operators +const aggregateOperators = Object.assign( + {}, + arithmeticOperators, + arrayOperators, + booleanOperators, + comparisonOperators, + conditionalOperators, + dateOperators, + literalOperators, + setOperators, + stringOperators, + variableOperators +); + +// operator definitions +const OPERATORS = { + 'aggregate': aggregateOperators, + 'group': groupOperators, + 'pipeline': pipelineOperators, + 'projection': projectionOperators, + 'query': queryOperators +}; + +/** + * Returns the operators defined for the given operator classes + */ +function ops () { + return reduce(arguments, (acc, cls) => into(acc, keys(OPERATORS[cls])), []) +} + +/** + * Add new operators + * + * @param opClass the operator class to extend + * @param fn a function returning an object of new operators + */ +function addOperators (opClass, fn) { + + const newOperators = fn(_internal()); + + // ensure correct type specified + assert(has(OPERATORS, opClass), `Invalid operator class ${opClass}`); + + let operators = OPERATORS[opClass]; + + // check for existing operators + each(newOperators, (fn, op) => { + assert(/^\$\w+$/.test(op), `Invalid operator name ${op}`); + assert(!has(operators, op), `${op} already exists for '${opClass}' operators`); + }); + + let wrapped = {}; + + switch (opClass) { + case OP_QUERY: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (selector, value) => { + return { + test: (obj) => { + // value of field must be fully resolved. + let lhs = resolve(obj, selector); + let result = f.call(ctx, selector, lhs, value); + if (isBoolean(result)) { + return result + } else if (result instanceof Query) { + return result.test(obj) + } else { + err("Invalid return type for '" + op + "'. Must return a Boolean or Query"); + } + } + } + } + })(fn, newOperators); + }); + break + case OP_PROJECTION: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (obj, expr, selector) => { + let lhs = resolve(obj, selector); + return f.call(ctx, selector, lhs, expr) + } + })(fn, newOperators); + }); + break + default: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (...args) => { + return f.apply(ctx, args) + } + })(fn, newOperators); + }); + } + + // toss the operator salad :) + Object.assign(OPERATORS[opClass], wrapped); +} + +/** + * Internal functions + */ + +// Settings used by Mingo internally +const settings = { + key: '_id' +}; + +/** + * Setup default settings for Mingo + * @param options + */ +function setup (options) { + Object.assign(settings, options || {}); +} + +/** + * Implementation of system variables + * @type {Object} + */ +const systemVariables = { + '$$ROOT' (obj, expr, opt) { + return opt.root + }, + '$$CURRENT' (obj, expr, opt) { + return obj + } +}; + +/** + * Implementation of $redact variables + * + * Each function accepts 3 arguments (obj, expr, opt) + * + * @type {Object} + */ +const redactVariables = { + '$$KEEP' (obj) { + return obj + }, + '$$PRUNE' () { + return undefined + }, + '$$DESCEND' (obj, expr, opt) { + // traverse nested documents iff there is a $cond + if (!has(expr, '$cond')) return obj + + let result; + + each(obj, (current, key) => { + if (isObjectLike(current)) { + if (isArray(current)) { + result = []; + each(current, (elem) => { + if (isObject(elem)) { + elem = redactObj(elem, expr, opt); + } + if (!isNil(elem)) result.push(elem); + }); + } else { + result = redactObj(current, expr, opt); + } + + if (isNil(result)) { + delete obj[key]; // pruned result + } else { + obj[key] = result; + } + } + }); + return obj + } +}; + +// system variables +const SYS_VARS = keys(systemVariables); +const REDACT_VARS = keys(redactVariables); + +/** + * Returns the key used as the collection's objects ids + */ +function idKey () { + return settings.key +} + +/** + * Retrieve the value of a given key on an object + * @param obj + * @param field + * @returns {*} + * @private + */ +function getValue (obj, field) { + return obj[field] +} + +/** + * Resolve the value of the field (dot separated) on the given object + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) + * @returns {*} + */ +function resolve (obj, selector, deepFlag = false) { + let names = selector.split('.'); + let value = obj; + + for (let i = 0; i < names.length; i++) { + let isText = names[i].match(/^\d+$/) === null; + + if (isText && isArray(value)) { + // On the first iteration, we check if we received a stop flag. + // If so, we stop to prevent iterating over a nested array value + // on consecutive object keys in the selector. + if (deepFlag === true && i === 0) { + return value + } + + value = value.map((item) => resolve(item, names[i], true)); + + // we mark this value as being multi-valued + addMeta(value, { isMulti: true }); + + // we unwrap for arrays of unit length + // this avoids excess wrapping when resolving deeply nested arrays + if (value.length === 1) { + value = value[0]; + } + } else { + value = getValue(value, names[i]); + deepFlag = false; // reset stop flag when we do a direct lookup + } + + if (isNil(value)) break + } + + return value +} + +/** + * Returns the full object to the resolved value given by the selector. + * This function excludes empty values as they aren't practically useful. + * + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + */ +function resolveObj (obj, selector) { + if (isNil(obj)) return + + let names = selector.split('.'); + let key = names[0]; + // get the next part of the selector + let next = names.length === 1 || names.slice(1).join('.'); + let isIndex = key.match(/^\d+$/) !== null; + let hasNext = names.length > 1; + let result; + let value; + + try { + if (isArray(obj)) { + if (isIndex) { + result = getValue(obj, key); + if (hasNext) { + result = resolveObj(result, next); + } + assert(!isUndefined(result)); + result = [result]; + } else { + result = []; + each(obj, (item) => { + value = resolveObj(item, selector); + if (!isNil(value)) result.push(value); + }); + assert(result.length > 0); + } + } else { + value = getValue(obj, key); + if (hasNext) { + value = resolveObj(value, next); + } + assert(!isUndefined(value)); + result = {}; + result[key] = value; + } + } catch (e) { + result = undefined; + } + + return result +} + +/** + * Walk the object graph and execute the given transform function + * @param {Object|Array} obj The object to traverse + * @param {String} selector The selector + * @param {Function} fn Function to execute for value at the end the traversal + * @param {Boolean} force Force generating missing parts of object graph + * @return {*} + */ +function traverse (obj, selector, fn, force = false) { + let names = selector.split('.'); + let key = names[0]; + let next = names.length === 1 || names.slice(1).join('.'); + + if (names.length === 1) { + fn(obj, key); + } else { // nested objects + if (isArray(obj) && !/^\d+$/.test(key)) { + each(obj, (item) => { + traverse(item, selector, fn, force); + }); + } else { + // force the rest of the graph while traversing + if (force === true) { + let exists = has(obj, key); + if (!exists || isNil(obj[key])) { + obj[key] = {}; + } + } + traverse(obj[key], next, fn, force); + } + } +} + +/** + * Set the value of the given object field + * + * @param obj {Object|Array} the object context + * @param selector {String} path to field + * @param value {*} the value to set + */ +function setValue (obj, selector, value) { + traverse(obj, selector, (item, key) => { + item[key] = value; + }, true); +} + +function removeValue (obj, selector) { + traverse(obj, selector, (item, key) => { + if (isArray(item) && /^\d+$/.test(key)) { + item.splice(parseInt(key), 1); + } else if (isObject(item)) { + delete item[key]; + } + }); +} + +/** + * Simplify expression for easy evaluation with query operators map + * @param expr + * @returns {*} + */ +function normalize (expr) { + // normalized primitives + if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { + return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr } + } + + // normalize object expression + if (isObjectLike(expr)) { + let exprKeys = keys(expr); + let noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0; + + // no valid query operator found, so we do simple comparison + if (noQuery) { + return { '$eq': expr } + } + + // ensure valid regex + if (inArray(exprKeys, '$regex')) { + let regex = expr['$regex']; + let options = expr['$options'] || ''; + let modifiers = ''; + if (isString(regex)) { + modifiers += (regex.ignoreCase || options.indexOf('i') >= 0) ? 'i' : ''; + modifiers += (regex.multiline || options.indexOf('m') >= 0) ? 'm' : ''; + modifiers += (regex.global || options.indexOf('g') >= 0) ? 'g' : ''; + regex = new RegExp(regex, modifiers); + } + expr['$regex'] = regex; + delete expr['$options']; + } + } + + return expr +} + +/** + * Computes the actual value of the expression using the given object as context + * + * @param obj the current object from the collection + * @param expr the expression for the given field + * @param field the field name (may also be an aggregate operator) + * @param opt {Object} extra options + * @returns {*} + */ +function computeValue (obj, expr, field = null, opt = {}) { + opt.root = opt.root || obj; + + // if the field of the object is a valid operator + if (inArray(ops(OP_AGGREGATE), field)) { + return aggregateOperators[field](obj, expr, opt) + } + + // we also handle $group accumulator operators + if (inArray(ops(OP_GROUP), field)) { + // we first fully resolve the expression + obj = computeValue(obj, expr, null, opt); + assert(isArray(obj), field + ' expression must resolve to an array'); + // we pass a null expression because all values have been resolved + return groupOperators[field](obj, null, opt) + } + + // if expr is a variable for an object field + // field not used in this case + if (isString(expr) && expr.length > 0 && expr[0] === '$') { + // we return system variables as literals + if (inArray(SYS_VARS, expr)) { + return systemVariables[expr](obj, null, opt) + } else if (inArray(REDACT_VARS, expr)) { + return expr + } + + // handle selectors with explicit prefix + let sysVar = SYS_VARS.filter((v) => expr.indexOf(v + '.') === 0); + + if (sysVar.length === 1) { + sysVar = sysVar[0]; + if (sysVar === '$$ROOT') { + obj = opt.root; + } + expr = expr.substr(sysVar.length); // '.' prefix will be sliced off below + } + + return resolve(obj, expr.slice(1)) + } + + // check and return value if already in a resolved state + switch (jsType(expr)) { + case T_ARRAY: + return expr.map((item) => computeValue(obj, item)) + case T_OBJECT: + let result = {}; + each(expr, (val, key) => { + result[key] = computeValue(obj, val, key, opt); + // must run ONLY one aggregate operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { + // there should be only one operator + assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'"); + result = result[key]; + return false // break + } + }); + return result + default: + return expr + } +} + +/** + * Returns a slice of the array + * + * @param {Array} xs + * @param {Number} skip + * @param {Number} limit + * @return {Array} + */ +function slice (xs, skip, limit = null) { + // MongoDB $slice works a bit differently from Array.slice + // Uses single argument for 'limit' and array argument [skip, limit] + if (isNil(limit)) { + if (skip < 0) { + skip = Math.max(0, xs.length + skip); + limit = xs.length - skip + 1; + } else { + limit = skip; + skip = 0; + } + } else { + if (skip < 0) { + skip = Math.max(0, xs.length + skip); + } + assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number'); + limit += skip; + } + return Array.prototype.slice.apply(xs, [skip, limit]) +} + +/** + * Compute the standard deviation of the data set + * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". + * @return {Number} + */ +function stddev (ctx) { + let sum = reduce(ctx.data, (acc, n) => acc + n, 0); + let N = ctx.data.length || 1; + let correction = ctx.sampled === true ? 1 : 0; + let avg = sum / (N - correction); + return Math.sqrt(reduce(ctx.data, (acc, n) => acc + Math.pow(n - avg, 2), 0) / N) +} + +/** + * Redact an object + * @param {Object} obj The object to redact + * @param {*} expr The redact expression + * @param {*} opt Options for value + * @return {*} Returns the redacted value + */ +function redactObj (obj, expr, opt = {}) { + opt.root = opt.root || obj; + + let result = computeValue(obj, expr, null, opt); + return inArray(REDACT_VARS, result) + ? redactVariables[result](obj, expr, opt) + : result +} + +/** + * Exported to the users to allow writing custom operators + */ +function _internal () { + return { + computeValue, + idKey, + ops, + resolve, + assert, + clone, + each, + err, + getType, + has, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isRegExp, + isString, + isUndefined, + keys, + map + } +} + +/** + * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` + */ +const CollectionMixin = { + + /** + * Runs a query and returns a cursor to the result + * @param criteria + * @param projection + * @returns {Cursor} + */ + query (criteria, projection) { + return new Query(criteria).find(this.toJSON(), projection) + }, + + /** + * Runs the given aggregation operators on this collection + * @params pipeline + * @returns {Array} + */ + aggregate (pipeline) { + return new Aggregator(pipeline).run(this.toJSON()) + } +}; + +const VERSION = '1.3.3'; + +// mingo! +var index = { + _internal, + Aggregator, + CollectionMixin, + Cursor, + OP_AGGREGATE, + OP_GROUP, + OP_PIPELINE, + OP_PROJECTION, + OP_QUERY, + Query, + VERSION, + addOperators, + aggregate, + find, + remove, + setup +}; + +export default index; diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js new file mode 100644 index 0000000..c830940 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js @@ -0,0 +1,4212 @@ +// mingo.js 1.3.3 +// Copyright (c) 2017 Francis Asante +// https://github.com/kofrasa/mingo +// MIT + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.mingo = factory()); +}(this, (function () { 'use strict'; + +/** + * Polyfill to add native methods for non-supported environments. + */ + +// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new Error('Function.prototype.bind - what is trying to be bound is not callable'); + } + + var aArgs = Array.prototype.slice.call(arguments, 1); + var fToBind = this; + var fNOP = function fNOP() {}; + var fBound = function fBound() { + return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + if (this.prototype) { + // Function.prototype doesn't have a prototype property + fNOP.prototype = this.prototype; + } + fBound.prototype = new fNOP(); + + return fBound; + }; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function value(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); + var len = o.length >>> 0; + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + + var thisArg = arguments[1]; + var k = 0; + + while (k < len) { + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return kValue; + } + k++; + } + return undefined; + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + value: function value(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); + var len = o.length >>> 0; + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + + var thisArg = arguments[1]; + var k = 0; + while (k < len) { + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return k; + } + k++; + } + return -1; + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes +if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + value: function value(searchElement, fromIndex) { + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); + var len = o.length >>> 0; + + if (len === 0) { + return false; + } + var n = fromIndex | 0; + var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); + + function sameValueZero(x, y) { + return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); + } + + while (k < len) { + if (sameValueZero(o[k], searchElement)) { + return true; + } + k++; + } + return false; + } + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign +if (typeof Object.assign != 'function') { + Object.assign = function (target, varArgs) { + // .length of function is 2 + + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + var args = Array.prototype.slice.call(arguments); + + for (var index = 1; index < args.length; index++) { + var nextSource = args[index]; + + if (nextSource != null) { + // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (nextSource.hasOwnProperty(nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }; +} + +// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html +if (!Object.keys) { + Object.keys = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.keys called on a non-object'); + } + + var result = []; + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(k); + } + } + return result; + }; +} + +// https://github.com/es-shims/Object.values/blob/master/implementation.js +if (!Object.values) { + Object.values = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.values called on a non-object'); + } + var result = []; + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(o[k]); + } + } + return result; + }; +} + +// Javascript native types +var T_NULL = 'null'; +var T_UNDEFINED = 'undefined'; +var T_BOOL = 'bool'; +var T_BOOLEAN = 'boolean'; +var T_NUMBER = 'number'; +var T_STRING = 'string'; +var T_DATE = 'date'; +var T_REGEX = 'regex'; +var T_REGEXP = 'regexp'; +var T_ARRAY = 'array'; +var T_OBJECT = 'object'; +var T_FUNCTION = 'function'; + +// no array, object, or function types +var JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP]; + +// operator classes +var OP_AGGREGATE = 'aggregate'; +var OP_GROUP = 'group'; +var OP_PIPELINE = 'pipeline'; +var OP_PROJECTION = 'projection'; +var OP_QUERY = 'query'; + +/** + * Utility functions + */ + +function assert(condition, message) { + if (falsey(condition)) err(message); +} + +/** + * Deep clone an object + * @param obj + * @returns {*} + */ +function clone(obj) { + switch (jsType(obj)) { + case T_ARRAY: + return obj.map(clone); + case T_OBJECT: + return map(obj, clone); + default: + return obj; + } +} + +function getType(v) { + if (v === null) return 'Null'; + if (v === undefined) return 'Undefined'; + return v.constructor.name; +} +function jsType(v) { + return getType(v).toLowerCase(); +} +function isBoolean(v) { + return jsType(v) === T_BOOLEAN; +} +function isString(v) { + return jsType(v) === T_STRING; +} +function isNumber(v) { + return jsType(v) === T_NUMBER; +} +function isArray(v) { + return jsType(v) === T_ARRAY; +} +function isArrayLike(v) { + return !isNil(v) && has(v, 'length'); +} +function isObject(v) { + return jsType(v) === T_OBJECT; +} +function isObjectLike(v) { + return v === Object(v); +} // objects, arrays, functions, date, custom object +function isDate(v) { + return jsType(v) === T_DATE; +} +function isRegExp(v) { + return jsType(v) === T_REGEXP; +} +function isFunction(v) { + return jsType(v) === T_FUNCTION; +} +function isNil(v) { + return isNull(v) || isUndefined(v); +} +function isNull(v) { + return jsType(v) === T_NULL; +} +function isUndefined(v) { + return jsType(v) === T_UNDEFINED; +} +function inArray(arr, item) { + return arr.includes(item); +} +function notInArray(arr, item) { + return !arr.includes(item); +} +function truthy(arg) { + return !!arg; +} +function falsey(arg) { + return !arg; +} +function isEmpty(x) { + return isNil(x) || isArray(x) && x.length === 0 || isObject(x) && keys(x).length === 0 || !x; +} +// ensure a value is an array +function array(x) { + return isArray(x) ? x : [x]; +} +function has(obj, prop) { + return obj.hasOwnProperty(prop); +} +function err(s) { + throw new Error(s); +} +function keys(o) { + return Object.keys(o); +} + +// ////////////////// UTILS //////////////////// + +// internal constants +var __MINGO_META = '__mingo__'; + +function addMeta(obj, value) { + obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value); +} + +function hasMeta(obj, value) { + return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]); +} + +function dropMeta(obj) { + if (has(obj, __MINGO_META)) delete obj[__MINGO_META]; +} + +/** + * Iterate over an array or object + * @param {Array|Object} obj An object-like value + * @param {Function} fn The callback to run per item + * @param {*} ctx The object to use a context + * @return {void} + */ +function each(obj, fn) { + var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'"); + + if (isArrayLike(obj)) { + for (var i = 0, len = obj.length; i < len; i++) { + if (fn.call(ctx, obj[i], i, obj) === false) break; + } + } else { + for (var k in obj) { + if (has(obj, k)) { + if (fn.call(ctx, obj[k], k, obj) === false) break; + } + } + } +} + +/** + * Transform values in a collection + * + * @param {Array|Object} obj An array/object whose values to transform + * @param {Function} fn The transform function + * @param {*} ctx The value to use as the "this" context for the transform + * @return {Array|Object} Result object after applying the transform + */ +function map(obj, fn) { + var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + if (isArray(obj)) { + return obj.map(fn, ctx); + } else if (isObject(obj)) { + var o = {}; + each(obj, function (v, k) { + return o[k] = fn.call(ctx, v, k); + }, obj); + return o; + } +} + +/** + * Reduce any array-like object + * @param collection + * @param fn + * @param accumulator + * @returns {*} + */ +function reduce(collection, fn, accumulator) { + if (isArray(collection)) return collection.reduce(fn, accumulator); + // array-like objects + each(collection, function (v, k) { + return accumulator = fn(accumulator, v, k, collection); + }); + return accumulator; +} + +/** + * Returns the intersection between two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} Result array + */ +function intersection(xs, ys) { + return xs.filter(inArray.bind(null, ys)); +} + +/** + * Returns the union of two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} The result array + */ +function union(xs, ys) { + return into(into([], xs), ys.filter(notInArray.bind(null, xs))); +} + +/** + * Flatten the array + * + * @param {Array} xs The array to flatten + * @param {Number} depth The number of nested lists to iterate + */ + + +/** + * Determine whether two values are the same or strictly equivalent + * + * @param {*} a The first value + * @param {*} b The second value + * @return {Boolean} Result of comparison + */ +function isEqual(a, b) { + // strictly equal must be equal. + if (a === b) return true; + + // unequal types and functions cannot be equal. + var type = jsType(a); + if (type !== jsType(b) || type === T_FUNCTION) return false; + + // we treat NaN as the same + if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true; + + // leverage toString for Date and RegExp types + if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString(); + + if (type === T_ARRAY) { + if (a.length === b.length && a.length === 0) return true; + if (a.length !== b.length) return false; + for (var i = 0, len = a.length; i < len; i++) { + if (!isEqual(a[i], b[i])) return false; + } + } else if (type === T_OBJECT) { + // deep compare objects + var ka = keys(a); + var kb = keys(b); + + // check length of keys early + if (ka.length !== kb.length) return false; + + // we know keys are strings so we sort before comparing + ka.sort(); + kb.sort(); + + // compare keys + if (!isEqual(ka, kb)) return false; + + // back to the drawing board + for (var _i = 0, _len = ka.length; _i < _len; _i++) { + var temp = ka[_i]; + if (!isEqual(a[temp], b[temp])) return false; + } + } else { + // we do not know how to compare custom types so we guess + return getHash(a) === getHash(b); + } + // best effort says values are equal :) + return true; +} + +/** + * Return a new unique version of the collection + * @param {Array} xs The input collection + * @return {Array} A new collection with unique values + */ +function unique(xs) { + var h = {}; + var arr = []; + each(xs, function (item) { + var k = getHash(item); + if (!has(h, k)) { + arr.push(item); + h[k] = 0; + } + }); + return arr; +} + +/** + * Generates a random string of max length range [24,27] + * @param n Size of string to return + * @returns {*} + */ +function randomString(n) { + return (Math.E + Math.random()).toString(36).slice(2, n + 2); +} + +/** + * Encode value using a simple optimistic stable scheme. + * @param value + * @returns {*} + */ +function encode(value) { + var type = jsType(value); + switch (type) { + case T_FUNCTION: + return randomString(7); + case T_BOOLEAN: + case T_NUMBER: + case T_REGEXP: + return value.toString(); + case T_STRING: + return JSON.stringify(value); + case T_DATE: + return value.toISOString(); + case T_NULL: + case T_UNDEFINED: + return type; + case T_ARRAY: + return '[' + map(value, function (v) { + return '' + encode(v); + }) + ']'; + default: + var prefix = type === T_OBJECT ? '' : getType(value) + '|'; + var objKeys = keys(value); + objKeys.sort(); + return prefix + '{' + map(objKeys, function (k) { + return encode(k) + ':' + encode(value[k]); + }) + '}'; + } +} + +/** + * Generate hash code + * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery + * + * @param value + * @returns {*} + */ +function getHash(value) { + var hash = 0, + i = void 0, + chr = void 0, + len = void 0, + s = encode(value); + if (s.length === 0) return hash; + for (i = 0, len = s.length; i < len; i++) { + chr = s.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; // Convert to 32bit integer + } + return hash.toString(); +} + +/** + * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee + * + * This implementation treats null/undefined sort keys as less than every other type + * + * @param {Array} collection + * @param {Function} fn The function used to resolve sort keys + * @param {Object} ctx The context to use for calling `fn` + * @return {Array} Returns a new sorted array by the given iteratee + */ +function sortBy(collection, fn) { + var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + var sortKeys = {}; + var sorted = []; + var len = collection.length; + var result = []; + + for (var i = 0; i < len; i++) { + var obj = collection[i]; + var key = fn.call(ctx, obj, i); + if (isNil(key)) { + // objects with null keys will go in first + result.push(obj); + } else { + var hash = getHash(obj); + if (!has(sortKeys, hash)) { + sortKeys[hash] = [key, i]; + } + sorted.push(obj); + } + } + // use native array sorting but enforce stableness + sorted.sort(function (a, b) { + var A = sortKeys[getHash(a)]; + var B = sortKeys[getHash(b)]; + if (A[0] < B[0]) return -1; + if (A[0] > B[0]) return 1; + if (A[1] < B[1]) return -1; + if (A[1] > B[1]) return 1; + return 0; + }); + return into(result, sorted); +} + +/** + * Groups the collection into sets by the returned key + * + * @param collection + * @param fn {Function} to compute the group key of an item in the collection + * @param ctx {Object} The context to use for calling `fn` + * @returns {{keys: Array, groups: Array}} + */ +function groupBy(collection, fn, ctx) { + var result = { + 'keys': [], + 'groups': [] + }; + var lookup = {}; + each(collection, function (obj) { + var key = fn.call(ctx, obj); + var hash = getHash(key); + var index = -1; + + if (isUndefined(lookup[hash])) { + index = result.keys.length; + lookup[hash] = index; + result.keys.push(key); + result.groups.push([]); + } + index = lookup[hash]; + result.groups[index].push(obj); + }); + return result; +} + +/** + * Push elements in given array into target array + * + * @param {*} target The array to push into + * @param {*} xs The array of elements to push + */ +function into(target, xs) { + Array.prototype.push.apply(target, xs); + return target; +} + +/** + * Find the insert index for the given key in a sorted array. + * + * @param {*} array The sorted array to search + * @param {*} key The search key + */ +function findInsertIndex(array, key) { + // uses binary search + var lo = 0; + var hi = array.length - 1; + while (lo <= hi) { + var mid = Math.round(lo + (hi - lo) / 2); + if (key < array[mid]) { + hi = mid - 1; + } else if (key > array[mid]) { + lo = mid + 1; + } else { + return mid; + } + } + return lo; +} + +/** + * This is a generic memoization function + * + * This implementation uses a cache independent of the function being memoized + * to allow old values to be garbage collected when the memoized function goes out of scope. + * + * @param {*} fn The function object to memoize + */ +function memoize(fn) { + var _this = this; + + return function (cache) { + return function () { + for (var _len2 = arguments.length, args = Array(_len2), _key = 0; _key < _len2; _key++) { + args[_key] = arguments[_key]; + } + + var key = getHash(args); + if (!has(cache, key)) { + cache[key] = fn.apply(_this, args); + } + return cache[key]; + }; + }({/* storage */}); +} + +/** + * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ + */ + +var groupOperators = { + + /** + * Returns an array of all the unique values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {*} + */ + $addToSet: function $addToSet(collection, expr) { + return unique(this.$push(collection, expr)); + }, + + + /** + * Returns the sum of all the values in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $sum: function $sum(collection, expr) { + if (!isArray(collection)) return 0; + + if (isNumber(expr)) { + // take a short cut if expr is number literal + return collection.length * expr; + } + return reduce(this.$push(collection, expr).filter(isNumber), function (acc, n) { + return acc + n; + }, 0); + }, + + + /** + * Returns the highest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $max: function $max(collection, expr) { + var mapped = this.$push(collection, expr); + return reduce(mapped, function (acc, n) { + return isNil(acc) || n > acc ? n : acc; + }, undefined); + }, + + + /** + * Returns the lowest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $min: function $min(collection, expr) { + var mapped = this.$push(collection, expr); + return reduce(mapped, function (acc, n) { + return isNil(acc) || n < acc ? n : acc; + }, undefined); + }, + + + /** + * Returns an average of all the values in a group. + * + * @param collection + * @param expr + * @returns {number} + */ + $avg: function $avg(collection, expr) { + var data = this.$push(collection, expr).filter(isNumber); + var sum = reduce(data, function (acc, n) { + return acc + n; + }, 0); + return sum / (data.length || 1); + }, + + + /** + * Returns an array of all values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $push: function $push(collection, expr) { + if (isNil(expr)) return collection; + return map(collection, function (obj) { + return computeValue(obj, expr); + }); + }, + + + /** + * Returns the first value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $first: function $first(collection, expr) { + return collection.length > 0 ? computeValue(collection[0], expr) : undefined; + }, + + + /** + * Returns the last value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $last: function $last(collection, expr) { + return collection.length > 0 ? computeValue(collection[collection.length - 1], expr) : undefined; + }, + + + /** + * Returns the population standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number} + */ + $stdDevPop: function $stdDevPop(collection, expr) { + var data = this.$push(collection, expr).filter(isNumber); + return stddev({ data: data, sampled: false }); + }, + + + /** + * Returns the sample standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number|null} + */ + $stdDevSamp: function $stdDevSamp(collection, expr) { + var data = this.$push(collection, expr).filter(isNumber); + return stddev({ data: data, sampled: true }); + } +}; + +/** + * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ + */ +var projectionOperators = { + + /** + * Projects the first element in an array that matches the query condition. + * + * @param obj + * @param field + * @param expr + */ + $: function $(obj, expr, field) { + err('$ not implemented'); + }, + + + /** + * Projects only the first element from an array that matches the specified $elemMatch condition. + * + * @param obj + * @param field + * @param expr + * @returns {*} + */ + $elemMatch: function $elemMatch(obj, expr, field) { + var arr = resolve(obj, field); + var query = new Query(expr); + + if (isNil(arr) || !isArray(arr)) { + return undefined; + } + + for (var i = 0; i < arr.length; i++) { + if (query.test(arr[i])) { + return [arr[i]]; + } + } + + return undefined; + }, + + + /** + * Limits the number of elements projected from an array. Supports skip and limit slices. + * + * @param obj + * @param field + * @param expr + */ + $slice: function $slice(obj, expr, field) { + var xs = resolve(obj, field); + + if (!isArray(xs)) return xs; + + if (isArray(expr)) { + return slice(xs, expr[0], expr[1]); + } else if (isNumber(expr)) { + return slice(xs, expr); + } else { + err('Invalid argument type for $slice projection operator'); + } + }, + + + /** + * Returns the population standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number} + */ + $stdDevPop: function $stdDevPop(obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: false + }); + }, + + + /** + * Returns the sample standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number|null} + */ + $stdDevSamp: function $stdDevSamp(obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: true + }); + } +}; + +/** + * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ + */ +var pipelineOperators = { + + /** + * Adds new fields to documents. + * Outputs documents that contain all existing fields from the input documents and newly added fields. + * + * @param {Array} collection + * @param {*} expr + */ + $addFields: function $addFields(collection, expr) { + var newFields = keys(expr); + + return collection.map(function (obj) { + obj = clone(obj); + each(newFields, function (field) { + var subExpr = expr[field]; + var newValue = computeValue(obj, subExpr); + traverse(obj, field, function (o, key) { + o[key] = newValue; + }, true); + }); + return obj; + }); + }, + + + /** + * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $group: function $group(collection, expr) { + // lookup key for grouping + var ID_KEY = idKey(); + var objectId = expr[ID_KEY]; + + var partitions = groupBy(collection, function (obj) { + return computeValue(obj, objectId, objectId); + }); + + var result = []; + + // remove the group key + delete expr[ID_KEY]; + + each(partitions.keys, function (value, i) { + var obj = {}; + + // exclude undefined key value + if (!isUndefined(value)) { + obj[ID_KEY] = value; + } + + // compute remaining keys in expression + each(expr, function (val, key) { + obj[key] = accumulate(partitions.groups[i], key, val); + }); + result.push(obj); + }); + + return result; + }, + + + /** + * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. + * + * @param collection + * @param expr + */ + $lookup: function $lookup(collection, expr) { + var joinColl = expr.from; + var localField = expr.localField; + var foreignField = expr.foreignField; + var asField = expr.as; + + var errorMsg = "Invalid $lookup expression. "; + assert(isArray(joinColl), errorMsg + "'from' must be an array"); + assert(isString(foreignField), errorMsg + "'foreignField' must be a string"); + assert(isString(localField), errorMsg + "'localField' must be a string"); + assert(isString(asField), errorMsg + "'as' must be a string"); + + var result = []; + var hash = {}; + + function hashCode(v) { + return getHash(isNil(v) ? null : v); + } + + if (joinColl.length <= collection.length) { + each(joinColl, function (obj, i) { + var k = hashCode(obj[foreignField]); + hash[k] = hash[k] || []; + hash[k].push(i); + }); + + each(collection, function (obj) { + var k = hashCode(obj[localField]); + var indexes = hash[k] || []; + var newObj = clone(obj); + newObj[asField] = indexes.map(function (i) { + return clone(joinColl[i]); + }); + result.push(newObj); + }); + } else { + + each(collection, function (obj, i) { + var k = hashCode(obj[localField]); + hash[k] = hash[k] || []; + hash[k].push(i); + }); + + var tempResult = {}; + each(joinColl, function (obj) { + var k = hashCode(obj[foreignField]); + var indexes = hash[k] || []; + each(indexes, function (i) { + var newObj = tempResult[i] || clone(collection[i]); + newObj[asField] = newObj[asField] || []; + newObj[asField].push(clone(obj)); + tempResult[i] = newObj; + }); + }); + for (var i = 0, len = keys(tempResult).length; i < len; i++) { + result.push(tempResult[i]); + } + } + + return result; + }, + + + /** + * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. + * $match uses standard MongoDB queries. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $match: function $match(collection, expr) { + return new Query(expr).find(collection).all(); + }, + + + /** + * Reshapes a document stream. + * $project can rename, add, or remove fields as well as create computed values and sub-documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $project: function $project(collection, expr) { + if (isEmpty(expr)) { + return collection; + } + + // result collection + var projected = []; + var objKeys = keys(expr); + var idOnlyExcludedExpression = false; + var ID_KEY = idKey(); + + // validate inclusion and exclusion + var check = [false, false]; + each(expr, function (v, k) { + if (k === ID_KEY) return; + if (v === 0 || v === false) { + check[0] = true; + } else { + check[1] = true; + } + assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.'); + }); + + if (inArray(objKeys, ID_KEY)) { + var id = expr[ID_KEY]; + if (id === 0 || id === false) { + objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])); + assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key'); + idOnlyExcludedExpression = isEmpty(objKeys); + } + } else { + // if not specified the add the ID field + objKeys.push(ID_KEY); + } + + each(collection, function (obj) { + var cloneObj = {}; + var foundSlice = false; + var foundExclusion = false; + var dropKeys = []; + + if (idOnlyExcludedExpression) { + dropKeys.push(ID_KEY); + } + + each(objKeys, function (key) { + var subExpr = expr[key]; + var value = void 0; // final computed value of the key + + if (key !== ID_KEY && subExpr === 0) { + foundExclusion = true; + } + + if (key === ID_KEY && isEmpty(subExpr)) { + // tiny optimization here to skip over id + value = obj[key]; + } else if (isString(subExpr)) { + value = computeValue(obj, subExpr, key); + } else if (subExpr === 1 || subExpr === true) { + // For direct projections, we use the resolved object value + } else if (isObject(subExpr)) { + var operator = keys(subExpr); + operator = operator.length > 1 ? false : operator[0]; + + if (inArray(ops(OP_PROJECTION), operator)) { + // apply the projection operator on the operator expression for the key + if (operator === '$slice') { + // $slice is handled differently for aggregation and projection operations + if (array(subExpr[operator]).every(isNumber)) { + // $slice for projection operation + value = projectionOperators[operator](obj, subExpr[operator], key); + foundSlice = true; + } else { + // $slice for aggregation operation + value = computeValue(obj, subExpr, key); + } + } else { + value = projectionOperators[operator](obj, subExpr[operator], key); + } + } else { + // compute the value for the sub expression for the key + value = computeValue(obj, subExpr, key); + } + } else { + dropKeys.push(key); + return; + } + + // clone resolved values + var objValue = clone(resolveObj(obj, key)); + + if (!isUndefined(objValue)) { + Object.assign(cloneObj, objValue); + } + if (!isUndefined(value)) { + setValue(cloneObj, key, clone(value)); + } + }); + // if projection included $slice operator + // Also if exclusion fields are found or we want to exclude only the id field + // include keys that were not explicitly excluded + if (foundSlice || foundExclusion || idOnlyExcludedExpression) { + cloneObj = Object.assign(clone(obj), cloneObj); + each(dropKeys, function (key) { + return removeValue(cloneObj, key); + }); + } + projected.push(cloneObj); + }); + + return projected; + }, + + + /** + * Restricts the number of documents in an aggregation pipeline. + * + * @param collection + * @param value + * @returns {Object|*} + */ + $limit: function $limit(collection, value) { + return collection.slice(0, value); + }, + + + /** + * Skips over a specified number of documents from the pipeline and returns the rest. + * + * @param collection + * @param value + * @returns {*} + */ + $skip: function $skip(collection, value) { + return collection.slice(value); + }, + + + /** + * Takes an array of documents and returns them as a stream of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $unwind: function $unwind(collection, expr) { + var result = []; + var field = expr.substr(1); + each(collection, function (obj) { + // must throw an error if value is not an array + var value = getValue(obj, field); + + assert(isArray(value), "Target field '" + field + "' is not of type Array."); + + each(value, function (item) { + var tmp = clone(obj); + tmp[field] = item; + result.push(tmp); + }); + }); + return result; + }, + + + /** + * Takes all input documents and returns them in a stream of sorted documents. + * + * @param collection + * @param sortKeys + * @returns {*} + */ + $sort: function $sort(collection, sortKeys) { + if (!isEmpty(sortKeys) && isObject(sortKeys)) { + var modifiers = keys(sortKeys); + each(modifiers.reverse(), function (key) { + var grouped = groupBy(collection, function (obj) { + return resolve(obj, key); + }); + var sortedIndex = {}; + var getIndex = function getIndex(k) { + return sortedIndex[getHash(k)]; + }; + + var indexKeys = sortBy(grouped.keys, function (item, i) { + sortedIndex[getHash(item)] = i; + return item; + }); + + if (sortKeys[key] === -1) { + indexKeys.reverse(); + } + collection = []; + each(indexKeys, function (item) { + return into(collection, grouped.groups[getIndex(item)]); + }); + }); + } + return collection; + }, + + + /** + * Groups incoming documents based on the value of a specified expression, + * then computes the count of documents in each distinct group. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sortByCount: function $sortByCount(collection, expr) { + var newExpr = { count: { $sum: 1 } }; + newExpr[idKey()] = expr; + + return this.$sort(this.$group(collection, newExpr), { count: -1 }); + }, + + + /** + * Randomly selects the specified number of documents from its input. + * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sample: function $sample(collection, expr) { + var size = expr.size; + assert(isNumber(size), '$sample size must be a positive integer'); + + var result = []; + var len = collection.length; + for (var i = 0; i < size; i++) { + var n = Math.floor(Math.random() * len); + result.push(collection[n]); + } + return result; + }, + + + /** + * Returns a document that contains a count of the number of documents input to the stage. + * @param {Array} collection + * @param {String} expr + * @return {Object} + */ + $count: function $count(collection, expr) { + assert(isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', 'Invalid expression value for $count'); + + var result = {}; + result[expr] = collection.length; + return result; + }, + + + /** + * Replaces a document with the specified embedded document or new one. + * The replacement document can be any valid expression that resolves to a document. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $replaceRoot: function $replaceRoot(collection, expr) { + var newRoot = expr.newRoot; + var result = []; + each(collection, function (obj) { + obj = computeValue(obj, newRoot); + assert(isObject(obj), '$replaceRoot expression must return a valid JS object'); + result.push(obj); + }); + return result; + }, + + + /** + * Restricts the contents of the documents based on information stored in the documents themselves. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ + */ + $redact: function $redact(collection, expr) { + return collection.map(function (obj) { + return redactObj(clone(obj), expr); + }); + }, + + + /** + * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ + */ + $bucket: function $bucket(collection, expr) { + var boundaries = expr.boundaries; + var defaultKey = expr.default; + var lower = boundaries[0]; // inclusive + var upper = boundaries[boundaries.length - 1]; // exclusive + var outputExpr = expr.output || { 'count': { '$sum': 1 } }; + + assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements"); + var boundType = getType(lower); + + for (var i = 0, len = boundaries.length - 1; i < len; i++) { + assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type"); + assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order"); + } + + if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { + assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range"); + } + + var grouped = {}; + each(boundaries, function (k) { + return grouped[k] = []; + }); + + // add default key if provided + if (!isNil(defaultKey)) grouped[defaultKey] = []; + + each(collection, function (obj) { + var key = computeValue(obj, expr.groupBy); + + if (isNil(key) || key < lower || key >= upper) { + assert(!isNil(defaultKey), '$bucket require a default for out of range values'); + grouped[defaultKey].push(obj); + } else if (key >= lower && key < upper) { + var index = findInsertIndex(boundaries, key); + var boundKey = boundaries[Math.max(0, index - 1)]; + grouped[boundKey].push(obj); + } else { + err("$bucket 'groupBy' expression must resolve to a value in range of boundaries"); + } + }); + + // upper bound is exclusive so we remove it + boundaries.pop(); + if (!isNil(defaultKey)) boundaries.push(defaultKey); + + return map(boundaries, function (key) { + var acc = accumulate(grouped[key], null, outputExpr); + return Object.assign(acc, { '_id': key }); + }); + }, + $bucketAuto: function $bucketAuto(collection, expr) { + var outputExpr = expr.output || { 'count': { '$sum': 1 } }; + var groupByExpr = expr.groupBy; + var bucketCount = expr.buckets; + + assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount); + + var approxBucketSize = Math.round(collection.length / bucketCount); + if (approxBucketSize < 1) { + approxBucketSize = 1; + } + + var computeValueOptimized = memoize(computeValue); + var grouped = {}; + var remaining = []; + var sorted = sortBy(collection, function (o) { + var key = computeValueOptimized(o, groupByExpr); + if (isNil(key)) { + remaining.push(o); + } else { + grouped[key] || (grouped[key] = []); + grouped[key].push(o); + } + return key; + }); + + var ID_KEY = idKey(); + var result = []; + var index = 0; // counter for sorted collection + + for (var i = 0, len = sorted.length; i < bucketCount && index < len; i++) { + var boundaries = {}; + var bucketItems = []; + + for (var j = 0; j < approxBucketSize && index < len; j++) { + var key = computeValueOptimized(sorted[index], groupByExpr); + + if (isNil(key)) key = null; + + // populate current bucket with all values for current key + into(bucketItems, isNil(key) ? remaining : grouped[key]); + + // increase sort index by number of items added + index += isNil(key) ? remaining.length : grouped[key].length; + + // set the min key boundary if not already present + if (!has(boundaries, 'min')) boundaries.min = key; + + if (result.length > 0) { + var lastBucket = result[result.length - 1]; + lastBucket[ID_KEY].max = boundaries.min; + } + } + + // if is last bucket add remaining items + if (i == bucketCount - 1) { + into(bucketItems, sorted.slice(index)); + } + + result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })); + } + + if (result.length > 0) { + result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr); + } + + return result; + }, + + + /** + * Processes multiple aggregation pipelines within a single stage on the same set of input documents. + * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + */ + $facet: function $facet(collection, expr) { + return map(expr, function (pipeline) { + return aggregate(collection, pipeline); + }); + } +}; + +/** + * Returns the result of evaluating a $group operation over a collection + * + * @param collection + * @param field the name of the aggregate operator or field + * @param expr the expression of the aggregate operator for the field + * @returns {*} + */ +function accumulate(collection, field, expr) { + if (inArray(ops(OP_GROUP), field)) { + return groupOperators[field](collection, expr); + } + + if (isObject(expr)) { + var result = {}; + each(expr, function (val, key) { + result[key] = accumulate(collection, key, expr[key]); + // must run ONLY one group operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_GROUP), key)) { + result = result[key]; + // if there are more keys in expression this is bad + assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'"); + return false; // break + } + }); + return result; + } + + return undefined; +} + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + +/** + * Aggregator for defining filter using mongoDB aggregation pipeline syntax + * + * @param operators an Array of pipeline operators + * @constructor + */ +var Aggregator = function () { + function Aggregator(operators) { + classCallCheck(this, Aggregator); + + this.__operators = operators; + } + + /** + * Apply the pipeline operations over the collection by order of the sequence added + * + * @param collection an array of objects to process + * @param query the `Query` object to use as context + * @returns {Array} + */ + + + createClass(Aggregator, [{ + key: 'run', + value: function run(collection, query) { + if (!isEmpty(this.__operators)) { + // run aggregation pipeline + each(this.__operators, function (operator) { + var key = keys(operator); + assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), 'Invalid aggregation operator ' + key); + key = key[0]; + if (query && query instanceof Query) { + collection = pipelineOperators[key].call(query, collection, operator[key]); + } else { + collection = pipelineOperators[key](collection, operator[key]); + } + }); + } + return collection; + } + }]); + return Aggregator; +}(); + +/** + * Return the result collection after running the aggregation pipeline for the given collection + * + * @param collection + * @param pipeline + * @returns {Array} + */ +function aggregate(collection, pipeline) { + assert(isArray(pipeline), 'Aggregation pipeline must be an array'); + return new Aggregator(pipeline).run(collection); +} + +/** + * Cursor to iterate and perform filtering on matched objects + * @param collection + * @param query + * @param projection + * @constructor + */ +var Cursor = function () { + function Cursor(collection, query, projection) { + classCallCheck(this, Cursor); + + this.__query = query; + this.__collection = collection; + this.__projection = projection || query.__projection; + this.__operators = {}; + this.__result = false; + this.__position = 0; + } + + createClass(Cursor, [{ + key: '_fetch', + value: function _fetch() { + var _this = this; + + if (this.__result !== false) { + return this.__result; + } + + // inject projection operator + if (isObject(this.__projection)) { + Object.assign(this.__operators, { '$project': this.__projection }); + } + + assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); + + // filter collection + this.__result = this.__collection.filter(this.__query.test, this.__query); + var pipeline = []; + + each(['$sort', '$skip', '$limit', '$project'], function (op) { + if (has(_this.__operators, op)) { + var selected = {}; + selected[op] = _this.__operators[op]; + pipeline.push(selected); + } + }); + + if (pipeline.length > 0) { + var aggregator = new Aggregator(pipeline); + this.__result = aggregator.run(this.__result, this.__query); + } + return this.__result; + } + + /** + * Fetch and return all matched results + * @returns {Array} + */ + + }, { + key: 'all', + value: function all() { + return this._fetch(); + } + + /** + * Fetch and return the first matching result + * @returns {Object} + */ + + }, { + key: 'first', + value: function first() { + return this.count() > 0 ? this._fetch()[0] : null; + } + + /** + * Fetch and return the last matching object from the result + * @returns {Object} + */ + + }, { + key: 'last', + value: function last() { + return this.count() > 0 ? this._fetch()[this.count() - 1] : null; + } + + /** + * Counts the number of matched objects found + * @returns {Number} + */ + + }, { + key: 'count', + value: function count() { + return this._fetch().length; + } + + /** + * Returns a cursor that begins returning results only after passing or skipping a number of documents. + * @param {Number} n the number of results to skip. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + + }, { + key: 'skip', + value: function skip(n) { + Object.assign(this.__operators, { '$skip': n }); + return this; + } + + /** + * Constrains the size of a cursor's result set. + * @param {Number} n the number of results to limit to. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + + }, { + key: 'limit', + value: function limit(n) { + Object.assign(this.__operators, { '$limit': n }); + return this; + } + + /** + * Returns results ordered according to a sort specification. + * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + + }, { + key: 'sort', + value: function sort(modifier) { + Object.assign(this.__operators, { '$sort': modifier }); + return this; + } + + /** + * Returns the next document in a cursor. + * @returns {Object | Boolean} + */ + + }, { + key: 'next', + value: function next() { + if (this.hasNext()) { + return this._fetch()[this.__position++]; + } + return null; + } + + /** + * Returns true if the cursor has documents and can be iterated. + * @returns {boolean} + */ + + }, { + key: 'hasNext', + value: function hasNext() { + return this.count() > this.__position; + } + + /** + * Specifies the exclusive upper bound for a specific field + * @param expr + * @returns {Number} + */ + + }, { + key: 'max', + value: function max(expr) { + return groupOperators.$max(this._fetch(), expr); + } + + /** + * Specifies the inclusive lower bound for a specific field + * @param expr + * @returns {Number} + */ + + }, { + key: 'min', + value: function min(expr) { + return groupOperators.$min(this._fetch(), expr); + } + + /** + * Applies a function to each document in a cursor and collects the return values in an array. + * @param callback + * @returns {Array} + */ + + }, { + key: 'map', + value: function map$$1(callback) { + return this._fetch().map(callback); + } + + /** + * Applies a JavaScript function for every document in a cursor. + * @param callback + */ + + }, { + key: 'forEach', + value: function forEach(callback) { + each(this._fetch(), callback); + } + + /** + * Applies an [ES2015 Iteration protocol][] compatible implementation + * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + * @returns {Object} + */ + + }, { + key: Symbol.iterator, + value: function value() { + var self = this; + return { + next: function next() { + if (!self.hasNext()) { + return { done: true }; + } + return { + done: false, + value: self.next() + }; + } + }; + } + }]); + return Cursor; +}(); + +/** + * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ + */ +var simpleOperators = { + + /** + * Checks that two values are equal. + * + * @param a The lhs operand as resolved from the object by the given selector + * @param b The rhs operand provided by the user + * @returns {*} + */ + $eq: function $eq(a, b) { + // start with simple equality check + if (isEqual(a, b)) return true; + + // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ + if (isNil(a) && isNil(b)) return true; + + if (isArray(a)) { + // is multi-valued lhs so we check each separately + if (hasMeta(a, { isMulti: true })) { + try { + for (var i = 0; i < a.length; i++) { + if (this.$eq(a[i], b)) { + return true; + } + } + } finally { + dropMeta(a); + } + } else { + // check one level deep + return a.findIndex(isEqual.bind(null, b)) !== -1; + } + } + return false; + }, + + + /** + * Matches all values that are not equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $ne: function $ne(a, b) { + return !this.$eq(a, b); + }, + + + /** + * Matches any of the values that exist in an array specified in the query. + * + * @param a + * @param b + * @returns {*} + */ + $in: function $in(a, b) { + a = array(a); + return intersection(a, b).length > 0; + }, + + + /** + * Matches values that do not exist in an array specified to the query. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $nin: function $nin(a, b) { + return isNil(a) || !this.$in(a, b); + }, + + + /** + * Matches values that are less than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lt: function $lt(a, b) { + a = array(a).find(function (val) { + return val < b; + }); + return a !== undefined; + }, + + + /** + * Matches values that are less than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lte: function $lte(a, b) { + a = array(a).find(function (val) { + return val <= b; + }); + return a !== undefined; + }, + + + /** + * Matches values that are greater than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gt: function $gt(a, b) { + a = array(a).find(function (val) { + return val > b; + }); + return a !== undefined; + }, + + + /** + * Matches values that are greater than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gte: function $gte(a, b) { + a = array(a).find(function (val) { + return val >= b; + }); + return a !== undefined; + }, + + + /** + * Performs a modulo operation on the value of a field and selects documents with a specified result. + * + * @param a + * @param b + * @returns {boolean} + */ + $mod: function $mod(a, b) { + a = array(a).find(function (val) { + return isNumber(val) && isArray(b) && b.length === 2 && val % b[0] === b[1]; + }); + return a !== undefined; + }, + + + /** + * Selects documents where values match a specified regular expression. + * + * @param a + * @param b + * @returns {boolean} + */ + $regex: function $regex(a, b) { + a = array(a).find(function (val) { + return isString(val) && isRegExp(b) && !!val.match(b); + }); + return a !== undefined; + }, + + + /** + * Matches documents that have the specified field. + * + * @param a + * @param b + * @returns {boolean} + */ + $exists: function $exists(a, b) { + return (b === false || b === 0) && isNil(a) || (b === true || b === 1) && !isNil(a); + }, + + + /** + * Matches arrays that contain all elements specified in the query. + * + * @param a + * @param b + * @returns boolean + */ + $all: function $all(a, b) { + var matched = false; + if (isArray(a) && isArray(b)) { + for (var i = 0, len = b.length; i < len; i++) { + if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { + matched = matched || this.$elemMatch(a, b[i].$elemMatch); + } else { + // order of arguments matter + return intersection(b, a).length === len; + } + } + } + return matched; + }, + + + /** + * Selects documents if the array field is a specified size. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $size: function $size(a, b) { + return isArray(a) && isNumber(b) && a.length === b; + }, + + + /** + * Selects documents if element in the array field matches all the specified $elemMatch condition. + * + * @param a + * @param b + */ + $elemMatch: function $elemMatch(a, b) { + if (isArray(a) && !isEmpty(a)) { + var query = new Query(b); + for (var i = 0, len = a.length; i < len; i++) { + if (query.test(a[i])) { + return true; + } + } + } + return false; + }, + + + /** + * Selects documents if a field is of the specified type. + * + * @param a + * @param b + * @returns {boolean} + */ + $type: function $type(a, b) { + switch (b) { + case 1: + case 'double': + return isNumber(a) && (a + '').indexOf('.') !== -1; + case 2: + case T_STRING: + return isString(a); + case 3: + case T_OBJECT: + return isObject(a); + case 4: + case T_ARRAY: + return isArray(a); + case 6: + case T_UNDEFINED: + return isNil(a); + case 8: + case T_BOOL: + return isBoolean(a); + case 9: + case T_DATE: + return isDate(a); + case 10: + case T_NULL: + return isNull(a); + case 11: + case T_REGEX: + return isRegExp(a); + case 16: + case 'int': + return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1; + case 18: + case 'long': + return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1; + case 19: + case 'decimal': + return isNumber(a); + default: + return false; + } + } +}; + +var queryOperators = { + + /** + * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $and: function $and(selector, value) { + assert(isArray(value), 'Invalid expression: $and expects value to be an Array'); + + var queries = []; + each(value, function (expr) { + return queries.push(new Query(expr)); + }); + + return { + test: function test(obj) { + for (var i = 0; i < queries.length; i++) { + if (!queries[i].test(obj)) { + return false; + } + } + return true; + } + }; + }, + + + /** + * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $or: function $or(selector, value) { + assert(isArray(value), 'Invalid expression. $or expects value to be an Array'); + + var queries = []; + each(value, function (expr) { + return queries.push(new Query(expr)); + }); + + return { + test: function test(obj) { + for (var i = 0; i < queries.length; i++) { + if (queries[i].test(obj)) { + return true; + } + } + return false; + } + }; + }, + + + /** + * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $nor: function $nor(selector, value) { + assert(isArray(value), 'Invalid expression. $nor expects value to be an Array'); + var query = this.$or('$or', value); + return { + test: function test(obj) { + return !query.test(obj); + } + }; + }, + + + /** + * Inverts the effect of a query expression and returns documents that do not match the query expression. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $not: function $not(selector, value) { + var criteria = {}; + criteria[selector] = normalize(value); + var query = new Query(criteria); + return { + test: function test(obj) { + return !query.test(obj); + } + }; + }, + + + /** + * Matches documents that satisfy a JavaScript expression. + * + * @param selector + * @param value + * @returns {{test: test}} + */ + $where: function $where(selector, value) { + if (!isFunction(value)) { + value = new Function('return ' + value + ';'); + } + return { + test: function test(obj) { + return value.call(obj) === true; + } + }; + } +}; + +// add simple query operators +each(simpleOperators, function (fn, op) { + queryOperators[op] = function (f, ctx) { + return function (selector, value) { + return { + test: function test(obj) { + // value of field must be fully resolved. + var lhs = resolve(obj, selector); + return f.call(ctx, lhs, value); + } + }; + }; + }(fn, simpleOperators); +}); + +/** + * Query object to test collection elements with + * @param criteria the pass criteria for the query + * @param projection optional projection specifiers + * @constructor + */ +var Query = function () { + function Query(criteria) { + var projection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, Query); + + this.__criteria = criteria; + this.__projection = projection; + this.__compiled = []; + this._compile(); + } + + createClass(Query, [{ + key: '_compile', + value: function _compile() { + var _this = this; + + if (isEmpty(this.__criteria)) return; + + assert(isObject(this.__criteria), 'Criteria must be of type Object'); + + var whereOperator = void 0; + + each(this.__criteria, function (expr, field) { + // save $where operators to be executed after other operators + if ('$where' === field) { + whereOperator = { field: field, expr: expr }; + } else if (inArray(['$and', '$or', '$nor'], field)) { + _this._processOperator(field, field, expr); + } else { + // normalize expression + expr = normalize(expr); + each(expr, function (val, op) { + _this._processOperator(field, op, val); + }); + } + + if (isObject(whereOperator)) { + _this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); + } + }); + } + }, { + key: '_processOperator', + value: function _processOperator(field, operator, value) { + if (inArray(ops(OP_QUERY), operator)) { + this.__compiled.push(queryOperators[operator](field, value)); + } else { + err("Invalid query operator '" + operator + "' detected"); + } + } + + /** + * Checks if the object passes the query criteria. Returns true if so, false otherwise. + * @param obj + * @returns {boolean} + */ + + }, { + key: 'test', + value: function test(obj) { + for (var i = 0, len = this.__compiled.length; i < len; i++) { + if (!this.__compiled[i].test(obj)) { + return false; + } + } + return true; + } + + /** + * Performs a query on a collection and returns a cursor object. + * @param collection + * @param projection + * @returns {Cursor} + */ + + }, { + key: 'find', + value: function find(collection, projection) { + return new Cursor(collection, this, projection); + } + + /** + * Remove matched documents from the collection returning the remainder + * @param collection + * @returns {Array} + */ + + }, { + key: 'remove', + value: function remove(collection) { + var _this2 = this; + + return reduce(collection, function (acc, obj) { + if (!_this2.test(obj)) acc.push(obj); + return acc; + }, []); + } + }]); + return Query; +}(); + +/** + * Performs a query on a collection and returns a cursor object. + * + * @param collection + * @param criteria + * @param projection + * @returns {Cursor} + */ +function find(collection, criteria, projection) { + return new Query(criteria).find(collection, projection); +} + +/** + * Returns a new array without objects which match the criteria + * + * @param collection + * @param criteria + * @returns {Array} + */ +function remove(collection, criteria) { + return new Query(criteria).remove(collection); +} + +var arithmeticOperators = { + + /** + * Returns the absolute value of a number. + * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs + * @param obj + * @param expr + * @return {Number|null|NaN} + */ + $abs: function $abs(obj, expr) { + var val = computeValue(obj, expr); + return val === null || val === undefined ? null : Math.abs(val); + }, + + + /** + * Computes the sum of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $add: function $add(obj, expr) { + var args = computeValue(obj, expr); + return reduce(args, function (acc, num) { + return acc + num; + }, 0); + }, + + + /** + * Returns the smallest integer greater than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $ceil: function $ceil(obj, expr) { + var arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN; + if (isNil(arg)) return null; + assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.'); + return Math.ceil(arg); + }, + + + /** + * Takes two numbers and divides the first number by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $divide: function $divide(obj, expr) { + var args = computeValue(obj, expr); + return args[0] / args[1]; + }, + + + /** + * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {number} + */ + $exp: function $exp(obj, expr) { + var arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN; + if (isNil(arg)) return null; + assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.'); + return Math.exp(arg); + }, + + + /** + * Returns the largest integer less than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $floor: function $floor(obj, expr) { + var arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN; + if (isNil(arg)) return null; + assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.'); + return Math.floor(arg); + }, + + + /** + * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $ln: function $ln(obj, expr) { + var arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN; + if (isNil(arg)) return null; + assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.'); + return Math.log(arg); + }, + + + /** + * Calculates the log of a number in the specified base and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log: function $log(obj, expr) { + var args = computeValue(obj, expr); + assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items'); + if (args.some(isNaN)) return NaN; + if (args.some(isNil)) return null; + assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers'); + return Math.log10(args[0]) / Math.log10(args[1]); + }, + + + /** + * Calculates the log base 10 of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log10: function $log10(obj, expr) { + var arg = computeValue(obj, expr); + if (isNaN(arg)) return NaN; + if (isNil(arg)) return null; + assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.'); + return Math.log10(arg); + }, + + + /** + * Takes two numbers and calculates the modulo of the first number divided by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $mod: function $mod(obj, expr) { + var args = computeValue(obj, expr); + return args[0] % args[1]; + }, + + + /** + * Computes the product of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $multiply: function $multiply(obj, expr) { + var args = computeValue(obj, expr); + return reduce(args, function (acc, num) { + return acc * num; + }, 1); + }, + + + /** + * Raises a number to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {Object} + */ + $pow: function $pow(obj, expr) { + var args = computeValue(obj, expr); + + assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers'); + assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent'); + + return Math.pow(args[0], args[1]); + }, + + + /** + * Calculates the square root of a positive number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $sqrt: function $sqrt(obj, expr) { + var n = computeValue(obj, expr); + if (isNaN(n)) return NaN; + if (isNil(n)) return null; + assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.'); + return Math.sqrt(n); + }, + + + /** + * Takes an array that contains two numbers or two dates and subtracts the second value from the first. + * + * @param obj + * @param expr + * @returns {number} + */ + $subtract: function $subtract(obj, expr) { + var args = computeValue(obj, expr); + return args[0] - args[1]; + }, + + + /** + * Truncates a number to its integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $trunc: function $trunc(obj, expr) { + var n = computeValue(obj, expr); + if (isNaN(n)) return NaN; + if (isNil(n)) return null; + assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.'); + return Math.trunc(n); + } +}; + +var arrayOperators = { + /** + * Returns the element at the specified array index. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $arrayElemAt: function $arrayElemAt(obj, expr) { + var arr = computeValue(obj, expr); + assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements'); + assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array'); + assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer'); + var idx = arr[1]; + arr = arr[0]; + if (idx < 0 && Math.abs(idx) <= arr.length) { + return arr[idx + arr.length]; + } else if (idx >= 0 && idx < arr.length) { + return arr[idx]; + } + return undefined; + }, + + + /** + * Converts an array of key value pairs to a document. + */ + $arrayToObject: function $arrayToObject(obj, expr) { + var arr = computeValue(obj, expr); + assert(isArray(arr), '$arrayToObject expression must resolve to an array'); + return reduce(arr, function (newObj, val) { + if (isArray(val) && val.length == 2) newObj[val[0]] = val[1];else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v;else err('$arrayToObject expression is invalid.'); + return newObj; + }, {}); + }, + + + /** + * Concatenates arrays to return the concatenated array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $concatArrays: function $concatArrays(obj, expr) { + var arr = computeValue(obj, expr, null); + assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements'); + + if (arr.some(isNil)) return null; + + return arr[0].concat(arr[1]); + }, + + + /** + * Selects a subset of the array to return an array with only the elements that match the filter condition. + * + * @param {Object} obj [description] + * @param {*} expr [description] + * @return {*} [description] + */ + $filter: function $filter(obj, expr) { + var input = computeValue(obj, expr.input); + var asVar = expr['as']; + var condExpr = expr['cond']; + + assert(isArray(input), "$filter 'input' expression must resolve to an array"); + + return input.filter(function (o) { + // inject variable + var tempObj = {}; + tempObj['$' + asVar] = o; + return computeValue(tempObj, condExpr) === true; + }); + }, + + + /** + * Returns a boolean indicating whether a specified value is in an array. + * + * @param {Object} obj + * @param {Array} expr + */ + $in: function $in(obj, expr) { + var val = computeValue(obj, expr[0]); + var arr = computeValue(obj, expr[1]); + assert(isArray(arr), '$in second argument must be an array'); + return inArray(arr, val); + }, + + + /** + * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfArray: function $indexOfArray(obj, expr) { + var args = computeValue(obj, expr); + if (isNil(args)) return null; + + var arr = args[0]; + if (isNil(arr)) return null; + + assert(isArray(arr), '$indexOfArray expression must resolve to an array.'); + + var searchValue = args[1]; + if (isNil(searchValue)) return null; + + var start = args[2] || 0; + var end = args[3] || arr.length; + + if (end < arr.length) { + arr = arr.slice(start, end); + } + + return arr.indexOf(searchValue, start); + }, + + + /** + * Determines if the operand is an array. Returns a boolean. + * + * @param {Object} obj + * @param {*} expr + * @return {Boolean} + */ + $isArray: function $isArray(obj, expr) { + return isArray(computeValue(obj, expr)); + }, + + + /** + * Applies a sub-expression to each element of an array and returns the array of resulting values in order. + * + * @param obj + * @param expr + * @returns {Array|*} + */ + $map: function $map(obj, expr) { + var inputExpr = computeValue(obj, expr.input); + assert(isArray(inputExpr), '$map \'input\' expression must resolve to an array'); + + var asExpr = expr['as']; + var inExpr = expr['in']; + + // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" + // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". + // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. + var tempKey = '$' + asExpr; + // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) + var original = obj[tempKey]; + return map(inputExpr, function (item) { + obj[tempKey] = item; + var value = computeValue(obj, inExpr); + // cleanup and restore + if (isUndefined(original)) { + delete obj[tempKey]; + } else { + obj[tempKey] = original; + } + return value; + }); + }, + + + /** + * Converts a document to an array of documents representing key-value pairs. + */ + $objectToArray: function $objectToArray(obj, expr) { + var val = computeValue(obj, expr); + assert(isObject(val), '$objectToArray expression must resolve to an object'); + var arr = []; + each(val, function (v, k) { + return arr.push({ k: k, v: v }); + }); + return arr; + }, + + + /** + * Returns an array whose elements are a generated sequence of numbers. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $range: function $range(obj, expr) { + var arr = computeValue(obj, expr); + var start = arr[0]; + var end = arr[1]; + var step = arr[2] || 1; + + var result = []; + + while (start < end && step > 0 || start > end && step < 0) { + result.push(start); + start += step; + } + + return result; + }, + + + /** + * Applies an expression to each element in an array and combines them into a single value. + * + * @param {Object} obj + * @param {*} expr + */ + $reduce: function $reduce(obj, expr) { + var input = computeValue(obj, expr.input); + var initialValue = computeValue(obj, expr.initialValue); + var inExpr = expr['in']; + + if (isNil(input)) return null; + assert(isArray(input), "$reduce 'input' expression must resolve to an array"); + return reduce(input, function (acc, n) { + return computeValue({ '$value': acc, '$this': n }, inExpr); + }, initialValue); + }, + + + /** + * Returns an array with the elements in reverse order. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $reverseArray: function $reverseArray(obj, expr) { + var arr = computeValue(obj, expr); + + if (isNil(arr)) return null; + assert(isArray(arr), '$reverseArray expression must resolve to an array'); + + var result = []; + into(result, arr); + result.reverse(); + return result; + }, + + + /** + * Counts and returns the total the number of items in an array. + * + * @param obj + * @param expr + */ + $size: function $size(obj, expr) { + var value = computeValue(obj, expr); + return isArray(value) ? value.length : undefined; + }, + + + /** + * Returns a subset of an array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $slice: function $slice(obj, expr) { + var arr = computeValue(obj, expr); + return slice(arr[0], arr[1], arr[2]); + }, + + + /** + * Merge two lists together. + * + * Transposes an array of input arrays so that the first element of the output array would be an array containing, + * the first element of the first input array, the first element of the second input array, etc. + * + * @param {Obj} obj + * @param {*} expr + * @return {*} + */ + $zip: function $zip(obj, expr) { + var inputs = computeValue(obj, expr.inputs); + var useLongestLength = expr.useLongestLength || false; + + assert(isArray(inputs), "'inputs' expression must resolve to an array"); + assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean"); + + if (isArray(expr.defaults)) { + assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'"); + } + + var zipCount = 0; + + for (var i = 0, len = inputs.length; i < len; i++) { + var arr = inputs[i]; + + if (isNil(arr)) return null; + + assert(isArray(arr), "'inputs' expression values must resolve to an array or null"); + + zipCount = useLongestLength ? Math.max(zipCount, arr.length) : Math.min(zipCount || arr.length, arr.length); + } + + var result = []; + var defaults = expr.defaults || []; + + var _loop = function _loop(_i) { + var temp = inputs.map(function (val, index) { + return isNil(val[_i]) ? defaults[index] || null : val[_i]; + }); + result.push(temp); + }; + + for (var _i = 0; _i < zipCount; _i++) { + _loop(_i); + } + + return result; + } +}; + +var booleanOperators = { + /** + * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $and: function $and(obj, expr) { + var value = computeValue(obj, expr); + return truthy(value) && value.every(truthy); + }, + + /** + * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $or: function $or(obj, expr) { + var value = computeValue(obj, expr); + return truthy(value) && value.some(truthy); + }, + + /** + * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $not: function $not(obj, expr) { + return !computeValue(obj, expr[0]); + } +}; + +var comparisonOperators = { + /** + * Compares two values and returns the result of the comparison as an integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $cmp: function $cmp(obj, expr) { + var args = computeValue(obj, expr); + if (args[0] > args[1]) return 1; + if (args[0] < args[1]) return -1; + return 0; + } +}; +// mixin comparison operators +each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], function (op) { + comparisonOperators[op] = function (obj, expr) { + var args = computeValue(obj, expr); + return simpleOperators[op](args[0], args[1]); + }; +}); + +/** + * Conditional operators + */ + +var conditionalOperators = { + + /** + * A ternary operator that evaluates one expression, + * and depending on the result returns the value of one following expressions. + * + * @param obj + * @param expr + */ + $cond: function $cond(obj, expr) { + var ifExpr = void 0, + thenExpr = void 0, + elseExpr = void 0; + if (isArray(expr)) { + assert(expr.length === 3, 'Invalid arguments for $cond operator'); + ifExpr = expr[0]; + thenExpr = expr[1]; + elseExpr = expr[2]; + } else if (isObject(expr)) { + ifExpr = expr['if']; + thenExpr = expr['then']; + elseExpr = expr['else']; + } + var condition = computeValue(obj, ifExpr); + return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr); + }, + + + /** + * An operator that evaluates a series of case expressions. When it finds an expression which + * evaluates to true, it returns the resulting expression for that case. If none of the cases + * evaluate to true, it returns the default expression. + * + * @param obj + * @param expr + */ + $switch: function $switch(obj, expr) { + assert(expr.branches, 'Invalid arguments for $switch operator'); + + var validBranch = expr.branches.find(function (branch) { + assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator'); + return computeValue(obj, branch['case']); + }); + + if (validBranch) { + return computeValue(obj, validBranch.then); + } else if (!expr.default) { + err('Invalid arguments for $switch operator'); + } else { + return computeValue(obj, expr.default); + } + }, + + + /** + * Evaluates an expression and returns the first expression if it evaluates to a non-null value. + * Otherwise, $ifNull returns the second expression's value. + * + * @param obj + * @param expr + * @returns {*} + */ + $ifNull: function $ifNull(obj, expr) { + assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator'); + var args = computeValue(obj, expr); + return args[0] === null || args[0] === undefined ? args[1] : args[0]; + } +}; + +// used for formatting dates in $dateToString operator +var DATE_SYM_TABLE = { + '%Y': ['$year', 4], + '%m': ['$month', 2], + '%d': ['$dayOfMonth', 2], + '%H': ['$hour', 2], + '%M': ['$minute', 2], + '%S': ['$second', 2], + '%L': ['$millisecond', 3], + '%j': ['$dayOfYear', 3], + '%w': ['$dayOfWeek', 1], + '%U': ['$week', 2], + '%%': '%' +}; + +var dateOperators = { + /** + * Returns the day of the year for a date as a number between 1 and 366 (leap year). + * @param obj + * @param expr + */ + $dayOfYear: function $dayOfYear(obj, expr) { + var d = computeValue(obj, expr); + if (isDate(d)) { + var start = new Date(d.getFullYear(), 0, 0); + var diff = d - start; + var oneDay = 1000 * 60 * 60 * 24; + return Math.round(diff / oneDay); + } + return undefined; + }, + + + /** + * Returns the day of the month for a date as a number between 1 and 31. + * @param obj + * @param expr + */ + $dayOfMonth: function $dayOfMonth(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getDate() : undefined; + }, + + + /** + * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). + * @param obj + * @param expr + */ + $dayOfWeek: function $dayOfWeek(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getDay() + 1 : undefined; + }, + + + /** + * Returns the year for a date as a number (e.g. 2014). + * @param obj + * @param expr + */ + $year: function $year(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getFullYear() : undefined; + }, + + + /** + * Returns the month for a date as a number between 1 (January) and 12 (December). + * @param obj + * @param expr + */ + $month: function $month(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getMonth() + 1 : undefined; + }, + + + /** + * Returns the week number for a date as a number between 0 + * (the partial week that precedes the first Sunday of the year) and 53 (leap year). + * @param obj + * @param expr + */ + $week: function $week(obj, expr) { + // source: http://stackoverflow.com/a/6117889/1370481 + var d = computeValue(obj, expr); + + // Copy date so don't modify original + d = new Date(+d); + d.setHours(0, 0, 0); + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + d.setDate(d.getDate() + 4 - (d.getDay() || 7)); + // Get first day of year + var yearStart = new Date(d.getFullYear(), 0, 1); + // Calculate full weeks to nearest Thursday + return Math.floor(((d - yearStart) / 8.64e7 + 1) / 7); + }, + + + /** + * Returns the hour for a date as a number between 0 and 23. + * @param obj + * @param expr + */ + $hour: function $hour(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getUTCHours() : undefined; + }, + + + /** + * Returns the minute for a date as a number between 0 and 59. + * @param obj + * @param expr + */ + $minute: function $minute(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getMinutes() : undefined; + }, + + + /** + * Returns the seconds for a date as a number between 0 and 60 (leap seconds). + * @param obj + * @param expr + */ + $second: function $second(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getSeconds() : undefined; + }, + + + /** + * Returns the milliseconds of a date as a number between 0 and 999. + * @param obj + * @param expr + */ + $millisecond: function $millisecond(obj, expr) { + var d = computeValue(obj, expr); + return isDate(d) ? d.getMilliseconds() : undefined; + }, + + + /** + * Returns the date as a formatted string. + * + * %Y Year (4 digits, zero padded) 0000-9999 + * %m Month (2 digits, zero padded) 01-12 + * %d Day of Month (2 digits, zero padded) 01-31 + * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 + * %M Minute (2 digits, zero padded) 00-59 + * %S Second (2 digits, zero padded) 00-60 + * %L Millisecond (3 digits, zero padded) 000-999 + * %j Day of year (3 digits, zero padded) 001-366 + * %w Day of week (1-Sunday, 7-Saturday) 1-7 + * %U Week of year (2 digits, zero padded) 00-53 + * %% Percent Character as a Literal % + * + * @param obj current object + * @param expr operator expression + */ + $dateToString: function $dateToString(obj, expr) { + var fmt = expr['format']; + var date = computeValue(obj, expr['date']); + var matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g); + + for (var i = 0, len = matches.length; i < len; i++) { + var hdlr = DATE_SYM_TABLE[matches[i]]; + var value = hdlr; + + if (isArray(hdlr)) { + // reuse date operators + var fn = this[hdlr[0]]; + var pad = hdlr[1]; + value = padDigits(fn.call(this, obj, date), pad); + } + // replace the match with resolved value + fmt = fmt.replace(matches[i], value); + } + + return fmt; + } +}; + +function padDigits(number, digits) { + return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number; +} + +var literalOperators = { + /** + * Return a value without parsing. + * @param obj + * @param expr + */ + $literal: function $literal(obj, expr) { + return expr; + } +}; + +var setOperators = { + /** + * Returns true if two sets have the same elements. + * @param obj + * @param expr + */ + $setEquals: function $setEquals(obj, expr) { + var args = computeValue(obj, expr); + var xs = unique(args[0]); + var ys = unique(args[1]); + return xs.length === ys.length && xs.length === intersection(xs, ys).length; + }, + + + /** + * Returns the common elements of the input sets. + * @param obj + * @param expr + */ + $setIntersection: function $setIntersection(obj, expr) { + var args = computeValue(obj, expr); + return intersection(args[0], args[1]); + }, + + + /** + * Returns elements of a set that do not appear in a second set. + * @param obj + * @param expr + */ + $setDifference: function $setDifference(obj, expr) { + var args = computeValue(obj, expr); + return args[0].filter(notInArray.bind(null, args[1])); + }, + + + /** + * Returns a set that holds all elements of the input sets. + * @param obj + * @param expr + */ + $setUnion: function $setUnion(obj, expr) { + var args = computeValue(obj, expr); + return union(args[0], args[1]); + }, + + + /** + * Returns true if all elements of a set appear in a second set. + * @param obj + * @param expr + */ + $setIsSubset: function $setIsSubset(obj, expr) { + var args = computeValue(obj, expr); + return intersection(args[0], args[1]).length === args[0].length; + }, + + + /** + * Returns true if any elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $anyElementTrue: function $anyElementTrue(obj, expr) { + // mongodb nests the array expression in another + var args = computeValue(obj, expr)[0]; + return args.some(truthy); + }, + + + /** + * Returns true if all elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $allElementsTrue: function $allElementsTrue(obj, expr) { + // mongodb nests the array expression in another + var args = computeValue(obj, expr)[0]; + return args.every(truthy); + } +}; + +var stringOperators = { + + /** + * Concatenates two strings. + * + * @param obj + * @param expr + * @returns {string|*} + */ + $concat: function $concat(obj, expr) { + var args = computeValue(obj, expr); + // does not allow concatenation with nulls + if ([null, undefined].some(inArray.bind(null, args))) { + return null; + } + return args.join(''); + }, + + + /** + * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfBytes: function $indexOfBytes(obj, expr) { + var arr = computeValue(obj, expr); + + if (isNil(arr[0])) return null; + + assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string'); + assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string'); + + var str = arr[0]; + var searchStr = arr[1]; + var start = arr[2]; + var end = arr[3]; + + assert(isNil(start) || isNumber(start) && start >= 0 && Math.round(start) === start, '$indexOfBytes third operand must resolve to a non-negative integer'); + start = start || 0; + + assert(isNil(end) || isNumber(end) && end >= 0 && Math.round(end) === end, '$indexOfBytes fourth operand must resolve to a non-negative integer'); + end = end || str.length; + + if (start > end) return -1; + + var index = str.substring(start, end).indexOf(searchStr); + return index > -1 ? index + start : index; + }, + + + /** + * Splits a string into substrings based on a delimiter. + * If the delimiter is not found within the string, returns an array containing the original string. + * + * @param {Object} obj + * @param {Array} expr + * @return {Array} Returns an array of substrings. + */ + $split: function $split(obj, expr) { + var args = computeValue(obj, expr); + assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])); + assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])); + return args[0].split(args[1]); + }, + + + /** + * Compares two strings and returns an integer that reflects the comparison. + * + * @param obj + * @param expr + * @returns {number} + */ + $strcasecmp: function $strcasecmp(obj, expr) { + var args = computeValue(obj, expr); + args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase(); + args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase(); + if (args[0] > args[1]) { + return 1; + } + return args[0] < args[1] ? -1 : 0; + }, + + + /** + * Returns a substring of a string, starting at a specified index position and including the specified number of characters. + * The index is zero-based. + * + * @param obj + * @param expr + * @returns {string} + */ + $substr: function $substr(obj, expr) { + var args = computeValue(obj, expr); + if (isString(args[0])) { + if (args[1] < 0) { + return ''; + } else if (args[2] < 0) { + return args[0].substr(args[1]); + } else { + return args[0].substr(args[1], args[2]); + } + } + return ''; + }, + + + /** + * Converts a string to lowercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toLower: function $toLower(obj, expr) { + var value = computeValue(obj, expr); + return isEmpty(value) ? '' : value.toLowerCase(); + }, + + + /** + * Converts a string to uppercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toUpper: function $toUpper(obj, expr) { + var value = computeValue(obj, expr); + return isEmpty(value) ? '' : value.toUpperCase(); + } +}; + +/** + * Aggregation framework variable operators + */ + +var variableOperators = { + /** + * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. + * + * @param obj + * @param expr + * @returns {*} + */ + $let: function $let(obj, expr) { + var varsExpr = expr['vars']; + var inExpr = expr['in']; + + // resolve vars + var originals = {}; + var varsKeys = keys(varsExpr); + each(varsKeys, function (key) { + var val = computeValue(obj, varsExpr[key]); + var tempKey = '$' + key; + // set value on object using same technique as in "$map" + originals[tempKey] = obj[tempKey]; + obj[tempKey] = val; + }); + + var value = computeValue(obj, inExpr); + + // cleanup and restore + each(varsKeys, function (key) { + var tempKey = '$' + key; + if (isUndefined(originals[tempKey])) { + delete obj[tempKey]; + } else { + obj[tempKey] = originals[tempKey]; + } + }); + + return value; + } +}; + +// combine aggregate operators +var aggregateOperators = Object.assign({}, arithmeticOperators, arrayOperators, booleanOperators, comparisonOperators, conditionalOperators, dateOperators, literalOperators, setOperators, stringOperators, variableOperators); + +// operator definitions +var OPERATORS = { + 'aggregate': aggregateOperators, + 'group': groupOperators, + 'pipeline': pipelineOperators, + 'projection': projectionOperators, + 'query': queryOperators + + /** + * Returns the operators defined for the given operator classes + */ +};function ops() { + return reduce(arguments, function (acc, cls) { + return into(acc, keys(OPERATORS[cls])); + }, []); +} + +/** + * Add new operators + * + * @param opClass the operator class to extend + * @param fn a function returning an object of new operators + */ +function addOperators(opClass, fn) { + + var newOperators = fn(_internal()); + + // ensure correct type specified + assert(has(OPERATORS, opClass), 'Invalid operator class ' + opClass); + + var operators = OPERATORS[opClass]; + + // check for existing operators + each(newOperators, function (fn, op) { + assert(/^\$\w+$/.test(op), 'Invalid operator name ' + op); + assert(!has(operators, op), op + ' already exists for \'' + opClass + '\' operators'); + }); + + var wrapped = {}; + + switch (opClass) { + case OP_QUERY: + each(newOperators, function (fn, op) { + wrapped[op] = function (f, ctx) { + return function (selector, value) { + return { + test: function test(obj) { + // value of field must be fully resolved. + var lhs = resolve(obj, selector); + var result = f.call(ctx, selector, lhs, value); + if (isBoolean(result)) { + return result; + } else if (result instanceof Query) { + return result.test(obj); + } else { + err("Invalid return type for '" + op + "'. Must return a Boolean or Query"); + } + } + }; + }; + }(fn, newOperators); + }); + break; + case OP_PROJECTION: + each(newOperators, function (fn, op) { + wrapped[op] = function (f, ctx) { + return function (obj, expr, selector) { + var lhs = resolve(obj, selector); + return f.call(ctx, selector, lhs, expr); + }; + }(fn, newOperators); + }); + break; + default: + each(newOperators, function (fn, op) { + wrapped[op] = function (f, ctx) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return f.apply(ctx, args); + }; + }(fn, newOperators); + }); + } + + // toss the operator salad :) + Object.assign(OPERATORS[opClass], wrapped); +} + +/** + * Internal functions + */ + +// Settings used by Mingo internally +var settings = { + key: '_id' + + /** + * Setup default settings for Mingo + * @param options + */ +};function setup(options) { + Object.assign(settings, options || {}); +} + +/** + * Implementation of system variables + * @type {Object} + */ +var systemVariables = { + '$$ROOT': function $$ROOT(obj, expr, opt) { + return opt.root; + }, + '$$CURRENT': function $$CURRENT(obj, expr, opt) { + return obj; + } +}; + +/** + * Implementation of $redact variables + * + * Each function accepts 3 arguments (obj, expr, opt) + * + * @type {Object} + */ +var redactVariables = { + '$$KEEP': function $$KEEP(obj) { + return obj; + }, + '$$PRUNE': function $$PRUNE() { + return undefined; + }, + '$$DESCEND': function $$DESCEND(obj, expr, opt) { + // traverse nested documents iff there is a $cond + if (!has(expr, '$cond')) return obj; + + var result = void 0; + + each(obj, function (current, key) { + if (isObjectLike(current)) { + if (isArray(current)) { + result = []; + each(current, function (elem) { + if (isObject(elem)) { + elem = redactObj(elem, expr, opt); + } + if (!isNil(elem)) result.push(elem); + }); + } else { + result = redactObj(current, expr, opt); + } + + if (isNil(result)) { + delete obj[key]; // pruned result + } else { + obj[key] = result; + } + } + }); + return obj; + } +}; + +// system variables +var SYS_VARS = keys(systemVariables); +var REDACT_VARS = keys(redactVariables); + +/** + * Returns the key used as the collection's objects ids + */ +function idKey() { + return settings.key; +} + +/** + * Retrieve the value of a given key on an object + * @param obj + * @param field + * @returns {*} + * @private + */ +function getValue(obj, field) { + return obj[field]; +} + +/** + * Resolve the value of the field (dot separated) on the given object + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) + * @returns {*} + */ +function resolve(obj, selector) { + var deepFlag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var names = selector.split('.'); + var value = obj; + + var _loop = function _loop(i) { + var isText = names[i].match(/^\d+$/) === null; + + if (isText && isArray(value)) { + // On the first iteration, we check if we received a stop flag. + // If so, we stop to prevent iterating over a nested array value + // on consecutive object keys in the selector. + if (deepFlag === true && i === 0) { + return { + v: value + }; + } + + value = value.map(function (item) { + return resolve(item, names[i], true); + }); + + // we mark this value as being multi-valued + addMeta(value, { isMulti: true }); + + // we unwrap for arrays of unit length + // this avoids excess wrapping when resolving deeply nested arrays + if (value.length === 1) { + value = value[0]; + } + } else { + value = getValue(value, names[i]); + deepFlag = false; // reset stop flag when we do a direct lookup + } + + if (isNil(value)) return 'break'; + }; + + _loop2: for (var i = 0; i < names.length; i++) { + var _ret = _loop(i); + + switch (_ret) { + case 'break': + break _loop2; + + default: + if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; + } + } + + return value; +} + +/** + * Returns the full object to the resolved value given by the selector. + * This function excludes empty values as they aren't practically useful. + * + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + */ +function resolveObj(obj, selector) { + if (isNil(obj)) return; + + var names = selector.split('.'); + var key = names[0]; + // get the next part of the selector + var next = names.length === 1 || names.slice(1).join('.'); + var isIndex = key.match(/^\d+$/) !== null; + var hasNext = names.length > 1; + var result = void 0; + var value = void 0; + + try { + if (isArray(obj)) { + if (isIndex) { + result = getValue(obj, key); + if (hasNext) { + result = resolveObj(result, next); + } + assert(!isUndefined(result)); + result = [result]; + } else { + result = []; + each(obj, function (item) { + value = resolveObj(item, selector); + if (!isNil(value)) result.push(value); + }); + assert(result.length > 0); + } + } else { + value = getValue(obj, key); + if (hasNext) { + value = resolveObj(value, next); + } + assert(!isUndefined(value)); + result = {}; + result[key] = value; + } + } catch (e) { + result = undefined; + } + + return result; +} + +/** + * Walk the object graph and execute the given transform function + * @param {Object|Array} obj The object to traverse + * @param {String} selector The selector + * @param {Function} fn Function to execute for value at the end the traversal + * @param {Boolean} force Force generating missing parts of object graph + * @return {*} + */ +function traverse(obj, selector, fn) { + var force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + var names = selector.split('.'); + var key = names[0]; + var next = names.length === 1 || names.slice(1).join('.'); + + if (names.length === 1) { + fn(obj, key); + } else { + // nested objects + if (isArray(obj) && !/^\d+$/.test(key)) { + each(obj, function (item) { + traverse(item, selector, fn, force); + }); + } else { + // force the rest of the graph while traversing + if (force === true) { + var exists = has(obj, key); + if (!exists || isNil(obj[key])) { + obj[key] = {}; + } + } + traverse(obj[key], next, fn, force); + } + } +} + +/** + * Set the value of the given object field + * + * @param obj {Object|Array} the object context + * @param selector {String} path to field + * @param value {*} the value to set + */ +function setValue(obj, selector, value) { + traverse(obj, selector, function (item, key) { + item[key] = value; + }, true); +} + +function removeValue(obj, selector) { + traverse(obj, selector, function (item, key) { + if (isArray(item) && /^\d+$/.test(key)) { + item.splice(parseInt(key), 1); + } else if (isObject(item)) { + delete item[key]; + } + }); +} + +/** + * Simplify expression for easy evaluation with query operators map + * @param expr + * @returns {*} + */ +function normalize(expr) { + // normalized primitives + if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { + return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr }; + } + + // normalize object expression + if (isObjectLike(expr)) { + var exprKeys = keys(expr); + var noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0; + + // no valid query operator found, so we do simple comparison + if (noQuery) { + return { '$eq': expr }; + } + + // ensure valid regex + if (inArray(exprKeys, '$regex')) { + var regex = expr['$regex']; + var options = expr['$options'] || ''; + var modifiers = ''; + if (isString(regex)) { + modifiers += regex.ignoreCase || options.indexOf('i') >= 0 ? 'i' : ''; + modifiers += regex.multiline || options.indexOf('m') >= 0 ? 'm' : ''; + modifiers += regex.global || options.indexOf('g') >= 0 ? 'g' : ''; + regex = new RegExp(regex, modifiers); + } + expr['$regex'] = regex; + delete expr['$options']; + } + } + + return expr; +} + +/** + * Computes the actual value of the expression using the given object as context + * + * @param obj the current object from the collection + * @param expr the expression for the given field + * @param field the field name (may also be an aggregate operator) + * @param opt {Object} extra options + * @returns {*} + */ +function computeValue(obj, expr) { + var field = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var opt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + opt.root = opt.root || obj; + + // if the field of the object is a valid operator + if (inArray(ops(OP_AGGREGATE), field)) { + return aggregateOperators[field](obj, expr, opt); + } + + // we also handle $group accumulator operators + if (inArray(ops(OP_GROUP), field)) { + // we first fully resolve the expression + obj = computeValue(obj, expr, null, opt); + assert(isArray(obj), field + ' expression must resolve to an array'); + // we pass a null expression because all values have been resolved + return groupOperators[field](obj, null, opt); + } + + // if expr is a variable for an object field + // field not used in this case + if (isString(expr) && expr.length > 0 && expr[0] === '$') { + // we return system variables as literals + if (inArray(SYS_VARS, expr)) { + return systemVariables[expr](obj, null, opt); + } else if (inArray(REDACT_VARS, expr)) { + return expr; + } + + // handle selectors with explicit prefix + var sysVar = SYS_VARS.filter(function (v) { + return expr.indexOf(v + '.') === 0; + }); + + if (sysVar.length === 1) { + sysVar = sysVar[0]; + if (sysVar === '$$ROOT') { + obj = opt.root; + } + expr = expr.substr(sysVar.length); // '.' prefix will be sliced off below + } + + return resolve(obj, expr.slice(1)); + } + + // check and return value if already in a resolved state + switch (jsType(expr)) { + case T_ARRAY: + return expr.map(function (item) { + return computeValue(obj, item); + }); + case T_OBJECT: + var result = {}; + each(expr, function (val, key) { + result[key] = computeValue(obj, val, key, opt); + // must run ONLY one aggregate operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { + // there should be only one operator + assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'"); + result = result[key]; + return false; // break + } + }); + return result; + default: + return expr; + } +} + +/** + * Returns a slice of the array + * + * @param {Array} xs + * @param {Number} skip + * @param {Number} limit + * @return {Array} + */ +function slice(xs, skip) { + var limit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + // MongoDB $slice works a bit differently from Array.slice + // Uses single argument for 'limit' and array argument [skip, limit] + if (isNil(limit)) { + if (skip < 0) { + skip = Math.max(0, xs.length + skip); + limit = xs.length - skip + 1; + } else { + limit = skip; + skip = 0; + } + } else { + if (skip < 0) { + skip = Math.max(0, xs.length + skip); + } + assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number'); + limit += skip; + } + return Array.prototype.slice.apply(xs, [skip, limit]); +} + +/** + * Compute the standard deviation of the data set + * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". + * @return {Number} + */ +function stddev(ctx) { + var sum = reduce(ctx.data, function (acc, n) { + return acc + n; + }, 0); + var N = ctx.data.length || 1; + var correction = ctx.sampled === true ? 1 : 0; + var avg = sum / (N - correction); + return Math.sqrt(reduce(ctx.data, function (acc, n) { + return acc + Math.pow(n - avg, 2); + }, 0) / N); +} + +/** + * Redact an object + * @param {Object} obj The object to redact + * @param {*} expr The redact expression + * @param {*} opt Options for value + * @return {*} Returns the redacted value + */ +function redactObj(obj, expr) { + var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + opt.root = opt.root || obj; + + var result = computeValue(obj, expr, null, opt); + return inArray(REDACT_VARS, result) ? redactVariables[result](obj, expr, opt) : result; +} + +/** + * Exported to the users to allow writing custom operators + */ +function _internal() { + return { + computeValue: computeValue, + idKey: idKey, + ops: ops, + resolve: resolve, + assert: assert, + clone: clone, + each: each, + err: err, + getType: getType, + has: has, + isArray: isArray, + isBoolean: isBoolean, + isDate: isDate, + isEmpty: isEmpty, + isEqual: isEqual, + isFunction: isFunction, + isNil: isNil, + isNull: isNull, + isNumber: isNumber, + isObject: isObject, + isRegExp: isRegExp, + isString: isString, + isUndefined: isUndefined, + keys: keys, + map: map + }; +} + +/** + * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` + */ +var CollectionMixin = { + + /** + * Runs a query and returns a cursor to the result + * @param criteria + * @param projection + * @returns {Cursor} + */ + query: function query(criteria, projection) { + return new Query(criteria).find(this.toJSON(), projection); + }, + + + /** + * Runs the given aggregation operators on this collection + * @params pipeline + * @returns {Array} + */ + aggregate: function aggregate$$1(pipeline) { + return new Aggregator(pipeline).run(this.toJSON()); + } +}; + +var VERSION = '1.3.3'; + +// mingo! +var index = { + _internal: _internal, + Aggregator: Aggregator, + CollectionMixin: CollectionMixin, + Cursor: Cursor, + OP_AGGREGATE: OP_AGGREGATE, + OP_GROUP: OP_GROUP, + OP_PIPELINE: OP_PIPELINE, + OP_PROJECTION: OP_PROJECTION, + OP_QUERY: OP_QUERY, + Query: Query, + VERSION: VERSION, + addOperators: addOperators, + aggregate: aggregate, + find: find, + remove: remove, + setup: setup +}; + +return index; + +}))); diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map new file mode 100644 index 0000000..7ef3a22 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map @@ -0,0 +1 @@ +{"version":3,"sources":["dist/mingo.js"],"names":["global","factory","exports","module","define","amd","mingo","this","assert","condition","message","falsey","err","clone","obj","jsType","T_ARRAY","map","T_OBJECT","getType","v","undefined","constructor","name","toLowerCase","isBoolean","T_BOOLEAN","isString","T_STRING","isNumber","T_NUMBER","isArray","isArrayLike","isNil","has","isObject","isObjectLike","Object","isDate","T_DATE","isRegExp","T_REGEXP","isFunction","T_FUNCTION","isNull","isUndefined","T_NULL","T_UNDEFINED","inArray","arr","item","includes","notInArray","truthy","arg","isEmpty","x","length","keys","array","prop","hasOwnProperty","s","Error","o","addMeta","value","__MINGO_META","assign","hasMeta","isEqual","dropMeta","each","fn","ctx","arguments","i","len","call","k","reduce","collection","accumulator","intersection","xs","ys","filter","bind","union","into","a","b","type","isNaN","toString","getHash","ka","kb","sort","_i","_len","temp","unique","h","push","randomString","n","Math","E","random","slice","encode","JSON","stringify","toISOString","prefix","objKeys","hash","chr","charCodeAt","sortBy","sortKeys","sorted","result","key","A","B","groupBy","groups","lookup","index","target","Array","prototype","apply","findInsertIndex","lo","hi","mid","round","memoize","_this","cache","_len2","args","_key","accumulate","field","expr","ops","OP_GROUP","groupOperators","val","aggregate","pipeline","Aggregator","run","find","criteria","projection","Query","remove","padDigits","number","digits","max","String","join","acc","cls","OPERATORS","addOperators","opClass","newOperators","_internal","operators","op","test","wrapped","OP_QUERY","f","selector","lhs","resolve","OP_PROJECTION","setup","options","settings","idKey","getValue","deepFlag","names","split","_loop2","_ret","match","isMulti","_typeof","resolveObj","next","isIndex","hasNext","e","traverse","force","exists","setValue","removeValue","splice","parseInt","normalize","JS_SIMPLE_TYPES","$regex","$eq","exprKeys","regex","modifiers","ignoreCase","indexOf","multiline","RegExp","computeValue","opt","root","OP_AGGREGATE","aggregateOperators","SYS_VARS","systemVariables","REDACT_VARS","sysVar","substr","skip","limit","stddev","sum","data","N","correction","sampled","avg","sqrt","pow","redactObj","redactVariables","Function","oThis","aArgs","fToBind","fNOP","fBound","concat","defineProperty","predicate","TypeError","thisArg","kValue","findIndex","searchElement","fromIndex","abs","y","varArgs","to","nextSource","nextKey","values","$addToSet","$push","$sum","$max","$min","$avg","$first","$last","$stdDevPop","$stdDevSamp","projectionOperators","$","$elemMatch","query","$slice","pipelineOperators","$addFields","newFields","subExpr","newValue","$group","ID_KEY","objectId","partitions","$lookup","hashCode","joinColl","from","localField","foreignField","asField","as","errorMsg","indexes","newObj","tempResult","$match","all","$project","projected","idOnlyExcludedExpression","check","id","cloneObj","foundSlice","foundExclusion","dropKeys","operator","every","objValue","$limit","$skip","$unwind","tmp","$sort","reverse","grouped","sortedIndex","getIndex","indexKeys","$sortByCount","newExpr","count","$sample","size","floor","$count","trim","$replaceRoot","newRoot","$redact","$bucket","boundaries","defaultKey","default","lower","upper","outputExpr","output","boundType","boundKey","pop","_id","$bucketAuto","groupByExpr","bucketCount","buckets","approxBucketSize","computeValueOptimized","remaining","bucketItems","j","min","$facet","Symbol","iterator","classCallCheck","instance","Constructor","createClass","defineProperties","props","descriptor","enumerable","configurable","writable","protoProps","staticProps","__operators","Cursor","__query","__collection","__projection","__result","__position","selected","aggregator","_fetch","modifier","callback","self","done","simpleOperators","$ne","$in","$nin","$lt","$lte","$gt","$gte","$mod","$exists","$all","matched","$size","$type","queryOperators","$and","queries","$or","$nor","$not","$where","__criteria","__compiled","_compile","whereOperator","_processOperator","_this2","arithmeticOperators","$abs","$add","num","$ceil","NaN","ceil","$divide","$exp","exp","$floor","$ln","log","$log","some","log10","$log10","$multiply","$pow","$sqrt","$subtract","$trunc","trunc","arrayOperators","$arrayElemAt","idx","$arrayToObject","$concatArrays","$filter","input","asVar","condExpr","tempObj","$indexOfArray","searchValue","start","end","$isArray","$map","inputExpr","asExpr","inExpr","tempKey","original","$objectToArray","$range","step","$reduce","initialValue","$value","$this","$reverseArray","$zip","inputs","useLongestLength","defaults","zipCount","booleanOperators","comparisonOperators","$cmp","conditionalOperators","$cond","ifExpr","thenExpr","elseExpr","$switch","branches","validBranch","branch","then","$ifNull","DATE_SYM_TABLE","%Y","%m","%d","%H","%M","%S","%L","%j","%w","%U","%%","dateOperators","$dayOfYear","d","Date","getFullYear","diff","$dayOfMonth","getDate","$dayOfWeek","getDay","$year","$month","getMonth","$week","setHours","setDate","yearStart","$hour","getUTCHours","$minute","getMinutes","$second","getSeconds","$millisecond","getMilliseconds","$dateToString","fmt","date","matches","hdlr","pad","replace","literalOperators","$literal","setOperators","$setEquals","$setIntersection","$setDifference","$setUnion","$setIsSubset","$anyElementTrue","$allElementsTrue","stringOperators","$concat","$indexOfBytes","str","searchStr","substring","$split","$strcasecmp","toUpperCase","$substr","$toLower","$toUpper","variableOperators","$let","varsExpr","originals","varsKeys","group","$$ROOT","$$CURRENT","$$KEEP","$$PRUNE","$$DESCEND","current","elem","CollectionMixin","toJSON","OP_PIPELINE","VERSION"],"mappings":"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"} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js new file mode 100644 index 0000000..42f2b9a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js @@ -0,0 +1,7 @@ +// mingo.js 1.3.3 +// Copyright (c) 2017 Francis Asante +// https://github.com/kofrasa/mingo +// MIT +!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.mingo=t()}(this,function(){"use strict";function n(n,t){b(n)&&w(t)}function t(n){switch(e(n)){case mn:return n.map(t);case bn:return E(n,t);default:return n}}function r(n){return null===n?"Null":void 0===n?"Undefined":n.constructor.name}function e(n){return r(n).toLowerCase()}function u(n){return e(n)===pn}function i(n){return e(n)===gn}function o(n){return e(n)===dn}function a(n){return e(n)===mn}function s(n){return!p(n)&&O(n,"length")}function c(n){return e(n)===bn}function f(n){return n===Object(n)}function l(n){return e(n)===$n}function v(n){return e(n)===yn}function h(n){return e(n)===_n}function p(n){return d(n)||g(n)}function d(n){return e(n)===vn}function g(n){return e(n)===hn}function $(n,t){return n.includes(t)}function y(n,t){return!n.includes(t)}function m(n){return!!n}function b(n){return!n}function _(n){return p(n)||a(n)&&0===n.length||c(n)&&0===j(n).length||!n}function x(n){return a(n)?n:[n]}function O(n,t){return n.hasOwnProperty(t)}function w(n){throw new Error(n)}function j(n){return Object.keys(n)}function k(n,t){n[Nn]=Object.assign(n[Nn]||{},t)}function N(n,t){return O(n,Nn)&&c(t)&&q(Object.assign({},n[Nn],t),n[Nn])}function M(n){O(n,Nn)&&delete n[Nn]}function A(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(n(t===Object(t),"Cannot iterate over object of type '"+e(t)+"'"),s(t))for(var i=0,o=t.length;i2&&void 0!==arguments[2]?arguments[2]:null;if(a(n))return n.map(t,r);if(c(n)){var e={};return A(n,function(n,u){return e[u]=t.call(r,n,u)},n),e}}function S(n,t,r){return a(n)?n.reduce(t,r):(A(n,function(e,u){return r=t(r,e,u,n)}),r)}function I(n,t){return n.filter($.bind(null,t))}function T(n,t){return L(L([],n),t.filter(y.bind(null,n)))}function q(n,t){if(n===t)return!0;var r=e(n);if(r!==e(t)||r===_n)return!1;if(r===dn&&isNaN(n)&&isNaN(t))return!0;if($([$n,yn],r))return n.toString()===t.toString();if(r===mn){if(n.length===t.length&&0===n.length)return!0;if(n.length!==t.length)return!1;for(var u=0,i=n.length;u2&&void 0!==arguments[2]?arguments[2]:null,e={},u=[],i=n.length,o=[],a=0;au[0]?1:r[1]u[1]?1:0}),L(o,u)}function U(n,t,r){var e={keys:[],groups:[]},u={};return A(n,function(n){var i=t.call(r,n),o=R(i),a=-1;g(u[o])&&(a=e.keys.length,u[o]=a,e.keys.push(i),e.groups.push([])),a=u[o],e.groups[a].push(n)}),e}function L(n,t){return Array.prototype.push.apply(n,t),n}function B(n,t){for(var r=0,e=n.length-1;r<=e;){var u=Math.round(r+(e-r)/2);if(tn[u]))return u;r=u+1}}return r}function Y(n){var t=this;return function(r){return function(){for(var e=arguments.length,u=Array(e),i=0;i2&&void 0!==arguments[2]&&arguments[2],e=t.split("."),u=n;n:for(var i=0;i1,c=void 0,f=void 0;try{a(t)?o?(c=Z(t,u),s&&(c=tn(c,i)),n(!g(c)),c=[c]):(c=[],A(t,function(n){f=tn(n,r),p(f)||c.push(f)}),n(c.length>0)):(f=Z(t,u),s&&(f=tn(f,i)),n(!g(f)),c={},c[u]=f)}catch(n){c=void 0}return c}}function rn(n,t,r){var e=arguments.length>3&&void 0!==arguments[3]&&arguments[3],u=t.split("."),i=u[0],o=1===u.length||u.slice(1).join(".");if(1===u.length)r(n,i);else if(a(n)&&!/^\d+$/.test(i))A(n,function(n){rn(n,t,r,e)});else{if(!0===e){var s=O(n,i);s&&!p(n[i])||(n[i]={})}rn(n[i],o,r,e)}}function en(n,t,r){rn(n,t,function(n,t){n[t]=r},!0)}function un(n,t){rn(n,t,function(n,t){a(n)&&/^\d+$/.test(t)?n.splice(parseInt(t),1):c(n)&&delete n[t]})}function on(n){if($(xn,e(n)))return v(n)?{$regex:n}:{$eq:n};if(f(n)){var t=j(n);if(0===I(V(kn),t).length)return{$eq:n};if($(t,"$regex")){var r=n.$regex,u=n.$options||"",o="";i(r)&&(o+=r.ignoreCase||u.indexOf("i")>=0?"i":"",o+=r.multiline||u.indexOf("m")>=0?"m":"",o+=r.global||u.indexOf("g")>=0?"g":"",r=new RegExp(r,o)),n.$regex=r,delete n.$options}}return n}function an(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(o.root=o.root||t,$(V(On),u))return Kn[u](t,r,o);if($(V(wn),u))return t=an(t,r,null,o),n(a(t),u+" expression must resolve to an array"),Mn[u](t,null,o);if(i(r)&&r.length>0&&"$"===r[0]){if($(tt,r))return Zn[r](t,null,o);if($(rt,r))return r;var s=tt.filter(function(n){return 0===r.indexOf(n+".")});return 1===s.length&&(s=s[0],"$$ROOT"===s&&(t=o.root),r=r.substr(s.length)),nn(t,r.slice(1))}switch(e(r)){case mn:return r.map(function(n){return an(t,n)});case bn:var c={};return A(r,function(e,u){if(c[u]=an(t,e,u,o),$(V(On,wn),u))return n(1===j(r).length,"Invalid aggregation expression '"+JSON.stringify(r)+"'"),c=c[u],!1}),c;default:return r}}function sn(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return p(e)?r<0?(r=Math.max(0,t.length+r),e=t.length-r+1):(e=r,r=0):(r<0&&(r=Math.max(0,t.length+r)),n(e>0,"Invalid argument value for $slice operator. Limit must be a positive number"),e+=r),Array.prototype.slice.apply(t,[r,e])}function cn(n){var t=S(n.data,function(n,t){return n+t},0),r=n.data.length||1,e=!0===n.sampled?1:0,u=t/(r-e);return Math.sqrt(S(n.data,function(n,t){return n+Math.pow(t-u,2)},0)/r)}function fn(n,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};r.root=r.root||n;var e=an(n,t,null,r);return $(rt,e)?nt[e](n,t,r):e}function ln(){return{computeValue:an,idKey:X,ops:V,resolve:nn,assert:n,clone:t,each:A,err:w,getType:r,has:O,isArray:a,isBoolean:u,isDate:l,isEmpty:_,isEqual:q,isFunction:h,isNil:p,isNull:d,isNumber:o,isObject:c,isRegExp:v,isString:i,isUndefined:g,keys:j,map:E}}Function.prototype.bind||(Function.prototype.bind=function(n){if("function"!=typeof this)throw new Error("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),r=this,e=function(){},u=function(){return r.apply(this instanceof e?this:n,t.concat(Array.prototype.slice.call(arguments)))};return this.prototype&&(e.prototype=this.prototype),u.prototype=new e,u}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),r=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u>>0;if(0===e)return!1;for(var u=0|t,i=Math.max(u>=0?u:e-Math.abs(u),0);in?t:n},void 0)},$min:function(n,t){return S(this.$push(n,t),function(n,t){return p(n)||t0?an(n[0],t):void 0},$last:function(n,t){return n.length>0?an(n[n.length-1],t):void 0},$stdDevPop:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!1})},$stdDevSamp:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!0})}},An={$:function(n,t,r){w("$ not implemented")},$elemMatch:function(n,t,r){var e=nn(n,r),u=new Rn(t);if(!p(e)&&a(e))for(var i=0;i1)&&p[0],$(V(jn),p)?"$slice"===p?x(a[p]).every(o)?(s=An[p](n,a[p],u),l=!0):s=an(n,a,u):s=An[p](n,a[p],u):s=an(n,a,u)}var d=t(tn(n,u));g(d)||Object.assign(r,d),g(s)||en(r,u,t(s))}),(l||v||s)&&(r=Object.assign(t(n),r),A(h,function(n){return un(r,n)})),u.push(r)}),u},$limit:function(n,t){return n.slice(0,t)},$skip:function(n,t){return n.slice(t)},$unwind:function(r,e){var u=[],i=e.substr(1);return A(r,function(r){var e=Z(r,i);n(a(e),"Target field '"+i+"' is not of type Array."),A(e,function(n){var e=t(r);e[i]=n,u.push(e)})}),u},$sort:function(n,t){if(!_(t)&&c(t)){A(j(t).reverse(),function(r){var e=U(n,function(n){return nn(n,r)}),u={},i=function(n){return u[R(n)]},o=F(e.keys,function(n,t){return u[R(n)]=t,n});-1===t[r]&&o.reverse(),n=[],A(o,function(t){return L(n,e.groups[i(t)])})})}return n},$sortByCount:function(n,t){var r={count:{$sum:1}};return r[X()]=t,this.$sort(this.$group(n,r),{count:-1})},$sample:function(t,r){var e=r.size;n(o(e),"$sample size must be a positive integer");for(var u=[],i=t.length,a=0;a2,"$bucket 'boundaries' expression must have at least 3 elements");for(var c=r(o),f=0,l=u.length-1;fe.default||a=a)n(!p(i),"$bucket require a default for out of range values"),v[i].push(t);else if(r>=o&&r0,"The $bucketAuto 'buckets' field must be greater than 0, but found: "+i);var o=Math.round(t.length/i);o<1&&(o=1);for(var a=Y(an),s={},c=[],f=F(t,function(n){var t=a(n,u);return p(t)?c.push(n):(s[t]||(s[t]=[]),s[t].push(n)),t}),l=X(),v=[],h=0,d=0,g=f.length;d0){v[v.length-1][l].max=$.min}}d==i-1&&L(y,f.slice(h)),v.push(Object.assign(J(y,null,e),{_id:$}))}return v.length>0&&(v[v.length-1][l].max=a(f[f.length-1],u)),v},$facet:function(n,t){return E(t,function(t){return z(n,t)})}},Sn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},In=function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")},Tn=function(){function n(n,t){for(var r=0;r0){var e=new qn(r);this.__result=e.run(this.__result,this.__query)}return this.__result}},{key:"all",value:function(){return this._fetch()}},{key:"first",value:function(){return this.count()>0?this._fetch()[0]:null}},{key:"last",value:function(){return this.count()>0?this._fetch()[this.count()-1]:null}},{key:"count",value:function(){return this._fetch().length}},{key:"skip",value:function(n){return Object.assign(this.__operators,{$skip:n}),this}},{key:"limit",value:function(n){return Object.assign(this.__operators,{$limit:n}),this}},{key:"sort",value:function(n){return Object.assign(this.__operators,{$sort:n}),this}},{key:"next",value:function(){return this.hasNext()?this._fetch()[this.__position++]:null}},{key:"hasNext",value:function(){return this.count()>this.__position}},{key:"max",value:function(n){return Mn.$max(this._fetch(),n)}},{key:"min",value:function(n){return Mn.$min(this._fetch(),n)}},{key:"map",value:function(n){return this._fetch().map(n)}},{key:"forEach",value:function(n){A(this._fetch(),n)}},{key:Symbol.iterator,value:function(){var n=this;return{next:function(){return n.hasNext()?{done:!1,value:n.next()}:{done:!0}}}}}]),t}(),Cn={$eq:function(n,t){if(q(n,t))return!0;if(p(n)&&p(t))return!0;if(a(n)){if(!N(n,{isMulti:!0}))return-1!==n.findIndex(q.bind(null,t));try{for(var r=0;r0},$nin:function(n,t){return p(n)||!this.$in(n,t)},$lt:function(n,t){return void 0!==(n=x(n).find(function(n){return nt}))},$gte:function(n,t){return void 0!==(n=x(n).find(function(n){return n>=t}))},$mod:function(n,t){return void 0!==(n=x(n).find(function(n){return o(n)&&a(t)&&2===t.length&&n%t[0]===t[1]}))},$regex:function(n,t){return void 0!==(n=x(n).find(function(n){return i(n)&&v(t)&&!!n.match(t)}))},$exists:function(n,t){return(!1===t||0===t)&&p(n)||(!0===t||1===t)&&!p(n)},$all:function(n,t){var r=!1;if(a(n)&&a(t))for(var e=0,u=t.length;e2147483647&&n<=0x8000000000000000&&-1===(n+"").indexOf(".");case 19:case"decimal":return o(n);default:return!1}}},Dn={$and:function(t,r){n(a(r),"Invalid expression: $and expects value to be an Array");var e=[];return A(r,function(n){return e.push(new Rn(n))}),{test:function(n){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:{};In(this,t),this.__criteria=n,this.__projection=r,this.__compiled=[],this._compile()}return Tn(t,[{key:"_compile",value:function(){var t=this;if(!_(this.__criteria)){n(c(this.__criteria),"Criteria must be of type Object");var r=void 0;A(this.__criteria,function(n,e){"$where"===e?r={field:e,expr:n}:$(["$and","$or","$nor"],e)?t._processOperator(e,e,n):(n=on(n),A(n,function(n,r){t._processOperator(e,r,n)})),c(r)&&t._processOperator(r.field,r.field,r.expr)})}}},{key:"_processOperator",value:function(n,t,r){$(V(kn),t)?this.__compiled.push(Dn[t](n,r)):w("Invalid query operator '"+t+"' detected")}},{key:"test",value:function(n){for(var t=0,r=this.__compiled.length;t0,"$sqrt expression must resolve to non-negative number."),Math.sqrt(e))},$subtract:function(n,t){var r=an(n,t);return r[0]-r[1]},$trunc:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e)&&e>0,"$trunc must be a valid expression that resolves to a non-negative number."),Math.trunc(e))}},Un={$arrayElemAt:function(t,r){var e=an(t,r);n(a(e)&&2===e.length,"$arrayElemAt expression must resolve to an array of 2 elements"),n(a(e[0]),"First operand to $arrayElemAt must resolve to an array"),n(o(e[1]),"Second operand to $arrayElemAt must resolve to an integer");var u=e[1];return e=e[0],u<0&&Math.abs(u)<=e.length?e[u+e.length]:u>=0&&u0||e>u&&i<0;)o.push(e),e+=i;return o},$reduce:function(t,r){var e=an(t,r.input),u=an(t,r.initialValue),i=r.in;return p(e)?null:(n(a(e),"$reduce 'input' expression must resolve to an array"),S(e,function(n,t){return an({$value:n,$this:t},i)},u))},$reverseArray:function(t,r){var e=an(t,r);if(p(e))return null;n(a(e),"$reverseArray expression must resolve to an array");var u=[];return L(u,e),u.reverse(),u},$size:function(n,t){var r=an(n,t);return a(r)?r.length:void 0},$slice:function(n,t){var r=an(n,t);return sn(r[0],r[1],r[2])},$zip:function(t,r){var e=an(t,r.inputs),i=r.useLongestLength||!1;n(a(e),"'inputs' expression must resolve to an array"),n(u(i),"'useLongestLength' must be a boolean"),a(r.defaults)&&n(m(i),"'useLongestLength' must be set to true to use 'defaults'");for(var o=0,s=0,c=e.length;sr[1]?1:r[0]=0&&Math.round(s)===s,"$indexOfBytes third operand must resolve to a non-negative integer"),s=s||0,n(p(c)||o(c)&&c>=0&&Math.round(c)===c,"$indexOfBytes fourth operand must resolve to a non-negative integer"),c=c||u.length,s>c)return-1;var f=u.substring(s,c).indexOf(a);return f>-1?f+s:f},$split:function(t,e){var u=an(t,e);return n(i(u[0]),"$split requires an expression that evaluates to a string as a first argument, found: "+r(u[0])),n(i(u[1]),"$split requires an expression that evaluates to a string as a second argument, found: "+r(u[1])),u[0].split(u[1])},$strcasecmp:function(n,t){var r=an(n,t);return r[0]=_(r[0])?"":r[0].toUpperCase(),r[1]=_(r[1])?"":r[1].toUpperCase(),r[0]>r[1]?1:r[0]KlRa{%mHTXWk+mVTdK0isw8FoG!3sokjp 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 { + let key = keys(operator) + assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), `Invalid aggregation operator ${key}`) + key = key[0] + if (query && query instanceof Query) { + collection = pipelineOperators[key].call(query, collection, operator[key]) + } else { + collection = pipelineOperators[key](collection, operator[key]) + } + }) + } + return collection + } +} + +/** + * Return the result collection after running the aggregation pipeline for the given collection + * + * @param collection + * @param pipeline + * @returns {Array} + */ +export function aggregate (collection, pipeline) { + assert(isArray(pipeline), 'Aggregation pipeline must be an array') + return (new Aggregator(pipeline)).run(collection) +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js new file mode 100644 index 0000000..a49df18 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js @@ -0,0 +1,24 @@ + +// Javascript native types +export const T_NULL = 'null' +export const T_UNDEFINED = 'undefined' +export const T_BOOL = 'bool' +export const T_BOOLEAN = 'boolean' +export const T_NUMBER = 'number' +export const T_STRING = 'string' +export const T_DATE = 'date' +export const T_REGEX = 'regex' +export const T_REGEXP = 'regexp' +export const T_ARRAY = 'array' +export const T_OBJECT = 'object' +export const T_FUNCTION = 'function' + +// no array, object, or function types +export const JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP] + +// operator classes +export const OP_AGGREGATE = 'aggregate' +export const OP_GROUP = 'group' +export const OP_PIPELINE = 'pipeline' +export const OP_PROJECTION = 'projection' +export const OP_QUERY = 'query' \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js new file mode 100644 index 0000000..00bccc7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js @@ -0,0 +1,191 @@ +import { assert, each, has, isArray, isObject } from './util' +import { Aggregator } from './aggregator' +import { groupOperators } from './operators/group.js' + +/** + * Cursor to iterate and perform filtering on matched objects + * @param collection + * @param query + * @param projection + * @constructor + */ +export class Cursor { + + constructor (collection, query, projection) { + this.__query = query + this.__collection = collection + this.__projection = projection || query.__projection + this.__operators = {} + this.__result = false + this.__position = 0 + } + + _fetch () { + + if (this.__result !== false) { + return this.__result + } + + // inject projection operator + if (isObject(this.__projection)) { + Object.assign(this.__operators, { '$project': this.__projection }) + } + + assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); + + // filter collection + this.__result = this.__collection.filter(this.__query.test, this.__query) + let pipeline = [] + + each(['$sort', '$skip', '$limit', '$project'], (op) => { + if (has(this.__operators, op)) { + let selected = {} + selected[op] = this.__operators[op] + pipeline.push(selected) + } + }) + + if (pipeline.length > 0) { + let aggregator = new Aggregator(pipeline) + this.__result = aggregator.run(this.__result, this.__query) + } + return this.__result + } + + /** + * Fetch and return all matched results + * @returns {Array} + */ + all () { + return this._fetch() + } + + /** + * Fetch and return the first matching result + * @returns {Object} + */ + first () { + return this.count() > 0 ? this._fetch()[0] : null + } + + /** + * Fetch and return the last matching object from the result + * @returns {Object} + */ + last () { + return this.count() > 0 ? this._fetch()[this.count() - 1] : null + } + + /** + * Counts the number of matched objects found + * @returns {Number} + */ + count () { + return this._fetch().length + } + + /** + * Returns a cursor that begins returning results only after passing or skipping a number of documents. + * @param {Number} n the number of results to skip. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + skip (n) { + Object.assign(this.__operators, { '$skip': n }) + return this + } + + /** + * Constrains the size of a cursor's result set. + * @param {Number} n the number of results to limit to. + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + limit (n) { + Object.assign(this.__operators, { '$limit': n }) + return this + } + + /** + * Returns results ordered according to a sort specification. + * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending + * @return {Cursor} Returns the cursor, so you can chain this call. + */ + sort (modifier) { + Object.assign(this.__operators, { '$sort': modifier }) + return this + } + + /** + * Returns the next document in a cursor. + * @returns {Object | Boolean} + */ + next () { + if (this.hasNext()) { + return this._fetch()[this.__position++] + } + return null + } + + /** + * Returns true if the cursor has documents and can be iterated. + * @returns {boolean} + */ + hasNext () { + return this.count() > this.__position + } + + /** + * Specifies the exclusive upper bound for a specific field + * @param expr + * @returns {Number} + */ + max (expr) { + return groupOperators.$max(this._fetch(), expr) + } + + /** + * Specifies the inclusive lower bound for a specific field + * @param expr + * @returns {Number} + */ + min (expr) { + return groupOperators.$min(this._fetch(), expr) + } + + /** + * Applies a function to each document in a cursor and collects the return values in an array. + * @param callback + * @returns {Array} + */ + map (callback) { + return this._fetch().map(callback) + } + + /** + * Applies a JavaScript function for every document in a cursor. + * @param callback + */ + forEach (callback) { + each(this._fetch(), callback) + } + + /** + * Applies an [ES2015 Iteration protocol][] compatible implementation + * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + * @returns {Object} + */ + [Symbol.iterator] () { + let self = this + return { + next () { + if (!self.hasNext()) { + return { done: true } + } + return { + done: false, + value: self.next() + } + } + } + } +} + diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js new file mode 100644 index 0000000..297e0c6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js @@ -0,0 +1,30 @@ +import './polyfill' +import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' +import { _internal, setup } from './internal' +import { Query, find, remove } from './query' +import { Aggregator, aggregate } from './aggregator' +import { CollectionMixin } from './mixin' +import { Cursor } from './cursor' +import { addOperators } from './operators/index' + +const VERSION = '1.3.3' + +// mingo! +export default { + _internal, + Aggregator, + CollectionMixin, + Cursor, + OP_AGGREGATE, + OP_GROUP, + OP_PIPELINE, + OP_PROJECTION, + OP_QUERY, + Query, + VERSION, + addOperators, + aggregate, + find, + remove, + setup +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js new file mode 100644 index 0000000..edea20f --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js @@ -0,0 +1,496 @@ +import { + T_ARRAY, + T_OBJECT, + JS_SIMPLE_TYPES, + OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY +} from './constants' +import { + addMeta, + assert, + clone, + dropMeta, + each, + err, + getHash, + getType, + has, + hasMeta, + inArray, + intersection, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isObjectLike, + isRegExp, + isString, + isUndefined, + jsType, + keys, + map, + notInArray, + reduce, + truthy +} from './util' +import { groupOperators } from './operators/group.js' +import { ops } from './operators/index.js' +import { aggregateOperators } from './operators/aggregation/index.js' + + +/** + * Internal functions + */ + +// Settings used by Mingo internally +const settings = { + key: '_id' +} + +/** + * Setup default settings for Mingo + * @param options + */ +export function setup (options) { + Object.assign(settings, options || {}) +} + +/** + * Implementation of system variables + * @type {Object} + */ +export const systemVariables = { + '$$ROOT' (obj, expr, opt) { + return opt.root + }, + '$$CURRENT' (obj, expr, opt) { + return obj + } +} + +/** + * Implementation of $redact variables + * + * Each function accepts 3 arguments (obj, expr, opt) + * + * @type {Object} + */ +export const redactVariables = { + '$$KEEP' (obj) { + return obj + }, + '$$PRUNE' () { + return undefined + }, + '$$DESCEND' (obj, expr, opt) { + // traverse nested documents iff there is a $cond + if (!has(expr, '$cond')) return obj + + let result + + each(obj, (current, key) => { + if (isObjectLike(current)) { + if (isArray(current)) { + result = [] + each(current, (elem) => { + if (isObject(elem)) { + elem = redactObj(elem, expr, opt) + } + if (!isNil(elem)) result.push(elem) + }) + } else { + result = redactObj(current, expr, opt) + } + + if (isNil(result)) { + delete obj[key] // pruned result + } else { + obj[key] = result + } + } + }) + return obj + } +} + +// system variables +export const SYS_VARS = keys(systemVariables) +export const REDACT_VARS = keys(redactVariables) + +/** + * Returns the key used as the collection's objects ids + */ +export function idKey () { + return settings.key +} + +/** + * Retrieve the value of a given key on an object + * @param obj + * @param field + * @returns {*} + * @private + */ +export function getValue (obj, field) { + return obj[field] +} + +/** + * Resolve the value of the field (dot separated) on the given object + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) + * @returns {*} + */ +export function resolve (obj, selector, deepFlag = false) { + let names = selector.split('.') + let value = obj + + for (let i = 0; i < names.length; i++) { + let isText = names[i].match(/^\d+$/) === null + + if (isText && isArray(value)) { + // On the first iteration, we check if we received a stop flag. + // If so, we stop to prevent iterating over a nested array value + // on consecutive object keys in the selector. + if (deepFlag === true && i === 0) { + return value + } + + value = value.map((item) => resolve(item, names[i], true)) + + // we mark this value as being multi-valued + addMeta(value, { isMulti: true }) + + // we unwrap for arrays of unit length + // this avoids excess wrapping when resolving deeply nested arrays + if (value.length === 1) { + value = value[0] + } + } else { + value = getValue(value, names[i]) + deepFlag = false // reset stop flag when we do a direct lookup + } + + if (isNil(value)) break + } + + return value +} + +/** + * Returns the full object to the resolved value given by the selector. + * This function excludes empty values as they aren't practically useful. + * + * @param obj {Object} the object context + * @param selector {String} dot separated path to field + */ +export function resolveObj (obj, selector) { + if (isNil(obj)) return + + let names = selector.split('.') + let key = names[0] + // get the next part of the selector + let next = names.length === 1 || names.slice(1).join('.') + let isIndex = key.match(/^\d+$/) !== null + let hasNext = names.length > 1 + let result + let value + + try { + if (isArray(obj)) { + if (isIndex) { + result = getValue(obj, key) + if (hasNext) { + result = resolveObj(result, next) + } + assert(!isUndefined(result)) + result = [result] + } else { + result = [] + each(obj, (item) => { + value = resolveObj(item, selector) + if (!isNil(value)) result.push(value) + }) + assert(result.length > 0) + } + } else { + value = getValue(obj, key) + if (hasNext) { + value = resolveObj(value, next) + } + assert(!isUndefined(value)) + result = {} + result[key] = value + } + } catch (e) { + result = undefined + } + + return result +} + +/** + * Walk the object graph and execute the given transform function + * @param {Object|Array} obj The object to traverse + * @param {String} selector The selector + * @param {Function} fn Function to execute for value at the end the traversal + * @param {Boolean} force Force generating missing parts of object graph + * @return {*} + */ +export function traverse (obj, selector, fn, force = false) { + let names = selector.split('.') + let key = names[0] + let next = names.length === 1 || names.slice(1).join('.') + + if (names.length === 1) { + fn(obj, key) + } else { // nested objects + if (isArray(obj) && !/^\d+$/.test(key)) { + each(obj, (item) => { + traverse(item, selector, fn, force) + }) + } else { + // force the rest of the graph while traversing + if (force === true) { + let exists = has(obj, key) + if (!exists || isNil(obj[key])) { + obj[key] = {} + } + } + traverse(obj[key], next, fn, force) + } + } +} + +/** + * Set the value of the given object field + * + * @param obj {Object|Array} the object context + * @param selector {String} path to field + * @param value {*} the value to set + */ +export function setValue (obj, selector, value) { + traverse(obj, selector, (item, key) => { + item[key] = value + }, true) +} + +export function removeValue (obj, selector) { + traverse(obj, selector, (item, key) => { + if (isArray(item) && /^\d+$/.test(key)) { + item.splice(parseInt(key), 1) + } else if (isObject(item)) { + delete item[key] + } + }) +} + +/** + * Simplify expression for easy evaluation with query operators map + * @param expr + * @returns {*} + */ +export function normalize (expr) { + // normalized primitives + if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { + return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr } + } + + // normalize object expression + if (isObjectLike(expr)) { + let exprKeys = keys(expr) + let noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0 + + // no valid query operator found, so we do simple comparison + if (noQuery) { + return { '$eq': expr } + } + + // ensure valid regex + if (inArray(exprKeys, '$regex')) { + let regex = expr['$regex'] + let options = expr['$options'] || '' + let modifiers = '' + if (isString(regex)) { + modifiers += (regex.ignoreCase || options.indexOf('i') >= 0) ? 'i' : '' + modifiers += (regex.multiline || options.indexOf('m') >= 0) ? 'm' : '' + modifiers += (regex.global || options.indexOf('g') >= 0) ? 'g' : '' + regex = new RegExp(regex, modifiers) + } + expr['$regex'] = regex + delete expr['$options'] + } + } + + return expr +} + +/** + * Computes the actual value of the expression using the given object as context + * + * @param obj the current object from the collection + * @param expr the expression for the given field + * @param field the field name (may also be an aggregate operator) + * @param opt {Object} extra options + * @returns {*} + */ +export function computeValue (obj, expr, field = null, opt = {}) { + opt.root = opt.root || obj + + // if the field of the object is a valid operator + if (inArray(ops(OP_AGGREGATE), field)) { + return aggregateOperators[field](obj, expr, opt) + } + + // we also handle $group accumulator operators + if (inArray(ops(OP_GROUP), field)) { + // we first fully resolve the expression + obj = computeValue(obj, expr, null, opt) + assert(isArray(obj), field + ' expression must resolve to an array') + // we pass a null expression because all values have been resolved + return groupOperators[field](obj, null, opt) + } + + // if expr is a variable for an object field + // field not used in this case + if (isString(expr) && expr.length > 0 && expr[0] === '$') { + // we return system variables as literals + if (inArray(SYS_VARS, expr)) { + return systemVariables[expr](obj, null, opt) + } else if (inArray(REDACT_VARS, expr)) { + return expr + } + + // handle selectors with explicit prefix + let sysVar = SYS_VARS.filter((v) => expr.indexOf(v + '.') === 0) + + if (sysVar.length === 1) { + sysVar = sysVar[0] + if (sysVar === '$$ROOT') { + obj = opt.root + } + expr = expr.substr(sysVar.length) // '.' prefix will be sliced off below + } + + return resolve(obj, expr.slice(1)) + } + + // check and return value if already in a resolved state + switch (jsType(expr)) { + case T_ARRAY: + return expr.map((item) => computeValue(obj, item)) + case T_OBJECT: + let result = {} + each(expr, (val, key) => { + result[key] = computeValue(obj, val, key, opt) + // must run ONLY one aggregate operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { + // there should be only one operator + assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'") + result = result[key] + return false // break + } + }) + return result + default: + return expr + } +} + +/** + * Returns a slice of the array + * + * @param {Array} xs + * @param {Number} skip + * @param {Number} limit + * @return {Array} + */ +export function slice (xs, skip, limit = null) { + // MongoDB $slice works a bit differently from Array.slice + // Uses single argument for 'limit' and array argument [skip, limit] + if (isNil(limit)) { + if (skip < 0) { + skip = Math.max(0, xs.length + skip) + limit = xs.length - skip + 1 + } else { + limit = skip + skip = 0 + } + } else { + if (skip < 0) { + skip = Math.max(0, xs.length + skip) + } + assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number') + limit += skip + } + return Array.prototype.slice.apply(xs, [skip, limit]) +} + +/** + * Compute the standard deviation of the data set + * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". + * @return {Number} + */ +export function stddev (ctx) { + let sum = reduce(ctx.data, (acc, n) => acc + n, 0) + let N = ctx.data.length || 1 + let correction = ctx.sampled === true ? 1 : 0 + let avg = sum / (N - correction) + return Math.sqrt(reduce(ctx.data, (acc, n) => acc + Math.pow(n - avg, 2), 0) / N) +} + +/** + * Redact an object + * @param {Object} obj The object to redact + * @param {*} expr The redact expression + * @param {*} opt Options for value + * @return {*} Returns the redacted value + */ +export function redactObj (obj, expr, opt = {}) { + opt.root = opt.root || obj + + let result = computeValue(obj, expr, null, opt) + return inArray(REDACT_VARS, result) + ? redactVariables[result](obj, expr, opt) + : result +} + +/** + * Exported to the users to allow writing custom operators + */ +export function _internal () { + return { + computeValue, + idKey, + ops, + resolve, + assert, + clone, + each, + err, + getType, + has, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isRegExp, + isString, + isUndefined, + keys, + map + } +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js new file mode 100644 index 0000000..72eb7d4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js @@ -0,0 +1,27 @@ +import { Aggregator } from './aggregator' +import { Query } from './query' + +/** + * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` + */ +export const CollectionMixin = { + + /** + * Runs a query and returns a cursor to the result + * @param criteria + * @param projection + * @returns {Cursor} + */ + query (criteria, projection) { + return new Query(criteria).find(this.toJSON(), projection) + }, + + /** + * Runs the given aggregation operators on this collection + * @params pipeline + * @returns {Array} + */ + aggregate (pipeline) { + return new Aggregator(pipeline).run(this.toJSON()) + } +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js new file mode 100644 index 0000000..edde5e7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js @@ -0,0 +1,214 @@ +import { assert, err, isNil, isNumber, isArray, reduce } from '../../util.js' +import { computeValue } from '../../internal.js' + +export const arithmeticOperators = { + + /** + * Returns the absolute value of a number. + * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs + * @param obj + * @param expr + * @return {Number|null|NaN} + */ + $abs (obj, expr) { + let val = computeValue(obj, expr) + return (val === null || val === undefined) ? null : Math.abs(val) + }, + + /** + * Computes the sum of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $add (obj, expr) { + let args = computeValue(obj, expr) + return reduce(args, (acc, num) => acc + num, 0) + }, + + /** + * Returns the smallest integer greater than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $ceil (obj, expr) { + let arg = computeValue(obj, expr) + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.') + return Math.ceil(arg) + }, + + /** + * Takes two numbers and divides the first number by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $divide (obj, expr) { + let args = computeValue(obj, expr) + return args[0] / args[1] + }, + + /** + * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {number} + */ + $exp (obj, expr) { + let arg = computeValue(obj, expr) + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.') + return Math.exp(arg) + }, + + /** + * Returns the largest integer less than or equal to the specified number. + * + * @param obj + * @param expr + * @returns {number} + */ + $floor (obj, expr) { + let arg = computeValue(obj, expr) + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.') + return Math.floor(arg) + }, + + /** + * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $ln (obj, expr) { + let arg = computeValue(obj, expr) + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.') + return Math.log(arg) + }, + + /** + * Calculates the log of a number in the specified base and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log (obj, expr) { + let args = computeValue(obj, expr) + assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items') + if (args.some(isNaN)) return NaN + if (args.some(isNil)) return null + assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers') + return Math.log10(args[0]) / Math.log10(args[1]) + }, + + /** + * Calculates the log base 10 of a number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $log10 (obj, expr) { + let arg = computeValue(obj, expr) + if (isNaN(arg)) return NaN + if (isNil(arg)) return null + assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.') + return Math.log10(arg) + }, + + /** + * Takes two numbers and calculates the modulo of the first number divided by the second. + * + * @param obj + * @param expr + * @returns {number} + */ + $mod (obj, expr) { + let args = computeValue(obj, expr) + return args[0] % args[1] + }, + + /** + * Computes the product of an array of numbers. + * + * @param obj + * @param expr + * @returns {Object} + */ + $multiply (obj, expr) { + let args = computeValue(obj, expr) + return reduce(args, (acc, num) => acc * num, 1) + }, + + /** + * Raises a number to the specified exponent and returns the result. + * + * @param obj + * @param expr + * @returns {Object} + */ + $pow (obj, expr) { + let args = computeValue(obj, expr) + + assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers') + assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent') + + return Math.pow(args[0], args[1]) + }, + + /** + * Calculates the square root of a positive number and returns the result as a double. + * + * @param obj + * @param expr + * @returns {number} + */ + $sqrt (obj, expr) { + let n = computeValue(obj, expr) + if (isNaN(n)) return NaN + if (isNil(n)) return null + assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.') + return Math.sqrt(n) + }, + + /** + * Takes an array that contains two numbers or two dates and subtracts the second value from the first. + * + * @param obj + * @param expr + * @returns {number} + */ + $subtract (obj, expr) { + let args = computeValue(obj, expr) + return args[0] - args[1] + }, + + /** + * Truncates a number to its integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $trunc (obj, expr) { + let n = computeValue(obj, expr) + if (isNaN(n)) return NaN + if (isNil(n)) return null + assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.') + return Math.trunc(n) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js new file mode 100644 index 0000000..51ceddf --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js @@ -0,0 +1,322 @@ +import { + assert, + each, + err, + has, + into, + inArray, + isArray, + isObject, + isNumber, + isBoolean, + isNil, + isUndefined, + keys, + map, + reduce, + truthy +} from '../../util.js' +import { computeValue, slice } from '../../internal.js' + +export const arrayOperators = { + /** + * Returns the element at the specified array index. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $arrayElemAt (obj, expr) { + let arr = computeValue(obj, expr) + assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements') + assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array') + assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer') + let idx = arr[1] + arr = arr[0] + if (idx < 0 && Math.abs(idx) <= arr.length) { + return arr[idx + arr.length] + } else if (idx >= 0 && idx < arr.length) { + return arr[idx] + } + return undefined + }, + + /** + * Converts an array of key value pairs to a document. + */ + $arrayToObject (obj, expr) { + let arr = computeValue(obj, expr) + assert(isArray(arr), '$arrayToObject expression must resolve to an array') + return reduce(arr, (newObj, val) => { + if (isArray(val) && val.length == 2) newObj[val[0]] = val[1] + else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v + else err('$arrayToObject expression is invalid.') + return newObj + }, {}) + }, + + /** + * Concatenates arrays to return the concatenated array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $concatArrays (obj, expr) { + let arr = computeValue(obj, expr, null) + assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements') + + if (arr.some(isNil)) return null + + return arr[0].concat(arr[1]) + }, + + /** + * Selects a subset of the array to return an array with only the elements that match the filter condition. + * + * @param {Object} obj [description] + * @param {*} expr [description] + * @return {*} [description] + */ + $filter (obj, expr) { + let input = computeValue(obj, expr.input) + let asVar = expr['as'] + let condExpr = expr['cond'] + + assert(isArray(input), "$filter 'input' expression must resolve to an array") + + return input.filter((o) => { + // inject variable + let tempObj = {} + tempObj['$' + asVar] = o + return computeValue(tempObj, condExpr) === true + }) + }, + + /** + * Returns a boolean indicating whether a specified value is in an array. + * + * @param {Object} obj + * @param {Array} expr + */ + $in (obj, expr) { + let val = computeValue(obj, expr[0]) + let arr = computeValue(obj, expr[1]) + assert(isArray(arr), '$in second argument must be an array') + return inArray(arr, val) + }, + + /** + * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfArray (obj, expr) { + let args = computeValue(obj, expr) + if (isNil(args)) return null + + let arr = args[0] + if (isNil(arr)) return null + + assert(isArray(arr), '$indexOfArray expression must resolve to an array.') + + let searchValue = args[1] + if (isNil(searchValue)) return null + + let start = args[2] || 0 + let end = args[3] || arr.length + + if (end < arr.length) { + arr = arr.slice(start, end) + } + + return arr.indexOf(searchValue, start) + }, + + /** + * Determines if the operand is an array. Returns a boolean. + * + * @param {Object} obj + * @param {*} expr + * @return {Boolean} + */ + $isArray (obj, expr) { + return isArray(computeValue(obj, expr)) + }, + + /** + * Applies a sub-expression to each element of an array and returns the array of resulting values in order. + * + * @param obj + * @param expr + * @returns {Array|*} + */ + $map (obj, expr) { + let inputExpr = computeValue(obj, expr.input) + assert(isArray(inputExpr), `$map 'input' expression must resolve to an array`) + + let asExpr = expr['as'] + let inExpr = expr['in'] + + // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" + // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". + // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. + let tempKey = '$' + asExpr + // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) + let original = obj[tempKey] + return map(inputExpr, (item) => { + obj[tempKey] = item + let value = computeValue(obj, inExpr) + // cleanup and restore + if (isUndefined(original)) { + delete obj[tempKey] + } else { + obj[tempKey] = original + } + return value + }) + }, + + /** + * Converts a document to an array of documents representing key-value pairs. + */ + $objectToArray (obj, expr) { + let val = computeValue(obj, expr) + assert(isObject(val), '$objectToArray expression must resolve to an object') + let arr = [] + each(val, (v,k) => arr.push({k,v})) + return arr + }, + + /** + * Returns an array whose elements are a generated sequence of numbers. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $range (obj, expr) { + let arr = computeValue(obj, expr) + let start = arr[0] + let end = arr[1] + let step = arr[2] || 1 + + let result = [] + + while ((start < end && step > 0) || (start > end && step < 0)) { + result.push(start) + start += step + } + + return result + }, + + /** + * Applies an expression to each element in an array and combines them into a single value. + * + * @param {Object} obj + * @param {*} expr + */ + $reduce (obj, expr) { + let input = computeValue(obj, expr.input) + let initialValue = computeValue(obj, expr.initialValue) + let inExpr = expr['in'] + + if (isNil(input)) return null + assert(isArray(input), "$reduce 'input' expression must resolve to an array") + return reduce(input, (acc, n) => computeValue({ '$value': acc, '$this': n }, inExpr), initialValue) + }, + + /** + * Returns an array with the elements in reverse order. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $reverseArray (obj, expr) { + let arr = computeValue(obj, expr) + + if (isNil(arr)) return null + assert(isArray(arr), '$reverseArray expression must resolve to an array') + + let result = [] + into(result, arr) + result.reverse() + return result + }, + + /** + * Counts and returns the total the number of items in an array. + * + * @param obj + * @param expr + */ + $size (obj, expr) { + let value = computeValue(obj, expr) + return isArray(value) ? value.length : undefined + }, + + /** + * Returns a subset of an array. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $slice (obj, expr) { + let arr = computeValue(obj, expr) + return slice(arr[0], arr[1], arr[2]) + }, + + /** + * Merge two lists together. + * + * Transposes an array of input arrays so that the first element of the output array would be an array containing, + * the first element of the first input array, the first element of the second input array, etc. + * + * @param {Obj} obj + * @param {*} expr + * @return {*} + */ + $zip (obj, expr) { + let inputs = computeValue(obj, expr.inputs) + let useLongestLength = expr.useLongestLength || false + + assert(isArray(inputs), "'inputs' expression must resolve to an array") + assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean") + + if (isArray(expr.defaults)) { + assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'") + } + + let zipCount = 0 + + for (let i = 0, len = inputs.length; i < len; i++) { + let arr = inputs[i] + + if (isNil(arr)) return null + + assert(isArray(arr), "'inputs' expression values must resolve to an array or null") + + zipCount = useLongestLength + ? Math.max(zipCount, arr.length) + : Math.min(zipCount || arr.length, arr.length) + } + + let result = [] + let defaults = expr.defaults || [] + + for (let i = 0; i < zipCount; i++) { + let temp = inputs.map((val, index) => { + return isNil(val[i]) ? (defaults[index] || null) : val[i] + }) + result.push(temp) + } + + return result + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js new file mode 100644 index 0000000..5cc96e7 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js @@ -0,0 +1,39 @@ +import { computeValue } from '../../internal' +import { truthy } from '../../util' + +export const booleanOperators = { + /** + * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $and: (obj, expr) => { + let value = computeValue(obj, expr) + return truthy(value) && value.every(truthy) + }, + + /** + * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $or: (obj, expr) => { + let value = computeValue(obj, expr) + return truthy(value) && value.some(truthy) + }, + + /** + * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. + * + * @param obj + * @param expr + * @returns {boolean} + */ + $not: (obj, expr) => { + return !computeValue(obj, expr[0]) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js new file mode 100644 index 0000000..0abe23d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js @@ -0,0 +1,26 @@ +import { each } from '../../util.js' +import { computeValue } from '../../internal.js' +import { simpleOperators } from '../query.js' + +export const comparisonOperators = { + /** + * Compares two values and returns the result of the comparison as an integer. + * + * @param obj + * @param expr + * @returns {number} + */ + $cmp (obj, expr) { + let args = computeValue(obj, expr) + if (args[0] > args[1]) return 1 + if (args[0] < args[1]) return -1 + return 0 + } +} +// mixin comparison operators +each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], (op) => { + comparisonOperators[op] = (obj, expr) => { + let args = computeValue(obj, expr) + return simpleOperators[op](args[0], args[1]) + } +}) diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js new file mode 100644 index 0000000..af02ebe --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js @@ -0,0 +1,71 @@ +/** + * Conditional operators + */ + +import { assert, err, isArray, isObject } from '../../util.js' +import { computeValue, resolve } from '../../internal.js' + +export const conditionalOperators = { + + /** + * A ternary operator that evaluates one expression, + * and depending on the result returns the value of one following expressions. + * + * @param obj + * @param expr + */ + $cond (obj, expr) { + let ifExpr, thenExpr, elseExpr + if (isArray(expr)) { + assert(expr.length === 3, 'Invalid arguments for $cond operator') + ifExpr = expr[0] + thenExpr = expr[1] + elseExpr = expr[2] + } else if (isObject(expr)) { + ifExpr = expr['if'] + thenExpr = expr['then'] + elseExpr = expr['else'] + } + let condition = computeValue(obj, ifExpr) + return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr) + }, + + /** + * An operator that evaluates a series of case expressions. When it finds an expression which + * evaluates to true, it returns the resulting expression for that case. If none of the cases + * evaluate to true, it returns the default expression. + * + * @param obj + * @param expr + */ + $switch (obj, expr) { + assert(expr.branches, 'Invalid arguments for $switch operator') + + let validBranch = expr.branches.find((branch) => { + assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator') + return computeValue(obj, branch['case']) + }) + + if (validBranch) { + return computeValue(obj, validBranch.then) + } else if (!expr.default) { + err('Invalid arguments for $switch operator') + } else { + return computeValue(obj, expr.default) + } + }, + + /** + * Evaluates an expression and returns the first expression if it evaluates to a non-null value. + * Otherwise, $ifNull returns the second expression's value. + * + * @param obj + * @param expr + * @returns {*} + */ + $ifNull (obj, expr) { + assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator') + let args = computeValue(obj, expr) + return (args[0] === null || args[0] === undefined) ? args[1] : args[0] + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js new file mode 100644 index 0000000..fae518a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js @@ -0,0 +1,182 @@ + +import { isDate, isArray } from '../../util.js' +import { computeValue } from '../../internal.js' + +// used for formatting dates in $dateToString operator +let DATE_SYM_TABLE = { + '%Y': ['$year', 4], + '%m': ['$month', 2], + '%d': ['$dayOfMonth', 2], + '%H': ['$hour', 2], + '%M': ['$minute', 2], + '%S': ['$second', 2], + '%L': ['$millisecond', 3], + '%j': ['$dayOfYear', 3], + '%w': ['$dayOfWeek', 1], + '%U': ['$week', 2], + '%%': '%' +} + +export const dateOperators = { + /** + * Returns the day of the year for a date as a number between 1 and 366 (leap year). + * @param obj + * @param expr + */ + $dayOfYear (obj, expr) { + let d = computeValue(obj, expr) + if (isDate(d)) { + let start = new Date(d.getFullYear(), 0, 0) + let diff = d - start + let oneDay = 1000 * 60 * 60 * 24 + return Math.round(diff / oneDay) + } + return undefined + }, + + /** + * Returns the day of the month for a date as a number between 1 and 31. + * @param obj + * @param expr + */ + $dayOfMonth (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getDate() : undefined + }, + + /** + * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). + * @param obj + * @param expr + */ + $dayOfWeek (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getDay() + 1 : undefined + }, + + /** + * Returns the year for a date as a number (e.g. 2014). + * @param obj + * @param expr + */ + $year (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getFullYear() : undefined + }, + + /** + * Returns the month for a date as a number between 1 (January) and 12 (December). + * @param obj + * @param expr + */ + $month (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getMonth() + 1 : undefined + }, + + /** + * Returns the week number for a date as a number between 0 + * (the partial week that precedes the first Sunday of the year) and 53 (leap year). + * @param obj + * @param expr + */ + $week (obj, expr) { + // source: http://stackoverflow.com/a/6117889/1370481 + let d = computeValue(obj, expr) + + // Copy date so don't modify original + d = new Date(+d) + d.setHours(0, 0, 0) + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + d.setDate(d.getDate() + 4 - (d.getDay() || 7)) + // Get first day of year + let yearStart = new Date(d.getFullYear(), 0, 1) + // Calculate full weeks to nearest Thursday + return Math.floor((((d - yearStart) / 8.64e7) + 1) / 7) + }, + + /** + * Returns the hour for a date as a number between 0 and 23. + * @param obj + * @param expr + */ + $hour (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getUTCHours() : undefined + }, + + /** + * Returns the minute for a date as a number between 0 and 59. + * @param obj + * @param expr + */ + $minute (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getMinutes() : undefined + }, + + /** + * Returns the seconds for a date as a number between 0 and 60 (leap seconds). + * @param obj + * @param expr + */ + $second (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getSeconds() : undefined + }, + + /** + * Returns the milliseconds of a date as a number between 0 and 999. + * @param obj + * @param expr + */ + $millisecond (obj, expr) { + let d = computeValue(obj, expr) + return isDate(d) ? d.getMilliseconds() : undefined + }, + + /** + * Returns the date as a formatted string. + * + * %Y Year (4 digits, zero padded) 0000-9999 + * %m Month (2 digits, zero padded) 01-12 + * %d Day of Month (2 digits, zero padded) 01-31 + * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 + * %M Minute (2 digits, zero padded) 00-59 + * %S Second (2 digits, zero padded) 00-60 + * %L Millisecond (3 digits, zero padded) 000-999 + * %j Day of year (3 digits, zero padded) 001-366 + * %w Day of week (1-Sunday, 7-Saturday) 1-7 + * %U Week of year (2 digits, zero padded) 00-53 + * %% Percent Character as a Literal % + * + * @param obj current object + * @param expr operator expression + */ + $dateToString (obj, expr) { + let fmt = expr['format'] + let date = computeValue(obj, expr['date']) + let matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g) + + for (let i = 0, len = matches.length; i < len; i++) { + let hdlr = DATE_SYM_TABLE[matches[i]] + let value = hdlr + + if (isArray(hdlr)) { + // reuse date operators + let fn = this[hdlr[0]] + let pad = hdlr[1] + value = padDigits(fn.call(this, obj, date), pad) + } + // replace the match with resolved value + fmt = fmt.replace(matches[i], value) + } + + return fmt + } +} + +function padDigits (number, digits) { + return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js new file mode 100644 index 0000000..d39a41d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js @@ -0,0 +1,25 @@ +import { arithmeticOperators } from './arithmetic.js' +import { arrayOperators } from './array.js' +import { booleanOperators } from './boolean.js' +import { comparisonOperators } from './comparison.js' +import { conditionalOperators } from './conditional.js' +import { dateOperators } from './date.js' +import { literalOperators } from './literal.js' +import { setOperators } from './set.js' +import { stringOperators } from './string.js' +import { variableOperators } from './variable.js' + +// combine aggregate operators +export const aggregateOperators = Object.assign( + {}, + arithmeticOperators, + arrayOperators, + booleanOperators, + comparisonOperators, + conditionalOperators, + dateOperators, + literalOperators, + setOperators, + stringOperators, + variableOperators +) diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js new file mode 100644 index 0000000..0788cf0 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js @@ -0,0 +1,11 @@ + +export const literalOperators = { + /** + * Return a value without parsing. + * @param obj + * @param expr + */ + $literal (obj, expr) { + return expr + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js new file mode 100644 index 0000000..d992786 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js @@ -0,0 +1,78 @@ +import { union, unique, intersection, notInArray, inArray, truthy } from '../../util.js' +import { computeValue, resolve } from '../../internal.js' + +export const setOperators = { + /** + * Returns true if two sets have the same elements. + * @param obj + * @param expr + */ + $setEquals (obj, expr) { + let args = computeValue(obj, expr) + let xs = unique(args[0]) + let ys = unique(args[1]) + return xs.length === ys.length && xs.length === intersection(xs, ys).length + }, + + /** + * Returns the common elements of the input sets. + * @param obj + * @param expr + */ + $setIntersection (obj, expr) { + let args = computeValue(obj, expr) + return intersection(args[0], args[1]) + }, + + /** + * Returns elements of a set that do not appear in a second set. + * @param obj + * @param expr + */ + $setDifference (obj, expr) { + let args = computeValue(obj, expr) + return args[0].filter(notInArray.bind(null, args[1])) + }, + + /** + * Returns a set that holds all elements of the input sets. + * @param obj + * @param expr + */ + $setUnion (obj, expr) { + let args = computeValue(obj, expr) + return union(args[0], args[1]) + }, + + /** + * Returns true if all elements of a set appear in a second set. + * @param obj + * @param expr + */ + $setIsSubset (obj, expr) { + let args = computeValue(obj, expr) + return intersection(args[0], args[1]).length === args[0].length + }, + + /** + * Returns true if any elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $anyElementTrue (obj, expr) { + // mongodb nests the array expression in another + let args = computeValue(obj, expr)[0] + return args.some(truthy) + }, + + /** + * Returns true if all elements of a set evaluate to true, and false otherwise. + * @param obj + * @param expr + */ + $allElementsTrue (obj, expr) { + // mongodb nests the array expression in another + let args = computeValue(obj, expr)[0] + return args.every(truthy) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js new file mode 100644 index 0000000..2362da9 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js @@ -0,0 +1,140 @@ +import { assert, err, isString, isNil, isNumber, isEmpty, inArray, getType } from '../../util.js' +import { computeValue, resolve } from '../../internal.js' + +export const stringOperators = { + + /** + * Concatenates two strings. + * + * @param obj + * @param expr + * @returns {string|*} + */ + $concat (obj, expr) { + let args = computeValue(obj, expr) + // does not allow concatenation with nulls + if ([null, undefined].some(inArray.bind(null, args))) { + return null + } + return args.join('') + }, + + /** + * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. + * If the substring is not found, returns -1. + * + * @param {Object} obj + * @param {*} expr + * @return {*} + */ + $indexOfBytes (obj, expr) { + let arr = computeValue(obj, expr) + + if (isNil(arr[0])) return null + + assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string') + assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string') + + let str = arr[0] + let searchStr = arr[1] + let start = arr[2] + let end = arr[3] + + assert( + isNil(start) || (isNumber(start) && start >= 0 && Math.round(start) === start), + '$indexOfBytes third operand must resolve to a non-negative integer' + ) + start = start || 0 + + assert( + isNil(end) || (isNumber(end) && end >= 0 && Math.round(end) === end), + '$indexOfBytes fourth operand must resolve to a non-negative integer' + ) + end = end || str.length + + if (start > end) return -1 + + let index = str.substring(start, end).indexOf(searchStr) + return (index > -1) + ? index + start + : index + }, + + /** + * Splits a string into substrings based on a delimiter. + * If the delimiter is not found within the string, returns an array containing the original string. + * + * @param {Object} obj + * @param {Array} expr + * @return {Array} Returns an array of substrings. + */ + $split (obj, expr) { + let args = computeValue(obj, expr) + assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])) + assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])) + return args[0].split(args[1]) + }, + + /** + * Compares two strings and returns an integer that reflects the comparison. + * + * @param obj + * @param expr + * @returns {number} + */ + $strcasecmp (obj, expr) { + let args = computeValue(obj, expr) + args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase() + args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase() + if (args[0] > args[1]) { + return 1 + } + return (args[0] < args[1]) ? -1 : 0 + }, + + /** + * Returns a substring of a string, starting at a specified index position and including the specified number of characters. + * The index is zero-based. + * + * @param obj + * @param expr + * @returns {string} + */ + $substr (obj, expr) { + let args = computeValue(obj, expr) + if (isString(args[0])) { + if (args[1] < 0) { + return '' + } else if (args[2] < 0) { + return args[0].substr(args[1]) + } else { + return args[0].substr(args[1], args[2]) + } + } + return '' + }, + + /** + * Converts a string to lowercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toLower (obj, expr) { + let value = computeValue(obj, expr) + return isEmpty(value) ? '' : value.toLowerCase() + }, + + /** + * Converts a string to uppercase. + * + * @param obj + * @param expr + * @returns {string} + */ + $toUpper (obj, expr) { + let value = computeValue(obj, expr) + return isEmpty(value) ? '' : value.toUpperCase() + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js new file mode 100644 index 0000000..a6a93d3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js @@ -0,0 +1,45 @@ +/** + * Aggregation framework variable operators + */ + +import { assert, each, err, map, isString, isNil, isUndefined, isEmpty, isArray, keys } from '../../util.js' +import { computeValue } from '../../internal.js' + +export const variableOperators = { + /** + * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. + * + * @param obj + * @param expr + * @returns {*} + */ + $let (obj, expr) { + let varsExpr = expr['vars'] + let inExpr = expr['in'] + + // resolve vars + let originals = {} + let varsKeys = keys(varsExpr) + each(varsKeys, (key) => { + let val = computeValue(obj, varsExpr[key]) + let tempKey = '$' + key + // set value on object using same technique as in "$map" + originals[tempKey] = obj[tempKey] + obj[tempKey] = val + }) + + let value = computeValue(obj, inExpr) + + // cleanup and restore + each(varsKeys, (key) => { + let tempKey = '$' + key + if (isUndefined(originals[tempKey])) { + delete obj[tempKey] + } else { + obj[tempKey] = originals[tempKey] + } + }) + + return value + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js new file mode 100644 index 0000000..d7ac61a --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js @@ -0,0 +1,158 @@ +import { + assert, + clone, + each, + err, + getType, + getHash, + has, + inArray, + intersection, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isObjectLike, + isRegExp, + isString, + isUndefined, + map, + notInArray, + reduce, + unique +} from '../util' +import { computeValue, stddev } from '../internal.js' + +/** + * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ + */ + +export const groupOperators = { + + /** + * Returns an array of all the unique values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {*} + */ + $addToSet (collection, expr) { + return unique(this.$push(collection, expr)) + }, + + /** + * Returns the sum of all the values in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $sum (collection, expr) { + if (!isArray(collection)) return 0 + + if (isNumber(expr)) { + // take a short cut if expr is number literal + return collection.length * expr + } + return reduce(this.$push(collection, expr).filter(isNumber), (acc, n) => acc + n, 0) + }, + + /** + * Returns the highest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $max (collection, expr) { + let mapped = this.$push(collection, expr) + return reduce(mapped, (acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) + }, + + /** + * Returns the lowest value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $min (collection, expr) { + let mapped = this.$push(collection, expr) + return reduce(mapped, (acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) + }, + + /** + * Returns an average of all the values in a group. + * + * @param collection + * @param expr + * @returns {number} + */ + $avg (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber) + let sum = reduce(data, (acc, n) => acc + n, 0) + return sum / (data.length || 1) + }, + + /** + * Returns an array of all values for the selected field among for each document in that group. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $push (collection, expr) { + if (isNil(expr)) return collection + return map(collection, (obj) => computeValue(obj, expr)) + }, + + /** + * Returns the first value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $first (collection, expr) { + return (collection.length > 0) ? computeValue(collection[0], expr) : undefined + }, + + /** + * Returns the last value in a group. + * + * @param collection + * @param expr + * @returns {*} + */ + $last (collection, expr) { + return (collection.length > 0) ? computeValue(collection[collection.length - 1], expr) : undefined + }, + + /** + * Returns the population standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number} + */ + $stdDevPop (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber) + return stddev({ data: data, sampled: false }) + }, + + /** + * Returns the sample standard deviation of the input values. + * @param {Array} collection + * @param {Object} expr + * @return {Number|null} + */ + $stdDevSamp (collection, expr) { + let data = this.$push(collection, expr).filter(isNumber) + return stddev({ data: data, sampled: true }) + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js new file mode 100644 index 0000000..9e449bb --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js @@ -0,0 +1,95 @@ +import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from '../constants' +import { assert, each, err, has, into, isBoolean, keys, reduce } from '../util' +import { _internal, computeValue, idKey, resolve } from '../internal' +import { Query } from '../query.js' +import { aggregateOperators } from './aggregation/index.js' +import { groupOperators } from './group.js' +import { pipelineOperators } from './pipeline.js' +import { projectionOperators } from './projection.js' +import { queryOperators } from './query.js' + +// operator definitions +const OPERATORS = { + 'aggregate': aggregateOperators, + 'group': groupOperators, + 'pipeline': pipelineOperators, + 'projection': projectionOperators, + 'query': queryOperators +} + +/** + * Returns the operators defined for the given operator classes + */ +export function ops () { + return reduce(arguments, (acc, cls) => into(acc, keys(OPERATORS[cls])), []) +} + +/** + * Add new operators + * + * @param opClass the operator class to extend + * @param fn a function returning an object of new operators + */ +export function addOperators (opClass, fn) { + + const newOperators = fn(_internal()) + + // ensure correct type specified + assert(has(OPERATORS, opClass), `Invalid operator class ${opClass}`) + + let operators = OPERATORS[opClass] + + // check for existing operators + each(newOperators, (fn, op) => { + assert(/^\$\w+$/.test(op), `Invalid operator name ${op}`) + assert(!has(operators, op), `${op} already exists for '${opClass}' operators`) + }) + + let wrapped = {} + + switch (opClass) { + case OP_QUERY: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (selector, value) => { + return { + test: (obj) => { + // value of field must be fully resolved. + let lhs = resolve(obj, selector) + let result = f.call(ctx, selector, lhs, value) + if (isBoolean(result)) { + return result + } else if (result instanceof Query) { + return result.test(obj) + } else { + err("Invalid return type for '" + op + "'. Must return a Boolean or Query") + } + } + } + } + })(fn, newOperators) + }) + break + case OP_PROJECTION: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (obj, expr, selector) => { + let lhs = resolve(obj, selector) + return f.call(ctx, selector, lhs, expr) + } + })(fn, newOperators) + }) + break + default: + each(newOperators, (fn, op) => { + wrapped[op] = ((f, ctx) => { + return (...args) => { + return f.apply(ctx, args) + } + })(fn, newOperators) + }) + } + + // toss the operator salad :) + Object.assign(OPERATORS[opClass], wrapped) +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js new file mode 100644 index 0000000..f38f7e2 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js @@ -0,0 +1,650 @@ +import { OP_GROUP, OP_PROJECTION } from '../constants' +import { + array, + assert, + clone, + each, + err, + findInsertIndex, + getHash, + getType, + groupBy, + has, + hasMeta, + inArray, + into, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isObjectLike, + isRegExp, + isString, + isUndefined, + keys, + map, + memoize, + notInArray, + sortBy +} from '../util' +import { + computeValue, + getValue, + idKey, + redactObj, + resolve, + resolveObj, + removeValue, + setValue, + traverse +} from '../internal.js' +import { aggregate } from '../aggregator.js' +import { Query } from '../query.js' +import { ops } from './index.js' +import { groupOperators } from './group.js' +import { projectionOperators } from './projection.js' + +/** + * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ + */ +export const pipelineOperators = { + + /** + * Adds new fields to documents. + * Outputs documents that contain all existing fields from the input documents and newly added fields. + * + * @param {Array} collection + * @param {*} expr + */ + $addFields (collection, expr) { + let newFields = keys(expr) + + return collection.map((obj) => { + obj = clone(obj) + each(newFields, (field) => { + let subExpr = expr[field] + let newValue = computeValue(obj, subExpr) + traverse(obj, field, (o, key) => { + o[key] = newValue + }, true) + }) + return obj + }) + }, + + /** + * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $group (collection, expr) { + // lookup key for grouping + const ID_KEY = idKey() + let objectId = expr[ID_KEY] + + let partitions = groupBy(collection, (obj) => { + return computeValue(obj, objectId, objectId) + }) + + let result = [] + + // remove the group key + delete expr[ID_KEY] + + each(partitions.keys, (value, i) => { + let obj = {} + + // exclude undefined key value + if (!isUndefined(value)) { + obj[ID_KEY] = value + } + + // compute remaining keys in expression + each(expr, (val, key) => { + obj[key] = accumulate(partitions.groups[i], key, val) + }) + result.push(obj) + }) + + return result + }, + + /** + * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. + * + * @param collection + * @param expr + */ + $lookup (collection, expr) { + let joinColl = expr.from + let localField = expr.localField + let foreignField = expr.foreignField + let asField = expr.as + + let errorMsg = "Invalid $lookup expression. " + assert(isArray(joinColl), errorMsg + "'from' must be an array") + assert(isString(foreignField), errorMsg + "'foreignField' must be a string") + assert(isString(localField), errorMsg + "'localField' must be a string") + assert(isString(asField), errorMsg + "'as' must be a string") + + let result = [] + let hash = {} + + function hashCode (v) { + return getHash(isNil(v) ? null : v) + } + + if (joinColl.length <= collection.length) { + each(joinColl, (obj, i) => { + let k = hashCode(obj[foreignField]) + hash[k] = hash[k] || [] + hash[k].push(i) + }) + + each(collection, (obj) => { + let k = hashCode(obj[localField]) + let indexes = hash[k] || [] + let newObj = clone(obj) + newObj[asField] = indexes.map((i) => clone(joinColl[i])) + result.push(newObj) + }) + + } else { + + each(collection, (obj, i) => { + let k = hashCode(obj[localField]) + hash[k] = hash[k] || [] + hash[k].push(i) + }) + + let tempResult = {} + each(joinColl, (obj) => { + let k = hashCode(obj[foreignField]) + let indexes = hash[k] || [] + each(indexes, (i) => { + let newObj = tempResult[i] || clone(collection[i]) + newObj[asField] = newObj[asField] || [] + newObj[asField].push(clone(obj)) + tempResult[i] = newObj + }) + }) + for (let i = 0, len = keys(tempResult).length; i < len; i++) { + result.push(tempResult[i]) + } + } + + return result + }, + + /** + * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. + * $match uses standard MongoDB queries. + * + * @param collection + * @param expr + * @returns {Array|*} + */ + $match (collection, expr) { + return (new Query(expr)).find(collection).all() + }, + + /** + * Reshapes a document stream. + * $project can rename, add, or remove fields as well as create computed values and sub-documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $project (collection, expr) { + if (isEmpty(expr)) { + return collection + } + + // result collection + let projected = [] + let objKeys = keys(expr) + let idOnlyExcludedExpression = false + const ID_KEY = idKey() + + // validate inclusion and exclusion + let check = [false, false] + each(expr, (v, k) => { + if (k === ID_KEY) return + if (v === 0 || v === false) { + check[0] = true + } else { + check[1] = true + } + assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.') + }) + + if (inArray(objKeys, ID_KEY)) { + let id = expr[ID_KEY] + if (id === 0 || id === false) { + objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])) + assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key') + idOnlyExcludedExpression = isEmpty(objKeys) + } + } else { + // if not specified the add the ID field + objKeys.push(ID_KEY) + } + + each(collection, (obj) => { + let cloneObj = {} + let foundSlice = false + let foundExclusion = false + let dropKeys = [] + + if (idOnlyExcludedExpression) { + dropKeys.push(ID_KEY) + } + + each(objKeys, (key) => { + let subExpr = expr[key] + let value // final computed value of the key + + if (key !== ID_KEY && subExpr === 0) { + foundExclusion = true + } + + if (key === ID_KEY && isEmpty(subExpr)) { + // tiny optimization here to skip over id + value = obj[key] + } else if (isString(subExpr)) { + value = computeValue(obj, subExpr, key) + } else if (subExpr === 1 || subExpr === true) { + // For direct projections, we use the resolved object value + } else if (isObject(subExpr)) { + let operator = keys(subExpr) + operator = operator.length > 1 ? false : operator[0] + + if (inArray(ops(OP_PROJECTION), operator)) { + // apply the projection operator on the operator expression for the key + if (operator === '$slice') { + // $slice is handled differently for aggregation and projection operations + if (array(subExpr[operator]).every(isNumber)) { + // $slice for projection operation + value = projectionOperators[operator](obj, subExpr[operator], key) + foundSlice = true + } else { + // $slice for aggregation operation + value = computeValue(obj, subExpr, key) + } + } else { + value = projectionOperators[operator](obj, subExpr[operator], key) + } + } else { + // compute the value for the sub expression for the key + value = computeValue(obj, subExpr, key) + } + } else { + dropKeys.push(key) + return + } + + // clone resolved values + let objValue = clone(resolveObj(obj, key)) + + if (!isUndefined(objValue)) { + Object.assign(cloneObj, objValue) + } + if (!isUndefined(value)) { + setValue(cloneObj, key, clone(value)) + } + + }) + // if projection included $slice operator + // Also if exclusion fields are found or we want to exclude only the id field + // include keys that were not explicitly excluded + if (foundSlice || foundExclusion || idOnlyExcludedExpression) { + cloneObj = Object.assign(clone(obj), cloneObj) + each(dropKeys, (key) => removeValue(cloneObj, key)) + } + projected.push(cloneObj) + }) + + return projected + }, + + /** + * Restricts the number of documents in an aggregation pipeline. + * + * @param collection + * @param value + * @returns {Object|*} + */ + $limit (collection, value) { + return collection.slice(0, value) + }, + + /** + * Skips over a specified number of documents from the pipeline and returns the rest. + * + * @param collection + * @param value + * @returns {*} + */ + $skip (collection, value) { + return collection.slice(value) + }, + + /** + * Takes an array of documents and returns them as a stream of documents. + * + * @param collection + * @param expr + * @returns {Array} + */ + $unwind (collection, expr) { + let result = [] + let field = expr.substr(1) + each(collection, (obj) => { + // must throw an error if value is not an array + let value = getValue(obj, field) + + assert(isArray(value), "Target field '" + field + "' is not of type Array.") + + each(value, (item) => { + let tmp = clone(obj) + tmp[field] = item + result.push(tmp) + }) + }) + return result + }, + + /** + * Takes all input documents and returns them in a stream of sorted documents. + * + * @param collection + * @param sortKeys + * @returns {*} + */ + $sort (collection, sortKeys) { + if (!isEmpty(sortKeys) && isObject(sortKeys)) { + let modifiers = keys(sortKeys) + each(modifiers.reverse(), (key) => { + let grouped = groupBy(collection, (obj) => resolve(obj, key)) + let sortedIndex = {} + let getIndex = (k) => sortedIndex[getHash(k)] + + let indexKeys = sortBy(grouped.keys, (item, i) => { + sortedIndex[getHash(item)] = i + return item + }) + + if (sortKeys[key] === -1) { + indexKeys.reverse() + } + collection = [] + each(indexKeys, (item) => into(collection, grouped.groups[getIndex(item)])) + }) + } + return collection + }, + + /** + * Groups incoming documents based on the value of a specified expression, + * then computes the count of documents in each distinct group. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sortByCount (collection, expr) { + let newExpr = { count: { $sum: 1 } } + newExpr[idKey()] = expr + + return this.$sort( + this.$group(collection, newExpr), + { count: -1 } + ) + }, + + /** + * Randomly selects the specified number of documents from its input. + * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $sample (collection, expr) { + let size = expr.size + assert(isNumber(size), '$sample size must be a positive integer') + + let result = [] + let len = collection.length + for (let i = 0; i < size; i++) { + let n = Math.floor(Math.random() * len) + result.push(collection[n]) + } + return result + }, + + /** + * Returns a document that contains a count of the number of documents input to the stage. + * @param {Array} collection + * @param {String} expr + * @return {Object} + */ + $count (collection, expr) { + assert( + isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', + 'Invalid expression value for $count' + ) + + let result = {} + result[expr] = collection.length + return result + }, + + /** + * Replaces a document with the specified embedded document or new one. + * The replacement document can be any valid expression that resolves to a document. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ + * + * @param {Array} collection + * @param {Object} expr + * @return {*} + */ + $replaceRoot (collection, expr) { + let newRoot = expr.newRoot + let result = [] + each(collection, (obj) => { + obj = computeValue(obj, newRoot) + assert(isObject(obj), '$replaceRoot expression must return a valid JS object') + result.push(obj) + }) + return result + }, + + /** + * Restricts the contents of the documents based on information stored in the documents themselves. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ + */ + $redact (collection, expr) { + return collection.map((obj) => { + return redactObj(clone(obj), expr) + }) + }, + + /** + * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. + * + * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ + */ + $bucket (collection, expr) { + let boundaries = expr.boundaries + let defaultKey = expr.default + let lower = boundaries[0] // inclusive + let upper = boundaries[boundaries.length - 1] // exclusive + let outputExpr = expr.output || { 'count': { '$sum': 1 } } + + assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements") + let boundType = getType(lower) + + for (let i = 0, len = boundaries.length - 1; i < len; i++) { + assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type") + assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order") + } + + if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { + assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range") + } + + let grouped = {} + each(boundaries, (k) => grouped[k] = []) + + // add default key if provided + if (!isNil(defaultKey)) grouped[defaultKey] = [] + + each(collection, (obj) => { + let key = computeValue(obj, expr.groupBy) + + if (isNil(key) || key < lower || key >= upper) { + assert(!isNil(defaultKey), '$bucket require a default for out of range values') + grouped[defaultKey].push(obj) + } else if (key >= lower && key < upper) { + let index = findInsertIndex(boundaries, key) + let boundKey = boundaries[Math.max(0, index - 1)] + grouped[boundKey].push(obj) + } else { + err("$bucket 'groupBy' expression must resolve to a value in range of boundaries") + } + }) + + // upper bound is exclusive so we remove it + boundaries.pop() + if (!isNil(defaultKey)) boundaries.push(defaultKey) + + return map(boundaries, (key) => { + let acc = accumulate(grouped[key], null, outputExpr) + return Object.assign(acc, { '_id': key }) + }) + }, + + $bucketAuto (collection, expr) { + let outputExpr = expr.output || { 'count': { '$sum': 1 } } + let groupByExpr = expr.groupBy + let bucketCount = expr.buckets + + assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount) + + let approxBucketSize = Math.round(collection.length / bucketCount) + if (approxBucketSize < 1) { + approxBucketSize = 1 + } + + let computeValueOptimized = memoize(computeValue) + let grouped = {} + let remaining = [] + let sorted = sortBy(collection, (o) => { + let key = computeValueOptimized(o, groupByExpr) + if (isNil(key)) { + remaining.push(o) + } else { + grouped[key] || (grouped[key] = []) + grouped[key].push(o) + } + return key + }) + + const ID_KEY = idKey() + let result = [] + let index = 0 // counter for sorted collection + + for (let i = 0, len = sorted.length; i < bucketCount && index < len; i++) { + let boundaries = {} + let bucketItems = [] + + for (let j = 0; j < approxBucketSize && index < len; j++) { + let key = computeValueOptimized(sorted[index], groupByExpr) + + if (isNil(key)) key = null + + // populate current bucket with all values for current key + into(bucketItems, isNil(key) ? remaining : grouped[key]) + + // increase sort index by number of items added + index += (isNil(key) ? remaining.length : grouped[key].length) + + // set the min key boundary if not already present + if (!has(boundaries, 'min')) boundaries.min = key + + if (result.length > 0) { + let lastBucket = result[result.length - 1] + lastBucket[ID_KEY].max = boundaries.min + } + } + + // if is last bucket add remaining items + if (i == bucketCount - 1) { + into(bucketItems, sorted.slice(index)) + } + + result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })) + } + + if (result.length > 0) { + result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr) + } + + return result + }, + + /** + * Processes multiple aggregation pipelines within a single stage on the same set of input documents. + * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + */ + $facet (collection, expr) { + return map(expr, (pipeline) => aggregate(collection, pipeline)) + } +} + +/** + * Returns the result of evaluating a $group operation over a collection + * + * @param collection + * @param field the name of the aggregate operator or field + * @param expr the expression of the aggregate operator for the field + * @returns {*} + */ +function accumulate (collection, field, expr) { + if (inArray(ops(OP_GROUP), field)) { + return groupOperators[field](collection, expr) + } + + if (isObject(expr)) { + let result = {} + each(expr, (val, key) => { + result[key] = accumulate(collection, key, expr[key]) + // must run ONLY one group operator per expression + // if so, return result of the computed value + if (inArray(ops(OP_GROUP), key)) { + result = result[key] + // if there are more keys in expression this is bad + assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'") + return false // break + } + }) + return result + } + + return undefined +} + diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js new file mode 100644 index 0000000..d449c6e --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js @@ -0,0 +1,119 @@ +import { + assert, + each, + err, + getHash, + getType, + has, + inArray, + intersection, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isObjectLike, + isRegExp, + isString, + isUndefined, + keys +} from '../util' +import { computeValue, resolve, resolveObj, traverse, idKey, stddev, slice } from '../internal.js' +import { Query } from '../query.js' + + +/** + * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ + */ +export const projectionOperators = { + + /** + * Projects the first element in an array that matches the query condition. + * + * @param obj + * @param field + * @param expr + */ + $ (obj, expr, field) { + err('$ not implemented') + }, + + /** + * Projects only the first element from an array that matches the specified $elemMatch condition. + * + * @param obj + * @param field + * @param expr + * @returns {*} + */ + $elemMatch (obj, expr, field) { + let arr = resolve(obj, field) + let query = new Query(expr) + + if (isNil(arr) || !isArray(arr)) { + return undefined + } + + for (let i = 0; i < arr.length; i++) { + if (query.test(arr[i])) { + return [arr[i]] + } + } + + return undefined + }, + + /** + * Limits the number of elements projected from an array. Supports skip and limit slices. + * + * @param obj + * @param field + * @param expr + */ + $slice (obj, expr, field) { + let xs = resolve(obj, field) + + if (!isArray(xs)) return xs + + if (isArray(expr)) { + return slice(xs, expr[0], expr[1]) + } else if (isNumber(expr)) { + return slice(xs, expr) + } else { + err('Invalid argument type for $slice projection operator') + } + }, + + /** + * Returns the population standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number} + */ + $stdDevPop (obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: false + }) + }, + + /** + * Returns the sample standard deviation of the input values. + * @param {Object} obj + * @param {Object} expr + * @param {String} field + * @return {Number|null} + */ + $stdDevSamp (obj, expr, field) { + return stddev({ + data: computeValue(obj, expr, field), + sampled: true + }) + } +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js new file mode 100644 index 0000000..cf63442 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js @@ -0,0 +1,419 @@ +/** + * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ + */ +import { + T_ARRAY, + T_BOOL, + T_BOOLEAN, + T_DATE, + T_FUNCTION, + T_NULL, + T_NUMBER, + T_OBJECT, + T_REGEX, + T_REGEXP, + T_STRING, + T_UNDEFINED +} from '../constants' +import { + array, + assert, + clone, + dropMeta, + each, + hasMeta, + inArray, + intersection, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isRegExp, + isString, + isUndefined, + keys +} from '../util' +import { computeValue, resolve, normalize } from '../internal.js' +import { Query } from '../query.js' + +export const simpleOperators = { + + /** + * Checks that two values are equal. + * + * @param a The lhs operand as resolved from the object by the given selector + * @param b The rhs operand provided by the user + * @returns {*} + */ + $eq (a, b) { + // start with simple equality check + if (isEqual(a, b)) return true + + // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ + if (isNil(a) && isNil(b)) return true + + if (isArray(a)) { + // is multi-valued lhs so we check each separately + if (hasMeta(a, { isMulti: true })) { + try { + for (let i = 0; i < a.length; i++) { + if (this.$eq(a[i], b)) { + return true; + } + } + } finally { + dropMeta(a) + } + } else { + // check one level deep + return a.findIndex(isEqual.bind(null, b)) !== -1 + } + } + return false; + }, + + /** + * Matches all values that are not equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $ne (a, b) { + return !this.$eq(a, b) + }, + + /** + * Matches any of the values that exist in an array specified in the query. + * + * @param a + * @param b + * @returns {*} + */ + $in (a, b) { + a = array(a) + return intersection(a, b).length > 0 + }, + + /** + * Matches values that do not exist in an array specified to the query. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $nin (a, b) { + return isNil(a) || !this.$in(a, b) + }, + + /** + * Matches values that are less than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lt (a, b) { + a = array(a).find((val) => val < b) + return a !== undefined + }, + + /** + * Matches values that are less than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $lte (a, b) { + a = array(a).find((val) => val <= b) + return a !== undefined + }, + + /** + * Matches values that are greater than the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gt (a, b) { + a = array(a).find((val) => val > b) + return a !== undefined + }, + + /** + * Matches values that are greater than or equal to the value specified in the query. + * + * @param a + * @param b + * @returns {boolean} + */ + $gte (a, b) { + a = array(a).find((val) => val >= b) + return a !== undefined + }, + + /** + * Performs a modulo operation on the value of a field and selects documents with a specified result. + * + * @param a + * @param b + * @returns {boolean} + */ + $mod (a, b) { + a = array(a).find((val) => isNumber(val) && isArray(b) && b.length === 2 && (val % b[0]) === b[1]) + return a !== undefined + }, + + /** + * Selects documents where values match a specified regular expression. + * + * @param a + * @param b + * @returns {boolean} + */ + $regex (a, b) { + a = array(a).find((val) => isString(val) && isRegExp(b) && (!!val.match(b))) + return a !== undefined + }, + + /** + * Matches documents that have the specified field. + * + * @param a + * @param b + * @returns {boolean} + */ + $exists (a, b) { + return ((b === false || b === 0) && isNil(a)) || ((b === true || b === 1) && !isNil(a)) + }, + + /** + * Matches arrays that contain all elements specified in the query. + * + * @param a + * @param b + * @returns boolean + */ + $all (a, b) { + let matched = false + if (isArray(a) && isArray(b)) { + for (let i = 0, len = b.length; i < len; i++) { + if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { + matched = matched || this.$elemMatch(a, b[i].$elemMatch) + } else { + // order of arguments matter + return intersection(b, a).length === len + } + } + } + return matched + }, + + /** + * Selects documents if the array field is a specified size. + * + * @param a + * @param b + * @returns {*|boolean} + */ + $size (a, b) { + return isArray(a) && isNumber(b) && (a.length === b) + }, + + /** + * Selects documents if element in the array field matches all the specified $elemMatch condition. + * + * @param a + * @param b + */ + $elemMatch (a, b) { + if (isArray(a) && !isEmpty(a)) { + let query = new Query(b) + for (let i = 0, len = a.length; i < len; i++) { + if (query.test(a[i])) { + return true + } + } + } + return false + }, + + /** + * Selects documents if a field is of the specified type. + * + * @param a + * @param b + * @returns {boolean} + */ + $type (a, b) { + switch (b) { + case 1: + case 'double': + return isNumber(a) && (a + '').indexOf('.') !== -1 + case 2: + case T_STRING: + return isString(a) + case 3: + case T_OBJECT: + return isObject(a) + case 4: + case T_ARRAY: + return isArray(a) + case 6: + case T_UNDEFINED: + return isNil(a) + case 8: + case T_BOOL: + return isBoolean(a) + case 9: + case T_DATE: + return isDate(a) + case 10: + case T_NULL: + return isNull(a) + case 11: + case T_REGEX: + return isRegExp(a) + case 16: + case 'int': + return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1 + case 18: + case 'long': + return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1 + case 19: + case 'decimal': + return isNumber(a) + default: + return false + } + } +} + +export const queryOperators = { + + /** + * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $and (selector, value) { + assert(isArray(value), 'Invalid expression: $and expects value to be an Array') + + let queries = [] + each(value, (expr) => queries.push(new Query(expr))) + + return { + test (obj) { + for (let i = 0; i < queries.length; i++) { + if (!queries[i].test(obj)) { + return false + } + } + return true + } + } + }, + + /** + * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $or (selector, value) { + assert(isArray(value),'Invalid expression. $or expects value to be an Array') + + let queries = [] + each(value, (expr) => queries.push(new Query(expr))) + + return { + test (obj) { + for (let i = 0; i < queries.length; i++) { + if (queries[i].test(obj)) { + return true + } + } + return false + } + } + }, + + /** + * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $nor (selector, value) { + assert(isArray(value),'Invalid expression. $nor expects value to be an Array') + let query = this.$or('$or', value) + return { + test (obj) { + return !query.test(obj) + } + } + }, + + /** + * Inverts the effect of a query expression and returns documents that do not match the query expression. + * + * @param selector + * @param value + * @returns {{test: Function}} + */ + $not (selector, value) { + let criteria = {} + criteria[selector] = normalize(value) + let query = new Query(criteria) + return { + test (obj) { + return !query.test(obj) + } + } + }, + + /** + * Matches documents that satisfy a JavaScript expression. + * + * @param selector + * @param value + * @returns {{test: test}} + */ + $where (selector, value) { + if (!isFunction(value)) { + value = new Function('return ' + value + ';') + } + return { + test (obj) { + return value.call(obj) === true + } + } + } +} + +// add simple query operators +each(simpleOperators, (fn, op) => { + queryOperators[op] = ((f, ctx) => { + return (selector, value) => { + return { + test (obj) { + // value of field must be fully resolved. + let lhs = resolve(obj, selector) + return f.call(ctx, lhs, value) + } + } + } + })(fn, simpleOperators) +}) \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js new file mode 100644 index 0000000..fda3416 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js @@ -0,0 +1,184 @@ + +/** + * Polyfill to add native methods for non-supported environments. + */ + +// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new Error('Function.prototype.bind - what is trying to be bound is not callable') + } + + var aArgs = Array.prototype.slice.call(arguments, 1) + var fToBind = this + var fNOP = function () {} + var fBound = function () { + return fToBind.apply( + (this instanceof fNOP) ? this : oThis, + aArgs.concat(Array.prototype.slice.call(arguments)) + ) + } + + if (this.prototype) { + // Function.prototype doesn't have a prototype property + fNOP.prototype = this.prototype + } + fBound.prototype = new fNOP() + + return fBound + } +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this) + var len = o.length >>> 0 + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function') + } + + var thisArg = arguments[1] + var k = 0 + + while (k < len) { + var kValue = o[k] + if (predicate.call(thisArg, kValue, k, o)) { + return kValue + } + k++ + } + return undefined + } + }) +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + value: function(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this) + var len = o.length >>> 0 + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function') + } + + var thisArg = arguments[1] + var k = 0 + while (k < len) { + var kValue = o[k] + if (predicate.call(thisArg, kValue, k, o)) { + return k + } + k++ + } + return -1 + } + }) +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes +if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + value: function(searchElement, fromIndex) { + if (this == null) { + throw new TypeError('"this" is null or not defined') + } + + var o = Object(this) + var len = o.length >>> 0 + + if (len === 0) { + return false + } + var n = fromIndex | 0 + var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0) + + function sameValueZero(x, y) { + return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) + } + + while (k < len) { + if (sameValueZero(o[k], searchElement)) { + return true + } + k++ + } + return false + } + }) +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign +if (typeof Object.assign != 'function') { + Object.assign = function(target, varArgs) { // .length of function is 2 + + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object') + } + + var to = Object(target) + var args = Array.prototype.slice.call(arguments) + + for (var index = 1; index < args.length; index++) { + var nextSource = args[index] + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (nextSource.hasOwnProperty(nextKey)) { + to[nextKey] = nextSource[nextKey] + } + } + } + } + return to + } +} + +// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html +if (!Object.keys) { + Object.keys = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.keys called on a non-object') + } + + var result = [] + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(k) + } + } + return result + } +} + +// https://github.com/es-shims/Object.values/blob/master/implementation.js +if (!Object.values) { + Object.values = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.values called on a non-object') + } + var result = [] + for (var k in o) { + if (o.hasOwnProperty(k)) { + result.push(o[k]) + } + } + return result + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js new file mode 100644 index 0000000..a0eee43 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js @@ -0,0 +1,142 @@ +import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' +import { + assert, + each, + err, + getType, + has, + inArray, + intersection, + isArray, + isBoolean, + isDate, + isEmpty, + isEqual, + isFunction, + isNil, + isNull, + isNumber, + isObject, + isObjectLike, + isRegExp, + isString, + isUndefined, + notInArray, + reduce +} from './util' +import { normalize } from './internal.js' +import { Cursor } from './cursor.js' +import { ops } from './operators/index.js' +import { groupOperators } from './operators/group.js' +import { queryOperators } from './operators/query.js' + +/** + * Query object to test collection elements with + * @param criteria the pass criteria for the query + * @param projection optional projection specifiers + * @constructor + */ +export class Query { + + constructor (criteria, projection = {}) { + this.__criteria = criteria + this.__projection = projection + this.__compiled = [] + this._compile() + } + + _compile () { + if (isEmpty(this.__criteria)) return + + assert(isObject(this.__criteria), 'Criteria must be of type Object') + + let whereOperator; + + each(this.__criteria, (expr, field) => { + // save $where operators to be executed after other operators + if ('$where' === field) { + whereOperator = { field: field, expr: expr }; + } else if (inArray(['$and', '$or', '$nor'], field)) { + this._processOperator(field, field, expr) + } else { + // normalize expression + expr = normalize(expr) + each(expr, (val, op) => { + this._processOperator(field, op, val) + }) + } + + if (isObject(whereOperator)) { + this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); + } + }) + } + + _processOperator (field, operator, value) { + if (inArray(ops(OP_QUERY), operator)) { + this.__compiled.push(queryOperators[operator](field, value)) + } else { + err("Invalid query operator '" + operator + "' detected") + } + } + + /** + * Checks if the object passes the query criteria. Returns true if so, false otherwise. + * @param obj + * @returns {boolean} + */ + test (obj) { + for (let i = 0, len = this.__compiled.length; i < len; i++) { + if (!this.__compiled[i].test(obj)) { + return false + } + } + return true + } + + /** + * Performs a query on a collection and returns a cursor object. + * @param collection + * @param projection + * @returns {Cursor} + */ + find (collection, projection) { + return new Cursor(collection, this, projection) + } + + /** + * Remove matched documents from the collection returning the remainder + * @param collection + * @returns {Array} + */ + remove (collection) { + return reduce(collection, (acc, obj) => { + if (!this.test(obj)) acc.push(obj) + return acc + }, []) + } +} + +/** + * Performs a query on a collection and returns a cursor object. + * + * @param collection + * @param criteria + * @param projection + * @returns {Cursor} + */ +export function find (collection, criteria, projection) { + return new Query(criteria).find(collection, projection) +} + +/** + * Returns a new array without objects which match the criteria + * + * @param collection + * @param criteria + * @returns {Array} + */ +export function remove (collection, criteria) { + return new Query(criteria).remove(collection) +} + diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js new file mode 100644 index 0000000..631a95c --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js @@ -0,0 +1,447 @@ +/** + * Utility functions + */ + +import { + T_ARRAY, + T_BOOL, + T_BOOLEAN, + T_DATE, + T_FUNCTION, + T_NULL, + T_NUMBER, + T_OBJECT, + T_REGEX, + T_REGEXP, + T_STRING, + T_UNDEFINED +} from './constants' + +export function assert (condition, message) { + if (falsey(condition)) err(message) +} + +/** + * Deep clone an object + * @param obj + * @returns {*} + */ +export function clone (obj) { + switch (jsType(obj)) { + case T_ARRAY: + return obj.map(clone) + case T_OBJECT: + return map(obj, clone) + default: + return obj + } +} + +export function getType (v) { + if (v === null) return 'Null' + if (v === undefined) return 'Undefined' + return v.constructor.name +} +export function jsType (v) { return getType(v).toLowerCase() } +export function isBoolean (v) { return jsType(v) === T_BOOLEAN } +export function isString (v) { return jsType(v) === T_STRING } +export function isNumber (v) { return jsType(v) === T_NUMBER } +export function isArray (v) { return jsType(v) === T_ARRAY } +export function isArrayLike (v) { return !isNil(v) && has(v, 'length') } +export function isObject (v) { return jsType(v) === T_OBJECT } +export function isObjectLike (v) { return v === Object(v) } // objects, arrays, functions, date, custom object +export function isDate (v) { return jsType(v) === T_DATE } +export function isRegExp (v) { return jsType(v) === T_REGEXP } +export function isFunction (v) { return jsType(v) === T_FUNCTION } +export function isNil (v) { return isNull(v) || isUndefined(v) } +export function isNull (v) { return jsType(v) === T_NULL } +export function isUndefined (v) { return jsType(v) === T_UNDEFINED } +export function inArray (arr, item) { return arr.includes(item) } +export function notInArray (arr, item) { return !arr.includes(item) } +export function truthy (arg) { return !!arg } +export function falsey (arg) { return !arg } +export function isEmpty (x) { + return isNil(x) || + isArray(x) && x.length === 0 || + isObject(x) && keys(x).length === 0 || !x +} +// ensure a value is an array +export function array (x) { return isArray(x) ? x : [x] } +export function has (obj, prop) { return obj.hasOwnProperty(prop) } +export function err (s) { throw new Error(s) } +export function keys (o) { return Object.keys(o) } + +// ////////////////// UTILS //////////////////// + +// internal constants +const __MINGO_META = '__mingo__' + +export function addMeta (obj, value) { + obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value) +} + +export function hasMeta (obj, value) { + return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]) +} + +export function dropMeta (obj) { + if (has(obj, __MINGO_META)) delete obj[__MINGO_META] +} + +/** + * Iterate over an array or object + * @param {Array|Object} obj An object-like value + * @param {Function} fn The callback to run per item + * @param {*} ctx The object to use a context + * @return {void} + */ +export function each (obj, fn, ctx = null) { + assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'") + + if (isArrayLike(obj)) { + for (let i = 0, len = obj.length; i < len; i++) { + if (fn.call(ctx, obj[i], i, obj) === false) break + } + } else { + for (let k in obj) { + if (has(obj, k)) { + if (fn.call(ctx, obj[k], k, obj) === false) break + } + } + } +} + +/** + * Transform values in a collection + * + * @param {Array|Object} obj An array/object whose values to transform + * @param {Function} fn The transform function + * @param {*} ctx The value to use as the "this" context for the transform + * @return {Array|Object} Result object after applying the transform + */ +export function map (obj, fn, ctx = null) { + if (isArray(obj)) { + return obj.map(fn, ctx) + } else if (isObject(obj)) { + let o = {} + each(obj, (v, k) => o[k] = fn.call(ctx, v, k), obj) + return o + } +} + +/** + * Reduce any array-like object + * @param collection + * @param fn + * @param accumulator + * @returns {*} + */ +export function reduce (collection, fn, accumulator) { + if (isArray(collection)) return collection.reduce(fn, accumulator) + // array-like objects + each(collection, (v, k) => accumulator = fn(accumulator, v, k, collection)) + return accumulator +} + +/** + * Returns the intersection between two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} Result array + */ +export function intersection (xs, ys) { + return xs.filter(inArray.bind(null, ys)) +} + +/** + * Returns the union of two arrays + * + * @param {Array} xs The first array + * @param {Array} ys The second array + * @return {Array} The result array + */ +export function union (xs, ys) { + return into(into([], xs), ys.filter(notInArray.bind(null, xs))) +} + +/** + * Flatten the array + * + * @param {Array} xs The array to flatten + * @param {Number} depth The number of nested lists to iterate + */ +export function flatten (xs, depth = -1) { + assert(isArray(xs), 'Input must be an Array') + let arr = [] + function unwrap(ys, iter) { + for (let i = 0, len = ys.length; i < len; i++) { + if (isArray(ys[i]) && (iter > 0 || iter < 0)) { + unwrap(ys[i], Math.max(-1, iter - 1)) + } else { + arr.push(ys[i]) + } + } + } + unwrap(xs, depth) + return arr +} + +/** + * Determine whether two values are the same or strictly equivalent + * + * @param {*} a The first value + * @param {*} b The second value + * @return {Boolean} Result of comparison + */ +export function isEqual (a, b) { + // strictly equal must be equal. + if (a === b) return true + + // unequal types and functions cannot be equal. + let type = jsType(a) + if (type !== jsType(b) || type === T_FUNCTION) return false + + // we treat NaN as the same + if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true + + // leverage toString for Date and RegExp types + if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString() + + if (type === T_ARRAY) { + if (a.length === b.length && a.length === 0) return true + if (a.length !== b.length) return false + for (let i = 0, len = a.length; i < len; i++) { + if (!isEqual(a[i], b[i])) return false + } + } else if (type === T_OBJECT) { + // deep compare objects + let ka = keys(a) + let kb = keys(b) + + // check length of keys early + if (ka.length !== kb.length) return false + + // we know keys are strings so we sort before comparing + ka.sort() + kb.sort() + + // compare keys + if (!isEqual(ka, kb)) return false + + // back to the drawing board + for (let i = 0, len = ka.length; i < len; i++) { + let temp = ka[i] + if (!isEqual(a[temp], b[temp])) return false + } + } else { + // we do not know how to compare custom types so we guess + return getHash(a) === getHash(b) + } + // best effort says values are equal :) + return true +} + +/** + * Return a new unique version of the collection + * @param {Array} xs The input collection + * @return {Array} A new collection with unique values + */ +export function unique (xs) { + let h = {} + let arr = [] + each(xs, (item) => { + let k = getHash(item) + if (!has(h, k)) { + arr.push(item) + h[k] = 0 + } + }) + return arr +} + +/** + * Generates a random string of max length range [24,27] + * @param n Size of string to return + * @returns {*} + */ +function randomString(n) { + return (Math.E + Math.random()).toString(36).slice(2, n+2) +} + +/** + * Encode value using a simple optimistic stable scheme. + * @param value + * @returns {*} + */ +export function encode (value) { + let type = jsType(value) + switch (type) { + case T_FUNCTION: + return randomString(7) + case T_BOOLEAN: + case T_NUMBER: + case T_REGEXP: + return value.toString() + case T_STRING: + return JSON.stringify(value) + case T_DATE: + return value.toISOString() + case T_NULL: + case T_UNDEFINED: + return type + case T_ARRAY: + return '[' + map(value, (v) => `${encode(v)}`) + ']' + default: + let prefix = (type === T_OBJECT)? '' : `${getType(value)}|` + let objKeys = keys(value) + objKeys.sort() + return `${prefix}{` + map(objKeys, (k) => `${encode(k)}:${encode(value[k])}`) + '}' + } +} + +/** + * Generate hash code + * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery + * + * @param value + * @returns {*} + */ +export function getHash (value) { + let hash = 0, i, chr, len, s = encode(value) + if (s.length === 0) return hash + for (i = 0, len = s.length; i < len; i++) { + chr = s.charCodeAt(i) + hash = ((hash << 5) - hash) + chr + hash |= 0 // Convert to 32bit integer + } + return hash.toString() +} + +/** + * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee + * + * This implementation treats null/undefined sort keys as less than every other type + * + * @param {Array} collection + * @param {Function} fn The function used to resolve sort keys + * @param {Object} ctx The context to use for calling `fn` + * @return {Array} Returns a new sorted array by the given iteratee + */ +export function sortBy (collection, fn, ctx = null) { + let sortKeys = {} + let sorted = [] + let len = collection.length + let result = [] + + for (let i = 0; i < len; i++) { + let obj = collection[i] + let key = fn.call(ctx, obj, i) + if (isNil(key)) { + // objects with null keys will go in first + result.push(obj) + } else { + let hash = getHash(obj) + if (!has(sortKeys, hash)) { + sortKeys[hash] = [key, i] + } + sorted.push(obj) + } + } + // use native array sorting but enforce stableness + sorted.sort((a, b) => { + let A = sortKeys[getHash(a)] + let B = sortKeys[getHash(b)] + if (A[0] < B[0]) return -1 + if (A[0] > B[0]) return 1 + if (A[1] < B[1]) return -1 + if (A[1] > B[1]) return 1 + return 0 + }) + return into(result, sorted) +} + +/** + * Groups the collection into sets by the returned key + * + * @param collection + * @param fn {Function} to compute the group key of an item in the collection + * @param ctx {Object} The context to use for calling `fn` + * @returns {{keys: Array, groups: Array}} + */ +export function groupBy (collection, fn, ctx) { + let result = { + 'keys': [], + 'groups': [] + } + let lookup = {} + each(collection, (obj) => { + let key = fn.call(ctx, obj) + let hash = getHash(key) + let index = -1 + + if (isUndefined(lookup[hash])) { + index = result.keys.length + lookup[hash] = index + result.keys.push(key) + result.groups.push([]) + } + index = lookup[hash] + result.groups[index].push(obj) + }) + return result +} + +/** + * Push elements in given array into target array + * + * @param {*} target The array to push into + * @param {*} xs The array of elements to push + */ +export function into (target, xs) { + Array.prototype.push.apply(target, xs) + return target +} + +/** + * Find the insert index for the given key in a sorted array. + * + * @param {*} array The sorted array to search + * @param {*} key The search key + */ +export function findInsertIndex (array, key) { + // uses binary search + let lo = 0 + let hi = array.length - 1 + while (lo <= hi) { + let mid = Math.round(lo + (hi - lo) / 2) + if (key < array[mid]) { + hi = mid - 1 + } else if (key > array[mid]) { + lo = mid + 1 + } else { + return mid + } + } + return lo +} + +/** + * This is a generic memoization function + * + * This implementation uses a cache independent of the function being memoized + * to allow old values to be garbage collected when the memoized function goes out of scope. + * + * @param {*} fn The function object to memoize + */ +export function memoize (fn) { + return ((cache) => { + return (...args) => { + let key = getHash(args) + if (!has(cache, key)) { + cache[key] = fn.apply(this, args) + } + return cache[key] + } + })({/* storage */}) +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/package.json b/Challenge/seokahi/010.star/node_modules/mingo/package.json new file mode 100644 index 0000000..89714d6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mingo/package.json @@ -0,0 +1,55 @@ +{ + "name": "mingo", + "version": "1.3.3", + "description": "JavaScript implementation of MongoDB query language", + "main": "dist/mingo.js", + "module": "lib/index.js", + "scripts": { + "build": "make build", + "prepublishOnly": "make build", + "test": "make test" + }, + "repository": { + "type": "git", + "url": "https://github.com/kofrasa/mingo.git" + }, + "files": [ + "dist", + "lib", + "LICENSE", + "README.md", + "CONTRIBUTORS.md", + "CHANGELOG.md", + "VERSION" + ], + "devDependencies": { + "babel-plugin-external-helpers": "^6.22.0", + "babel-preset-env": "^1.6.0", + "backbone": ">=1.3.x", + "bson": "1.x.x", + "gulp": ">=3.9.x", + "rollup": "^0.45.2", + "rollup-plugin-babel": "^2.7.1", + "rollup-plugin-commonjs": "^8.0.2", + "rollup-plugin-node-resolve": "^3.0.0", + "tape": ">=4.x.x", + "uglify-js": "2.x.x" + }, + "keywords": [ + "util", + "mongo", + "nosql", + "query", + "aggregate", + "filter", + "group", + "project", + "search", + "transform" + ], + "author": "Francis Asante ", + "license": "MIT", + "bugs": { + "url": "https://github.com/kofrasa/mingo/issues" + } +} diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE b/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/README.md b/Challenge/seokahi/010.star/node_modules/mute-stream/README.md new file mode 100644 index 0000000..8ab1238 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mute-stream/README.md @@ -0,0 +1,68 @@ +# mute-stream + +Bytes go in, but they don't come out (when muted). + +This is a basic pass-through stream, but when muted, the bytes are +silently dropped, rather than being passed through. + +## Usage + +```javascript +var MuteStream = require('mute-stream') + +var ms = new MuteStream(options) + +ms.pipe(process.stdout) +ms.write('foo') // writes 'foo' to stdout +ms.mute() +ms.write('bar') // does not write 'bar' +ms.unmute() +ms.write('baz') // writes 'baz' to stdout + +// can also be used to mute incoming data +var ms = new MuteStream +input.pipe(ms) + +ms.on('data', function (c) { + console.log('data: ' + c) +}) + +input.emit('data', 'foo') // logs 'foo' +ms.mute() +input.emit('data', 'bar') // does not log 'bar' +ms.unmute() +input.emit('data', 'baz') // logs 'baz' +``` + +## Options + +All options are optional. + +* `replace` Set to a string to replace each character with the + specified string when muted. (So you can show `****` instead of the + password, for example.) + +* `prompt` If you are using a replacement char, and also using a + prompt with a readline stream (as for a `Password: *****` input), + then specify what the prompt is so that backspace will work + properly. Otherwise, pressing backspace will overwrite the prompt + with the replacement character, which is weird. + +## ms.mute() + +Set `muted` to `true`. Turns `.write()` into a no-op. + +## ms.unmute() + +Set `muted` to `false` + +## ms.isTTY + +True if the pipe destination is a TTY, or if the incoming pipe source is +a TTY. + +## Other stream methods... + +The other standard readable and writable stream methods are all +available. The MuteStream object acts as a facade to its pipe source +and destination. diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js b/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js new file mode 100644 index 0000000..a24fc09 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js @@ -0,0 +1,145 @@ +var Stream = require('stream') + +module.exports = MuteStream + +// var out = new MuteStream(process.stdout) +// argument auto-pipes +function MuteStream (opts) { + Stream.apply(this) + opts = opts || {} + this.writable = this.readable = true + this.muted = false + this.on('pipe', this._onpipe) + this.replace = opts.replace + + // For readline-type situations + // This much at the start of a line being redrawn after a ctrl char + // is seen (such as backspace) won't be redrawn as the replacement + this._prompt = opts.prompt || null + this._hadControl = false +} + +MuteStream.prototype = Object.create(Stream.prototype) + +Object.defineProperty(MuteStream.prototype, 'constructor', { + value: MuteStream, + enumerable: false +}) + +MuteStream.prototype.mute = function () { + this.muted = true +} + +MuteStream.prototype.unmute = function () { + this.muted = false +} + +Object.defineProperty(MuteStream.prototype, '_onpipe', { + value: onPipe, + enumerable: false, + writable: true, + configurable: true +}) + +function onPipe (src) { + this._src = src +} + +Object.defineProperty(MuteStream.prototype, 'isTTY', { + get: getIsTTY, + set: setIsTTY, + enumerable: true, + configurable: true +}) + +function getIsTTY () { + return( (this._dest) ? this._dest.isTTY + : (this._src) ? this._src.isTTY + : false + ) +} + +// basically just get replace the getter/setter with a regular value +function setIsTTY (isTTY) { + Object.defineProperty(this, 'isTTY', { + value: isTTY, + enumerable: true, + writable: true, + configurable: true + }) +} + +Object.defineProperty(MuteStream.prototype, 'rows', { + get: function () { + return( this._dest ? this._dest.rows + : this._src ? this._src.rows + : undefined ) + }, enumerable: true, configurable: true }) + +Object.defineProperty(MuteStream.prototype, 'columns', { + get: function () { + return( this._dest ? this._dest.columns + : this._src ? this._src.columns + : undefined ) + }, enumerable: true, configurable: true }) + + +MuteStream.prototype.pipe = function (dest, options) { + this._dest = dest + return Stream.prototype.pipe.call(this, dest, options) +} + +MuteStream.prototype.pause = function () { + if (this._src) return this._src.pause() +} + +MuteStream.prototype.resume = function () { + if (this._src) return this._src.resume() +} + +MuteStream.prototype.write = function (c) { + if (this.muted) { + if (!this.replace) return true + if (c.match(/^\u001b/)) { + if(c.indexOf(this._prompt) === 0) { + c = c.substr(this._prompt.length); + c = c.replace(/./g, this.replace); + c = this._prompt + c; + } + this._hadControl = true + return this.emit('data', c) + } else { + if (this._prompt && this._hadControl && + c.indexOf(this._prompt) === 0) { + this._hadControl = false + this.emit('data', this._prompt) + c = c.substr(this._prompt.length) + } + c = c.toString().replace(/./g, this.replace) + } + } + this.emit('data', c) +} + +MuteStream.prototype.end = function (c) { + if (this.muted) { + if (c && this.replace) { + c = c.toString().replace(/./g, this.replace) + } else { + c = null + } + } + if (c) this.emit('data', c) + this.emit('end') +} + +function proxy (fn) { return function () { + var d = this._dest + var s = this._src + if (d && d[fn]) d[fn].apply(d, arguments) + if (s && s[fn]) s[fn].apply(s, arguments) +}} + +MuteStream.prototype.destroy = proxy('destroy') +MuteStream.prototype.destroySoon = proxy('destroySoon') +MuteStream.prototype.close = proxy('close') diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/package.json b/Challenge/seokahi/010.star/node_modules/mute-stream/package.json new file mode 100644 index 0000000..56ebb36 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/mute-stream/package.json @@ -0,0 +1,29 @@ +{ + "name": "mute-stream", + "version": "0.0.8", + "main": "mute.js", + "directories": { + "test": "test" + }, + "devDependencies": { + "tap": "^12.1.1" + }, + "scripts": { + "test": "tap test/*.js --cov" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/mute-stream" + }, + "keywords": [ + "mute", + "stream", + "pipe" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "description": "Bytes go in, but they don't come out (when muted).", + "files": [ + "mute.js" + ] +} diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore b/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore new file mode 100644 index 0000000..13abef4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore @@ -0,0 +1,3 @@ +node_modules +node_modules/* +npm_debug.log diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE b/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE new file mode 100644 index 0000000..6a477d4 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE @@ -0,0 +1,231 @@ +Dual Licensed MIT and Apache 2 + +The MIT License + +Copyright (c) 2013 Dominic Tarr + +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. + + + ----------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2013 Dominic Tarr + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/index.js b/Challenge/seokahi/010.star/node_modules/pause-stream/index.js new file mode 100644 index 0000000..0e0bf96 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/index.js @@ -0,0 +1,3 @@ +//through@2 handles this by default! +module.exports = require('through') + diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/package.json b/Challenge/seokahi/010.star/node_modules/pause-stream/package.json new file mode 100644 index 0000000..2a22646 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/package.json @@ -0,0 +1,35 @@ +{ + "name": "pause-stream", + "version": "0.0.11", + "description": "a ThroughStream that strictly buffers all readable events when paused.", + "main": "index.js", + "directories": { + "test": "test" + }, + "devDependencies": { + "stream-tester": "0.0.2", + "stream-spec": "~0.2.0" + }, + "scripts": { + "test": "node test/index.js && node test/pause-end.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/pause-stream.git" + }, + "keywords": [ + "stream", + "pipe", + "pause", + "drain", + "buffer" + ], + "author": "Dominic Tarr (dominictarr.com)", + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } +} diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown new file mode 100644 index 0000000..2366939 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown @@ -0,0 +1,29 @@ +# PauseStream + +This is a `Stream` that will strictly buffer when paused. +Connect it to anything you need buffered. + +``` js + var ps = require('pause-stream')(); + + badlyBehavedStream.pipe(ps.pause()) + + aLittleLater(function (err, data) { + ps.pipe(createAnotherStream(data)) + ps.resume() + }) +``` + +`PauseStream` will buffer whenever paused. +it will buffer when yau have called `pause` manually. +but also when it's downstream `dest.write()===false`. +it will attempt to drain the buffer when you call resume +or the downstream emits `'drain'` + +`PauseStream` is tested using [stream-spec](https://github.com/dominictarr/stream-spec) +and [stream-tester](https://github.com/dominictarr/stream-tester) + +This is now the default case of +[through](https://github.com/dominictarr/through) + +https://github.com/dominictarr/pause-stream/commit/4a6fe3dc2c11091b1efbfde912e0473719ed9cc0 diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js b/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js new file mode 100644 index 0000000..db8778d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js @@ -0,0 +1,17 @@ +var spec = require('stream-spec') +var tester = require('stream-tester') +var ps = require('..')() + +spec(ps) + .through({strict: false}) + .validateOnExit() + +var master = tester.createConsistent + +tester.createRandomStream(1000) //1k random numbers + .pipe(master = tester.createConsistentStream()) + .pipe(tester.createUnpauseStream()) + .pipe(ps) + .pipe(tester.createPauseStream()) + .pipe(master.createSlave()) + diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js b/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js new file mode 100644 index 0000000..a6c27ef --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js @@ -0,0 +1,33 @@ + +var pause = require('..') +var assert = require('assert') + +var ps = pause() +var read = [], ended = false + +ps.on('data', function (i) { + read.push(i) +}) + +ps.on('end', function () { + ended = true +}) + +assert.deepEqual(read, []) + +ps.write(0) +ps.write(1) +ps.write(2) + +assert.deepEqual(read, [0, 1, 2]) + +ps.pause() + +assert.deepEqual(read, [0, 1, 2]) + +ps.end() +assert.equal(ended, false) +ps.resume() +assert.equal(ended, true) + + diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc b/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc new file mode 100644 index 0000000..67bc628 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc @@ -0,0 +1,22 @@ +{ + "extends": [ + "eslint:recommended" + ], + "env": { + "node": true, + "es6": false, + }, + "globals": { + "Promise": true // used only when no callback are passed + }, + "rules": { + "no-control-regex": "warn", + "no-prototype-builtins": "warn", + "indent": ["warn", 2, {"SwitchCase": 1}], + "linebreak-style": ["warn", "unix"], + "quotes": ["warn", "single"], + "no-unused-vars": "warn", + "no-sequences": "error", + "no-unused-expressions": "error", + } +} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc b/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc new file mode 100644 index 0000000..0d97986 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc @@ -0,0 +1,54 @@ +{ + "passfail": false, + "maxerr": 100, + + "browser": false, + "node": true, + "rhino": false, + "couch": true, + "wsh": true, + "jquery": true, + "prototypejs": false, + "mootools": false, + "dojo": false, + + "devel": false, + + "es5": true, + "strict": false, + "globalstrict": false, + + "asi": false, + "lastsemic": true, + "laxbreak": true, + "laxcomma": false, + "bitwise": false, + "boss": false, + "curly": true, + "eqeqeq": true, + "eqnull": false, + "evil": false, + "expr": false, + "forin": false, + "immed": false, + "latedef": false, + "loopfunc": true, + "noarg": true, + "regexp": true, + "regexdash": false, + "scripturl": true, + "shadow": true, + "supernew": true, + "undef": true, + + "newcap": true, + "noempty": true, + "nonew": true, + "nomen": false, + "onevar": true, + "plusplus": false, + "sub": true, + "trailing": true, + "white": false, + "indent": 2 +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml b/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml new file mode 100644 index 0000000..150a777 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +node_js: + - "node" + - "0.12" + - "4" + - "5" + +before_script: + - npx eslint . --quiet + +sudo: false diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json b/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json new file mode 100644 index 0000000..9792498 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": false +} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md b/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md new file mode 100644 index 0000000..b094c48 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md @@ -0,0 +1,13 @@ + +0.2.7 / 2012-08-30 +================== + + * Fixed handling of numeric inputs with parseFloat + * Fixed overwriting of non-string inputs + * Added support for boolean types + +0.2.6 / 2012-08-12 +================== + + * Added allowance of empty default values + diff --git a/Challenge/seokahi/010.star/node_modules/prompt/LICENSE b/Challenge/seokahi/010.star/node_modules/prompt/LICENSE new file mode 100644 index 0000000..56217ca --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Nodejitsu Inc. + +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. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/README.md b/Challenge/seokahi/010.star/node_modules/prompt/README.md new file mode 100644 index 0000000..5980812 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/README.md @@ -0,0 +1,468 @@ +# prompt [![Build Status](https://secure.travis-ci.org/flatiron/prompt.svg)](http://travis-ci.org/flatiron/prompt) [![Npm package version](https://img.shields.io/npm/v/prompt.svg?maxAge=2592000)](https://npmjs.com/package/prompt) + + +A beautiful command-line prompt for node.js + +## Features + +* prompts the user for input +* supports validation and defaults +* hides passwords + +## Usage +Using prompt is relatively straight forward. There are two core methods you should be aware of: `prompt.get()` and `prompt.addProperties()`. Their methods take strings representing property names in addition to objects for complex property validation (and more). There are a number of [examples][0] that you should examine for detailed usage. + +### Getting Basic Prompt Information +Getting started with `prompt` is easy. Lets take a look at `examples/simple-prompt.js`: + +``` js + var prompt = require('prompt'); + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and email + // + prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + }); +``` + +This will result in the following command-line output: + +``` + $ node examples/simple-prompt.js + prompt: username: some-user + prompt: email: some-user@some-place.org + Command-line input received: + username: some-user + email: some-user@some-place.org +``` + +If no callback is passed to `prompt.get(schema)`, then it returns a `Promise`, so you can also write: +```js +const {username, email} = await prompt.get(['username', 'email']); +``` + + +### Prompting with Validation, Default Values, and More (Complex Properties) +In addition to prompting the user with simple string prompts, there is a robust API for getting and validating complex information from a command-line prompt. Here's a quick sample: + +``` js + var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s\-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + password: { + hidden: true + } + } + }; + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: name, password + // + prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' password: ' + result.password); + }); +``` + +Pretty easy right? The output from the above script is: + +``` + $ node examples/property-prompt.js + prompt: name: nodejitsu000 + error: Invalid input for name + error: Name must be only letters, spaces, or dashes + prompt: name: Nodejitsu Inc + prompt: password: + Command-line input received: + name: Nodejitsu Inc + password: some-password +``` + +## Valid Property Settings +`prompt` understands JSON-schema with a few extra parameters and uses [revalidator](https://github.com/flatiron/revalidator) for validation. + +Here's an overview of the properties that may be used for validation and prompting controls: + +``` js + { + description: 'Enter your password', // Prompt displayed to the user. If not supplied name will be used. + type: 'string', // Specify the type of input to expect. + pattern: /^\w+$/, // Regular expression that input must be valid against. + message: 'Password must be letters', // Warning message to display if validation fails. + hidden: true, // If true, characters entered will either not be output to console or will be outputed using the `replace` string. + replace: '*', // If `hidden` is set it will replace each hidden character with the specified string. + default: 'lamepassword', // Default value to use if no value is entered. + required: true // If true, value entered must be non-empty. + before: function(value) { return 'v' + value; } // Runs before node-prompt callbacks. It modifies user's input + } +``` + +Alternatives to `pattern` include `format` and `conform`, as documented in [revalidator](https://github.com/flatiron/revalidator). + +Supported types are `string`, `boolean`, `number`, `integer`, `array` + +Using `type: 'boolean'` accepts case insensitive values 'true', 't', 'false', 'f' + +Using `type: 'array'` has some special cases. + +- `description` will not work in the schema if `type: 'array'` is defined. +- `maxItems` takes precedence over `minItems`. +- Arrays that do not have `maxItems` defined will require users to `SIGINT` (`^C`) before the array is ended. +- If `SIGINT` (`^C`) is triggered before `minItems` is met, a validation error will appear. This will require users to `SIGEOF` (`^D`) to end the input. + +For more information on things such as `maxItems` and `minItems`, refer to the [revalidator](https://github.com/flatiron/revalidator) repository. + +### Alternate Validation API: + +Prompt, in addition to iterating over JSON-Schema properties, will also happily iterate over an array of validation objects given an extra 'name' property: + +```js + var prompt = require('../lib/prompt'); + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and password + // + prompt.get([{ + name: 'username', + required: true + }, { + name: 'password', + hidden: true, + conform: function (value) { + return true; + } + }], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' password: ' + result.password); + }); +``` + +### Backward Compatibility + +Note that, while this structure is similar to that used by prompt 0.1.x, that the object properties use the same names as in JSON-Schema. prompt 0.2.x is backward compatible with prompt 0.1.x except for asynchronous validation. + +### Skipping Prompts + +Sometimes power users may wish to skip prompts and specify all data as command line options. +if a value is set as a property of `prompt.override` prompt will use that instead of +prompting the user. + +``` js + //prompt-override.js + + var prompt = require('prompt'), + optimist = require('optimist') + + // + // set the overrides + // + prompt.override = optimist.argv + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and email + // + prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + }) + + //: node prompt-override.js --username USER --email EMAIL +``` + +It is also possible to skip prompts dynamically based on previous prompts. +If an `ask` method is added, prompt will use it to determine if the prompt should be displayed. +If `ask` returns true the prompt is displayed. otherwise, the default value or empty string are used. + +``` js + var schema = { + properties: { + proxy: { + description: 'Proxy url', + }, + proxyCredentials: { + description: 'Proxy credentials', + ask: function() { + // only ask for proxy credentials if a proxy was set + return prompt.history('proxy').value > 0; + } + } + } + }; + + // + // Start the prompt + // + prompt.start(); + + // + // Get one or two properties from the user, depending on + // what the user answered for proxy + // + prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' proxy: ' + result.proxy); + console.log(' credentials: ' + result.proxyCredentials); + }); +``` + + +### Adding Properties to an Object +A common use-case for prompting users for data from the command-line is to extend or create a configuration object that is passed onto the entry-point method for your CLI tool. `prompt` exposes a convenience method for doing just this: + +``` js + var obj = { + password: 'lamepassword', + mindset: 'NY' + } + + // + // Log the initial object. + // + console.log('Initial object to be extended:'); + console.dir(obj); + + // + // Add two properties to the empty object: username and email + // + prompt.addProperties(obj, ['username', 'email'], function (err) { + // + // Log the results. + // + console.log('Updated object received:'); + console.dir(obj); + }); +``` + +### Prompt history +You can use the `prompt.history()` method to get access to previous prompt input. + +``` js + prompt.get([{ + name: 'name', + description: 'Your name', + type: 'string', + required: true + }, { + name: 'surname', + description: 'Your surname', + type: 'string', + required: true, + message: 'Please dont use the demo credentials', + conform: function(surname) { + var name = prompt.history('name').value; + return (name !== 'John' || surname !== 'Smith'); + } + }], function(err, results) { + console.log(results); + }); +``` + +## Customizing your prompt +Aside from changing `property.message`, you can also change `prompt.message` +and `prompt.delimiter` to change the appearance of your prompt. + +The basic structure of a prompt is this: + +``` js +prompt.message + prompt.delimiter + property.message + prompt.delimiter; +``` + +The default `prompt.message` is "prompt," the default `prompt.delimiter` is +": ", and the default `property.message` is `property.name`. +Changing these allows you to customize the appearance of your prompts! In +addition, prompt supports ANSI color codes via the +[colors module](https://github.com/DABH/colors.js) for custom colors. For a +very colorful example: + +``` js + var prompt = require("prompt"); + var colors = require("@colors/colors/safe"); + // + // Setting these properties customizes the prompt. + // + prompt.message = colors.rainbow("Question!"); + prompt.delimiter = colors.green("><"); + + prompt.start(); + + prompt.get({ + properties: { + name: { + description: colors.magenta("What is your name?") + } + } + }, function (err, result) { + console.log(colors.cyan("You said your name is: " + result.name)); + }); +``` + +If you don't want colors, you can set + +```js +var prompt = require('prompt'); + +prompt.colors = false; +``` + +## Integration with streamlinejs + +When integrating prompt with projects using streamlinejs such as the following + +``` +prompt.start(); +function test_prompt(_){ + console.log(prompt.get(loadDataValues(), _).output); +} +test_prompt(_); +``` + +This will work, however the process is then stuck with a stdin stream still open. If you setup the traditional way (with callback) such as this + + ``` +prompt.start(); +function test_prompt(){ + prompt.get(loadDataValues(), function(err, data){ + console.log(data.output); + }); +} +test_prompt(); +``` +This works and ends correctly. + +To resolve this we have added a new method to prompt, which will stop the stdin stream + +``` +// +// ### function stop () +// Stops input coming in from stdin +// +prompt.stop = function () { + if (prompt.stopped || !prompt.started) { + return; + } + + stdin.destroy(); + prompt.emit('stop'); + prompt.stopped = true; + prompt.started = false; + prompt.paused = false; + return prompt; +} +``` + +And you can find an example in the example folder `examples/prompt-streamline.js` + +``` +/* + * prompt-streamline._js: Example of how to use prompt with streamlinejs. + * + * calling syntax: _node prompt-streamline._js + * + */ +var prompt = require('../lib/prompt'); + +function getSampleData(){ + return [ + { + name: 'username', + message: 'Enter a username' + } + ]; +}; + +// +// Start the prompt +// +prompt.start(); + +function get_username_prompt(_){ + console.log(prompt.get(getSampleData(), _).username); +} + +get_username_prompt(_); + +// +// Clean the prompt +// +prompt.stop(); +``` + +## Disabling prompt's built-in SIGINT handling + +By default, prompt prompt binds a process-killing event handler to the SIGINT event (CTRL+C). This allows easily exiting from prompts, but can prevent an app from executing other event handlers when an interrupt is received. In order to override this default behavior, pass a `{noHandleSIGINT: true}` option into `prompt.start`. + +``` js + // + // Disable prompt's built-in SIGINT handling: + // + prompt.start({noHandleSIGINT: true}); + + process.on('SIGINT', function() { + console.log("This will execute when you hit CTRL+C"); + process.exit(); + }); +``` + + +## Installation + +``` bash + $ [sudo] npm install prompt +``` + +## Running tests + +``` bash + $ npm test +``` + +#### License: MIT +#### Author: [Charlie Robbins](http://github.com/indexzero) +#### Contributors: [Josh Holbrook](http://github.com/jesusabdullah), [Pavan Kumar Sunkara](http://github.com/pksunkara) + +[0]: https://github.com/flatiron/prompt/tree/master/examples diff --git a/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css b/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css new file mode 100644 index 0000000..bd54134 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css @@ -0,0 +1,194 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h4, h5, h6 { + color: #333; + margin: 6px 0 6px 0; + font-size: 13px; +} + h2, h3 { + margin-bottom: 0; + color: #000; + } + h1 { + margin-top: 40px; + margin-bottom: 15px; + color: #000; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html b/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html new file mode 100644 index 0000000..7776f5b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html @@ -0,0 +1,296 @@ + prompt.js

prompt.js

/*
+ * prompt.js: Simple prompt for prompting information from the command line 
+ *
+ * (C) 2010, Nodejitsu Inc.
+ *
+ */
+
+var events = require('events'),
+    async = require('async'),
+    colors = require('colors'),
+    winston = require('winston'),
+    stdio = process.binding('stdio');

@private function capitalize (str)

+ +

str {string} String to capitalize

+ +

Capitalizes the string supplied.

function capitalize(str) {
+  return str.charAt(0).toUpperCase() + str.slice(1);
+}
+
+var prompt = module.exports = Object.create(events.EventEmitter.prototype);
+
+var logger = prompt.logger = new winston.Logger({
+  transports: [
+    new (winston.transports.Console)()
+  ]
+});
+    
+prompt.started    = false;
+prompt.paused     = false;
+prompt.allowEmpty = false; 
+
+var stdin, stdout;

Create an empty object for the properties +known to prompt

prompt.properties = {};

Setup the default winston logger to use +the cli levels and colors.

logger.cli();

function start (options)

+ +

@options {Object} Optional Options to consume by prompt

+ +

Starts the prompt by listening to the appropriate events on options.stdin +and options.stdout. If no streams are supplied, then process.stdin +and process.stdout are used, respectively.

prompt.start = function (options) {
+  if (prompt.started) {
+    return;
+  }
+  
+  options = options        || {};
+  stdin   = options.stdin  || process.openStdin();
+  stdout  = options.stdout || process.stdout;
+  
+  prompt.allowEmpty = options.allowEmpty || false;
+  
+  process.on('SIGINT', function () {
+    stdout.write('\n');
+    process.exit(1);
+  })
+  
+  prompt.emit('start');
+  prompt.started = true;
+  return prompt;
+};

function pause ()

+ +

Pauses input coming in from stdin

prompt.pause = function () {
+  if (!prompt.started || prompt.paused) {
+    return;
+  }
+  
+  stdin.pause();
+  prompt.emit('pause');
+  prompt.paused = true;
+  return prompt;
+};

function resume ()

+ +

Resumes input coming in from stdin

prompt.resume = function () {
+  if (!prompt.started || !prompt.paused) {
+    return;
+  }
+  
+  stdin.resume();
+  prompt.emit('resume');
+  prompt.paused = false;
+  return prompt;
+};

function get (msg, [validator,] callback)

+ +

@msg {Array|Object|string} Set of variables to get input for.

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Gets input from the user via stdin for the specified message(s) msg.

prompt.get = function (msg, callback) {
+  var vars = !Array.isArray(msg) ? [msg] : msg,
+      result = {};
+  
+  vars = vars.map(function (v) {
+    if (typeof v === 'string') {
+      v = v.toLowerCase();
+    }
+    
+    return prompt.properties[v] || v;
+  });
+  
+  function get(target, next) {
+    prompt.getInput(target, function (err, line) {
+      if (err) {
+        return next(err);
+      }
+      
+      var name = target.name || target;
+      result[name] = line;
+      next();
+    });
+  }
+  
+  async.forEachSeries(vars, get, function (err) {
+    return err ? callback(err) : callback(null, result);
+  });
+  
+  return prompt;
+};

function getInput (msg, validator, callback)

+ +

@msg {Object|string} Variable to get input for.

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Gets input from the user via stdin for the specified message msg.

prompt.getInput = function (prop, callback) {
+  var name   = prop.message || prop.name || prop,
+      raw    = ['prompt', ': ' + name.grey, ': '.grey],
+      read   = prop.hidden ? prompt.readLineHidden : prompt.readLine,
+      length, msg;
+  
+  if (prop.default) {
+    raw.splice(2, -1, ' (' + prop.default + ')');
+  }
+  

Calculate the raw length and colorize the prompt

  length = raw.join('').length;
+  raw[0] = raw[0];
+  msg = raw.join('');
+  
+  if (prop.help) {
+    prop.help.forEach(function (line) {
+      logger.help(line);
+    });
+  }
+  
+  stdout.write(msg); 
+  prompt.emit('prompt', prop);
+  
+  read.call(null, function (err, line) {
+    if (err) {
+      return callback(err);
+    }
+  
+    if (!line || line === '') {
+      line = prop.default || line;
+    }
+    
+    if (prop.validator || prop.empty === false) {
+      var valid;
+      
+      if (prop.validator) {
+        valid = prop.validator.test 
+         ? prop.validator.test(line)
+         : prop.validator(line);
+      }
+      
+      if (prop.empty === false && valid) {
+        valid = line.length > 0;
+        prop.warning = prop.warning || 'You must supply a value.';
+      }
+      
+      if (!valid) {
+        logger.error('Invalid input for ' + name.grey);
+        if (prop.warning) {
+          logger.error(prop.warning);
+        }
+        
+        prompt.emit('invalid', prop, line);
+        return prompt.getInput(prop, callback);
+      }
+    }
+        
+    logger.input(line.yellow);
+    callback(null, line);
+  });
+
+  return prompt;
+};

function addProperties (obj, properties, callback)

+ +

@obj {Object} Object to add properties to

+ +

@properties {Array} List of properties to get values for

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Prompts the user for values each of the properties if obj does not already +have a value for the property. Responds with the modified object.

prompt.addProperties = function (obj, properties, callback) {
+  properties = properties.filter(function (prop) {
+    return typeof obj[prop] === 'undefined';
+  });
+  
+  if (properties.length === 0) {
+    return callback(obj);
+  }
+  
+  prompt.get(properties, function (err, results) {
+    if (err) {
+      return callback(err);
+    }
+    else if (!results) {
+      return callback(null, obj);
+    }
+    
+    function putNested (obj, path, value) {
+      var last = obj, key; 
+      
+      while (path.length > 1) {
+        key = path.shift();
+        if (!last[key]) {
+          last[key] = {};
+        }
+        
+        last = last[key];
+      }
+      
+      last[path.shift()] = value;
+    }
+    
+    Object.keys(results).forEach(function (key) {
+      putNested(obj, key.split('.'), results[key]);
+    });
+    
+    callback(null, obj);
+  });
+  
+  return prompt;
+};

function readLine (callback)

+ +

@callback {function} Continuation to respond to when complete

+ +

Gets a single line of input from the user.

prompt.readLine = function (callback) {
+  var value = '', buffer = '';
+  prompt.resume();
+  stdin.setEncoding('utf8');
+  stdin.on('error', callback);
+  stdin.on('data', function data (chunk) {
+    value += buffer + chunk;
+    buffer = '';
+    value = value.replace(/\r/g, '');
+    if (value.indexOf('\n') !== -1) {
+      if (value !== '\n') {
+        value = value.replace(/^\n+/, '');
+      }
+      
+      buffer = value.substr(value.indexOf('\n'));
+      val = value.substr(0, value.indexOf('\n'));
+      prompt.pause();
+      stdin.removeListener('data', data);
+      stdin.removeListener('error', callback);
+      value = value.trim();
+      callback(null, value);
+    }
+  });
+  
+  return prompt;
+};

function readLineHidden (callback)

+ +

@callback {function} Continuation to respond to when complete

+ +

Gets a single line of hidden input (i.e. rawMode = true) from the user.

prompt.readLineHidden = function (callback) {
+  var value = '', buffer = '';
+  stdio.setRawMode(true);
+  prompt.resume();
+  stdin.on('error', callback);
+  stdin.on('data', function data (c) {
+    c = '' + c;
+    switch (c) {
+      case '\n': case '\r': case '\r\n': case '\u0004':
+        stdio.setRawMode(false);
+        stdin.removeListener('data', data);
+        stdin.removeListener('error', callback);
+        value = value.trim();
+        stdout.write('\n');
+        stdout.flush();
+        prompt.pause();
+        return callback(null, value)
+      case '\u0003': case '\0':
+        stdout.write('\n');
+        process.exit(1);
+        break;
+      default:
+        value += buffer + c
+        buffer = '';
+        break;
+    }
+  });
+  
+  return prompt;
+};
+
+
diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js new file mode 100644 index 0000000..1a56176 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js @@ -0,0 +1,35 @@ +/* + * add-properties.js: Example of how to add properties to an object using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var obj = { + password: 'lamepassword', + mindset: 'NY' +} + +// +// Log the initial object. +// +console.log('Initial object to be extended:'); +console.dir(obj); + +// +// Add two properties to the empty object: username and email +// +prompt.addProperties(obj, ['username', 'email'], function (err) { + // + // Log the results. + // + console.log('Updated object received:'); + console.dir(obj); +}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js new file mode 100644 index 0000000..0a90b88 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js @@ -0,0 +1,19 @@ +var prompt = require("../lib/prompt"); +var colors = require("@colors/colors/safe"); +// +// Setting these properties customizes the prompt. +// +prompt.message = colors.rainbow("Question!"); +prompt.delimiter = colors.green("><"); + +prompt.start(); + +prompt.get({ + properties: { + name: { + description: colors.magenta("What is your name?") + } + } +}, function (err, result) { + console.log(colors.cyan("You said your name is: " + result.name)); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js new file mode 100644 index 0000000..194e1ef --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js @@ -0,0 +1,38 @@ +/* + * dynamic-ask-prompt.js: Dynamically decide whether to display prompt. + */ + +var prompt = require('../lib/prompt'); + +var schema = { + properties: { + proxy: { + description: 'Proxy url' + }, + proxyCredentials: { + description: 'Proxy credentials', + ask: function() { + // only ask for proxy credentials if a proxy was set + return prompt.history('proxy').value > 0; + } + } + } +}; + +// +// Start the prompt +// +prompt.start(); + +// +// Get one or two properties from the user, depending on +// what the user answered for proxy +// +prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' proxy: ' + result.proxy); + console.log(' credentials: ' + result.proxyCredentials); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js new file mode 100644 index 0000000..d87503b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js @@ -0,0 +1,35 @@ +/* + * existing-properties.js: Example of using prompt with predefined properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +prompt.properties = { + email: { + format: 'email', + message: 'Must be a valid email address' + }, + password: { + hidden: true + } +}; + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(['email', 'password'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' email: ' + result.email); + console.log(' password: ' + result.password); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js new file mode 100644 index 0000000..fd4369d --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js @@ -0,0 +1,44 @@ +/* + * history.js: Example of using the prompt history capabilities. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var properties = { + properties: { + animal: { + description: 'Enter an animal', + default: 'dog', + pattern: /dog|cat/ + }, + sound: { + description: 'What sound does this animal make?', + conform: function (value) { + var animal = prompt.history(0).value; + + return animal === 'dog' && value === 'woof' + || animal === 'cat' && value === 'meow'; + } + } + } +} + +// +// Get two properties from the user +// +prompt.get(properties, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' animal: ' + result.animal); + console.log(' sound: ' + result.sound); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js new file mode 100644 index 0000000..25106a2 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js @@ -0,0 +1,37 @@ +/* + * property-prompt.js: Example of using prompt with complex properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +var schema = { + properties: { + url: { + required: true, + format: 'url' + }, + auth: { + properties: { + username: { + required: true + }, + password: { + required: true, + hidden: true + } + } + } + } +}; + +prompt.start(); + +prompt.get(schema, function (err, result) { + console.log('Command-line input received:'); + console.log(' url: ' + result.url); + console.log(' auth:username: ' + result.auth.username); + console.log(' auth:password: ' + result.auth.password); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js new file mode 100644 index 0000000..631b7b5 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js @@ -0,0 +1,36 @@ +/* + * simple-prompt.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get([ + { + name: 'username', + validator: /^[a-z]+$/, + warning: 'Username should consist only lowercase alphabets', + empty: false + }, + { + name: 'email', + message: 'Email Address' + } +], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js new file mode 100644 index 0000000..0ca9ddd --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js @@ -0,0 +1,52 @@ +/* + * override-validation.js: Example of using prompt with complex properties and command-line input. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'), + optimist = require('optimist'); + +var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + email: { + name: 'email', + format: 'email', + message: 'Must be a valid email address' + } + } +}; + +// +// Set the overrides +// +prompt.override = optimist.argv + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' email: ' + result.email); +}); + +// try running +// $ node ./override-validation.js --name USER --email EMAIL +// You will only be asked for email because it's invalid +// $ node ./override-validation.js --name h$acker --email me@example.com +// You will only be asked for name becasue it's invalid diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js new file mode 100644 index 0000000..e8015e6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js @@ -0,0 +1,42 @@ +/* + * password.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and password and password masked +// +prompt.get([{ + name: 'username', + required: true + }, { + name: 'password', + hidden: true, + conform: function (value) { + return true; + } + }, { + name: 'passwordMasked', + hidden: true, + replace: '*', + conform: function (value) { + return true; + } + }], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' password: ' + result.password); + console.log(' passwordMasked: ' + result.passwordMasked); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js new file mode 100644 index 0000000..7f2848b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js @@ -0,0 +1,36 @@ +var prompt = require('../lib/prompt'), + optimist; + +try { + optimist = require('optimist'); +} catch (err) { + throw new Error([ + 'You need to install optimist before this example will work!', + 'Try: `npm install optimist`.' + ].join('\n')); +} + +// +// Set the overrides +// +prompt.override = optimist.argv + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + prompt.pause(); +}) + +// $ node ./prompt-override.js --username USER --email EMAIL diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js new file mode 100644 index 0000000..e7fef42 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js @@ -0,0 +1,32 @@ +/* + * prompt-streamline._js: Example of how to use prompt with streamlinejs. + * + * calling syntax: _node prompt-streamline._js + * + */ +var prompt = require('../lib/prompt'); + +function getSampleData(){ + return [ + { + name: 'username', + message: 'Enter a username' + } + ]; +}; + +// +// Start the prompt +// +prompt.start(); + +function get_username_prompt(_){ + console.log(prompt.get(getSampleData(), _).username); +} + +get_username_prompt(_); + +// +// Clean the prompt +// +prompt.stop(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js new file mode 100644 index 0000000..c8b343b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js @@ -0,0 +1,45 @@ +/* + * property-prompt.js: Example of using prompt with complex properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + email: { + name: 'email', + format: 'email', + message: 'Must be a valid email address' + }, + password: { + required: true, + hidden: true + } + } +}; + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' email: ' + result.email); + console.log(' password: ' + result.password); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js new file mode 100644 index 0000000..062e529 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js @@ -0,0 +1,25 @@ +/* + * simple-prompt.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); +}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js new file mode 100644 index 0000000..83f45a6 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js @@ -0,0 +1,20 @@ +var prompt = require('../lib/prompt'); + +prompt.start(); + +prompt.get([{ + name: 'integer', + type: 'integer', + required: true + }, { + name: 'number', + type: 'number', + required: true + }, { + name: 'boolean', + type: 'boolean', + required: true + }], function (err, result) { + console.log('Input received:'); + console.log(JSON.stringify(result, null, 2)); +}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js new file mode 100644 index 0000000..512b556 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js @@ -0,0 +1,32 @@ +/* + * yes-or-no-prompt.js: Simple example of using prompt. + * + * (C) 2012, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var property = { + name: 'yesno', + message: 'are you sure?', + validator: /y[es]*|n[o]?/, + warning: 'Must respond yes or no', + default: 'no' +}; + +// +// Get the simple yes or no property +// +prompt.get(property, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' result: ' + result.yesno); +}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js new file mode 100644 index 0000000..df28f82 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js @@ -0,0 +1,822 @@ +/* + * prompt.js: Simple prompt for prompting information from the command line + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var events = require('events'), + readline = require('readline'), + eachSeries = require('async/eachSeries'), + rejectSeries = require('async/rejectSeries'), + read = require('read'), + validate = require('revalidator').validate, + winston = require('winston'), + colors = require('@colors/colors/safe'); + +// +// Monkey-patch readline.Interface to work-around +// https://github.com/joyent/node/issues/3860 +// +readline.Interface.prototype.setPrompt = function(prompt, length) { + this._prompt = prompt; + if (length) { + this._promptLength = length; + } else { + var lines = prompt.split(/[\r\n]/); + var lastLine = lines[lines.length - 1]; + this._promptLength = lastLine.replace(/\u001b\[(\d+(;\d+)*)?m/g, '').length; + } +}; + +// +// Expose version using `pkginfo` +// +module.exports.version = require('../package.json').version; + +var stdin, stdout, history = []; +var prompt = module.exports = Object.create(events.EventEmitter.prototype); +var logger = prompt.logger = new winston.Logger({ + transports: [new (winston.transports.Console)()] +}); + +prompt.started = false; +prompt.paused = false; +prompt.stopped = true; +prompt.allowEmpty = false; +prompt.message = 'prompt'; +prompt.delimiter = ': '; +prompt.colors = true; + +// +// Create an empty object for the properties +// known to `prompt` +// +prompt.properties = {}; + +// +// Setup the default winston logger to use +// the `cli` levels and colors. +// +logger.cli(); + +// +// ### function start (options) +// #### @options {Object} **Optional** Options to consume by prompt +// Starts the prompt by listening to the appropriate events on `options.stdin` +// and `options.stdout`. If no streams are supplied, then `process.stdin` +// and `process.stdout` are used, respectively. +// +prompt.start = function (options) { + if (prompt.started) { + return; + } + + options = options || {}; + stdin = options.stdin || process.stdin; + stdout = options.stdout || process.stdout; + + // + // By default: Remember the last `10` prompt property / + // answer pairs and don't allow empty responses globally. + // + prompt.memory = options.memory || 10; + prompt.allowEmpty = options.allowEmpty || false; + prompt.message = options.message || prompt.message; + prompt.delimiter = options.delimiter || prompt.delimiter; + prompt.colors = options.colors || prompt.colors; + + if (!options.noHandleSIGINT) { + if (process.platform !== 'win32') { + // windows falls apart trying to deal with SIGINT + process.on('SIGINT', function () { + stdout.write('\n'); + process.exit(1); + }); + } else { + // listen for the "Ctrl+C" key combination and trigger process event. + // See https://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js + stdin.on('keypress', function(char, key) { + if (key && key.ctrl && key.name == 'c') { + stdout.write('\n'); + process.emit("SIGINT"); + process.exit(1); + } + }); + } + } + + prompt.emit('start'); + prompt.started = true; + prompt.stopped = false; + return prompt; +}; + +// +// ### function pause () +// Pauses input coming in from stdin +// +prompt.pause = function () { + if (!prompt.started || prompt.stopped || prompt.paused) { + return; + } + + stdin.pause(); + prompt.emit('pause'); + prompt.paused = true; + return prompt; +}; + +// +// ### function stop () +// Stops input coming in from stdin +// +prompt.stop = function () { + if (prompt.stopped || !prompt.started) { + return; + } + + stdin.destroy(); + prompt.emit('stop'); + prompt.stopped = true; + prompt.started = false; + prompt.paused = false; + return prompt; +} + +// +// ### function resume () +// Resumes input coming in from stdin +// +prompt.resume = function () { + if (!prompt.started || !prompt.paused) { + return; + } + + stdin.resume(); + prompt.emit('resume'); + prompt.paused = false; + return prompt; +}; + +// +// ### function history (search) +// #### @search {Number|string} Index or property name to find. +// Returns the `property:value` pair from within the prompts +// `history` array. +// +prompt.history = function (search) { + if (typeof search === 'number') { + return history[search] || {}; + } + + var names = history.map(function (pair) { + return typeof pair.property === 'string' + ? pair.property + : pair.property.name; + }); + + if (!~names.indexOf(search)) { + return null; + } + + return history.filter(function (pair) { + return typeof pair.property === 'string' + ? pair.property === search + : pair.property.name === search; + })[0]; +}; + +// +// ### function get (schema, callback) +// #### @schema {Array|Object|string} Set of variables to get input for. +// #### @callback {function} Continuation to pass control to when complete. +// Gets input from the user via stdin for the specified message(s) `msg`. +// +prompt.get = function (schema, callback) { + if (typeof callback === 'function') return prompt._get(schema, callback); + + return new Promise(function (resolve, reject) { + prompt._get(schema, function (err, result) { + return err ? reject(err) : resolve(result); + }); + }); +}; + +prompt._get = function (schema, callback) { + // + // Transforms a full JSON-schema into an array describing path and sub-schemas. + // Used for iteration purposes. + // + function untangle(schema, path) { + var results = []; + path = path || []; + + if (schema.properties) { + // + // Iterate over the properties in the schema and use recursion + // to process sub-properties. + // + Object.keys(schema.properties).forEach(function (key) { + var obj = {}; + obj[key] = schema.properties[key]; + + // + // Concat a sub-untangling to the results. + // + results = results.concat(untangle(obj[key], path.concat(key))); + }); + + // Return the results. + return results; + } + + // + // This is a schema "leaf". + // + return { + path: path, + schema: schema + }; + } + + // + // Iterate over the values in the schema, represented as + // a legit single-property object subschemas. Accepts `schema` + // of the forms: + // + // 'prop-name' + // + // ['string-name', { path: ['or-well-formed-subschema'], properties: ... }] + // + // { path: ['or-well-formed-subschema'], properties: ... ] } + // + // { properties: { 'schema-with-no-path' } } + // + // And transforms them all into + // + // { path: ['path', 'to', 'property'], properties: { path: { to: ...} } } + // + function iterate(schema, get, done) { + var iterator = [], + result = {}; + + if (typeof schema === 'string') { + // + // We can iterate over a single string. + // + iterator.push({ + path: [schema], + schema: prompt.properties[schema.toLowerCase()] || {} + }); + } + else if (Array.isArray(schema)) { + // + // An array of strings and/or single-prop schema and/or no-prop schema. + // + iterator = schema.map(function (element) { + if (typeof element === 'string') { + return { + path: [element], + schema: prompt.properties[element.toLowerCase()] || {} + }; + } + else if (element.properties) { + return { + path: [Object.keys(element.properties)[0]], + schema: element.properties[Object.keys(element.properties)[0]] + }; + } + else if (element.path && element.schema) { + return element; + } + else { + return { + path: [element.name || 'question'], + schema: element + }; + } + }); + } + else if (schema.properties) { + // + // Or a complete schema `untangle` it for use. + // + iterator = untangle(schema); + } + else { + // + // Or a partial schema and path. + // TODO: Evaluate need for this option. + // + iterator = [{ + schema: schema.schema ? schema.schema : schema, + path: schema.path || [schema.name || 'question'] + }]; + } + + // + // Now, iterate and assemble the result. + // + eachSeries(iterator, function (branch, next) { + get(branch, function assembler(err, line) { + if (err) { + return next(err); + } + + function build(path, line) { + var obj = {}; + if (path.length) { + obj[path[0]] = build(path.slice(1), line); + return obj; + } + + return line; + } + + function attach(obj, attr) { + var keys; + if (typeof attr !== 'object' || attr instanceof Array) { + return attr; + } + + keys = Object.keys(attr); + if (keys.length) { + if (!obj[keys[0]]) { + obj[keys[0]] = {}; + } + obj[keys[0]] = attach(obj[keys[0]], attr[keys[0]]); + } + + return obj; + } + + result = attach(result, build(branch.path, line)); + next(); + }); + }, function (err) { + return err ? done(err) : done(null, result); + }); + } + + iterate(schema, function get(target, next) { + prompt.getInput(target, function (err, line) { + return err ? next(err) : next(null, line); + }); + }, callback); + + return prompt; +}; + +// +// ### function confirm (msg, callback) +// #### @msg {Array|Object|string} set of message to confirm +// #### @callback {function} Continuation to pass control to when complete. +// Confirms a single or series of messages by prompting the user for a Y/N response. +// Returns `true` if ALL messages are answered in the affirmative, otherwise `false` +// +// `msg` can be a string, or object (or array of strings/objects). +// An object may have the following properties: +// +// { +// description: 'yes/no' // message to prompt user +// pattern: /^[yntf]{1}/i // optional - regex defining acceptable responses +// yes: /^[yt]{1}/i // optional - regex defining `affirmative` responses +// message: 'yes/no' // optional - message to display for invalid responses +// } +// +prompt.confirm = function (/* msg, options, callback */) { + var args = Array.prototype.slice.call(arguments), + msg = args.shift(), + callback = args.pop(), + opts = args.shift(), + vars = !Array.isArray(msg) ? [msg] : msg, + RX_Y = /^[yt]{1}/i, + RX_YN = /^[yntf]{1}/i; + + function confirm(target, next) { + var yes = target.yes || RX_Y, + options = { + description: typeof target === 'string' ? target : target.description || 'yes/no', + pattern: target.pattern || RX_YN, + name: 'confirm', + message: target.message || 'yes/no' + }; + + for (var k in (opts || {})) { + if (opts.hasOwnProperty(k)) { + options[k] = opts[k]; + } + } + + prompt.get([options], function (err, result) { + next(null, err ? false : yes.test(result[options.name])); + }); + } + + rejectSeries(vars, confirm, function(err, result) { + callback(null, result.length===0); + }); +}; + + +// Variables needed outside of getInput for multiline arrays. +var tmp = []; + + +// ### function getInput (prop, callback) +// #### @prop {Object|string} Variable to get input for. +// #### @callback {function} Continuation to pass control to when complete. +// Gets input from the user via stdin for the specified message `msg`. +// +prompt.getInput = function (prop, callback) { + var schema = prop.schema || prop, + propName = prop.path && prop.path.join(':') || prop, + storedSchema = prompt.properties[propName.toLowerCase()], + delim = prompt.delimiter, + defaultLine, + against, + hidden, + length, + valid, + name, + raw, + msg; + + // + // If there is a stored schema for `propName` in `propmpt.properties` + // then use it. + // + if (schema instanceof Object && !Object.keys(schema).length && + typeof storedSchema !== 'undefined') { + schema = storedSchema; + } + + // + // Build a proper validation schema if we just have a string + // and no `storedSchema`. + // + if (typeof prop === 'string' && !storedSchema) { + schema = {}; + } + + schema = convert(schema); + defaultLine = schema.default; + name = prop.description || schema.description || propName; + raw = prompt.colors + ? [colors.grey(name), colors.grey(delim)] + : [name, delim]; + + if (prompt.message) + raw.unshift(prompt.message, delim); + + prop = { + schema: schema, + path: propName.split(':') + }; + + // + // If the schema has no `properties` value then set + // it to an object containing the current schema + // for `propName`. + // + if (!schema.properties) { + schema = (function () { + var obj = { properties: {} }; + obj.properties[propName] = schema; + return obj; + })(); + } + + // + // Handle overrides here. + // TODO: Make overrides nestable + // + if (prompt.override && prompt.override.hasOwnProperty(propName)) { + if (prompt._performValidation(name, prop, prompt.override, schema, -1, callback)) { + return callback(null, prompt.override[propName]); + } + + delete prompt.override[propName]; + } + + // + // Check if we should skip this prompt + // + if (typeof prop.schema.ask === 'function' && + !prop.schema.ask()) { + return callback(null, prop.schema.default || ''); + } + + var type = (schema.properties && schema.properties[propName] && + schema.properties[propName].type || '').toLowerCase().trim(), + wait = type === 'array'; + + if (type === 'array') { + length = prop.schema.maxItems; + if (length) { + msg = (tmp.length + 1).toString() + '/' + length.toString(); + } + else { + msg = (tmp.length + 1).toString(); + } + msg += delim; + raw.push(prompt.colors ? colors.grey(msg) : msg); + } + + // + // Calculate the raw length and colorize the prompt + // + length = raw.join('').length; + // raw[0] = raw[0]; + msg = raw.join(''); + + if (schema.help) { + schema.help.forEach(function (line) { + logger.help(line); + }); + } + + // + // Emit a "prompting" event + // + prompt.emit('prompt', prop); + + // + // If defaultLine is a function, execute it and store it back to defaultLine + // + if(typeof defaultLine === 'function') { + defaultLine = defaultLine(); + } + + // + // If there is no default line, set it to an empty string + // + if(typeof defaultLine === 'undefined') { + defaultLine = ''; + } + + // + // set to string for readline ( will not accept Numbers ) + // + defaultLine = defaultLine.toString(); + + // + // Make the actual read + // + read({ + prompt: msg, + silent: prop.schema && prop.schema.hidden, + replace: prop.schema && prop.schema.replace, + default: defaultLine, + input: stdin, + output: stdout + }, function (err, line) { + if (err && wait === false) { + return callback(err); + } + + var against = {}, + numericInput, + isValid; + + if (line !== '') { + + if (schema.properties[propName]) { + var type = (schema.properties[propName].type || '').toLowerCase().trim() || undefined; + + // + // If type is some sort of numeric create a Number object to pass to revalidator + // + if (type === 'number' || type === 'integer') { + line = Number(line); + } + + // + // Attempt to parse input as a boolean if the schema expects a boolean + // + if (type == 'boolean') { + if(line.toLowerCase() === "true" || line.toLowerCase() === 't') { + line = true; + } else if(line.toLowerCase() === "false" || line.toLowerCase() === 'f') { + line = false; + } + } + + // + // If the type is an array, wait for the end. Fixes #54 + // + if (type == 'array') { + var length = prop.schema.maxItems; + if (err) { + if (err.message == 'canceled') { + wait = false; + stdout.write('\n'); + } + } + else { + if (length) { + if (tmp.length + 1 < length) { + isValid = false; + wait = true; + } + else { + isValid = true; + wait = false; + } + } + else { + isValid = false; + wait = true; + } + tmp.push(line); + } + line = tmp; + } + } + + against[propName] = line; + } + + if (prop && prop.schema.before) { + line = prop.schema.before(line); + } + + // Validate + if (isValid === undefined) isValid = prompt._performValidation(name, prop, against, schema, line, callback); + + if (!isValid) { + return prompt.getInput(prop, callback); + } + + // + // Log the resulting line, append this `property:value` + // pair to the history for `prompt` and respond to + // the callback. + // + logger.input(line.yellow); + prompt._remember(propName, line); + callback(null, line); + + // Make sure `tmp` is emptied + tmp = []; + }); +}; + +// +// ### function performValidation (name, prop, against, schema, line, callback) +// #### @name {Object} Variable name +// #### @prop {Object|string} Variable to get input for. +// #### @against {Object} Input +// #### @schema {Object} Validation schema +// #### @line {String|Boolean} Input line +// #### @callback {function} Continuation to pass control to when complete. +// Perfoms user input validation, print errors if needed and returns value according to validation +// +prompt._performValidation = function (name, prop, against, schema, line, callback) { + var numericInput, valid, msg; + try { + valid = validate(against, schema); + } + catch (err) { + return (line !== -1) ? callback(err) : false; + } + + if (!valid.valid) { + if (prop.schema.message) { + logger.error(prop.schema.message); + } else { + msg = line !== -1 ? 'Invalid input for ' : 'Invalid command-line input for '; + + if (prompt.colors) { + logger.error(msg + colors.grey(name)); + } + else { + logger.error(msg + name); + } + } + + prompt.emit('invalid', prop, line); + } + + return valid.valid; +}; + +// +// ### function addProperties (obj, properties, callback) +// #### @obj {Object} Object to add properties to +// #### @properties {Array} List of properties to get values for +// #### @callback {function} Continuation to pass control to when complete. +// Prompts the user for values each of the `properties` if `obj` does not already +// have a value for the property. Responds with the modified object. +// +prompt.addProperties = function (obj, properties, callback) { + properties = properties.filter(function (prop) { + return typeof obj[prop] === 'undefined'; + }); + + if (properties.length === 0) { + return callback(null, obj); + } + + prompt.get(properties, function (err, results) { + if (err) { + return callback(err); + } + else if (!results) { + return callback(null, obj); + } + + function putNested (obj, path, value) { + var last = obj, key; + + while (path.length > 1) { + key = path.shift(); + if (!last[key]) { + last[key] = {}; + } + + last = last[key]; + } + + last[path.shift()] = value; + } + + Object.keys(results).forEach(function (key) { + putNested(obj, key.split('.'), results[key]); + }); + + callback(null, obj); + }); + + return prompt; +}; + +// +// ### @private function _remember (property, value) +// #### @property {Object|string} Property that the value is in response to. +// #### @value {string} User input captured by `prompt`. +// Prepends the `property:value` pair into the private `history` Array +// for `prompt` so that it can be accessed later. +// +prompt._remember = function (property, value) { + history.unshift({ + property: property, + value: value + }); + + // + // If the length of the `history` Array + // has exceeded the specified length to remember, + // `prompt.memory`, truncate it. + // + if (history.length > prompt.memory) { + history.splice(prompt.memory, history.length - prompt.memory); + } +}; + +// +// ### @private function convert (schema) +// #### @schema {Object} Schema for a property +// Converts the schema into new format if it is in old format +// +function convert(schema) { + var newProps = Object.keys(validate.messages), + newSchema = false, + key; + + newProps = newProps.concat(['description', 'dependencies']); + + for (key in schema) { + if (newProps.indexOf(key) > 0) { + newSchema = true; + break; + } + } + + if (!newSchema || schema.validator || schema.warning || typeof schema.empty !== 'undefined') { + if(typeof schema.message !== 'undefined'){ + schema.description = schema.message; + } + + if(typeof schema.warning !== 'undefined'){ + schema.message = schema.warning; + } + + if (typeof schema.validator === 'function') { + schema.conform = schema.validator; + } else { + schema.pattern = schema.validator; + } + + if (typeof schema.empty !== 'undefined') { + schema.required = !(schema.empty); + } + + delete schema.warning; + delete schema.validator; + delete schema.empty; + } + + return schema; +} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/package.json b/Challenge/seokahi/010.star/node_modules/prompt/package.json new file mode 100644 index 0000000..f101c6b --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/package.json @@ -0,0 +1,40 @@ +{ + "name": "prompt", + "version": "1.3.0", + "description": "A beautiful command-line prompt for node.js", + "author": "Nodejitsu Inc. ", + "maintainers": [ + "indexzero ", + "jesusabdullah " + ], + "repository": { + "type": "git", + "url": "http://github.com/flatiron/prompt.git" + }, + "keywords": [ + "prompt", + "command-line", + "customize", + "validation" + ], + "dependencies": { + "@colors/colors": "1.5.0", + "async": "3.2.3", + "read": "1.0.x", + "revalidator": "0.1.x", + "winston": "2.x" + }, + "devDependencies": { + "eslint": "^7.32.0", + "vows": "^0.7.0" + }, + "main": "./lib/prompt", + "scripts": { + "test": "vows test/prompt-test.js --spec", + "test-all": "vows --spec" + }, + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } +} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js b/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js new file mode 100644 index 0000000..404ebe8 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js @@ -0,0 +1,177 @@ +/* + * helpers.js: test helpers for the prompt tests. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var stream = require('stream'), + util = require('util'), + prompt = require('../lib/prompt'); + +var helpers = exports; + +var MockReadWriteStream = helpers.MockReadWriteStream = function () { + // + // No need to do anything here, it's just a mock. + // + var self = this; + this.on('pipe', function (src) { + var _emit = src.emit; + src.emit = function () { + //console.dir(arguments); + _emit.apply(src, arguments); + }; + + src.on('data', function (d) { + self.emit('data', d + ''); + }) + }) +}; + +util.inherits(MockReadWriteStream, stream.Stream); + +['resume', 'pause', 'setEncoding', 'flush', 'end'].forEach(function (method) { + MockReadWriteStream.prototype[method] = function () { /* Mock */ }; +}); + +MockReadWriteStream.prototype.write = function (msg) { + this.emit('data', msg); + return true; +}; + +MockReadWriteStream.prototype.writeNextTick = function (msg) { + var self = this + process.nextTick(function () { + self.write(msg); + }); +}; + +// +// Create some mock streams for asserting against +// in our prompt teSts. +// +helpers.stdin = new MockReadWriteStream(); +helpers.stdout = new MockReadWriteStream(); +helpers.stderr = new MockReadWriteStream(); + +// +// Because `read` uses a `process.nextTick` for reading from +// stdin, it is necessary to write sequences of input with extra +// `process.nextTick` calls +// +helpers.stdin.writeSequence = function (lines) { + if (!lines || !lines.length) { + return; + } + + helpers.stdin.writeNextTick(lines.shift()); + prompt.once('prompt', function () { + process.nextTick(function () { + helpers.stdin.writeSequence(lines); + }); + }); +} + +// +// Monkey punch `util.error` to silence console output +// and redirect to helpers.stderr for testing. +// +process.stderr.write = function () { + helpers.stderr.write.apply(helpers.stderr, arguments); +} + +// 1) .properties +// 2) warning --> message +// 3) Name --> description || key +// 4) validator --> conform (fxns), pattern (regexp), format (built-in) +// 5) empty --> required +helpers.schema = { + properties: { + oldschema: { + message: 'Enter your username', + validator: /^[\w|-]+$/, + warning: 'username can only be letters, numbers, and dashes', + empty: false + }, + riffwabbles: { + pattern: /^[\w|-]+$/, + message: 'riffwabbles can only be letters, numbers, and dashes', + default: 'foobizzles' + }, + functiondefaultpluralanimal: { + message: 'function default plural animal', + default: function () { + return prompt.history('animal').value + 's'; + } + }, + functiondefaulttest: { + message: 'function default test', + default: function () { + return 'test'; + } + }, + functiondefaultundefined: { + message: 'function default undefined', + default: function () { } + }, + number: { + type: 'number', + message: 'pick a number, any number', + default: 10 + }, + integer: { + type: 'integer' + }, + boolean: { + type: 'boolean' + }, + username: { + pattern: /^[\w|-]+$/, + message: 'Username can only be letters, numbers, and dashes' + }, + notblank: { + required: true + }, + password: { + hidden: true, + required: true + }, + badValidator: { + pattern: ['cant', 'use', 'array'] + }, + animal: { + description: 'Enter an animal', + default: 'dog', + pattern: /dog|cat/ + }, + sound: { + description: 'What sound does this animal make?', + conform: function (value) { + var animal = prompt.history(0).value; + + return animal === 'dog' && value === 'woof' + || animal === 'cat' && value === 'meow'; + } + }, + fnvalidator: { + name: 'fnvalidator', + validator: function (line) { + return line.slice(0,2) == 'fn'; + }, + message: 'fnvalidator must start with "fn"' + }, + fnconform: { + conform: function (line) { + return line.slice(0,2) == 'fn'; + }, + message: 'fnconform must start with "fn"' + }/*, + cbvalidator: { + conform: function (line, next) { + next(line.slice(0,2) == 'cb'); + }, + message: 'cbvalidator must start with "cb"' + }*/ + } +}; diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js b/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js new file mode 100644 index 0000000..a3032e3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js @@ -0,0 +1,49 @@ +/* + * prompt-test.js: Tests for prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var assert = require('assert'), + vows = require('vows'), + prompt = require('../lib/prompt'), + winston = require('winston').cli(), + helpers = require('./helpers'); + +vows.describe('prompt/interactive').addBatch({ + "When using prompt": { + topic: function () { + // + // Reset the prompt for interactive testing + // + prompt.started = false; + prompt.start(); + winston.info('These prompt tests are interactive'); + winston.info('Not following instructions will result in test failure'); + return null; + }, + "the getInput() method": { + "when passed a complex property with `hidden: true`": { + topic: function () { + winston.info('When prompted, enter: 12345 [backspace] [backspace] [enter]'); + prompt.getInput({ path: ['password'], schema: helpers.schema.properties.password }, this.callback); + }, + "should respond with `123`": function (err, result) { + assert.isNull(err); + assert.equal(result, '123'); + }, + "and then when passed a complex property expecting a number": { + topic: function () { + winston.info('When prompted, enter: 123 [enter]'); + prompt.getInput({ path: ['number'], schema: helpers.schema.properties.number }, this.callback); + }, + "should respond with `123` (as a number)": function (err, result) { + assert.isNull(err); + assert.equal(result, 123); + } + } + } + } + } +}).export(module); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js b/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js new file mode 100644 index 0000000..9f58f08 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js @@ -0,0 +1,82 @@ +/* + * macros.js: Test macros for prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var assert = require('assert'), + helpers = require('./helpers'), + prompt = require('../lib/prompt'); + +exports.shouldConfirm = function (options, mixin) { + var message = options.response.toString().replace(/\n/g, ''), + messages = ["When using prompt", "the confirm() method"], + context = {}, + last = context; + + messages = messages.concat(options.messages || []); + + while (messages.length) { + var text = messages.shift(); + last[text] = {}; + last = last[text]; + } + + last['responding with ' + message] = { + topic: function () { + if(!mixin) + prompt.confirm(options.prop, this.callback); + else + prompt.confirm(options.prop, mixin, this.callback); + + if (!Array.isArray(options.response)) { + helpers.stdin.writeNextTick(options.response + '\n'); + } + else { + helpers.stdin.writeSequence(options.response); + } + }, + "should respond with true" : function(err, result) { + assert.isNull(err); + assert.isTrue(result); + } + } + + return context; +}; + +exports.shouldNotConfirm = function (options) { + var message = options.response.toString().replace(/\n/g, ''), + messages = ["When using prompt", "the confirm() method"], + context = {}, + last = context; + + messages = messages.concat(options.messages || []); + + while (messages.length) { + var text = messages.shift(); + last[text] = {}; + last = last[text]; + } + + last['responding with ' + message] = { + topic: function () { + prompt.confirm(options.prop, this.callback); + + if (!Array.isArray(options.response)) { + helpers.stdin.writeNextTick(options.response + '\n'); + } + else { + helpers.stdin.writeSequence(options.response); + } + }, + "should respond with false" : function(err, result) { + assert.isNull(err); + assert.isFalse(result); + } + }; + + return context; +}; + diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js b/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js new file mode 100644 index 0000000..1e9ab81 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js @@ -0,0 +1,960 @@ +/* + * prompt-test.js: Tests for prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var assert = require('assert'), + vows = require('vows'), + prompt = require('../lib/prompt'), + helpers = require('./helpers'), + macros = require('./macros'), + schema = helpers.schema; + +// fix for vows, util.print/puts was removed from node +require('util').print = console.log; +require('util').puts = console.log; + +// A helper to pass fragments of our schema into prompt as full schemas. +function grab () { + var names = [].slice.call(arguments), + complete = { schema: {} }; + + names.forEach(function (name) { + complete.path = [name]; + complete.schema = schema.properties[name]; + }); + return complete; +} + +// +// Reset the prompt for mock testing +// +prompt.started = false; +prompt.start({ + stdin: helpers.stdin, + stdout: helpers.stdout +}); + +vows.describe('prompt').addBatch({ + "When using prompt": { + "the getInput() method": { + "with a simple string prompt": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }) + + prompt.getInput('test input', this.callback); + helpers.stdin.writeNextTick('test value\n'); + }, + "should prompt to stdout and respond with data": function (err, input) { + assert.isNull(err); + assert.equal(input, 'test value'); + assert.isTrue(this.msg.indexOf('test input') !== -1); + } + }, + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with any field that is not supposed to be empty": { + "and we don't provide any input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + helpers.stderr.once('data', function (msg) { + that.errmsg = msg; + }); + + prompt.getInput(grab('notblank'), function () {}); + prompt.once('invalid', this.callback.bind(null, null)) + helpers.stdin.writeNextTick('\n'); + }, + "should prompt with an error": function (_, prop, input) { + assert.isObject(prop); + assert.equal(input, ''); + assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); + assert.isTrue(this.msg.indexOf('notblank') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a hidden field that is not supposed to be empty": { + "and we provide valid input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.getInput('password', this.callback); + helpers.stdin.writeNextTick('trustno1\n'); + }, + + "should prompt to stdout and respond with data": function (err, input) { + assert.isNull(err); + assert.equal(input, 'trustno1'); + assert.isTrue(this.msg.indexOf('password') !== -1); + } + }, + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a hidden field that is not supposed to be empty": { + "and we don't provide an input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + helpers.stderr.once('data', function (msg) { + that.errmsg = msg; + }); + + prompt.getInput(grab('password'), function () {} ); + prompt.once('invalid', this.callback.bind(null, null)) + helpers.stdin.writeNextTick('\n'); + }, + "should prompt with an error": function (ign, prop, input) { + assert.isObject(prop); + assert.equal(input, ''); + assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); + assert.isTrue(this.msg.indexOf('password') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with an integer field": { + "and we provide valid input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.getInput(grab('integer'), this.callback); + helpers.stdin.writeNextTick('42\n'); + }, + "should prompt to stdout and respond with data": function (err, input) { + assert.isNull(err); + assert.equal(input, '42'); + assert.isTrue(this.msg.indexOf('integer') !== -1); + } + }, + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with an integer field": { + "and we don't provide an integer": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + helpers.stderr.once('data', function (msg) { + that.errmsg = msg; + }) + + prompt.getInput(grab('integer'), this.callback); + + prompt.once('invalid', function () { + prompt.once('prompt', function () { + process.nextTick(function () { + helpers.stdin.writeNextTick('42\n'); + }) + }) + }); + + helpers.stdin.writeNextTick('4.2\n'); + }, + "should prompt with an error before completing the operation": function (err, input) { + assert.isNull(err); + assert.equal(input, '42'); + assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); + assert.isTrue(this.msg.indexOf('integer') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a boolean field": { + "and we provide valid input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.getInput(grab('boolean'), this.callback); + helpers.stdin.writeNextTick('true\n'); + }, + "should prompt to stdout and respond with data": function (err, input) { + assert.isNull(err); + assert.equal(input, true); + assert.isTrue(this.msg.indexOf('boolean') !== -1); + } + }, + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a boolean field": { + "and we don't provide an bool": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + helpers.stderr.once('data', function (msg) { + that.errmsg = msg; + }) + + prompt.getInput(grab('boolean'), this.callback); + + prompt.once('invalid', function () { + prompt.once('prompt', function () { + process.nextTick(function () { + helpers.stdin.writeNextTick('F\n'); + }) + }) + }); + + helpers.stdin.writeNextTick('4.2\n'); + }, + "should prompt with an error before completing the operation": function (err, input) { + assert.isNull(err); + assert.equal(input, false); + assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); + assert.isTrue(this.msg.indexOf('boolean') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a complex property prompt": { + "and a valid input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.getInput(grab('username'), this.callback); + helpers.stdin.writeNextTick('some-user\n'); + }, + "should prompt to stdout and respond with data": function (err, input) { + assert.isNull(err); + assert.equal(input, 'some-user'); + assert.isTrue(this.msg.indexOf('username') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a complex property prompt": { + "and an invalid input": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + helpers.stderr.once('data', function (msg) { + that.errmsg = msg; + }) + + prompt.getInput(grab('username'), this.callback); + + prompt.once('invalid', function () { + prompt.once('prompt', function () { + process.nextTick(function () { + helpers.stdin.writeNextTick('some-user\n'); + }) + }) + }); + + helpers.stdin.writeNextTick('some -user\n'); + }, + "should prompt with an error before completing the operation": function (err, input) { + assert.isNull(err); + assert.equal(input, 'some-user'); + assert.isTrue(this.errmsg.indexOf('Username can only be letters, numbers, and dashes') !== -1); + assert.isTrue(this.msg.indexOf('username') !== -1); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the getInput() method": { + "with a complex property prompt": { + "with an invalid validator (array)": { + topic: function () { + var that = this, + called; + + prompt.getInput(grab('badValidator'), function (err) { + if (!called) { + called = true; + that.callback(err); + } + }); + helpers.stdin.writeNextTick('some-user\n'); + }, + "should respond with an error": function (err, ign) { + assert.isTrue(!!err); + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is not a property in prompt.properties": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }) + + prompt.get('test input', this.callback); + helpers.stdin.writeNextTick('test value\n'); + }, + "should prompt to stdout and respond with the value": function (err, result) { + assert.isNull(err); + assert.include(result, 'test input'); + assert.equal(result['test input'], 'test value'); + assert.isTrue(this.msg.indexOf('test input') !== -1); + } + }, + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a string literal default value": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.properties.riffwabbles = schema.properties.riffwabbles; + prompt.get('riffwabbles', this.callback); + helpers.stdin.writeNextTick('\n'); + }, + "should prompt to stdout and respond with the default value": function (err, result) { + assert.isNull(err); + assert.notStrictEqual(this.msg.indexOf('riffwabbles'), -1); + assert.notStrictEqual(this.msg.indexOf('(foobizzles)'), -1); + assert.include(result, 'riffwabbles'); + assert.equal(result['riffwabbles'], schema.properties['riffwabbles'].default); + } + }, + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a function default returning a string literal": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.properties.functiondefaulttest = schema.properties.functiondefaulttest; + prompt.get('functionDefaultTest', this.callback); + helpers.stdin.writeNextTick('\n'); + }, + "should respond with the default value function's return value": function (err, result) { + assert.isNull(err); + assert.notStrictEqual(this.msg.indexOf('function default test'), -1); + assert.notStrictEqual(this.msg.indexOf('(test)'), -1); + assert.include(result, 'functionDefaultTest'); + assert.strictEqual(result['functionDefaultTest'], 'test'); + } + }, + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a function default returning a string literal": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + // we really need the second message, so we'll + // ignore the first and look out for the second + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }) + }); + + prompt.properties.animal = schema.properties.animal; + prompt.properties.functiondefaultpluralanimal = + schema.properties.functiondefaultpluralanimal; + prompt.get(['animal', 'functiondefaultpluralanimal'], this.callback); + helpers.stdin.writeSequence(['cat\n', '\n']); + }, + "should respond with the default value function's return value": function (err, result) { + assert.isNull(err); + assert.notStrictEqual(this.msg.indexOf('function default plural animal'), -1); + assert.notStrictEqual(this.msg.indexOf('(cats)'), -1); + assert.strictEqual(result['animal'], 'cat'); + assert.include(result, 'functiondefaultpluralanimal'); + assert.strictEqual(result['functiondefaultpluralanimal'], 'cats'); + } + }, + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a function default that returns undefined": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.properties.functiondefaultundefined = + schema.properties.functiondefaultundefined; + prompt.get('functionDefaultUndefined', this.callback); + helpers.stdin.writeNextTick('\n'); + }, + "should prompt without a default value": function (err, result) { + assert.isNull(err); + assert.notStrictEqual(this.msg.indexOf('function default undefined'), -1); + assert.strictEqual(this.msg.indexOf('('), -1); + assert.include(result, 'functionDefaultUndefined'); + assert.strictEqual(result['functionDefaultUndefined'], ''); + } + }, + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "that expects a numeric value": { + "and gets valid input": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.properties.number = schema.properties.number; + prompt.get('number', this.callback); + helpers.stdin.writeNextTick('15\n'); + }, + "should prompt to stdout and respond with a numeric value": function (err, result) { + assert.isNull(err); + assert.include(result, 'number'); + assert.equal(result['number'], 15); + } + } + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a sync function validator (.validator)": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.get(helpers.schema.properties.fnvalidator, this.callback); + helpers.stdin.writeNextTick('fn123\n'); + }, + "should accept a value that is checked": function (err, result) { + assert.isNull(err); + assert.equal(result['fnvalidator'],'fn123'); + } + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a sync function validator (.conform)": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.get(grab('fnconform'), this.callback); + helpers.stdin.writeNextTick('fn123\n'); + }, + "should accept a value that is checked": function (err, result) { + assert.isNull(err); + assert.equal(result['fnconform'],'fn123'); + } + } + // + // Remark Does not work with revalidator + // + // "with a callback validator": { + // topic: function () { + // var that = this; + // + // helpers.stdout.once('data', function (msg) { + // that.msg = msg; + // }); + // + // prompt.get(grab('cbvalidator'), this.callback); + // helpers.stdin.writeNextTick('cb123\n'); + // }, + // "should not accept a value that is correct": function (err, result) { + // assert.isNull(err); + // assert.equal(result['cbvalidator'],'cb123'); + // } + // } + } + }, + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with a simple string prompt": { + "that is a property name in prompt.properties": { + "with a sync function before (.before)": { + topic: function() { + var that = this; + + helpers.stdout.once('data', function(msg) { + that.msg = msg; + }); + + prompt.get({ + properties: { + fnbefore: { + before: function(v) { + return 'v' + v; + } + } + } + }, this.callback); + helpers.stdin.writeNextTick('fn456\n'); + }, + "should modify user's input": function(e, result) { + assert.equal(result.fnbefore, 'vfn456'); + } + } + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "skip prompt with prompt.overide": { + topic: function () { + prompt.override = { coconihet: 'whatever' } + prompt.get('coconihet', this.callback); + }, + "skips prompt and uses overide": function (err, results) { + assert.equal(results.coconihet, 'whatever') + } + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "skip prompt with falsy prompt.overide": { + topic: function () { + prompt.override = { coconihet: false } + prompt.get('coconihet', this.callback); + }, + "skips prompt and uses overide": function (err, results) { + assert.equal(results.coconihet, false) + } + } + } + } +}).addBatch({ + "When using prompt": { + "the addProperties() method": { + topic: function () { + prompt.addProperties({}, ['foo', 'bar'], this.callback); + helpers.stdin.writeSequence(['foo\n', 'bar\n']); + }, + "should add the properties to the object": function (err, obj) { + assert.isNull(err); + assert.isObject(obj); + assert.equal(obj.foo, 'foo'); + assert.equal(obj.bar, 'bar'); + } + } + } +}).addBatch({ + "When using prompt": { + "the addProperties() method": { + topic: function () { + prompt.addProperties({'foo': 'foo', 'bar': 'bar'}, [], this.callback); + }, + "should return the object as-is when no properties provided": function (err, obj) { + assert.isNull(err); + assert.isObject(obj); + assert.equal(obj.foo, 'foo'); + assert.equal(obj.bar, 'bar'); + } + } + } +}).addBatch({ + "When using prompt": { + "the get() method": { + "with old schema": { + topic: function () { + var that = this; + + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.properties.username = schema.properties.oldschema; + prompt.get('username', this.callback); + + helpers.stdin.writeSequence(['\n', 'hell$\n', 'hello\n']); + }, + "should prompt to stdout and respond with the default value": function (err, result) { + assert.isNull(err); + assert.isTrue(this.msg.indexOf('username') !== -1); + assert.include(result, 'username'); + assert.equal(result.username, 'hello'); + } + } + } + } +}).addBatch({ + "When using prompt": { + "the history() method": { + "when used inside of a complex property": { + "with correct value(s)": { + topic: function () { + prompt.get([grab('animal'), grab('sound')], this.callback); + helpers.stdin.writeSequence(['dog\n', 'woof\n']); + }, + "should respond with the values entered": function (err, result) { + assert.isTrue(!err); + assert.equal(result.animal, 'dog'); + assert.equal(result.sound, 'woof'); + assert.equal(prompt.history('nothing'), null); + assert.deepEqual(prompt.history('animal'), { property: 'animal', value: 'dog' }); + } + }, + } + } + } +}).addBatch({ + "When using prompt": { + "the history() method": { + "when used inside of a complex property": { + "with an incorrect value": { + topic: function () { + prompt.get([grab('animal'), grab('sound')], function () {}); + prompt.once('invalid', this.callback.bind(null, null)); + helpers.stdin.writeSequence(['dog\n', 'meow\n']); + }, + "should prompt for the error": function (ign, property, line) { + assert.equal(property.path.join(''), 'sound'); + assert.equal(line, 'meow'); + } + } + } + } + } +}).addBatch({ + "when using prompt": { + "the get() method": { + topic: function () { + prompt.override = { xyz: 468, abc: 123 } + prompt.get(['xyz', 'abc'], this.callback); + }, + "should respond with overrides": function (err, results) { + assert.isNull(err); + assert.deepEqual(results, { xyz: 468, abc: 123 }); + } + } + } +}).addBatch({ + "when using prompt": { + "the get() method also works as a Promise": { + topic: function () { + var that = this; + + prompt.override = { xyz: 468, abc: 123 }; + prompt.get(['xyz', 'abc']) + .then(function (result) { return that.callback(null, result); }); + }, + "should respond with overrides": function (err, results) { + assert.isNull(err); + assert.deepEqual(results, { xyz: 468, abc: 123 }); + } + } + } +}).addBatch({ + "When using prompt": { + "with fancy properties": { + "the get() method": { + topic: function () { + prompt.override = { UVW: 5423, DEF: 64235 } + prompt.get({ + properties: { + 'UVW': { + description: 'a custom message', + default: 6 + }, + 'DEF': { + description: 'a custom message', + default: 6 + } + } + }, this.callback); + }, + "should respond with overrides": function (err, results) { + assert.isNull(err); + assert.deepEqual(results, { UVW: 5423, DEF: 64235 }); + } + } + } + } +}).addBatch({ + "When using prompt": { + "with a type and a description property": { + "the get() method": { + topic: function () { + var that = this; + helpers.stdout.once('data', function (msg) { + that.msg = msg; + }); + + prompt.get({ + name: 'test', + type: 'number', + description: 'Please input a number' + }, this.callback); + helpers.stdin.writeNextTick('42\n'); + }, + "should prompt to stdout and respond with the value": function (err, result) { + assert.isNull(err); + assert.include(result, 'test'); + assert.equal(result['test'], '42'); + assert.isTrue(this.msg.indexOf('Please input a number') !== -1); + } + }, + } + } + }) +.addBatch( + macros.shouldConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'Y' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with an empty string and default yes'], + prop: 'test', + response: '' + }, { + default: 'yes' + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'N' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'YES' + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'NO' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'T' + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'F' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'TRUE' + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with a string message'], + prop: 'test', + response: 'FALSE' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with an object', 'and description set'], + prop: { description: 'a custom message' }, + response: 'Y' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with an object', 'and they forgot the description'], + prop: { description: 'a custom message' }, + response: 'Y' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with an object', 'and custom validators'], + prop: { + description: 'node or jitsu?', + pattern: /^(node|jitsu)/i, + yes: /^node/i + }, + response: 'node' + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with an object', 'and custom validators'], + prop: { + description: 'node or jitsu?', + pattern: /^(node|jitsu)/i, + yes: /^node/i + }, + response: 'jitsu' + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with multiple strings'], + prop: ["test", "test2", "test3"], + response: ['Y\n', 'y\n', 'YES\n'] + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with multiple strings'], + prop: ["test", "test2", "test3"], + response: ['Y\n', 'N\n', 'YES\n'] + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with multiple strings'], + prop: ["test", "test2", "test3"], + response: ['n\n', 'NO\n', 'N\n'] + }) +).addBatch( + macros.shouldConfirm({ + messages: ['with multiple objects'], + prop: [ + { message: "test" }, + { message: "test2" } + ], + response: ['y\n', 'y\n'] + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with multiple objects'], + prop: [ + { message: "test" }, + { message: "test2" } + ], + response: ['n\n', 'n\n'] + }) +).addBatch( + macros.shouldNotConfirm({ + messages: ['with multiple objects'], + prop: [ + { message: "test" }, + { message: "test2" } + ], + response: ['n\n', 'y\n'] + }) +).export(module); diff --git a/Challenge/seokahi/010.star/node_modules/read/LICENSE b/Challenge/seokahi/010.star/node_modules/read/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/read/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Challenge/seokahi/010.star/node_modules/read/README.md b/Challenge/seokahi/010.star/node_modules/read/README.md new file mode 100644 index 0000000..5967fad --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/read/README.md @@ -0,0 +1,53 @@ +## read + +For reading user input from stdin. + +Similar to the `readline` builtin's `question()` method, but with a +few more features. + +## USAGE + +```javascript +var read = require("read") +read(options, callback) +``` + +The callback gets called with either the user input, or the default +specified, or an error, as `callback(error, result, isDefault)` +node style. + +## OPTIONS + +Every option is optional. + +* `prompt` What to write to stdout before reading input. +* `silent` Don't echo the output as the user types it. +* `replace` Replace silenced characters with the supplied character value. +* `timeout` Number of ms to wait for user input before giving up. +* `default` The default value if the user enters nothing. +* `edit` Allow the user to edit the default value. +* `terminal` Treat the output as a TTY, whether it is or not. +* `input` Readable stream to get input data from. (default `process.stdin`) +* `output` Writeable stream to write prompts to. (default: `process.stdout`) + +If silent is true, and the input is a TTY, then read will set raw +mode, and read character by character. + +## COMPATIBILITY + +This module works sort of with node 0.6. It does not work with node +versions less than 0.6. It is best on node 0.8. + +On node version 0.6, it will remove all listeners on the input +stream's `data` and `keypress` events, because the readline module did +not fully clean up after itself in that version of node, and did not +make it possible to clean up after it in a way that has no potential +for side effects. + +Additionally, some of the readline options (like `terminal`) will not +function in versions of node before 0.8, because they were not +implemented in the builtin readline module. + +## CONTRIBUTING + +Patches welcome. diff --git a/Challenge/seokahi/010.star/node_modules/read/lib/read.js b/Challenge/seokahi/010.star/node_modules/read/lib/read.js new file mode 100644 index 0000000..a93d1b3 --- /dev/null +++ b/Challenge/seokahi/010.star/node_modules/read/lib/read.js @@ -0,0 +1,113 @@ + +module.exports = read + +var readline = require('readline') +var Mute = require('mute-stream') + +function read (opts, cb) { + if (opts.num) { + throw new Error('read() no longer accepts a char number limit') + } + + if (typeof opts.default !== 'undefined' && + typeof opts.default !== 'string' && + typeof opts.default !== 'number') { + throw new Error('default value must be string or number') + } + + var input = opts.input || process.stdin + var output = opts.output || process.stdout + var prompt = (opts.prompt || '').trim() + ' ' + var silent = opts.silent + var editDef = false + var timeout = opts.timeout + + var def = opts.default || '' + if (def) { + if (silent) { + prompt += '(

lt>d3ueR)29x+c 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' + s + ''; -} - -var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; -var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); - -colors.mode = 'console'; -assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m'); -assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m'); -assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m'); -assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m'); -assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[27m'); - -assert.ok(s.rainbow); - -aE(s, 'white', 37); -aE(s, 'grey', 90); -aE(s, 'black', 30); -aE(s, 'blue', 34); -aE(s, 'cyan', 36); -aE(s, 'green', 32); -aE(s, 'magenta', 35); -aE(s, 'red', 31); -aE(s, 'yellow', 33); - -assert.equal(s, 'string'); - -colors.setTheme({error:'red'}); - -assert.equal(typeof("astring".red),'string'); -assert.equal(typeof("astring".error),'string'); - diff --git a/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js b/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js deleted file mode 100644 index daad4f9..0000000 --- a/Challenge/seokahi/010.star/node_modules/colors/tests/safe-test.js +++ /dev/null @@ -1,45 +0,0 @@ -var assert = require('assert'), - colors = require('../safe'); - -var s = 'string'; - -function a(s, code) { - return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m'; -} - -function aE(s, color, code) { - assert.equal(colors[color](s), a(s, code)); - assert.equal(colors.strip(s), s); -} - -function h(s, color) { - return '' + s + ''; -} - -var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; -var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); - -colors.mode = 'console'; -assert.equal(colors.bold(s), '\x1B[1m' + s + '\x1B[22m'); -assert.equal(colors.italic(s), '\x1B[3m' + s + '\x1B[23m'); -assert.equal(colors.underline(s), '\x1B[4m' + s + '\x1B[24m'); -assert.equal(colors.strikethrough(s), '\x1B[9m' + s + '\x1B[29m'); -assert.equal(colors.inverse(s), '\x1B[7m' + s + '\x1B[27m'); - -assert.ok(colors.rainbow); - -aE(s, 'white', 37); -aE(s, 'grey', 90); -aE(s, 'black', 30); -aE(s, 'blue', 34); -aE(s, 'cyan', 36); -aE(s, 'green', 32); -aE(s, 'magenta', 35); -aE(s, 'red', 31); -aE(s, 'yellow', 33); - -assert.equal(s, 'string'); -colors.setTheme({error:'red'}); - -assert.equal(typeof(colors.red("astring")), 'string'); -assert.equal(typeof(colors.error("astring")), 'string'); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js b/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js deleted file mode 100644 index 571972c..0000000 --- a/Challenge/seokahi/010.star/node_modules/colors/themes/generic-logging.js +++ /dev/null @@ -1,12 +0,0 @@ -module['exports'] = { - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red' -}; \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/cycle/README.md b/Challenge/seokahi/010.star/node_modules/cycle/README.md deleted file mode 100644 index de9a06d..0000000 --- a/Challenge/seokahi/010.star/node_modules/cycle/README.md +++ /dev/null @@ -1,49 +0,0 @@ -Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`. - -# Contributors - -* Douglas Crockford -* Nuno Job -* Justin Warkentin - -# JSON in JavaScript - -Douglas Crockford -douglas@crockford.com - -2010-11-18 - - -JSON is a light-weight, language independent, data interchange format. -See http://www.JSON.org/ - -The files in this collection implement JSON encoders/decoders in JavaScript. - -JSON became a built-in feature of JavaScript when the ECMAScript Programming -Language Standard - Fifth Edition was adopted by the ECMA General Assembly -in December 2009. Most of the files in this collection are for applications -that are expected to run in obsolete web browsers. For most purposes, json2.js -is the best choice. - - -json2.js: This file creates a JSON property in the global object, if there -isn't already one, setting its value to an object containing a stringify -method and a parse method. The parse method uses the eval method to do the -parsing, guarding it with several regular expressions to defend against -accidental code execution hazards. On current browsers, this file does nothing, -prefering the built-in JSON object. - -json.js: This file does everything that json2.js does. It also adds a -toJSONString method and a parseJSON method to Object.prototype. Use of this -file is not recommended. - -json_parse.js: This file contains an alternative JSON parse function that -uses recursive descent instead of eval. - -json_parse_state.js: This files contains an alternative JSON parse function that -uses a state machine instead of eval. - -cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, -which make it possible to encode cyclical structures and dags in JSON, and to -then recover them. JSONPath is used to represent the links. -http://GOESSNER.net/articles/JsonPath/ diff --git a/Challenge/seokahi/010.star/node_modules/cycle/cycle.js b/Challenge/seokahi/010.star/node_modules/cycle/cycle.js deleted file mode 100644 index 2e776ad..0000000 --- a/Challenge/seokahi/010.star/node_modules/cycle/cycle.js +++ /dev/null @@ -1,170 +0,0 @@ -/* - cycle.js - 2013-02-19 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. -*/ - -/*jslint evil: true, regexp: true */ - -/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, - retrocycle, stringify, test, toString -*/ - -var cycle = exports; - -cycle.decycle = function decycle(object) { - 'use strict'; - -// Make a deep copy of an object or array, assuring that there is at most -// one instance of each object or array in the resulting structure. The -// duplicate references (which might be forming cycles) are replaced with -// an object of the form -// {$ref: PATH} -// where the PATH is a JSONPath string that locates the first occurance. -// So, -// var a = []; -// a[0] = a; -// return JSON.stringify(JSON.decycle(a)); -// produces the string '[{"$ref":"$"}]'. - -// JSONPath is used to locate the unique object. $ indicates the top level of -// the object or array. [NUMBER] or [STRING] indicates a child member or -// property. - - var objects = [], // Keep a reference to each unique object or array - paths = []; // Keep the path to each unique object or array - - return (function derez(value, path) { - -// The derez recurses through the object, producing the deep copy. - - var i, // The loop counter - name, // Property name - nu; // The new object or array - -// typeof null === 'object', so go on if this value is really an object but not -// one of the weird builtin objects. - - if (typeof value === 'object' && value !== null && - !(value instanceof Boolean) && - !(value instanceof Date) && - !(value instanceof Number) && - !(value instanceof RegExp) && - !(value instanceof String)) { - -// If the value is an object or array, look to see if we have already -// encountered it. If so, return a $ref/path object. This is a hard way, -// linear search that will get slower as the number of unique objects grows. - - for (i = 0; i < objects.length; i += 1) { - if (objects[i] === value) { - return {$ref: paths[i]}; - } - } - -// Otherwise, accumulate the unique value and its path. - - objects.push(value); - paths.push(path); - -// If it is an array, replicate the array. - - if (Object.prototype.toString.apply(value) === '[object Array]') { - nu = []; - for (i = 0; i < value.length; i += 1) { - nu[i] = derez(value[i], path + '[' + i + ']'); - } - } else { - -// If it is an object, replicate the object. - - nu = {}; - for (name in value) { - if (Object.prototype.hasOwnProperty.call(value, name)) { - nu[name] = derez(value[name], - path + '[' + JSON.stringify(name) + ']'); - } - } - } - return nu; - } - return value; - }(object, '$')); -}; - - -cycle.retrocycle = function retrocycle($) { - 'use strict'; - -// Restore an object that was reduced by decycle. Members whose values are -// objects of the form -// {$ref: PATH} -// are replaced with references to the value found by the PATH. This will -// restore cycles. The object will be mutated. - -// The eval function is used to locate the values described by a PATH. The -// root object is kept in a $ variable. A regular expression is used to -// assure that the PATH is extremely well formed. The regexp contains nested -// * quantifiers. That has been known to have extremely bad performance -// problems on some browsers for very long strings. A PATH is expected to be -// reasonably short. A PATH is allowed to belong to a very restricted subset of -// Goessner's JSONPath. - -// So, -// var s = '[{"$ref":"$"}]'; -// return JSON.retrocycle(JSON.parse(s)); -// produces an array containing a single element which is the array itself. - - var px = - /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; - - (function rez(value) { - -// The rez function walks recursively through the object looking for $ref -// properties. When it finds one that has a value that is a path, then it -// replaces the $ref object with a reference to the value that is found by -// the path. - - var i, item, name, path; - - if (value && typeof value === 'object') { - if (Object.prototype.toString.apply(value) === '[object Array]') { - for (i = 0; i < value.length; i += 1) { - item = value[i]; - if (item && typeof item === 'object') { - path = item.$ref; - if (typeof path === 'string' && px.test(path)) { - value[i] = eval(path); - } else { - rez(item); - } - } - } - } else { - for (name in value) { - if (typeof value[name] === 'object') { - item = value[name]; - if (item) { - path = item.$ref; - if (typeof path === 'string' && px.test(path)) { - value[name] = eval(path); - } else { - rez(item); - } - } - } - } - } - } - }($)); - return $; -}; diff --git a/Challenge/seokahi/010.star/node_modules/cycle/package.json b/Challenge/seokahi/010.star/node_modules/cycle/package.json deleted file mode 100644 index 6d85022..0000000 --- a/Challenge/seokahi/010.star/node_modules/cycle/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ "name" : "cycle" -, "description" : "decycle your json" -, "author" : "" -, "version" : "1.0.3" -, "main" : "./cycle.js" -, "homepage" : "https://github.com/douglascrockford/JSON-js" -, "repository" : - { "type": "git", "url": "http://github.com/dscape/cycle.git" } -, "bugs" : "http://github.com/douglascrockford/JSON-js/issues" -, "keywords" : [ "json", "cycle", "stringify", "parse" ] -, "engines" : { "node" : ">=0.4.0" } -} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml b/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml deleted file mode 100644 index ed05f88..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -node_js: - - "0.11" - - "0.10" - - "0.8" - - "0.6" diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE b/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE deleted file mode 100644 index a23e08a..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/LICENCE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Raynos. - -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. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/README.md b/Challenge/seokahi/010.star/node_modules/duplexer/README.md deleted file mode 100644 index 1dd3b89..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# duplexer - -[![build status][1]][2] [![dependency status][3]][4] - -[![browser support][5]][6] - -Creates a duplex stream - -Taken from [event-stream][7] - -## duplex (writeStream, readStream) - -Takes a writable stream and a readable stream and makes them appear as a readable writable stream. - -It is assumed that the two streams are connected to each other in some way. - -## Example - -```js -var cp = require('child_process') - , duplex = require('duplexer') - , grep = cp.exec('grep Stream') - -duplex(grep.stdin, grep.stdout) -``` - -## Installation - -`npm install duplexer` - -## Tests - -`npm test` - -## Contributors - - - Dominictarr - - Raynos - - samccone - -## MIT Licenced - - [1]: https://secure.travis-ci.org/Raynos/duplexer.png - [2]: https://travis-ci.org/Raynos/duplexer - [3]: https://david-dm.org/Raynos/duplexer.png - [4]: https://david-dm.org/Raynos/duplexer - [5]: https://ci.testling.com/Raynos/duplexer.png - [6]: https://ci.testling.com/Raynos/duplexer - [7]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/index.js b/Challenge/seokahi/010.star/node_modules/duplexer/index.js deleted file mode 100644 index a188a21..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/index.js +++ /dev/null @@ -1,87 +0,0 @@ -var Stream = require("stream") -var writeMethods = ["write", "end", "destroy"] -var readMethods = ["resume", "pause"] -var readEvents = ["data", "close"] -var slice = Array.prototype.slice - -module.exports = duplex - -function forEach (arr, fn) { - if (arr.forEach) { - return arr.forEach(fn) - } - - for (var i = 0; i < arr.length; i++) { - fn(arr[i], i) - } -} - -function duplex(writer, reader) { - var stream = new Stream() - var ended = false - - forEach(writeMethods, proxyWriter) - - forEach(readMethods, proxyReader) - - forEach(readEvents, proxyStream) - - reader.on("end", handleEnd) - - writer.on("drain", function() { - stream.emit("drain") - }) - - writer.on("error", reemit) - reader.on("error", reemit) - - stream.writable = writer.writable - stream.readable = reader.readable - - return stream - - function proxyWriter(methodName) { - stream[methodName] = method - - function method() { - return writer[methodName].apply(writer, arguments) - } - } - - function proxyReader(methodName) { - stream[methodName] = method - - function method() { - stream.emit(methodName) - var func = reader[methodName] - if (func) { - return func.apply(reader, arguments) - } - reader.emit(methodName) - } - } - - function proxyStream(methodName) { - reader.on(methodName, reemit) - - function reemit() { - var args = slice.call(arguments) - args.unshift(methodName) - stream.emit.apply(stream, args) - } - } - - function handleEnd() { - if (ended) { - return - } - ended = true - var args = slice.call(arguments) - args.unshift("end") - stream.emit.apply(stream, args) - } - - function reemit(err) { - stream.emit("error", err) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/package.json b/Challenge/seokahi/010.star/node_modules/duplexer/package.json deleted file mode 100644 index 015bd41..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "duplexer", - "version": "0.1.2", - "description": "Creates a duplex stream", - "keywords": [], - "author": "Raynos ", - "repository": "git://github.com/Raynos/duplexer.git", - "main": "index", - "homepage": "https://github.com/Raynos/duplexer", - "contributors": [ - { - "name": "Jake Verbaten" - } - ], - "bugs": { - "url": "https://github.com/Raynos/duplexer/issues", - "email": "raynos2@gmail.com" - }, - "devDependencies": { - "tape": "0.3.3", - "through": "~0.1.4" - }, - "license": "MIT", - "scripts": { - "test": "node test" - }, - "testling": { - "files": "test/index.js", - "browsers": [ - "ie/8..latest", - "firefox/16..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest" - ] - } -} diff --git a/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js b/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js deleted file mode 100644 index a154567..0000000 --- a/Challenge/seokahi/010.star/node_modules/duplexer/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -var through = require("through") -var test = require("tape") - -var duplex = require("../index") - -var readable = through() -var writable = through(write) -var written = 0 -var data = 0 - -var stream = duplex(writable, readable) - -function write() { - written++ -} - -stream.on("data", ondata) - -function ondata() { - data++ -} - -test("emit and write", function(t) { - t.plan(2) - - stream.write() - readable.emit("data") - - t.equal(written, 1, "should have written once") - t.equal(data, 1, "should have received once") -}) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml b/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml deleted file mode 100644 index 6e5919d..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - "0.10" diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE b/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE deleted file mode 100644 index 2af26fe..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/LICENCE +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2011 Dominic Tarr - -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/Challenge/seokahi/010.star/node_modules/event-stream/examples/data b/Challenge/seokahi/010.star/node_modules/event-stream/examples/data deleted file mode 100644 index 8c40730..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/examples/data +++ /dev/null @@ -1,3 +0,0 @@ -{"foo": 1} -{"foo": 2} -{"foo": 3, "bar": "test"} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js deleted file mode 100644 index 02eb840..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/examples/map.js +++ /dev/null @@ -1,15 +0,0 @@ -var es = require('..') - -process.stdin - .pipe(es.map(function (data, callback) { - for (var i = 0; i < data.length; i++) { - if (data[i] == 0x61) { - data[i] = 0x41 - } - } - callback(null, data) - })) - .pipe(process.stdout) - -// echo abcdabcd | node map.js -// AbcdAbcd \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js deleted file mode 100644 index 5ec88a4..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/examples/pretty.js +++ /dev/null @@ -1,18 +0,0 @@ - -var inspect = require('util').inspect -var es = require('..') - -es.pipe( //pipe joins streams together - process.openStdin(), //open stdin - es.split(null, null, {trailing: false}), //split stream to break on newlines - es.map(function (data, callback) { //turn this async function into a stream - var obj = JSON.parse(data) //parse input into json - callback(null, inspect(obj) + '\n') //render it nicely - }), - process.stdout // pipe it to stdout ! -) - -// cat data | node pretty.js -// { foo: 1 } -// { foo: 2 } -// { foo: 3, bar: 'test' } \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js b/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js deleted file mode 100644 index e21d579..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/examples/split.js +++ /dev/null @@ -1,12 +0,0 @@ -var es = require('..') - -process.stdin - .pipe(es.split(null, null, {trailing: false})) // ignore trailing empty line - .on('data', function (data) { - console.log('data: ' + data) - }) - -// cat data | node map.js -// data: {"foo": 1} -// data: {"foo": 2} -// data: {"foo": 3, "bar": "test"} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/index.js b/Challenge/seokahi/010.star/node_modules/event-stream/index.js deleted file mode 100644 index adb0468..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/index.js +++ /dev/null @@ -1,351 +0,0 @@ -//filter will reemit the data if cb(err,pass) pass is truthy - -// reduce is more tricky -// maybe we want to group the reductions or emit progress updates occasionally -// the most basic reduce just emits one 'data' event after it has recieved 'end' - -var Stream = require('stream').Stream - , es = exports - , through = require('through') - , from = require('from') - , duplex = require('duplexer') - , map = require('map-stream') - , pause = require('pause-stream') - , split = require('split') - , pipeline = require('stream-combiner') - , immediately = global.setImmediate || process.nextTick; - -es.Stream = Stream //re-export Stream from core -es.through = through -es.from = from -es.duplex = duplex -es.map = map -es.pause = pause -es.split = split -es.pipeline = es.connect = es.pipe = pipeline -// merge / concat -// -// combine multiple streams into a single stream. -// will emit end only once - -es.concat = //actually this should be called concat -es.merge = function (/*streams...*/) { - var toMerge = [].slice.call(arguments) - if (toMerge.length === 1 && (toMerge[0] instanceof Array)) { - toMerge = toMerge[0] //handle array as arguments object - } - var stream = new Stream() - stream.setMaxListeners(0) // allow adding more than 11 streams - var endCount = 0 - stream.writable = stream.readable = true - - if (toMerge.length) { - toMerge.forEach(function (e) { - e.pipe(stream, {end: false}) - var ended = false - e.on('end', function () { - if(ended) return - ended = true - endCount ++ - if(endCount == toMerge.length) - stream.emit('end') - }) - }) - } else { - process.nextTick(function () { - stream.emit('end') - }) - } - - stream.write = function (data) { - this.emit('data', data) - } - stream.destroy = function () { - toMerge.forEach(function (e) { - if(e.destroy) e.destroy() - }) - } - return stream -} - - -// writable stream, collects all events into an array -// and calls back when 'end' occurs -// mainly I'm using this to test the other functions - -es.collect = -es.writeArray = function (done) { - if ('function' !== typeof done) - throw new Error('function writeArray (done): done must be function') - - var a = new Stream () - , array = [], isDone = false - a.write = function (l) { - array.push(l) - } - a.end = function () { - isDone = true - done(null, array) - } - a.writable = true - a.readable = false - a.destroy = function () { - a.writable = a.readable = false - if(isDone) return - done(new Error('destroyed before end'), array) - } - return a -} - -//return a Stream that reads the properties of an object -//respecting pause() and resume() - -es.readArray = function (array) { - var stream = new Stream() - , i = 0 - , paused = false - , ended = false - - stream.readable = true - stream.writable = false - - if(!Array.isArray(array)) - throw new Error('event-stream.read expects an array') - - stream.resume = function () { - if(ended) return - paused = false - var l = array.length - while(i < l && !paused && !ended) { - stream.emit('data', array[i++]) - } - if(i == l && !ended) - ended = true, stream.readable = false, stream.emit('end') - } - process.nextTick(stream.resume) - stream.pause = function () { - paused = true - } - stream.destroy = function () { - ended = true - stream.emit('close') - } - return stream -} - -// -// readable (asyncFunction) -// return a stream that calls an async function while the stream is not paused. -// -// the function must take: (count, callback) {... -// - -es.readable = -function (func, continueOnError) { - var stream = new Stream() - , i = 0 - , paused = false - , ended = false - , reading = false - - stream.readable = true - stream.writable = false - - if('function' !== typeof func) - throw new Error('event-stream.readable expects async function') - - stream.on('end', function () { ended = true }) - - function get (err, data) { - - if(err) { - stream.emit('error', err) - if(!continueOnError) stream.emit('end') - } else if (arguments.length > 1) - stream.emit('data', data) - - immediately(function () { - if(ended || paused || reading) return - try { - reading = true - func.call(stream, i++, function () { - reading = false - get.apply(null, arguments) - }) - } catch (err) { - stream.emit('error', err) - } - }) - } - stream.resume = function () { - paused = false - get() - } - process.nextTick(get) - stream.pause = function () { - paused = true - } - stream.destroy = function () { - stream.emit('end') - stream.emit('close') - ended = true - } - return stream -} - - -// -// map sync -// - -es.mapSync = function (sync) { - return es.through(function write(data) { - var mappedData - try { - mappedData = sync(data) - } catch (err) { - return this.emit('error', err) - } - if (mappedData !== undefined) - this.emit('data', mappedData) - }) -} - -// -// filterSync -// - -es.filterSync = function (test) { - return es.through(function(data){ - var s = this - if (test(data)) { - s.queue(data) - } - }); -} - -// -// flatmapSync -// - -es.flatmapSync = function (mapper) { - return es.through(function(data) { - var s = this - data.forEach(function(e) { - s.queue(mapper(e)) - }) - }) -} - -// -// log just print out what is coming through the stream, for debugging -// - -es.log = function (name) { - return es.through(function (data) { - var args = [].slice.call(arguments) - if(name) console.error(name, data) - else console.error(data) - this.emit('data', data) - }) -} - - -// -// child -- pipe through a child process -// - -es.child = function (child) { - - return es.duplex(child.stdin, child.stdout) - -} - -// -// parse -// -// must be used after es.split() to ensure that each chunk represents a line -// source.pipe(es.split()).pipe(es.parse()) - -es.parse = function (options) { - var emitError = !!(options ? options.error : false) - return es.through(function (data) { - var obj - try { - if(data) //ignore empty lines - obj = JSON.parse(data.toString()) - } catch (err) { - if (emitError) - return this.emit('error', err) - return console.error(err, 'attempting to parse:', data) - } - //ignore lines that where only whitespace. - if(obj !== undefined) - this.emit('data', obj) - }) -} -// -// stringify -// - -es.stringify = function () { - var Buffer = require('buffer').Buffer - return es.mapSync(function (e){ - return JSON.stringify(Buffer.isBuffer(e) ? e.toString() : e) + '\n' - }) -} - -// -// replace a string within a stream. -// -// warn: just concatenates the string and then does str.split().join(). -// probably not optimal. -// for smallish responses, who cares? -// I need this for shadow-npm so it's only relatively small json files. - -es.replace = function (from, to) { - return es.pipeline(es.split(from), es.join(to)) -} - -// -// join chunks with a joiner. just like Array#join -// also accepts a callback that is passed the chunks appended together -// this is still supported for legacy reasons. -// - -es.join = function (str) { - - //legacy api - if('function' === typeof str) - return es.wait(str) - - var first = true - return es.through(function (data) { - if(!first) - this.emit('data', str) - first = false - this.emit('data', data) - return true - }) -} - - -// -// wait. callback when 'end' is emitted, with all chunks appended as string. -// - -es.wait = function (callback) { - var arr = [] - return es.through(function (data) { arr.push(data) }, - function () { - var body = Buffer.isBuffer(arr[0]) ? Buffer.concat(arr) - : arr.join('') - this.emit('data', body) - this.emit('end') - if(callback) callback(null, body) - }) -} - -es.pipeable = function () { - throw new Error('[EVENT-STREAM] es.pipeable is deprecated') -} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/package.json b/Challenge/seokahi/010.star/node_modules/event-stream/package.json deleted file mode 100644 index a2a487d..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "event-stream", - "version": "4.0.1", - "description": "construct pipes of streams of events", - "homepage": "http://github.com/dominictarr/event-stream", - "repository": { - "type": "git", - "url": "git://github.com/dominictarr/event-stream.git" - }, - "dependencies": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - }, - "devDependencies": { - "asynct": "^1.1.0", - "it-is": "^1.0.3", - "stream-spec": "^0.3.6", - "tape": "^4.9.1", - "ubelt": "^3.2.2" - }, - "scripts": { - "prepublish": "npm ls && npm test", - "test": "asynct test/", - "test_tap": "set -e; for t in test/*.js; do node $t; done" - }, - "keywords": [ - "stream", "map", "flatmap", "filter", "split", "join", "merge", "replace" - ], - "license": "MIT", - "author": "Dominic Tarr (http://bit.ly/dominictarr)" -} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown deleted file mode 100644 index 4ce5177..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/readme.markdown +++ /dev/null @@ -1,345 +0,0 @@ -# EventStream - -[Streams](http://nodejs.org/api/stream.html "Stream") are node's best and most misunderstood idea, and EventStream is a toolkit to make creating and working with streams easy. - -Normally, streams are only used for IO, but in event stream we send all kinds of objects down the pipe. If your application's input and output are streams, shouldn't the throughput be a stream too? - -The *EventStream* functions resemble the array functions, because Streams are like Arrays, but laid out in time, rather than in memory. - -All the `event-stream` functions return instances of `Stream`. - -`event-stream` creates [0.8 streams](https://github.com/joyent/node/blob/v0.8/doc/api/stream.markdown), which are compatible with [0.10 streams](http://nodejs.org/api/stream.html "Stream"). - ->NOTE: I shall use the term "through stream" to refer to a stream that is writable and readable. - ->NOTE for Gulp users: Merge will not work for gulp 4. [merge-stream](https://npmjs.com/merge-stream) should be used. - -### [simple example](https://github.com/dominictarr/event-stream/blob/master/examples/pretty.js): - -``` js -//pretty.js - -if(!module.parent) { - var es = require('event-stream') - var inspect = require('util').inspect - - process.stdin //connect streams together with `pipe` - .pipe(es.split()) //split stream to break on newlines - .pipe(es.map(function (data, cb) { //turn this async function into a stream - cb(null - , inspect(JSON.parse(data))) //render it nicely - })) - .pipe(process.stdout) // pipe it to stdout ! -} -``` -run it ... - -``` bash -curl -sS registry.npmjs.org/event-stream | node pretty.js -``` - -[node Stream documentation](http://nodejs.org/api/stream.html) - -## through (write?, end?) - -Re-emits data synchronously. Easy way to create synchronous through streams. -Pass in optional `write` and `end` methods. They will be called in the -context of the stream. Use `this.pause()` and `this.resume()` to manage flow. -Check `this.paused` to see current flow state. (write always returns `!this.paused`) - -this function is the basis for most of the synchronous streams in `event-stream`. - -``` js - -es.through(function write(data) { - this.emit('data', data) - //this.pause() - }, - function end () { //optional - this.emit('end') - }) - -``` - -## map (asyncFunction) - -Create a through stream from an asynchronous function. - -``` js -var es = require('event-stream') - -es.map(function (data, callback) { - //transform data - // ... - callback(null, data) -}) - -``` - -Each map MUST call the callback. It may callback with data, with an error or with no arguments, - - * `callback()` drop this data. - this makes the map work like `filter`, - note:`callback(null,null)` is not the same, and will emit `null` - - * `callback(null, newData)` turn data into newData - - * `callback(error)` emit an error for this item. - ->Note: if a callback is not called, `map` will think that it is still being processed, ->every call must be answered or the stream will not know when to end. -> ->Also, if the callback is called more than once, every call but the first will be ignored. - -## mapSync (syncFunction) - -Same as `map`, but the callback is called synchronously. Based on `es.through` - -## flatmapSync (syncFunction) - -Map elements nested. - -``` js -var es = require('event-stream') - -es.flatmapSync(function (data) { - //transform data - // ... - return data -}) - -``` - -## filterSync (syncFunction) - -Filter elements. - -``` js -var es = require('event-stream') - -es.filterSync(function (data) { - return data > 0 -}) - -``` - -## split (matcher) - -Break up a stream and reassemble it so that each line is a chunk. matcher may be a `String`, or a `RegExp` - -Example, read every line in a file ... - -``` js -fs.createReadStream(file, {flags: 'r'}) - .pipe(es.split()) - .pipe(es.map(function (line, cb) { - //do something with the line - cb(null, line) - })) -``` - -`split` takes the same arguments as `string.split` except it defaults to '\n' instead of ',', and the optional `limit` parameter is ignored. -[String#split](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split) - -**NOTE** - Maintaining Line Breaks -If you want to process each line of the stream, transform the data, reassemble, and **KEEP** the line breaks the example will look like this: - -```javascript -fs.createReadStream(file, {flags: 'r'}) - .pipe(es.split(/(\r?\n)/)) - .pipe(es.map(function (line, cb) { - //do something with the line - cb(null, line) - })) -``` - -This technique is mentioned in the [underlying documentation](https://www.npmjs.com/package/split#keep-matched-splitter) for the split npm package. - -## join (separator) - -Create a through stream that emits `separator` between each chunk, just like Array#join. - -(for legacy reasons, if you pass a callback instead of a string, join is a synonym for `es.wait`) - -## merge (stream1,...,streamN) or merge (streamArray) -> concat → merge - -Merges streams into one and returns it. -Incoming data will be emitted as soon it comes into - no ordering will be applied (for example: `data1 data1 data2 data1 data2` - where `data1` and `data2` is data from two streams). -Counts how many streams were passed to it and emits end only when all streams emitted end. - -```js -es.merge( - process.stdout, - process.stderr -).pipe(fs.createWriteStream('output.log')); -``` - -It can also take an Array of streams as input like this: -```js -es.merge([ - fs.createReadStream('input1.txt'), - fs.createReadStream('input2.txt') -]).pipe(fs.createWriteStream('output.log')); -``` - -## replace (from, to) - -Replace all occurrences of `from` with `to`. `from` may be a `String` or a `RegExp`. -Works just like `string.split(from).join(to)`, but streaming. - - -## parse - -Convenience function for parsing JSON chunks. For newline separated JSON, -use with `es.split`. By default it logs parsing errors by `console.error`; -for another behaviour, transforms created by `es.parse({error: true})` will -emit error events for exceptions thrown from `JSON.parse`, unmodified. - -``` js -fs.createReadStream(filename) - .pipe(es.split()) //defaults to lines. - .pipe(es.parse()) -``` - -## stringify - -convert javascript objects into lines of text. The text will have whitespace escaped and have a `\n` appended, so it will be compatible with `es.parse` - -``` js -objectStream - .pipe(es.stringify()) - .pipe(fs.createWriteStream(filename)) -``` - -## readable (asyncFunction) - -create a readable stream (that respects pause) from an async function. -while the stream is not paused, -the function will be polled with `(count, callback)`, -and `this` will be the readable stream. - -``` js - -es.readable(function (count, callback) { - if(streamHasEnded) - return this.emit('end') - - //... - - this.emit('data', data) //use this way to emit multiple chunks per call. - - callback() // you MUST always call the callback eventually. - // the function will not be called again until you do this. -}) -``` -you can also pass the data and the error to the callback. -you may only call the callback once. -calling the same callback more than once will have no effect. - -## readArray (array) - -Create a readable stream from an Array. - -Just emit each item as a data event, respecting `pause` and `resume`. - -``` js - var es = require('event-stream') - , reader = es.readArray([1,2,3]) - - reader.pipe(...) -``` - -If you want the stream behave like a 0.10 stream you will need to wrap it using [`Readable.wrap()`](http://nodejs.org/api/stream.html#stream_readable_wrap_stream) function. Example: - -``` js - var s = new stream.Readable({objectMode: true}).wrap(es.readArray([1,2,3])); -``` - -## writeArray (callback) - -create a writeable stream from a callback, -all `data` events are stored in an array, which is passed to the callback when the stream ends. - -``` js - var es = require('event-stream') - , reader = es.readArray([1, 2, 3]) - , writer = es.writeArray(function (err, array){ - //array deepEqual [1, 2, 3] - }) - - reader.pipe(writer) -``` - -## pause () - -A stream that buffers all chunks when paused. - - -``` js - var ps = es.pause() - ps.pause() //buffer the stream, also do not allow 'end' - ps.resume() //allow chunks through -``` - -## duplex (writeStream, readStream) - -Takes a writable stream and a readable stream and makes them appear as a readable writable stream. - -It is assumed that the two streams are connected to each other in some way. - -(This is used by `pipeline` and `child`.) - -``` js - var grep = cp.exec('grep Stream') - - es.duplex(grep.stdin, grep.stdout) -``` - -## child (child_process) - -Create a through stream from a child process ... - -``` js - var cp = require('child_process') - - es.child(cp.exec('grep Stream')) // a through stream - -``` - -## wait (callback) - -waits for stream to emit 'end'. -joins chunks of a stream into a single string or buffer. -takes an optional callback, which will be passed the -complete string/buffer when it receives the 'end' event. - -also, emits a single 'data' event. - -``` js - -readStream.pipe(es.wait(function (err, body) { - // have complete text here. -})) - -``` - -# Other Stream Modules - -These modules are not included as a part of *EventStream* but may be -useful when working with streams. - -## [reduce (syncFunction, initial)](https://github.com/parshap/node-stream-reduce) - -Like `Array.prototype.reduce` but for streams. Given a sync reduce -function and an initial value it will return a through stream that emits -a single data event with the reduced value once the input stream ends. - -``` js -var reduce = require("stream-reduce"); -process.stdin.pipe(reduce(function(acc, data) { - return acc + data.length; -}, 0)).on("data", function(length) { - console.log("stdin size:", length); -}); -``` diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js deleted file mode 100644 index e6a442b..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/connect.asynct.js +++ /dev/null @@ -1,86 +0,0 @@ -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - -function makeExamplePipe() { - - return es.connect( - es.map(function (data, callback) { - callback(null, data * 2) - }), - es.map(function (data, callback) { - d.delay(callback)(null, data) - }), - es.map(function (data, callback) { - callback(null, data + 2) - })) -} - -exports['simple pipe'] = function (test) { - - var pipe = makeExamplePipe() - - pipe.on('data', function (data) { - it(data).equal(18) - test.done() - }) - - pipe.write(8) - -} - -exports['read array then map'] = function (test) { - - var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 - , first = es.readArray(readThis) - , read = [] - , pipe = - es.connect( - first, - es.map(function (data, callback) { - callback(null, {data: data}) - }), - es.map(function (data, callback) { - callback(null, {data: data}) - }), - es.writeArray(function (err, array) { - it(array).deepEqual(d.map(readThis, function (data) { - return {data: {data: data}} - })) - test.done() - }) - ) -} - -exports ['connect returns a stream'] = function (test) { - - var rw = - es.connect( - es.map(function (data, callback) { - callback(null, data * 2) - }), - es.map(function (data, callback) { - callback(null, data * 5) - }) - ) - - it(rw).has({readable: true, writable: true}) - - var array = [190, 24, 6, 7, 40, 57, 4, 6] - , _array = [] - , c = - es.connect( - es.readArray(array), - rw, - es.log('after rw:'), - es.writeArray(function (err, _array) { - it(_array).deepEqual(array.map(function (e) { return e * 10 })) - test.done() - }) - ) - -} - - -require('./helper')(module) - diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js deleted file mode 100644 index 1d2e4f9..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/filter.asynct.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -var es = require('../') - , it = require('it-is') - -exports ['filter'] = function (test) { - es.readArray([1, 2, 3, 4]) - .pipe(es.filterSync(function(e) { - return e > 2 - })) - .pipe(es.writeArray(function(error, array) { - test.deepEqual([3, 4], array) - test.end() - })) -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js deleted file mode 100644 index ae6a9a0..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/flatmap.asynct.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -var es = require('../') - , it = require('it-is') - -exports ['flatmap'] = function (test) { - es.readArray([[1], [1, 2], [1, 2, 3]]) - .pipe(es.flatmapSync(function(e) { - return e + 1 - })) - .pipe(es.writeArray(function(error, array) { - test.deepEqual([2, 2, 3, 2, 3, 4], array) - test.end() - })) -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js deleted file mode 100644 index 96abaeb..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/helper/index.js +++ /dev/null @@ -1,12 +0,0 @@ -var tape = require('tape') - -module.exports = function (m) { - if(m.parent) return - for(var name in m.exports) { - tape(name, function (t) { - console.log('start', name) - t.done = t.end - m.exports[name](t) - }) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js deleted file mode 100644 index 68f38ba..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/merge.asynct.js +++ /dev/null @@ -1,29 +0,0 @@ -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - -exports.merge = function (t) { - var odd = d.map(1, 3, 100, d.id) //array of multiples of 3 < 100 - var even = d.map(2, 4, 100, d.id) //array of multiples of 3 < 100 - - var r1 = es.readArray(even) - var r2 = es.readArray(odd) - var endCount = 0 - - var writer = es.writeArray(function (err, array){ - if(err) throw err //unpossible - it(array.sort()).deepEqual(even.concat(odd).sort()) - if (++endCount === 2) t.done() - }) - - var writer2 = es.writeArray(function (err, array){ - if(err) throw err //unpossible - it(array.sort()).deepEqual(even.concat(odd).sort()) - if (++endCount === 2) t.done() - }) - - es.merge(r1, r2).pipe(writer) - es.merge([r1, r2]).pipe(writer2) - -} -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js deleted file mode 100644 index a5fefcf..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/parse.asynct.js +++ /dev/null @@ -1,32 +0,0 @@ -var es = require('../') - , it = require('it-is').style('colour') - -exports ['es.parse() writes parsing errors with console.error'] = function (test) { - var parseStream = es.parse() - var oldConsoleError = console.error - console.error = function () { - console.error = oldConsoleError - it(arguments.length > 0).ok() - test.done() - } - - // bare word is not valid JSON - parseStream.write('A') -} - -exports ['es.parse({error: true(thy)}) emits error events from parsing'] = function (test) { - var parseStream = es.parse({error: 1}) - var expectedError - try { - JSON.parse('A') - } catch(e) { - expectedError = e - } - - parseStream.on('error', function (e) { - it(e).deepEqual(expectedError) - process.nextTick(function () { - test.done() - }) - }).write('A') -} diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js deleted file mode 100644 index b073604..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/pause.asynct.js +++ /dev/null @@ -1,39 +0,0 @@ - -var es = require('../') - , it = require('it-is') - , d = require('ubelt') - -exports ['gate buffers when shut'] = function (test) { - - var hundy = d.map(1,100, d.id) - , gate = es.pause() - , ten = 10 - es.connect( - es.readArray(hundy), - es.log('after readArray'), - gate, - //es.log('after gate'), - es.map(function (num, next) { - //stick a map in here to check that gate never emits when open - it(gate.paused).equal(false) - console.log('data', num) - if(!--ten) { - console.log('PAUSE') - gate.pause()//.resume() - d.delay(gate.resume.bind(gate), 10)() - ten = 10 - } - - next(null, num) - }), - es.writeArray(function (err, array) { //just realized that I should remove the error param. errors will be emitted - console.log('eonuhoenuoecbulc') - it(array).deepEqual(hundy) - test.done() - }) - ) - - gate.resume() - -} -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js deleted file mode 100644 index f07c6fa..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/pipeline.asynct.js +++ /dev/null @@ -1,52 +0,0 @@ -var es = require('..') - -exports['do not duplicate errors'] = function (test) { - - var errors = 0; - var pipe = es.pipeline( - es.through(function(data) { - return this.emit('data', data); - }), - es.through(function(data) { - return this.emit('error', new Error(data)); - }) - ) - - pipe.on('error', function(err) { - errors++ - console.log('error count', errors) - process.nextTick(function () { - return test.done(); - }) - }) - - return pipe.write('meh'); - -} - -exports['3 pipe do not duplicate errors'] = function (test) { - - var errors = 0; - var pipe = es.pipeline( - es.through(function(data) { - return this.emit('data', data); - }), - es.through(function(data) { - return this.emit('error', new Error(data)); - }), - es.through() - ) - - pipe.on('error', function(err) { - errors++ - console.log('error count', errors) - process.nextTick(function () { - return test.done(); - }) - }) - - return pipe.write('meh'); - -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js deleted file mode 100644 index 3eeb90a..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/readArray.asynct.js +++ /dev/null @@ -1,89 +0,0 @@ - -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - -function readStream(stream, pauseAt, done) { - if(!done) done = pauseAt, pauseAt = -1 - var array = [] - stream.on('data', function (data) { - array.push(data) - if(!--pauseAt ) - stream.pause(), done(null, array) - }) - stream.on('error', done) - stream.on('end', function (data) { - done(null, array) - }) - -} - -exports ['read an array'] = function (test) { - - var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 - - var reader = es.readArray(readThis) - - var writer = es.writeArray(function (err, array){ - if(err) throw err //unpossible - it(array).deepEqual(readThis) - test.done() - }) - - reader.pipe(writer) -} - -exports ['read an array and pause it.'] = function (test) { - - var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 - - var reader = es.readArray(readThis) - - readStream(reader, 10, function (err, data) { - if(err) throw err - it(data).deepEqual([3, 6, 9, 12, 15, 18, 21, 24, 27, 30]) - readStream(reader, 10, function (err, data) { - it(data).deepEqual([33, 36, 39, 42, 45, 48, 51, 54, 57, 60]) - test.done() - }) - reader.resume() - }) - -} - -exports ['reader is readable, but not writeable'] = function (test) { - var reader = es.readArray([1]) - it(reader).has({ - readable: true, - writable: false - }) - - test.done() -} - - -exports ['read one item per tick'] = function (test) { - var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 - var drains = 0 - var reader = es.readArray(readThis) - var tickMapper = es.map(function (data,callback) { - process.nextTick(function () { - callback(null, data) - }) - //since tickMapper is returning false - //pipe should pause the writer until a drain occurs - return false - }) - reader.pipe(tickMapper) - readStream(tickMapper, function (err, array) { - it(array).deepEqual(readThis) - it(array.length).deepEqual(readThis.length) - it(drains).equal(readThis.length) - test.done() - }) - tickMapper.on('drain', function () { - drains ++ - }) - -} -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js deleted file mode 100644 index 6ea2fdb..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/readable.asynct.js +++ /dev/null @@ -1,197 +0,0 @@ - -var es = require('../') - , it = require('it-is').style('colour') - , u = require('ubelt') - -exports ['read an array'] = function (test) { - - - console.log('readable') - return test.end() - var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 - - console.log('readable') - - var reader = - es.readable(function (i, callback) { - if(i >= readThis.length) - return this.emit('end') - console.log('readable') - callback(null, readThis[i]) - }) - - var writer = es.writeArray(function (err, array){ - if(err) throw err - it(array).deepEqual(readThis) - test.done() - }) - - reader.pipe(writer) -} - -exports ['read an array - async'] = function (test) { - - var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 - - var reader = - es.readable(function (i, callback) { - if(i >= readThis.length) - return this.emit('end') - u.delay(callback)(null, readThis[i]) - }) - - var writer = es.writeArray(function (err, array){ - if(err) throw err - it(array).deepEqual(readThis) - test.done() - }) - - reader.pipe(writer) -} - - -exports ['emit data then call next() also works'] = function (test) { - - var readThis = u.map(3, 6, 100, u.id) //array of multiples of 3 < 100 - - var reader = - es.readable(function (i, next) { - if(i >= readThis.length) - return this.emit('end') - this.emit('data', readThis[i]) - next() - }) - - var writer = es.writeArray(function (err, array){ - if(err) throw err - it(array).deepEqual(readThis) - test.done() - }) - - reader.pipe(writer) -} - - -exports ['callback emits error, then stops'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , called = 0 - - var reader = - es.readable(function (i, callback) { - if(called++) - return - callback(err) - }) - - reader.on('error', function (_err){ - it(_err).deepEqual(err) - u.delay(function() { - it(called).equal(1) - test.done() - }, 50)() - }) -} - -exports['readable does not call read concurrently'] = function (test) { - - var current = 0 - var source = es.readable(function(count, cb){ - current ++ - if(count > 100) - return this.emit('end') - u.delay(function(){ - current -- - it(current).equal(0) - cb(null, {ok: true, n: count}); - })(); - }); - - var destination = es.map(function(data, cb){ - //console.info(data); - cb(); - }); - - var all = es.connect(source, destination); - - destination.on('end', test.done) -} - -exports ['does not raise a warning: Recursive process.nextTick detected'] = function (test) { - var readThisDelayed; - - u.delay(function () { - readThisDelayed = [1, 3, 5]; - })(); - - es.readable(function (count, callback) { - - if (readThisDelayed) { - var that = this; - readThisDelayed.forEach(function (item) { - that.emit('data', item); - }); - - this.emit('end'); - test.done(); - } - - callback(); - }); -}; - -// -// emitting multiple errors is not supported by stream. -// -// I do not think that this is a good idea, at least, there should be an option to pipe to -// continue on error. it makes alot ef sense, if you are using Stream like I am, to be able to emit multiple errors. -// an error might not necessarily mean the end of the stream. it depends on the error, at least. -// -// I will start a thread on the mailing list. I'd rather that than use a custom `pipe` implementation. -// -// basically, I want to be able use pipe to transform objects, and if one object is invalid, -// the next might still be good, so I should get to choose if it's gonna stop. -// re-enstate this test when this issue progresses. -// -// hmm. I could add this to es.connect by deregistering the error listener, -// but I would rather it be an option in core. - -/* -exports ['emit multiple errors, with 2nd parameter (continueOnError)'] = function (test) { - - var readThis = d.map(1, 100, d.id) - , errors = 0 - var reader = - es.readable(function (i, callback) { - console.log(i, readThis.length) - if(i >= readThis.length) - return this.emit('end') - if(!(readThis[i] % 7)) - return callback(readThis[i]) - callback(null, readThis[i]) - }, true) - - var writer = es.writeArray(function (err, array) { - if(err) throw err - it(array).every(function (u){ - it(u % 7).notEqual(0) - }).property('length', 80) - it(errors).equal(14) - test.done() - }) - - reader.on('error', function (u) { - errors ++ - console.log(u) - if('number' !== typeof u) - throw u - - it(u % 7).equal(0) - - }) - - reader.pipe(writer) -} -*/ - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js deleted file mode 100644 index 1c8735b..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/replace.asynct.js +++ /dev/null @@ -1,76 +0,0 @@ -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - , spec = require('stream-spec') - -var next = process.nextTick - -var fizzbuzz = '12F4BF78FB11F1314FB1617F19BF2223FB26F2829FB3132F34BF3738FB41F4344FB4647F49BF5253FB56F5859FB6162F64BF6768FB71F7374FB7677F79BF8283FB86F8889FB9192F94BF9798FB' - , fizz7buzz = '12F4BFseven8FB11F1314FB161sevenF19BF2223FB26F2829FB3132F34BF3seven38FB41F4344FB464sevenF49BF5253FB56F5859FB6162F64BF6seven68FBseven1Fseven3seven4FBseven6sevensevenFseven9BF8283FB86F8889FB9192F94BF9seven98FB' - , fizzbuzzwhitespce = ' 12F4BF78FB11F1314FB1617F19BF2223FB26F2829FB3132F34BF3738FB41F4344FB4647F49BF5253FB56F5859FB6162F64BF6768FB71F7374FB7677F79BF8283FB86F8889FB9192F94BF9798FB ' - -exports ['fizz buzz'] = function (test) { - - var readThis = d.map(1, 100, function (i) { - return ( - ! (i % 3 || i % 5) ? "FB" : - !(i % 3) ? "F" : - !(i % 5) ? "B" : - ''+i - ) - }) //array of multiples of 3 < 100 - - var reader = es.readArray(readThis) - var join = es.wait(function (err, string){ - it(string).equal(fizzbuzz) - test.done() - }) - reader.pipe(join) - -} - - -exports ['fizz buzz replace'] = function (test) { - var split = es.split(/(1)/) - var replace = es.replace('7', 'seven') -// var x = spec(replace).through() - split - .pipe(replace) - .pipe(es.join(function (err, string) { - it(string).equal(fizz7buzz) - })) - - replace.on('close', function () { -// x.validate() - test.done() - }) - - split.write(fizzbuzz) - split.end() - -} - - -exports ['fizz buzz replace whitespace using regexp'] = function (test) { - var split = es.split(/(1)/) - var replaceLeading = es.replace(/^[\s]*/, '') - var replaceTrailing = es.replace(/[\s]*$/, '') -// var x = spec(replace).through() - split - .pipe(replaceLeading) - .pipe(replaceTrailing) - .pipe(es.join(function (err, string) { - it(string).equal(fizzbuzz) - })) - - replaceTrailing.on('close', function () { -// x.validate() - test.done() - }) - - split.write(fizzbuzz) - split.end() - -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js deleted file mode 100644 index 25121f9..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/simple-map.asynct.js +++ /dev/null @@ -1,343 +0,0 @@ -'use strict'; - -var es = require('../') - , it = require('it-is') - , u = require('ubelt') - , spec = require('stream-spec') - , Stream = require('stream') - , from = require('from') - , through = require('through') - -//REFACTOR THIS TEST TO USE es.readArray and es.writeArray - -function writeArray(array, stream) { - - array.forEach( function (j) { - stream.write(j) - }) - stream.end() - -} - -function readStream(stream, done) { - - var array = [] - stream.on('data', function (data) { - array.push(data) - }) - stream.on('error', done) - stream.on('end', function (data) { - done(null, array) - }) - -} - -//call sink on each write, -//and complete when finished. - -function pauseStream (prob, delay) { - var pauseIf = ( - 'number' == typeof prob - ? function () { - return Math.random() < prob - } - : 'function' == typeof prob - ? prob - : 0.1 - ) - var delayer = ( - !delay - ? process.nextTick - : 'number' == typeof delay - ? function (next) { setTimeout(next, delay) } - : delay - ) - - return es.through(function (data) { - if(!this.paused && pauseIf()) { - console.log('PAUSE STREAM PAUSING') - this.pause() - var self = this - delayer(function () { - console.log('PAUSE STREAM RESUMING') - self.resume() - }) - } - console.log("emit ('data', " + data + ')') - this.emit('data', data) - }) -} - -exports ['simple map'] = function (test) { - - var input = u.map(1, 1000, function () { - return Math.random() - }) - var expected = input.map(function (v) { - return v * 2 - }) - - var pause = pauseStream(0.1) - var fs = from(input) - var ts = es.writeArray(function (err, ar) { - it(ar).deepEqual(expected) - test.done() - }) - var map = es.through(function (data) { - this.emit('data', data * 2) - }) - - spec(map).through().validateOnExit() - spec(pause).through().validateOnExit() - - fs.pipe(map).pipe(pause).pipe(ts) -} - -exports ['simple map applied to a stream'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - //create event stream from - - var doubler = es.map(function (data, cb) { - cb(null, data * 2) - }) - - spec(doubler).through().validateOnExit() - - //a map is only a middle man, so it is both readable and writable - - it(doubler).has({ - readable: true, - writable: true, - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.map(function (j) { - return j * 2 - })) -// process.nextTick(x.validate) - test.done() - }) - - writeArray(input, doubler) - -} - -exports['pipe two maps together'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - //create event stream from - function dd (data, cb) { - cb(null, data * 2) - } - var doubler1 = es.map(dd), doubler2 = es.map(dd) - - doubler1.pipe(doubler2) - - spec(doubler1).through().validateOnExit() - spec(doubler2).through().validateOnExit() - - readStream(doubler2, function (err, output) { - it(output).deepEqual(input.map(function (j) { - return j * 4 - })) - test.done() - }) - - writeArray(input, doubler1) - -} - -//next: -// -// test pause, resume and drian. -// - -// then make a pipe joiner: -// -// plumber (evStr1, evStr2, evStr3, evStr4, evStr5) -// -// will return a single stream that write goes to the first - -exports ['map will not call end until the callback'] = function (test) { - - var ticker = es.map(function (data, cb) { - process.nextTick(function () { - cb(null, data * 2) - }) - }) - - spec(ticker).through().validateOnExit() - - ticker.write('x') - ticker.end() - - ticker.on('end', function () { - test.done() - }) -} - - -exports ['emit error thrown'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , mapper = - es.map(function () { - throw err - }) - - mapper.on('error', function (_err) { - it(_err).equal(err) - test.done() - }) - -// onExit(spec(mapper).basic().validate) -//need spec that says stream may error. - - mapper.write('hello') - -} - -exports ['emit error calledback'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , mapper = - es.map(function (data, callback) { - callback(err) - }) - - mapper.on('error', function (_err) { - it(_err).equal(err) - test.done() - }) - - mapper.write('hello') - -} - -exports ['do not emit drain if not paused'] = function (test) { - - var map = es.map(function (data, callback) { - u.delay(callback)(null, 1) - return true - }) - - spec(map).through().pausable().validateOnExit() - - map.on('drain', function () { - it(false).ok('should not emit drain unless the stream is paused') - }) - - it(map.write('hello')).equal(true) - it(map.write('hello')).equal(true) - it(map.write('hello')).equal(true) - setTimeout(function () {map.end()},10) - map.on('end', test.done) -} - -exports ['emits drain if paused, when all '] = function (test) { - var active = 0 - var drained = false - var map = es.map(function (data, callback) { - active ++ - u.delay(function () { - active -- - callback(null, 1) - })() - console.log('WRITE', false) - return false - }) - - spec(map).through().validateOnExit() - - map.on('drain', function () { - drained = true - it(active).equal(0, 'should emit drain when all maps are done') - }) - - it(map.write('hello')).equal(false) - it(map.write('hello')).equal(false) - it(map.write('hello')).equal(false) - - process.nextTick(function () {map.end()},10) - - map.on('end', function () { - console.log('end') - it(drained).ok('shoud have emitted drain before end') - test.done() - }) - -} - -exports ['map applied to a stream with filtering'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - - var doubler = es.map(function (data, callback) { - if (data % 2) - callback(null, data * 2) - else - callback() - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.filter(function (j) { - return j % 2 - }).map(function (j) { - return j * 2 - })) - test.done() - }) - - spec(doubler).through().validateOnExit() - - writeArray(input, doubler) - -} - -exports ['simple mapSync applied to a stream'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - - var doubler = es.mapSync(function (data) { - return data * 2 - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.map(function (j) { - return j * 2 - })) - test.done() - }) - - spec(doubler).through().validateOnExit() - - writeArray(input, doubler) - -} - -exports ['mapSync applied to a stream with filtering'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - - var doubler = es.mapSync(function (data) { - if (data % 2) - return data * 2 - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.filter(function (j) { - return j % 2 - }).map(function (j) { - return j * 2 - })) - test.done() - }) - - spec(doubler).through().validateOnExit() - - writeArray(input, doubler) - -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js deleted file mode 100644 index 6d5fb6b..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/spec.asynct.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - assert that data is called many times - assert that end is called eventually - - assert that when stream enters pause state, - on drain is emitted eventually. -*/ - -var es = require('..') -var it = require('it-is').style('colour') -var spec = require('stream-spec') - -exports['simple stream'] = function (test) { - - var stream = es.through() - var x = spec(stream).basic().pausable() - - stream.write(1) - stream.write(1) - stream.pause() - stream.write(1) - stream.resume() - stream.write(1) - stream.end(2) //this will call write() - - process.nextTick(function (){ - x.validate() - test.done() - }) -} - -exports['throw on write when !writable'] = function (test) { - - var stream = es.through() - var x = spec(stream).basic().pausable() - - stream.write(1) - stream.write(1) - stream.end(2) //this will call write() - stream.write(1) //this will be throwing..., but the spec will catch it. - - process.nextTick(function () { - x.validate() - test.done() - }) - -} - -exports['end fast'] = function (test) { - - var stream = es.through() - var x = spec(stream).basic().pausable() - - stream.end() //this will call write() - - process.nextTick(function () { - x.validate() - test.done() - }) - -} - - -/* - okay, that was easy enough, whats next? - - say, after you call paused(), write should return false - until resume is called. - - simple way to implement this: - write must return !paused - after pause() paused = true - after resume() paused = false - - on resume, if !paused drain is emitted again. - after drain, !paused - - there are lots of subtle ordering bugs in streams. - - example, set !paused before emitting drain. - - the stream api is stateful. -*/ - - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js deleted file mode 100644 index 7d44bac..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/split.asynct.js +++ /dev/null @@ -1,47 +0,0 @@ -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - , join = require('path').join - , fs = require('fs') - , Stream = require('stream').Stream - , spec = require('stream-spec') - -exports ['es.split() works like String#split'] = function (test) { - var readme = join(__filename) - , expected = fs.readFileSync(readme, 'utf-8').split('\n') - , cs = es.split() - , actual = [] - , ended = false - , x = spec(cs).through() - - var a = new Stream () - - a.write = function (l) { - actual.push(l.trim()) - } - a.end = function () { - - ended = true - expected.forEach(function (v,k) { - //String.split will append an empty string '' - //if the string ends in a split pattern. - //es.split doesn't which was breaking this test. - //clearly, appending the empty string is correct. - //tests are passing though. which is the current job. - if(v) - it(actual[k]).like(v) - }) - //give the stream time to close - process.nextTick(function () { - test.done() - x.validate() - }) - } - a.writable = true - - fs.createReadStream(readme, {flags: 'r'}).pipe(cs) - cs.pipe(a) - -} - -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js deleted file mode 100644 index d158185..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/stringify.js +++ /dev/null @@ -1,15 +0,0 @@ - - - -var es = require('../') - -exports['handle buffer'] = function (t) { - - - es.stringify().on('data', function (d) { - t.equal(d.trim(), JSON.stringify('HELLO')) - t.end() - }).write(new Buffer('HELLO')) - -} -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js b/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js deleted file mode 100644 index 5d705de..0000000 --- a/Challenge/seokahi/010.star/node_modules/event-stream/test/writeArray.asynct.js +++ /dev/null @@ -1,31 +0,0 @@ - -var es = require('../') - , it = require('it-is').style('colour') - , d = require('ubelt') - -exports ['write an array'] = function (test) { - - var readThis = d.map(3, 6, 100, d.id) //array of multiples of 3 < 100 - - var writer = es.writeArray(function (err, array){ - if(err) throw err //unpossible - it(array).deepEqual(readThis) - test.done() - }) - - d.each(readThis, writer.write.bind(writer)) - writer.end() - -} - - -exports ['writer is writable, but not readable'] = function (test) { - var reader = es.writeArray(function () {}) - it(reader).has({ - readable: false, - writable: true - }) - - test.done() -} -require('./helper')(module) diff --git a/Challenge/seokahi/010.star/node_modules/eyes/LICENSE b/Challenge/seokahi/010.star/node_modules/eyes/LICENSE deleted file mode 100644 index a1edd93..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2009 cloudhead - -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/Challenge/seokahi/010.star/node_modules/eyes/Makefile b/Challenge/seokahi/010.star/node_modules/eyes/Makefile deleted file mode 100644 index a121dea..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -test: - @@node test/eyes-test.js - -.PHONY: test diff --git a/Challenge/seokahi/010.star/node_modules/eyes/README.md b/Challenge/seokahi/010.star/node_modules/eyes/README.md deleted file mode 100644 index c4f6f76..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/README.md +++ /dev/null @@ -1,73 +0,0 @@ -eyes -==== - -a customizable value inspector for Node.js - -synopsis --------- - -I was tired of looking at cluttered output in the console -- something needed to be done, -`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. -So I decided to have some fun. _eyes_ were born. - -![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif) - -_example of the output of a user-customized eyes.js inspector_ - -*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals. - -usage ------ - - var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); - - inspect(something); // inspect with the settings passed to `inspector` - -or - - var eyes = require('eyes'); - - eyes.inspect(something); // inspect with the default settings - -you can pass a _label_ to `inspect()`, to keep track of your inspections: - - eyes.inspect(something, "a random value"); - -If you want to return the output of eyes without printing it, you can set it up this way: - - var inspect = require('eyes').inspector({ stream: null }); - - sys.puts(inspect({ something: 42 })); - -customization -------------- - -These are the default styles and settings used by _eyes_. - - styles: { // Styles applied to stdout - all: 'cyan', // Overall style applied to everything - label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` - other: 'inverted', // Objects which don't have a literal representation, such as functions - key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` - special: 'grey', // null, undefined... - string: 'green', - number: 'magenta', - bool: 'blue', // true false - regexp: 'green', // /\d+/ - }, - - pretty: true, // Indent object literals - hideFunctions: false, // Don't output functions at all - stream: process.stdout, // Stream to write to, or null - maxLength: 2048 // Truncate output if longer - -You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`. - - var inspect = require('eyes').inspector({ - styles: { - all: 'magenta', - special: 'bold' - }, - maxLength: 512 - }); - diff --git a/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js b/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js deleted file mode 100644 index 10d964b..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/lib/eyes.js +++ /dev/null @@ -1,236 +0,0 @@ -// -// Eyes.js - a customizable value inspector for Node.js -// -// usage: -// -// var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); -// inspect(something); // inspect with the settings passed to `inspector` -// -// or -// -// var eyes = require('eyes'); -// eyes.inspect(something); // inspect with the default settings -// -var eyes = exports, - stack = []; - -eyes.defaults = { - styles: { // Styles applied to stdout - all: 'cyan', // Overall style applied to everything - label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` - other: 'inverted', // Objects which don't have a literal representation, such as functions - key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` - special: 'grey', // null, undefined... - string: 'green', - number: 'magenta', - bool: 'blue', // true false - regexp: 'green', // /\d+/ - }, - pretty: true, // Indent object literals - hideFunctions: false, - showHidden: false, - stream: process.stdout, - maxLength: 2048 // Truncate output if longer -}; - -// Return a curried inspect() function, with the `options` argument filled in. -eyes.inspector = function (options) { - var that = this; - return function (obj, label, opts) { - return that.inspect.call(that, obj, label, - merge(options || {}, opts || {})); - }; -}; - -// If we have a `stream` defined, use it to print a styled string, -// if not, we just return the stringified object. -eyes.inspect = function (obj, label, options) { - options = merge(this.defaults, options || {}); - - if (options.stream) { - return this.print(stringify(obj, options), label, options); - } else { - return stringify(obj, options) + (options.styles ? '\033[39m' : ''); - } -}; - -// Output using the 'stream', and an optional label -// Loop through `str`, and truncate it after `options.maxLength` has been reached. -// Because escape sequences are, at this point embeded within -// the output string, we can't measure the length of the string -// in a useful way, without separating what is an escape sequence, -// versus a printable character (`c`). So we resort to counting the -// length manually. -eyes.print = function (str, label, options) { - for (var c = 0, i = 0; i < str.length; i++) { - if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5 - else if (c === options.maxLength) { - str = str.slice(0, i - 1) + '…'; - break; - } else { c++ } - } - return options.stream.write.call(options.stream, (label ? - this.stylize(label, options.styles.label, options.styles) + ': ' : '') + - this.stylize(str, options.styles.all, options.styles) + '\033[0m' + "\n"); -}; - -// Apply a style to a string, eventually, -// I'd like this to support passing multiple -// styles. -eyes.stylize = function (str, style, styles) { - var codes = { - 'bold' : [1, 22], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'cyan' : [36, 39], - 'magenta' : [35, 39], - 'blue' : [34, 39], - 'yellow' : [33, 39], - 'green' : [32, 39], - 'red' : [31, 39], - 'grey' : [90, 39] - }, endCode; - - if (style && codes[style]) { - endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0] - : codes[style][1]; - return '\033[' + codes[style][0] + 'm' + str + - '\033[' + endCode + 'm'; - } else { return str } -}; - -// Convert any object to a string, ready for output. -// When an 'array' or an 'object' are encountered, they are -// passed to specialized functions, which can then recursively call -// stringify(). -function stringify(obj, options) { - var that = this, stylize = function (str, style) { - return eyes.stylize(str, options.styles[style], options.styles) - }, index, result; - - if ((index = stack.indexOf(obj)) !== -1) { - return stylize(new(Array)(stack.length - index + 1).join('.'), 'special'); - } - stack.push(obj); - - result = (function (obj) { - switch (typeOf(obj)) { - case "string" : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'" - : '"' + obj + '"'); - return stylize(obj, 'string'); - case "regexp" : return stylize('/' + obj.source + '/', 'regexp'); - case "number" : return stylize(obj + '', 'number'); - case "function" : return options.stream ? stylize("Function", 'other') : '[Function]'; - case "null" : return stylize("null", 'special'); - case "undefined": return stylize("undefined", 'special'); - case "boolean" : return stylize(obj + '', 'bool'); - case "date" : return stylize(obj.toUTCString()); - case "array" : return stringifyArray(obj, options, stack.length); - case "object" : return stringifyObject(obj, options, stack.length); - } - })(obj); - - stack.pop(); - return result; -}; - -// Escape invisible characters in a string -function stringifyString (str, options) { - return str.replace(/\\/g, '\\\\') - .replace(/\n/g, '\\n') - .replace(/[\u0001-\u001F]/g, function (match) { - return '\\0' + match[0].charCodeAt(0).toString(8); - }); -} - -// Convert an array to a string, such as [1, 2, 3]. -// This function calls stringify() for each of the elements -// in the array. -function stringifyArray(ary, options, level) { - var out = []; - var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) { - return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) || - (Array.isArray(o) && o.length > 0); - })); - var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; - - for (var i = 0; i < ary.length; i++) { - out.push(stringify(ary[i], options)); - } - - if (out.length === 0) { - return '[]'; - } else { - return '[' + ws - + out.join(',' + (pretty ? ws : ' ')) - + (pretty ? ws.slice(0, -4) : ws) + - ']'; - } -}; - -// Convert an object to a string, such as {a: 1}. -// This function calls stringify() for each of its values, -// and does not output functions or prototype values. -function stringifyObject(obj, options, level) { - var out = []; - var pretty = options.pretty && (Object.keys(obj).length > 2 || - Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' })); - var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; - - var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj); - keys.forEach(function (k) { - if (Object.prototype.hasOwnProperty.call(obj, k) - && !(obj[k] instanceof Function && options.hideFunctions)) { - out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' + - stringify(obj[k], options)); - } - }); - - if (out.length === 0) { - return '{}'; - } else { - return "{" + ws - + out.join(',' + (pretty ? ws : ' ')) - + (pretty ? ws.slice(0, -4) : ws) + - "}"; - } -}; - -// A better `typeof` -function typeOf(value) { - var s = typeof(value), - types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; - - if (s === 'object' || s === 'function') { - if (value) { - types.forEach(function (t) { - if (value instanceof t) { s = t.name.toLowerCase() } - }); - } else { s = 'null' } - } - return s; -} - -function merge(/* variable args */) { - var objs = Array.prototype.slice.call(arguments); - var target = {}; - - objs.forEach(function (o) { - Object.keys(o).forEach(function (k) { - if (k === 'styles') { - if (! o.styles) { - target.styles = false; - } else { - target.styles = {} - for (var s in o.styles) { - target.styles[s] = o.styles[s]; - } - } - } else { - target[k] = o[k]; - } - }); - }); - return target; -} - diff --git a/Challenge/seokahi/010.star/node_modules/eyes/package.json b/Challenge/seokahi/010.star/node_modules/eyes/package.json deleted file mode 100644 index bc40240..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name" : "eyes", - "description" : "a customizable value inspector", - "url" : "http://github.com/cloudhead/eyes.js", - "keywords" : ["inspector", "debug", "inspect", "print"], - "author" : "Alexis Sellier ", - "contributors" : [{ "name": "Charlie Robbins", "email": "charlie@nodejitsu.com" }], - "licenses" : ["MIT"], - "main" : "./lib/eyes", - "version" : "0.1.8", - "scripts" : { "test": "node test/*-test.js" }, - "directories" : { "lib": "./lib", "test": "./test" }, - "engines" : { "node": "> 0.1.90" } -} diff --git a/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js b/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js deleted file mode 100644 index 1f9606a..0000000 --- a/Challenge/seokahi/010.star/node_modules/eyes/test/eyes-test.js +++ /dev/null @@ -1,56 +0,0 @@ -var util = require('util'); -var eyes = require('../lib/eyes'); - -eyes.inspect({ - number: 42, - string: "John Galt", - regexp: /[a-z]+/, - array: [99, 168, 'x', {}], - func: function () {}, - bool: false, - nil: null, - undef: undefined, - object: {attr: []} -}, "native types"); - -eyes.inspect({ - number: new(Number)(42), - string: new(String)("John Galt"), - regexp: new(RegExp)(/[a-z]+/), - array: new(Array)(99, 168, 'x', {}), - bool: new(Boolean)(false), - object: new(Object)({attr: []}), - date: new(Date) -}, "wrapped types"); - -var obj = {}; -obj.that = { self: obj }; -obj.self = obj; - -eyes.inspect(obj, "circular object"); -eyes.inspect({hello: 'moto'}, "small object"); -eyes.inspect({hello: new(Array)(6) }, "big object"); -eyes.inspect(["hello 'world'", 'hello "world"'], "quotes"); -eyes.inspect({ - recommendations: [{ - id: 'a7a6576c2c822c8e2bd81a27e41437d8', - key: [ 'spree', 3.764316258020699 ], - value: { - _id: 'a7a6576c2c822c8e2bd81a27e41437d8', - _rev: '1-2e2d2f7fd858c4a5984bcf809d22ed98', - type: 'domain', - domain: 'spree', - weight: 3.764316258020699, - product_id: 30 - } - }] -}, 'complex'); - -eyes.inspect([null], "null in array"); - -var inspect = eyes.inspector({ stream: null }); - -util.puts(inspect('something', "something")); -util.puts(inspect("something else")); - -util.puts(inspect(["no color"], null, { styles: false })); diff --git a/Challenge/seokahi/010.star/node_modules/from/.npmignore b/Challenge/seokahi/010.star/node_modules/from/.npmignore deleted file mode 100644 index 3c3629e..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/Challenge/seokahi/010.star/node_modules/from/.travis.yml b/Challenge/seokahi/010.star/node_modules/from/.travis.yml deleted file mode 100644 index 76db03f..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -node_js: - - "node" - - "6" - - "5" - - "4" diff --git a/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 b/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 deleted file mode 100644 index 6366c04..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/LICENSE.APACHE2 +++ /dev/null @@ -1,15 +0,0 @@ -Apache License, Version 2.0 - -Copyright (c) 2011 Dominic Tarr - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT b/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT deleted file mode 100644 index 6eafbd7..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/LICENSE.MIT +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2011 Dominic Tarr - -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/Challenge/seokahi/010.star/node_modules/from/index.js b/Challenge/seokahi/010.star/node_modules/from/index.js deleted file mode 100644 index e3e7bfd..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/index.js +++ /dev/null @@ -1,68 +0,0 @@ - -'use strict'; - -var Stream = require('stream') - -// from -// -// a stream that reads from an source. -// source may be an array, or a function. -// from handles pause behaviour for you. - -module.exports = -function from (source) { - if(Array.isArray(source)) { - var source_index = 0, source_len = source.length; - return from (function (i) { - if(source_index < source_len) - this.emit('data', source[source_index++]) - else - this.emit('end') - return true - }) - } - var s = new Stream(), i = 0 - s.ended = false - s.started = false - s.readable = true - s.writable = false - s.paused = false - s.ended = false - s.pause = function () { - s.started = true - s.paused = true - } - function next () { - s.started = true - if(s.ended) return - while(!s.ended && !s.paused && source.call(s, i++, function () { - if(!s.ended && !s.paused) - process.nextTick(next); - })) - ; - } - s.resume = function () { - s.started = true - s.paused = false - next() - } - s.on('end', function () { - s.ended = true - s.readable = false - process.nextTick(s.destroy) - }) - s.destroy = function () { - s.ended = true - s.emit('close') - } - /* - by default, the stream will start emitting at nextTick - if you want, you can pause it, after pipeing. - you can also resume before next tick, and that will also - work. - */ - process.nextTick(function () { - if(!s.started) s.resume() - }) - return s -} diff --git a/Challenge/seokahi/010.star/node_modules/from/package.json b/Challenge/seokahi/010.star/node_modules/from/package.json deleted file mode 100644 index a265d84..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "from", - "version": "0.1.7", - "description": "Easy way to make a Readable Stream", - "main": "index.js", - "scripts": { - "test": "asynct test/*.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/dominictarr/from.git" - }, - "keywords": [ - "stream", - "streams", - "readable", - "easy" - ], - "devDependencies": { - "asynct": "1", - "stream-spec": "0", - "assertions": "~2.3.0" - }, - "author": "Dominic Tarr (dominictarr.com)", - "license": "MIT" -} diff --git a/Challenge/seokahi/010.star/node_modules/from/readme.markdown b/Challenge/seokahi/010.star/node_modules/from/readme.markdown deleted file mode 100644 index c84fc9b..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/readme.markdown +++ /dev/null @@ -1,40 +0,0 @@ -[![TravisCI Build Status](https://travis-ci.org/nmhnmh/from.svg?branch=master)](https://travis-ci.org/nmhnmh/from) - -# from - -An easy way to create a `readable Stream`. - -## from(function getChunk(count, next)) - -from takes a `getChunk` function and returns a stream. - -`getChunk` is called again and again, after each time the user calls `next()`, -until the user emits `'end'` - -if `pause()` is called, the `getChunk` won't be called again untill `resume()` is called. - - -```js -var from = require('from') - -var stream = - from(function getChunk(count, next) { - //do some sort of data - this.emit('data', whatever) - - if(itsOver) - this.emit('end') - - //ready to handle the next chunk - next() - //or, if it's sync: - return true - }) -``` - -## from(array) - -from also takes an `Array` whose elements it emits one after another. - -## License -MIT / Apache2 diff --git a/Challenge/seokahi/010.star/node_modules/from/test/index.js b/Challenge/seokahi/010.star/node_modules/from/test/index.js deleted file mode 100644 index 5e2f161..0000000 --- a/Challenge/seokahi/010.star/node_modules/from/test/index.js +++ /dev/null @@ -1,210 +0,0 @@ -var from = require('..') -var spec = require('stream-spec') -var a = require('assertions') - -function read(stream, callback) { - var actual = [] - stream.on('data', function (data) { - actual.push(data) - }) - stream.once('end', function () { - callback(null, actual) - }) - stream.once('error', function (err) { - callback(err) - }) -} - -function pause(stream) { - stream.on('data', function () { - if(Math.random() > 0.1) return - stream.pause() - process.nextTick(function () { - stream.resume() - }) - }) -} - -exports['inc'] = function (test) { - - var fs = from(function (i) { - this.emit('data', i) - if(i >= 99) - return this.emit('end') - return true - }) - - spec(fs).readable().validateOnExit() - - read(fs, function (err, arr) { - test.equal(arr.length, 100) - test.done() - }) -} - -exports['inc - async'] = function (test) { - - var fs = from(function (i, next) { - this.emit('data', i) - if(i >= 99) - return this.emit('end') - next(); - }) - - spec(fs).readable().validateOnExit() - - read(fs, function (err, arr) { - test.equal(arr.length, 100) - test.done() - }) -} - -exports['large stream - from an array'] = function (test) { - - var l = 100000 - , expected = [] - - while(l--) expected.push(l * Math.random()) - - var fs = from(expected.slice()) - - spec(fs).readable().validateOnExit() - - read(fs, function (err, arr) { - a.deepEqual(arr, expected) - test.done() - }) -} - -exports['large stream - callback return true'] = function (test) { - - var fs = from(function (i, next) { - this.emit('data', i) - if(i >= 99999) - return this.emit('end') - return true; - }) - - spec(fs).readable().validateOnExit() - - read(fs, function (err, arr) { - test.equal(arr.length, 100000) - test.done() - }) -} - -exports['large stream - callback call next()'] = function (test) { - - var fs = from(function (i, next) { - this.emit('data', i) - if(i >= 99999) - return this.emit('end') - next(); - }) - - spec(fs).readable().validateOnExit() - - read(fs, function (err, arr) { - test.equal(arr.length, 100000) - test.done() - }) -} - -exports['simple'] = function (test) { - - var l = 1000 - , expected = [] - - while(l--) expected.push(l * Math.random()) - - var t = from(expected.slice()) - - spec(t) - .readable() - .pausable({strict: true}) - .validateOnExit() - - read(t, function (err, actual) { - if(err) test.error(err) //fail - a.deepEqual(actual, expected) - test.done() - }) - -} - -exports['simple pausable'] = function (test) { - - var l = 1000 - , expected = [] - - while(l--) expected.push(l * Math.random()) - - var t = from(expected.slice()) - - spec(t) - .readable() - .pausable({strict: true}) - .validateOnExit() - - pause(t) - - read(t, function (err, actual) { - if(err) test.error(err) //fail - a.deepEqual(actual, expected) - test.done() - }) - -} - -exports['simple (not strictly pausable) setTimeout'] = function (test) { - - var l = 10 - , expected = [] - while(l--) expected.push(l * Math.random()) - - - var _expected = expected.slice() - var t = from(function (i, n) { - var self = this - setTimeout(function () { - if(_expected.length) - self.emit('data', _expected.shift()) - else - if(!self.ended) - self.emit('end') - n() - }, 3) - }) - - /* - using from in this way will not be strictly pausable. - it could be extended to buffer outputs, but I think a better - way would be to use a PauseStream that implements strict pause. - */ - - spec(t) - .readable() - .pausable({strict: false }) - .validateOnExit() - - //pause(t) - var paused = false - var i = setInterval(function () { - if(!paused) t.pause() - else t.resume() - paused = !paused - }, 2) - - t.on('end', function () { - clearInterval(i) - }) - - read(t, function (err, actual) { - if(err) test.error(err) //fail - a.deepEqual(actual, expected) - test.done() - }) - -} - - diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc b/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc deleted file mode 100644 index c8ef3ca..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/.jshintrc +++ /dev/null @@ -1,59 +0,0 @@ -{ - "predef": [ ] - , "bitwise": false - , "camelcase": false - , "curly": false - , "eqeqeq": false - , "forin": false - , "immed": false - , "latedef": false - , "noarg": true - , "noempty": true - , "nonew": true - , "plusplus": false - , "quotmark": true - , "regexp": false - , "undef": true - , "unused": true - , "strict": false - , "trailing": true - , "maxlen": 120 - , "asi": true - , "boss": true - , "debug": true - , "eqnull": true - , "esnext": true - , "evil": true - , "expr": true - , "funcscope": false - , "globalstrict": false - , "iterator": false - , "lastsemic": true - , "laxbreak": true - , "laxcomma": true - , "loopfunc": true - , "multistr": false - , "onecase": false - , "proto": false - , "regexdash": false - , "scripturl": true - , "smarttabs": false - , "shadow": false - , "sub": true - , "supernew": false - , "validthis": true - , "browser": true - , "couch": false - , "devel": false - , "dojo": false - , "mootools": false - , "node": true - , "nonstandard": true - , "prototypejs": false - , "rhino": false - , "worker": true - , "wsh": false - , "nomen": false - , "onevar": false - , "passfail": false -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.npmignore b/Challenge/seokahi/010.star/node_modules/isstream/.npmignore deleted file mode 100644 index aa1ec1e..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/.npmignore +++ /dev/null @@ -1 +0,0 @@ -*.tgz diff --git a/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml b/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml deleted file mode 100644 index 1fec2ab..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" - - "0.11" -branches: - only: - - master -notifications: - email: - - rod@vagg.org -script: npm test diff --git a/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md b/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md deleted file mode 100644 index 43f7153..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/LICENSE.md +++ /dev/null @@ -1,11 +0,0 @@ -The MIT License (MIT) -===================== - -Copyright (c) 2015 Rod Vagg ---------------------------- - -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/Challenge/seokahi/010.star/node_modules/isstream/README.md b/Challenge/seokahi/010.star/node_modules/isstream/README.md deleted file mode 100644 index 06770e8..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# isStream - -[![Build Status](https://secure.travis-ci.org/rvagg/isstream.png)](http://travis-ci.org/rvagg/isstream) - -**Test if an object is a `Stream`** - -[![NPM](https://nodei.co/npm/isstream.svg)](https://nodei.co/npm/isstream/) - -The missing `Stream.isStream(obj)`: determine if an object is standard Node.js `Stream`. Works for Node-core `Stream` objects (for 0.8, 0.10, 0.11, and in theory, older and newer versions) and all versions of **[readable-stream](https://github.com/isaacs/readable-stream)**. - -## Usage: - -```js -var isStream = require('isstream') -var Stream = require('stream') - -isStream(new Stream()) // true - -isStream({}) // false - -isStream(new Stream.Readable()) // true -isStream(new Stream.Writable()) // true -isStream(new Stream.Duplex()) // true -isStream(new Stream.Transform()) // true -isStream(new Stream.PassThrough()) // true -``` - -## But wait! There's more! - -You can also test for `isReadable(obj)`, `isWritable(obj)` and `isDuplex(obj)` to test for implementations of Streams2 (and Streams3) base classes. - -```js -var isReadable = require('isstream').isReadable -var isWritable = require('isstream').isWritable -var isDuplex = require('isstream').isDuplex -var Stream = require('stream') - -isReadable(new Stream()) // false -isWritable(new Stream()) // false -isDuplex(new Stream()) // false - -isReadable(new Stream.Readable()) // true -isReadable(new Stream.Writable()) // false -isReadable(new Stream.Duplex()) // true -isReadable(new Stream.Transform()) // true -isReadable(new Stream.PassThrough()) // true - -isWritable(new Stream.Readable()) // false -isWritable(new Stream.Writable()) // true -isWritable(new Stream.Duplex()) // true -isWritable(new Stream.Transform()) // true -isWritable(new Stream.PassThrough()) // true - -isDuplex(new Stream.Readable()) // false -isDuplex(new Stream.Writable()) // false -isDuplex(new Stream.Duplex()) // true -isDuplex(new Stream.Transform()) // true -isDuplex(new Stream.PassThrough()) // true -``` - -*Reminder: when implementing your own streams, please [use **readable-stream** rather than core streams](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).* - - -## License - -**isStream** is Copyright (c) 2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details. diff --git a/Challenge/seokahi/010.star/node_modules/isstream/isstream.js b/Challenge/seokahi/010.star/node_modules/isstream/isstream.js deleted file mode 100644 index a1d104a..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/isstream.js +++ /dev/null @@ -1,27 +0,0 @@ -var stream = require('stream') - - -function isStream (obj) { - return obj instanceof stream.Stream -} - - -function isReadable (obj) { - return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' -} - - -function isWritable (obj) { - return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' -} - - -function isDuplex (obj) { - return isReadable(obj) && isWritable(obj) -} - - -module.exports = isStream -module.exports.isReadable = isReadable -module.exports.isWritable = isWritable -module.exports.isDuplex = isDuplex diff --git a/Challenge/seokahi/010.star/node_modules/isstream/package.json b/Challenge/seokahi/010.star/node_modules/isstream/package.json deleted file mode 100644 index 9ee8bf8..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "isstream", - "version": "0.1.2", - "description": "Determine if an object is a Stream", - "main": "isstream.js", - "scripts": { - "test": "tar --xform 's/^package/readable-stream-1.0/' -zxf readable-stream-1.0.*.tgz && tar --xform 's/^package/readable-stream-1.1/' -zxf readable-stream-1.1.*.tgz && node test.js; rm -rf readable-stream-1.?/" - }, - "repository": { - "type": "git", - "url": "https://github.com/rvagg/isstream.git" - }, - "keywords": [ - "stream", - "type", - "streams", - "readable-stream", - "hippo" - ], - "devDependencies": { - "tape": "~2.12.3", - "core-util-is": "~1.0.0", - "isarray": "0.0.1", - "string_decoder": "~0.10.x", - "inherits": "~2.0.1" - }, - "author": "Rod Vagg ", - "license": "MIT", - "bugs": { - "url": "https://github.com/rvagg/isstream/issues" - }, - "homepage": "https://github.com/rvagg/isstream" -} diff --git a/Challenge/seokahi/010.star/node_modules/isstream/test.js b/Challenge/seokahi/010.star/node_modules/isstream/test.js deleted file mode 100644 index 8c950c5..0000000 --- a/Challenge/seokahi/010.star/node_modules/isstream/test.js +++ /dev/null @@ -1,168 +0,0 @@ -var tape = require('tape') - , EE = require('events').EventEmitter - , util = require('util') - - - , isStream = require('./') - , isReadable = require('./').isReadable - , isWritable = require('./').isWritable - , isDuplex = require('./').isDuplex - - , CoreStreams = require('stream') - , ReadableStream10 = require('./readable-stream-1.0/') - , ReadableStream11 = require('./readable-stream-1.1/') - - -function test (pass, type, stream) { - tape('isStream(' + type + ')', function (t) { - t.plan(1) - t.ok(pass === isStream(stream), type) - }) -} - - -function testReadable (pass, type, stream) { - tape('isReadable(' + type + ')', function (t) { - t.plan(1) - t.ok(pass === isReadable(stream), type) - }) -} - - -function testWritable (pass, type, stream) { - tape('isWritable(' + type + ')', function (t) { - t.plan(1) - t.ok(pass === isWritable(stream), type) - }) -} - - -function testDuplex (pass, type, stream) { - tape('isDuplex(' + type + ')', function (t) { - t.plan(1) - t.ok(pass === isDuplex(stream), type) - }) -} - - -[ undefined, null, '', true, false, 0, 1, 1.0, 'string', {}, function foo () {} ].forEach(function (o) { - test(false, 'non-stream / primitive: ' + (JSON.stringify(o) || (o && o.toString()) || o), o) -}) - - -test(false, 'fake stream obj', { pipe: function () {} }) - - -;(function () { - - // looks like a stream! - - function Stream () { - EE.call(this) - } - util.inherits(Stream, EE) - Stream.prototype.pipe = function () {} - Stream.Stream = Stream - - test(false, 'fake stream "new Stream()"', new Stream()) - -}()) - - -test(true, 'CoreStreams.Stream', new (CoreStreams.Stream)()) -test(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) -test(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) -test(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) -test(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) -test(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) - -test(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) -test(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) -test(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) -test(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) -test(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) - -test(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) -test(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) -test(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) -test(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) -test(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) - - -testReadable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) -testReadable(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) -testReadable(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) -testReadable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) -testReadable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) -testReadable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) - -testReadable(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) -testReadable(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) -testReadable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) -testReadable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) -testReadable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) - -testReadable(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) -testReadable(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) -testReadable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) -testReadable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) -testReadable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) - - -testWritable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) -testWritable(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) -testWritable(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) -testWritable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) -testWritable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) -testWritable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) - -testWritable(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) -testWritable(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) -testWritable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) -testWritable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) -testWritable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) - -testWritable(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) -testWritable(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) -testWritable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) -testWritable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) -testWritable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) - - -testDuplex(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) -testDuplex(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) -testDuplex(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) -testDuplex(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) -testDuplex(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) -testDuplex(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) - -testDuplex(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) -testDuplex(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) -testDuplex(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) -testDuplex(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) -testDuplex(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) - -testDuplex(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) -testDuplex(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) -testDuplex(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) -testDuplex(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) -testDuplex(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) - - -;[ CoreStreams, ReadableStream10, ReadableStream11 ].forEach(function (p) { - [ 'Stream', 'Readable', 'Writable', 'Duplex', 'Transform', 'PassThrough' ].forEach(function (k) { - if (!p[k]) - return - - function SubStream () { - p[k].call(this) - } - util.inherits(SubStream, p[k]) - - test(true, 'Stream subclass: ' + p.name + '.' + k, new SubStream()) - - }) -}) - - - diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE b/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE deleted file mode 100644 index e0c69d5..0000000 --- a/Challenge/seokahi/010.star/node_modules/lodash.assign/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright jQuery Foundation and other contributors - -Based on Underscore.js, copyright Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/lodash/lodash - -The following license applies to all parts of this software except as -documented below: - -==== - -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. - -==== - -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code displayed within the prose of the -documentation. - -CC0: http://creativecommons.org/publicdomain/zero/1.0/ - -==== - -Files located in the node_modules and vendor directories are externally -maintained libraries used by this software which have their own -licenses; we recommend you read them, as their terms may differ from the -terms above. diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md b/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md deleted file mode 100644 index 6bce2d6..0000000 --- a/Challenge/seokahi/010.star/node_modules/lodash.assign/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# lodash.assign v4.2.0 - -The [lodash](https://lodash.com/) method `_.assign` exported as a [Node.js](https://nodejs.org/) module. - -## Installation - -Using npm: -```bash -$ {sudo -H} npm i -g npm -$ npm i --save lodash.assign -``` - -In Node.js: -```js -var assign = require('lodash.assign'); -``` - -See the [documentation](https://lodash.com/docs#assign) or [package source](https://github.com/lodash/lodash/blob/4.2.0-npm-packages/lodash.assign) for more details. diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js b/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js deleted file mode 100644 index 8b007bc..0000000 --- a/Challenge/seokahi/010.star/node_modules/lodash.assign/index.js +++ /dev/null @@ -1,637 +0,0 @@ -/** - * lodash (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright jQuery Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]'; - -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeKeys = overArg(Object.keys, Object), - nativeMax = Math.max; - -/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ -var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - // Safari 9 makes `arguments.length` enumerable in strict mode. - var result = (isArray(value) || isArguments(value)) - ? baseTimes(value.length, String) - : []; - - var length = result.length, - skipIndexes = !!length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && (key == 'length' || isIndex(key, length)))) { - result.push(key); - } - } - return result; -} - -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - object[key] = value; - } -} - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = array; - return apply(func, this, otherArgs); - }; -} - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - assignValue(object, key, newValue === undefined ? source[key] : newValue); - } - return object; -} - -/** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ -function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); -} - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); -} - -/** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; -} - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; -} - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -function isArguments(value) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8-9 which returns 'object' for typed array and other constructors. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} - -/** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ -var assign = createAssigner(function(object, source) { - if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } -}); - -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} - -module.exports = assign; diff --git a/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json b/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json deleted file mode 100644 index 78672ea..0000000 --- a/Challenge/seokahi/010.star/node_modules/lodash.assign/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "lodash.assign", - "version": "4.2.0", - "description": "The lodash method `_.assign` exported as a module.", - "homepage": "https://lodash.com/", - "icon": "https://lodash.com/icon.svg", - "license": "MIT", - "keywords": "lodash-modularized, assign", - "author": "John-David Dalton (http://allyoucanleet.com/)", - "contributors": [ - "John-David Dalton (http://allyoucanleet.com/)", - "Blaine Bublitz (https://github.com/phated)", - "Mathias Bynens (https://mathiasbynens.be/)" - ], - "repository": "lodash/lodash", - "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" } -} diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore b/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore deleted file mode 100644 index 13abef4..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -node_modules/* -npm_debug.log diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml b/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml deleted file mode 100644 index 895dbd3..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE b/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE deleted file mode 100644 index 2af26fe..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/LICENCE +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2011 Dominic Tarr - -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/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js b/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js deleted file mode 100644 index ab07398..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/examples/pretty.js +++ /dev/null @@ -1,26 +0,0 @@ - -var inspect = require('util').inspect - -if(!module.parent) { - var map = require('..') //load map-stream - var es = require('event-stream') //load event-stream - es.pipe( //pipe joins streams together - process.openStdin(), //open stdin - es.split(), //split stream to break on newlines - map(function (data, callback) { //turn this async function into a stream - var j - try { - j = JSON.parse(data) //try to parse input into json - } catch (err) { - return callback(null, data) //if it fails just pass it anyway - } - callback(null, inspect(j)) //render it nicely - }), - process.stdout // pipe it to stdout ! - ) - } - -// run this -// -// curl -sS registry.npmjs.org/event-stream | node pretty.js -// diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/index.js b/Challenge/seokahi/010.star/node_modules/map-stream/index.js deleted file mode 100644 index cbf3970..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/index.js +++ /dev/null @@ -1,144 +0,0 @@ -//filter will reemit the data if cb(err,pass) pass is truthy - -// reduce is more tricky -// maybe we want to group the reductions or emit progress updates occasionally -// the most basic reduce just emits one 'data' event after it has recieved 'end' - - -var Stream = require('stream').Stream - - -//create an event stream and apply function to each .write -//emitting each response as data -//unless it's an empty callback - -module.exports = function (mapper, opts) { - - var stream = new Stream() - , inputs = 0 - , outputs = 0 - , ended = false - , paused = false - , destroyed = false - , lastWritten = 0 - , inNext = false - - opts = opts || {}; - var errorEventName = opts.failures ? 'failure' : 'error'; - - // Items that are not ready to be written yet (because they would come out of - // order) get stuck in a queue for later. - var writeQueue = {} - - stream.writable = true - stream.readable = true - - function queueData (data, number) { - var nextToWrite = lastWritten + 1 - - if (number === nextToWrite) { - // If it's next, and its not undefined write it - if (data !== undefined) { - stream.emit.apply(stream, ['data', data]) - } - lastWritten ++ - nextToWrite ++ - } else { - // Otherwise queue it for later. - writeQueue[number] = data - } - - // If the next value is in the queue, write it - if (writeQueue.hasOwnProperty(nextToWrite)) { - var dataToWrite = writeQueue[nextToWrite] - delete writeQueue[nextToWrite] - return queueData(dataToWrite, nextToWrite) - } - - outputs ++ - if(inputs === outputs) { - if(paused) paused = false, stream.emit('drain') //written all the incoming events - if(ended) end() - } - } - - function next (err, data, number) { - if(destroyed) return - inNext = true - - if (!err || opts.failures) { - queueData(data, number) - } - - if (err) { - stream.emit.apply(stream, [ errorEventName, err ]); - } - - inNext = false; - } - - // Wrap the mapper function by calling its callback with the order number of - // the item in the stream. - function wrappedMapper (input, number, callback) { - return mapper.call(null, input, function(err, data){ - callback(err, data, number) - }) - } - - stream.write = function (data) { - if(ended) throw new Error('map stream is not writable') - inNext = false - inputs ++ - - try { - //catch sync errors and handle them like async errors - var written = wrappedMapper(data, inputs, next) - paused = (written === false) - return !paused - } catch (err) { - //if the callback has been called syncronously, and the error - //has occured in an listener, throw it again. - if(inNext) - throw err - next(err) - return !paused - } - } - - function end (data) { - //if end was called with args, write it, - ended = true //write will emit 'end' if ended is true - stream.writable = false - if(data !== undefined) { - return queueData(data, inputs) - } else if (inputs == outputs) { //wait for processing - stream.readable = false, stream.emit('end'), stream.destroy() - } - } - - stream.end = function (data) { - if(ended) return - end(data) - } - - stream.destroy = function () { - ended = destroyed = true - stream.writable = stream.readable = paused = false - process.nextTick(function () { - stream.emit('close') - }) - } - stream.pause = function () { - paused = true - } - - stream.resume = function () { - paused = false - } - - return stream -} - - - - diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/package.json b/Challenge/seokahi/010.star/node_modules/map-stream/package.json deleted file mode 100644 index 91f46d7..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "map-stream", - "version": "0.0.7", - "license": "MIT", - "description": "construct pipes of streams of events", - "homepage": "http://github.com/dominictarr/map-stream", - "repository": { - "type": "git", - "url": "git://github.com/dominictarr/map-stream.git" - }, - "dependencies": {}, - "devDependencies": { - "asynct": "*", - "it-is": "1", - "ubelt": "~2.9", - "stream-spec": "~0.2", - "event-stream": "~2.1", - "from": "0.0.2" - }, - "scripts": { - "test": "asynct test/" - }, - "author": "Dominic Tarr (http://dominictarr.com)" -} diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown deleted file mode 100644 index 1897158..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/readme.markdown +++ /dev/null @@ -1,37 +0,0 @@ -# MapStream - -Refactored out of [event-stream](https://github.com/dominictarr/event-stream) - -##map (asyncFunction[, options]) - -Create a through stream from an asyncronous function. - -``` js -var map = require('map-stream') - -map(function (data, callback) { - //transform data - // ... - callback(null, data) -}) - -``` - -Each map MUST call the callback. It may callback with data, with an error or with no arguments, - - * `callback()` drop this data. - this makes the map work like `filter`, - note:`callback(null,null)` is not the same, and will emit `null` - - * `callback(null, newData)` turn data into newData - - * `callback(error)` emit an error for this item. - ->Note: if a callback is not called, `map` will think that it is still being processed, ->every call must be answered or the stream will not know when to end. -> ->Also, if the callback is called more than once, every call but the first will be ignored. - -##Options - - * `failures` - `boolean` continue mapping even if error occured. On error `map-stream` will emit `failure` event. (default: `false`) diff --git a/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js b/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js deleted file mode 100644 index 2b9a292..0000000 --- a/Challenge/seokahi/010.star/node_modules/map-stream/test/simple-map.asynct.js +++ /dev/null @@ -1,318 +0,0 @@ -'use strict'; - -var map = require('../') - , it = require('it-is') - , u = require('ubelt') - , spec = require('stream-spec') - , from = require('from') - , Stream = require('stream') - , es = require('event-stream') - -//REFACTOR THIS TEST TO USE es.readArray and es.writeArray - -function writeArray(array, stream) { - - array.forEach( function (j) { - stream.write(j) - }) - stream.end() - -} - -function readStream(stream, done) { - - var array = [] - stream.on('data', function (data) { - array.push(data) - }) - stream.on('error', done) - stream.on('end', function (data) { - done(null, array) - }) - -} - -//call sink on each write, -//and complete when finished. - -function pauseStream (prob, delay) { - var pauseIf = ( - 'number' == typeof prob - ? function () { - return Math.random() < prob - } - : 'function' == typeof prob - ? prob - : 0.1 - ) - var delayer = ( - !delay - ? process.nextTick - : 'number' == typeof delay - ? function (next) { setTimeout(next, delay) } - : delay - ) - - return es.through(function (data) { - if(!this.paused && pauseIf()) { - console.log('PAUSE STREAM PAUSING') - this.pause() - var self = this - delayer(function () { - console.log('PAUSE STREAM RESUMING') - self.resume() - }) - } - console.log("emit ('data', " + data + ')') - this.emit('data', data) - }) -} - -exports ['simple map applied to a stream'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - //create event stream from - - var doubler = map(function (data, cb) { - cb(null, data * 2) - }) - - spec(doubler).through().validateOnExit() - - //a map is only a middle man, so it is both readable and writable - - it(doubler).has({ - readable: true, - writable: true, - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.map(function (j) { - return j * 2 - })) -// process.nextTick(x.validate) - test.done() - }) - - writeArray(input, doubler) - -} - -exports ['stream comes back in the correct order'] = function (test) { - var input = [3, 2, 1] - - var delayer = map(function(data, cb){ - setTimeout(function () { - cb(null, data) - }, 100 * data) - }) - - readStream(delayer, function (err, output) { - it(output).deepEqual(input) - test.done() - }) - - writeArray(input, delayer) -} - -exports ['continues on error event with failures `true`'] = function (test) { - var input = [1, 2, 3] - - var delayer = map(function(data, cb){ - cb(new Error('Something gone wrong'), data) - }, { failures: true }) - - readStream(delayer, function (err, output) { - it(output).deepEqual(input) - test.done() - }) - - writeArray(input, delayer) -} - -exports['pipe two maps together'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - //create event stream from - function dd (data, cb) { - cb(null, data * 2) - } - var doubler1 = map(dd), doubler2 = map(dd) - - doubler1.pipe(doubler2) - - spec(doubler1).through().validateOnExit() - spec(doubler2).through().validateOnExit() - - readStream(doubler2, function (err, output) { - it(output).deepEqual(input.map(function (j) { - return j * 4 - })) - test.done() - }) - - writeArray(input, doubler1) - -} - -//next: -// -// test pause, resume and drian. -// - -// then make a pipe joiner: -// -// plumber (evStr1, evStr2, evStr3, evStr4, evStr5) -// -// will return a single stream that write goes to the first - -exports ['map will not call end until the callback'] = function (test) { - - var ticker = map(function (data, cb) { - process.nextTick(function () { - cb(null, data * 2) - }) - }) - - spec(ticker).through().validateOnExit() - - ticker.write('x') - ticker.end() - - ticker.on('end', function () { - test.done() - }) -} - -exports ['emit failures with opts.failures === `ture`'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , mapper = - map(function () { - throw err - }, { failures: true }) - - mapper.on('failure', function (_err) { - it(_err).equal(err) - test.done() - }) - - mapper.write('hello') - -} - -exports ['emit error thrown'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , mapper = - map(function () { - throw err - }) - - mapper.on('error', function (_err) { - it(_err).equal(err) - test.done() - }) - - mapper.write('hello') - -} - -exports ['emit error calledback'] = function (test) { - - var err = new Error('INTENSIONAL ERROR') - , mapper = - map(function (data, callback) { - callback(err) - }) - - mapper.on('error', function (_err) { - it(_err).equal(err) - test.done() - }) - - mapper.write('hello') - -} - -exports ['do not emit drain if not paused'] = function (test) { - - var maps = map(function (data, callback) { - u.delay(callback)(null, 1) - return true - }) - - spec(maps).through().pausable().validateOnExit() - - maps.on('drain', function () { - it(false).ok('should not emit drain unless the stream is paused') - }) - - it(maps.write('hello')).equal(true) - it(maps.write('hello')).equal(true) - it(maps.write('hello')).equal(true) - setTimeout(function () {maps.end()},10) - maps.on('end', test.done) -} - -exports ['emits drain if paused, when all '] = function (test) { - var active = 0 - var drained = false - var maps = map(function (data, callback) { - active ++ - u.delay(function () { - active -- - callback(null, 1) - })() - console.log('WRITE', false) - return false - }) - - spec(maps).through().validateOnExit() - - maps.on('drain', function () { - drained = true - it(active).equal(0, 'should emit drain when all maps are done') - }) - - it(maps.write('hello')).equal(false) - it(maps.write('hello')).equal(false) - it(maps.write('hello')).equal(false) - - process.nextTick(function () {maps.end()},10) - - maps.on('end', function () { - console.log('end') - it(drained).ok('shoud have emitted drain before end') - test.done() - }) - -} - -exports ['map applied to a stream with filtering'] = function (test) { - - var input = [1,2,3,7,5,3,1,9,0,2,4,6] - - var doubler = map(function (data, callback) { - if (data % 2) - callback(null, data * 2) - else - callback() - }) - - readStream(doubler, function (err, output) { - it(output).deepEqual(input.filter(function (j) { - return j % 2 - }).map(function (j) { - return j * 2 - })) - test.done() - }) - - spec(doubler).through().validateOnExit() - - writeArray(input, doubler) - -} - - diff --git a/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md b/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md deleted file mode 100644 index 468b0b7..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/CHANGELOG.md +++ /dev/null @@ -1,98 +0,0 @@ -Changelog -========= -## 1.3.3 / 2017-08-02 -- Fix `computeValue` not overriding group operator keys after resolving expression -- Added `$in`, `$objectToArray`, and `$arrayToObject` array aggregation operators -- Minor refactoring - -## 1.3.2 / 2017-07-28 -- Restore `setup` function. https://github.com/kofrasa/mingo/issues/56 - -## 1.3.1 / 2017-07-24 -- Replaced core-js because it bloats compiled library by 10K i.e. ~24% -- Fix #55 - -## 1.3.0 / 2017-07-23 -- Support ES6 modules -- Fix matching null and missing values. https://github.com/kofrasa/mingo/issues/54 -- Improve comparing user-defined types - -## v1.2.0 / 2017-07-17 -- Fix `$where` operator not executed last. https://github.com/kofrasa/mingo/pull/50 -- Fix matching nested arrays. https://github.com/kofrasa/mingo/issues/51 -- Added `$facet` and `$bucket` operators -- Added `$bucketAuto` operator without granularity support -- Added string keys for `$type` operator -- Added Cursor support for [ES2015 Iterator Protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) -- Sort null/undefined values to front of sorted result -- Revert to operator names with format `Mingo.OP_` - -## v1.1.2 / 2017-03-30 -- Optimize `$lookup` implementation -- Avoid reversing original input to `$reverseArray` -- Refactor some methods - -## v1.1.1 / 2017-03-12 -- Fix incorrect method call for ObjectProto -- Limit exposed util methods to type checking - -## v1.1.0 / 2017-03-11 -- Renamed `Mingo.OP_` functions to `Mingo.KEY_` -- Added pipeline stage operator (`$lookup`) - -## v1.0.1 / 2017-03-01 -- Updated polyfills to fix failing build on older node versions - -## v1.0.0 / 2017-02-28 -- Added array aggregation operators - (`$arrayElemAt`,`$concatArrays`,`$filter`,`$indexOfArray`,`$isArray`,`$range`,`$reverseArray`,`$reduce`,`$slice`,`$zip`) -- Added string aggregation operators (`$indexOfBytes`,`$split`) -- Added arithmetic aggregation operators (`$ceil`,`$exp`,`$floor`,`$ln`,`$log`,`$log10`,`$pow`,`$sqrt`,`$trunc`) -- Added .editorconfig -- Pass utility functions to custom operator implementation -- Rename function to retrieve collection id to `idKey` in custom operators -- Moved support for query projection streaming to a new package [mingo-stream](https://github.com/kofrasa/mingo-stream) - -## v0.9.1 / 2017-02-08 -- Fix resolving system variables with subpaths. See [issue#41](https://github.com/kofrasa/mingo/issues/41) - -## v0.9.0 / 2017-02-06 -- Added support for system variables (`$$ROOT`,`$$CURRENT`) -- Implemented more pipeline operators (`$redact`,`$addFields`,`$sample`,`$sortByCount`,`$count`,`$replaceRoot`) -- Added `$switch` conditional operator -- Fixed `$ifNull` conditional operator -- Allow use of `$in` and `$nin` as aggregation comparison operators - -## v0.8.1 / 2016-12-08 -- Fix querying deeply nested nested arrays and object equality matching. See [issue#36](https://github.com/kofrasa/mingo/issues/36) - -## v0.8.0 / 2016-09-26 -- Make this library zero-dependent - -## v0.7.0 / 2016-09-10 -- Fix nested projections for objects and arrays. See [issue#25](https://github.com/kofrasa/mingo/issues/25) - -## v0.6.5 / 2016-07-04 -- Fix incorrect de-duping of Date types in $sort aggregate operator. See [issue#23](https://github.com/kofrasa/mingo/pull/23) - -## v0.6.4 / 2016-05-19 -- Support matching against user-defined types. See [issue#22](https://github.com/kofrasa/mingo/issues/22) - -## v0.6.3 / 2015-12-27 -- Fixed numeric aggregation over undefined values. See [issues#21](https://github.com/kofrasa/mingo/issues/21) - -## v0.6.2 / 2015-11-17 -- Fixed erroneous cloning of objects. See [issue#20](https://github.com/kofrasa/mingo/pull/20) - -## v0.6.1 / 2015-09-20 -- Fixed matching nested array fields without specifying index. See [issue#19](https://github.com/kofrasa/mingo/issues/19) -- Added `VERSION` global field - -## v0.6.0 / 2015-05-28 -- Added `$dateToString` aggregation operator - -## v0.5.0 / 2015-04-29 -- Added support for extending operators via `Mingo.addOperators` -- Added `bower.json` -- Fixed grouping documents by an object key -- Fixed exclusive select projection not returning correct fields diff --git a/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md b/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md deleted file mode 100644 index 9b0ae59..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/CONTRIBUTORS.md +++ /dev/null @@ -1,2 +0,0 @@ -Francis Asante -Shane Holloway diff --git a/Challenge/seokahi/010.star/node_modules/mingo/LICENSE b/Challenge/seokahi/010.star/node_modules/mingo/LICENSE deleted file mode 100644 index 9613755..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Francis Asante - -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/Challenge/seokahi/010.star/node_modules/mingo/README.md b/Challenge/seokahi/010.star/node_modules/mingo/README.md deleted file mode 100644 index 5a908b8..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/README.md +++ /dev/null @@ -1,172 +0,0 @@ -# mingo -JavaScript implementation of MongoDB query language - -[![version](https://img.shields.io/npm/v/mingo.svg)](https://www.npmjs.org/package/mingo) -[![build status](https://secure.travis-ci.org/kofrasa/mingo.png)](http://travis-ci.org/kofrasa/mingo) - -## Install -```$ npm install mingo``` - -## Features -- Supports Dot Notation for both '_<array>.<index>_' and '_<document>.<field>_' selectors -- Query and Projection Operators - - [Array Operators](https://docs.mongodb.com/manual/reference/operator/query-array/) - - [Comparisons Operators](https://docs.mongodb.com/manual/reference/operator/query-comparison/) - - [Element Operators](https://docs.mongodb.com/manual/reference/operator/query-element/) - - [Evaluation Operators](https://docs.mongodb.com/manual/reference/operator/query-evaluation/) - - [Logical Operators](https://docs.mongodb.com/manual/reference/operator/query-logical/) -- Aggregation Framework Operators - - [Pipeline Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/) - - [Group Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-group/) - - [Projection Operators](https://docs.mongodb.com/manual/reference/operator/projection/) - - [Arithmetic Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-arithmetic/) - - [Array Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-array/) - - [Boolean Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-boolean/) - - [Comparisons Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-comparison/) - - [Conditional Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-conditional/) - - [Date Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-date/) - - [Literal Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-literal/) - - [Set Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-set/) - - [String Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-string/) - - [Variable Operators](https://docs.mongodb.com/manual/reference/operator/aggregation-projection/) -- Support for adding custom operators -- Match against user-defined types -- Support for aggregaion variables - - [`$$ROOT`,`$$CURRENT`,`$$DESCEND`,`$$PRUNE`,`$$KEEP`](https://docs.mongodb.com/manual/reference/aggregation-variables/) -- Fully ES6 module compatible -- Support integrating with custom collections via mixin -- Query filter and projection streaming. See [mingo-stream](https://github.com/kofrasa/mingo-stream) - -For documentation on using query operators see [mongodb](http://docs.mongodb.org/manual/reference/operator/query/) - - -## Usage -On the server side -```js -// Use as es6 module -import mingo from 'mingo' - -// or vanilla nodeJS -var mingo = require('mingo') -``` - -For the browser -``` -// minified UMD module - - -// or gzipped UMD module - -``` - -Tiny configuration if needed -```js -// setup the key field for your collection -mingo.setup({ - key: '_id' // default -}); - - -## Using query object to test objects -// create a query with criteria -// find all grades for homework with score >= 50 -let query = new mingo.Query({ - type: "homework", - score: { $gte: 50 } -}); - -query.test(someObject) -``` - -## Searching and Filtering -```js -// `collection` is an Array of objects you want to query - -// filter collection with find() -let cursor = query.find(collection); - -// shorthand with query criteria -// cursor = mingo.find(collection, criteria); - -// sort, skip and limit by chaining -cursor.sort({student_id: 1, score: -1}) - .skip(100) - .limit(100); - -// count matches -cursor.count(); - -// iterate cursor -// iteration is forward only -while (cursor.hasNext()) { - console.log(cursor.next()); -} - -// use first(), last() and all() to retrieve matched objects -cursor.first(); -cursor.last(); -cursor.all(); - -// Filter non-matched objects ( -console.log(query.remove(collection)); -``` - -## Aggregation Pipeline -```js -let agg = new mingo.Aggregator([ - {'$match': { "type": "homework"}}, - {'$group':{'_id':'$student_id', 'score':{$min:'$score'}}}, - {'$sort':{'_id': 1, 'score': 1}} -]); - -let result = agg.run(collection); - -// shorthand -result = mingo.aggregate( - collection, - [ - {'$match': { "type": "homework"}}, - {'$group':{'_id':'$student_id', 'score':{$min:'$score'}}}, - {'$sort':{'_id': 1, 'score': 1}} - ] -); -``` - -## Integration with custom collection -```js -// using Backbone.Collection as an example (any user-defined object will do) -let Grades = Backbone.Collection.extend(mingo.CollectionMixin); - -// `collection` is an array of objects -let grades = new Grades(collection); - -// find students with grades less than 50 in homework or quiz -// sort by score ascending and type descending -cursor = grades.query({ - $or: [{type: "quiz", score: {$lt: 50}}, {type: "homework", score: {$lt: 50}}] -}).sort({score: 1, type: -1}).limit(10); - -// return grade with the lowest score -cursor.first(); -``` - -The collection to mixin needs to provide a method with signature `toJSON() -> Array[Object]`. - -## Documentation -- [API](https://github.com/kofrasa/mingo/wiki/API) -- [Custom Operators](https://github.com/kofrasa/mingo/wiki/Custom-Operators) - -## Why? - - Born out of a real need - - Alternative to writing a lot of custom code for transforming collections of JSON objects - - Quick validation of MongoDB queries without the need for a database - - MongoDB query language is among the best in the market and is well documented - - Finally, because queries are better than me and perhaps you too :) - -## Contributing -* Submit pull requests to the [development](https://github.com/kofrasa/mingo/tree/development) branch -* Squash changes into one commit -* Run `make` to ensure build and tests pass - -## License -MIT diff --git a/Challenge/seokahi/010.star/node_modules/mingo/VERSION b/Challenge/seokahi/010.star/node_modules/mingo/VERSION deleted file mode 100644 index 785cda8..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.3.3 \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js deleted file mode 100644 index 3af3184..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.es6.js +++ /dev/null @@ -1,3866 +0,0 @@ -// mingo.js 1.3.3 -// Copyright (c) 2017 Francis Asante -// https://github.com/kofrasa/mingo -// MIT - -/** - * Polyfill to add native methods for non-supported environments. - */ - -// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new Error('Function.prototype.bind - what is trying to be bound is not callable') - } - - var aArgs = Array.prototype.slice.call(arguments, 1); - var fToBind = this; - var fNOP = function () {}; - var fBound = function () { - return fToBind.apply( - (this instanceof fNOP) ? this : oThis, - aArgs.concat(Array.prototype.slice.call(arguments)) - ) - }; - - if (this.prototype) { - // Function.prototype doesn't have a prototype property - fNOP.prototype = this.prototype; - } - fBound.prototype = new fNOP(); - - return fBound - }; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find -if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this); - var len = o.length >>> 0; - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function') - } - - var thisArg = arguments[1]; - var k = 0; - - while (k < len) { - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return kValue - } - k++; - } - return undefined - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex -if (!Array.prototype.findIndex) { - Object.defineProperty(Array.prototype, 'findIndex', { - value: function(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this); - var len = o.length >>> 0; - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function') - } - - var thisArg = arguments[1]; - var k = 0; - while (k < len) { - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return k - } - k++; - } - return -1 - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes -if (!Array.prototype.includes) { - Object.defineProperty(Array.prototype, 'includes', { - value: function(searchElement, fromIndex) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this); - var len = o.length >>> 0; - - if (len === 0) { - return false - } - var n = fromIndex | 0; - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); - - function sameValueZero(x, y) { - return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) - } - - while (k < len) { - if (sameValueZero(o[k], searchElement)) { - return true - } - k++; - } - return false - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign -if (typeof Object.assign != 'function') { - Object.assign = function(target, varArgs) { // .length of function is 2 - - if (target == null) { - throw new TypeError('Cannot convert undefined or null to object') - } - - var to = Object(target); - var args = Array.prototype.slice.call(arguments); - - for (var index = 1; index < args.length; index++) { - var nextSource = args[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (nextSource.hasOwnProperty(nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to - }; -} - -// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html -if (!Object.keys) { - Object.keys = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.keys called on a non-object') - } - - var result = []; - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(k); - } - } - return result - }; -} - -// https://github.com/es-shims/Object.values/blob/master/implementation.js -if (!Object.values) { - Object.values = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.values called on a non-object') - } - var result = []; - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(o[k]); - } - } - return result - }; -} - -// Javascript native types -const T_NULL = 'null'; -const T_UNDEFINED = 'undefined'; -const T_BOOL = 'bool'; -const T_BOOLEAN = 'boolean'; -const T_NUMBER = 'number'; -const T_STRING = 'string'; -const T_DATE = 'date'; -const T_REGEX = 'regex'; -const T_REGEXP = 'regexp'; -const T_ARRAY = 'array'; -const T_OBJECT = 'object'; -const T_FUNCTION = 'function'; - -// no array, object, or function types -const JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP]; - -// operator classes -const OP_AGGREGATE = 'aggregate'; -const OP_GROUP = 'group'; -const OP_PIPELINE = 'pipeline'; -const OP_PROJECTION = 'projection'; -const OP_QUERY = 'query'; - -/** - * Utility functions - */ - -function assert (condition, message) { - if (falsey(condition)) err(message); -} - -/** - * Deep clone an object - * @param obj - * @returns {*} - */ -function clone (obj) { - switch (jsType(obj)) { - case T_ARRAY: - return obj.map(clone) - case T_OBJECT: - return map(obj, clone) - default: - return obj - } -} - -function getType (v) { - if (v === null) return 'Null' - if (v === undefined) return 'Undefined' - return v.constructor.name -} -function jsType (v) { return getType(v).toLowerCase() } -function isBoolean (v) { return jsType(v) === T_BOOLEAN } -function isString (v) { return jsType(v) === T_STRING } -function isNumber (v) { return jsType(v) === T_NUMBER } -function isArray (v) { return jsType(v) === T_ARRAY } -function isArrayLike (v) { return !isNil(v) && has(v, 'length') } -function isObject (v) { return jsType(v) === T_OBJECT } -function isObjectLike (v) { return v === Object(v) } // objects, arrays, functions, date, custom object -function isDate (v) { return jsType(v) === T_DATE } -function isRegExp (v) { return jsType(v) === T_REGEXP } -function isFunction (v) { return jsType(v) === T_FUNCTION } -function isNil (v) { return isNull(v) || isUndefined(v) } -function isNull (v) { return jsType(v) === T_NULL } -function isUndefined (v) { return jsType(v) === T_UNDEFINED } -function inArray (arr, item) { return arr.includes(item) } -function notInArray (arr, item) { return !arr.includes(item) } -function truthy (arg) { return !!arg } -function falsey (arg) { return !arg } -function isEmpty (x) { - return isNil(x) || - isArray(x) && x.length === 0 || - isObject(x) && keys(x).length === 0 || !x -} -// ensure a value is an array -function array (x) { return isArray(x) ? x : [x] } -function has (obj, prop) { return obj.hasOwnProperty(prop) } -function err (s) { throw new Error(s) } -function keys (o) { return Object.keys(o) } - -// ////////////////// UTILS //////////////////// - -// internal constants -const __MINGO_META = '__mingo__'; - -function addMeta (obj, value) { - obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value); -} - -function hasMeta (obj, value) { - return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]) -} - -function dropMeta (obj) { - if (has(obj, __MINGO_META)) delete obj[__MINGO_META]; -} - -/** - * Iterate over an array or object - * @param {Array|Object} obj An object-like value - * @param {Function} fn The callback to run per item - * @param {*} ctx The object to use a context - * @return {void} - */ -function each (obj, fn, ctx = null) { - assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'"); - - if (isArrayLike(obj)) { - for (let i = 0, len = obj.length; i < len; i++) { - if (fn.call(ctx, obj[i], i, obj) === false) break - } - } else { - for (let k in obj) { - if (has(obj, k)) { - if (fn.call(ctx, obj[k], k, obj) === false) break - } - } - } -} - -/** - * Transform values in a collection - * - * @param {Array|Object} obj An array/object whose values to transform - * @param {Function} fn The transform function - * @param {*} ctx The value to use as the "this" context for the transform - * @return {Array|Object} Result object after applying the transform - */ -function map (obj, fn, ctx = null) { - if (isArray(obj)) { - return obj.map(fn, ctx) - } else if (isObject(obj)) { - let o = {}; - each(obj, (v, k) => o[k] = fn.call(ctx, v, k), obj); - return o - } -} - -/** - * Reduce any array-like object - * @param collection - * @param fn - * @param accumulator - * @returns {*} - */ -function reduce (collection, fn, accumulator) { - if (isArray(collection)) return collection.reduce(fn, accumulator) - // array-like objects - each(collection, (v, k) => accumulator = fn(accumulator, v, k, collection)); - return accumulator -} - -/** - * Returns the intersection between two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} Result array - */ -function intersection (xs, ys) { - return xs.filter(inArray.bind(null, ys)) -} - -/** - * Returns the union of two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} The result array - */ -function union (xs, ys) { - return into(into([], xs), ys.filter(notInArray.bind(null, xs))) -} - -/** - * Flatten the array - * - * @param {Array} xs The array to flatten - * @param {Number} depth The number of nested lists to iterate - */ - - -/** - * Determine whether two values are the same or strictly equivalent - * - * @param {*} a The first value - * @param {*} b The second value - * @return {Boolean} Result of comparison - */ -function isEqual (a, b) { - // strictly equal must be equal. - if (a === b) return true - - // unequal types and functions cannot be equal. - let type = jsType(a); - if (type !== jsType(b) || type === T_FUNCTION) return false - - // we treat NaN as the same - if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true - - // leverage toString for Date and RegExp types - if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString() - - if (type === T_ARRAY) { - if (a.length === b.length && a.length === 0) return true - if (a.length !== b.length) return false - for (let i = 0, len = a.length; i < len; i++) { - if (!isEqual(a[i], b[i])) return false - } - } else if (type === T_OBJECT) { - // deep compare objects - let ka = keys(a); - let kb = keys(b); - - // check length of keys early - if (ka.length !== kb.length) return false - - // we know keys are strings so we sort before comparing - ka.sort(); - kb.sort(); - - // compare keys - if (!isEqual(ka, kb)) return false - - // back to the drawing board - for (let i = 0, len = ka.length; i < len; i++) { - let temp = ka[i]; - if (!isEqual(a[temp], b[temp])) return false - } - } else { - // we do not know how to compare custom types so we guess - return getHash(a) === getHash(b) - } - // best effort says values are equal :) - return true -} - -/** - * Return a new unique version of the collection - * @param {Array} xs The input collection - * @return {Array} A new collection with unique values - */ -function unique (xs) { - let h = {}; - let arr = []; - each(xs, (item) => { - let k = getHash(item); - if (!has(h, k)) { - arr.push(item); - h[k] = 0; - } - }); - return arr -} - -/** - * Generates a random string of max length range [24,27] - * @param n Size of string to return - * @returns {*} - */ -function randomString(n) { - return (Math.E + Math.random()).toString(36).slice(2, n+2) -} - -/** - * Encode value using a simple optimistic stable scheme. - * @param value - * @returns {*} - */ -function encode (value) { - let type = jsType(value); - switch (type) { - case T_FUNCTION: - return randomString(7) - case T_BOOLEAN: - case T_NUMBER: - case T_REGEXP: - return value.toString() - case T_STRING: - return JSON.stringify(value) - case T_DATE: - return value.toISOString() - case T_NULL: - case T_UNDEFINED: - return type - case T_ARRAY: - return '[' + map(value, (v) => `${encode(v)}`) + ']' - default: - let prefix = (type === T_OBJECT)? '' : `${getType(value)}|`; - let objKeys = keys(value); - objKeys.sort(); - return `${prefix}{` + map(objKeys, (k) => `${encode(k)}:${encode(value[k])}`) + '}' - } -} - -/** - * Generate hash code - * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery - * - * @param value - * @returns {*} - */ -function getHash (value) { - let hash = 0, i, chr, len, s = encode(value); - if (s.length === 0) return hash - for (i = 0, len = s.length; i < len; i++) { - chr = s.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer - } - return hash.toString() -} - -/** - * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee - * - * This implementation treats null/undefined sort keys as less than every other type - * - * @param {Array} collection - * @param {Function} fn The function used to resolve sort keys - * @param {Object} ctx The context to use for calling `fn` - * @return {Array} Returns a new sorted array by the given iteratee - */ -function sortBy (collection, fn, ctx = null) { - let sortKeys = {}; - let sorted = []; - let len = collection.length; - let result = []; - - for (let i = 0; i < len; i++) { - let obj = collection[i]; - let key = fn.call(ctx, obj, i); - if (isNil(key)) { - // objects with null keys will go in first - result.push(obj); - } else { - let hash = getHash(obj); - if (!has(sortKeys, hash)) { - sortKeys[hash] = [key, i]; - } - sorted.push(obj); - } - } - // use native array sorting but enforce stableness - sorted.sort((a, b) => { - let A = sortKeys[getHash(a)]; - let B = sortKeys[getHash(b)]; - if (A[0] < B[0]) return -1 - if (A[0] > B[0]) return 1 - if (A[1] < B[1]) return -1 - if (A[1] > B[1]) return 1 - return 0 - }); - return into(result, sorted) -} - -/** - * Groups the collection into sets by the returned key - * - * @param collection - * @param fn {Function} to compute the group key of an item in the collection - * @param ctx {Object} The context to use for calling `fn` - * @returns {{keys: Array, groups: Array}} - */ -function groupBy (collection, fn, ctx) { - let result = { - 'keys': [], - 'groups': [] - }; - let lookup = {}; - each(collection, (obj) => { - let key = fn.call(ctx, obj); - let hash = getHash(key); - let index = -1; - - if (isUndefined(lookup[hash])) { - index = result.keys.length; - lookup[hash] = index; - result.keys.push(key); - result.groups.push([]); - } - index = lookup[hash]; - result.groups[index].push(obj); - }); - return result -} - -/** - * Push elements in given array into target array - * - * @param {*} target The array to push into - * @param {*} xs The array of elements to push - */ -function into (target, xs) { - Array.prototype.push.apply(target, xs); - return target -} - -/** - * Find the insert index for the given key in a sorted array. - * - * @param {*} array The sorted array to search - * @param {*} key The search key - */ -function findInsertIndex (array, key) { - // uses binary search - let lo = 0; - let hi = array.length - 1; - while (lo <= hi) { - let mid = Math.round(lo + (hi - lo) / 2); - if (key < array[mid]) { - hi = mid - 1; - } else if (key > array[mid]) { - lo = mid + 1; - } else { - return mid - } - } - return lo -} - -/** - * This is a generic memoization function - * - * This implementation uses a cache independent of the function being memoized - * to allow old values to be garbage collected when the memoized function goes out of scope. - * - * @param {*} fn The function object to memoize - */ -function memoize (fn) { - return ((cache) => { - return (...args) => { - let key = getHash(args); - if (!has(cache, key)) { - cache[key] = fn.apply(this, args); - } - return cache[key] - } - })({/* storage */}) -} - -/** - * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ - */ - -const groupOperators = { - - /** - * Returns an array of all the unique values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {*} - */ - $addToSet (collection, expr) { - return unique(this.$push(collection, expr)) - }, - - /** - * Returns the sum of all the values in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $sum (collection, expr) { - if (!isArray(collection)) return 0 - - if (isNumber(expr)) { - // take a short cut if expr is number literal - return collection.length * expr - } - return reduce(this.$push(collection, expr).filter(isNumber), (acc, n) => acc + n, 0) - }, - - /** - * Returns the highest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $max (collection, expr) { - let mapped = this.$push(collection, expr); - return reduce(mapped, (acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) - }, - - /** - * Returns the lowest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $min (collection, expr) { - let mapped = this.$push(collection, expr); - return reduce(mapped, (acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) - }, - - /** - * Returns an average of all the values in a group. - * - * @param collection - * @param expr - * @returns {number} - */ - $avg (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber); - let sum = reduce(data, (acc, n) => acc + n, 0); - return sum / (data.length || 1) - }, - - /** - * Returns an array of all values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $push (collection, expr) { - if (isNil(expr)) return collection - return map(collection, (obj) => computeValue(obj, expr)) - }, - - /** - * Returns the first value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $first (collection, expr) { - return (collection.length > 0) ? computeValue(collection[0], expr) : undefined - }, - - /** - * Returns the last value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $last (collection, expr) { - return (collection.length > 0) ? computeValue(collection[collection.length - 1], expr) : undefined - }, - - /** - * Returns the population standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number} - */ - $stdDevPop (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber); - return stddev({ data: data, sampled: false }) - }, - - /** - * Returns the sample standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number|null} - */ - $stdDevSamp (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber); - return stddev({ data: data, sampled: true }) - } -}; - -/** - * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ - */ -const projectionOperators = { - - /** - * Projects the first element in an array that matches the query condition. - * - * @param obj - * @param field - * @param expr - */ - $ (obj, expr, field) { - err('$ not implemented'); - }, - - /** - * Projects only the first element from an array that matches the specified $elemMatch condition. - * - * @param obj - * @param field - * @param expr - * @returns {*} - */ - $elemMatch (obj, expr, field) { - let arr = resolve(obj, field); - let query = new Query(expr); - - if (isNil(arr) || !isArray(arr)) { - return undefined - } - - for (let i = 0; i < arr.length; i++) { - if (query.test(arr[i])) { - return [arr[i]] - } - } - - return undefined - }, - - /** - * Limits the number of elements projected from an array. Supports skip and limit slices. - * - * @param obj - * @param field - * @param expr - */ - $slice (obj, expr, field) { - let xs = resolve(obj, field); - - if (!isArray(xs)) return xs - - if (isArray(expr)) { - return slice(xs, expr[0], expr[1]) - } else if (isNumber(expr)) { - return slice(xs, expr) - } else { - err('Invalid argument type for $slice projection operator'); - } - }, - - /** - * Returns the population standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number} - */ - $stdDevPop (obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: false - }) - }, - - /** - * Returns the sample standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number|null} - */ - $stdDevSamp (obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: true - }) - } -}; - -/** - * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ - */ -const pipelineOperators = { - - /** - * Adds new fields to documents. - * Outputs documents that contain all existing fields from the input documents and newly added fields. - * - * @param {Array} collection - * @param {*} expr - */ - $addFields (collection, expr) { - let newFields = keys(expr); - - return collection.map((obj) => { - obj = clone(obj); - each(newFields, (field) => { - let subExpr = expr[field]; - let newValue = computeValue(obj, subExpr); - traverse(obj, field, (o, key) => { - o[key] = newValue; - }, true); - }); - return obj - }) - }, - - /** - * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $group (collection, expr) { - // lookup key for grouping - const ID_KEY = idKey(); - let objectId = expr[ID_KEY]; - - let partitions = groupBy(collection, (obj) => { - return computeValue(obj, objectId, objectId) - }); - - let result = []; - - // remove the group key - delete expr[ID_KEY]; - - each(partitions.keys, (value, i) => { - let obj = {}; - - // exclude undefined key value - if (!isUndefined(value)) { - obj[ID_KEY] = value; - } - - // compute remaining keys in expression - each(expr, (val, key) => { - obj[key] = accumulate(partitions.groups[i], key, val); - }); - result.push(obj); - }); - - return result - }, - - /** - * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. - * - * @param collection - * @param expr - */ - $lookup (collection, expr) { - let joinColl = expr.from; - let localField = expr.localField; - let foreignField = expr.foreignField; - let asField = expr.as; - - let errorMsg = "Invalid $lookup expression. "; - assert(isArray(joinColl), errorMsg + "'from' must be an array"); - assert(isString(foreignField), errorMsg + "'foreignField' must be a string"); - assert(isString(localField), errorMsg + "'localField' must be a string"); - assert(isString(asField), errorMsg + "'as' must be a string"); - - let result = []; - let hash = {}; - - function hashCode (v) { - return getHash(isNil(v) ? null : v) - } - - if (joinColl.length <= collection.length) { - each(joinColl, (obj, i) => { - let k = hashCode(obj[foreignField]); - hash[k] = hash[k] || []; - hash[k].push(i); - }); - - each(collection, (obj) => { - let k = hashCode(obj[localField]); - let indexes = hash[k] || []; - let newObj = clone(obj); - newObj[asField] = indexes.map((i) => clone(joinColl[i])); - result.push(newObj); - }); - - } else { - - each(collection, (obj, i) => { - let k = hashCode(obj[localField]); - hash[k] = hash[k] || []; - hash[k].push(i); - }); - - let tempResult = {}; - each(joinColl, (obj) => { - let k = hashCode(obj[foreignField]); - let indexes = hash[k] || []; - each(indexes, (i) => { - let newObj = tempResult[i] || clone(collection[i]); - newObj[asField] = newObj[asField] || []; - newObj[asField].push(clone(obj)); - tempResult[i] = newObj; - }); - }); - for (let i = 0, len = keys(tempResult).length; i < len; i++) { - result.push(tempResult[i]); - } - } - - return result - }, - - /** - * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. - * $match uses standard MongoDB queries. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $match (collection, expr) { - return (new Query(expr)).find(collection).all() - }, - - /** - * Reshapes a document stream. - * $project can rename, add, or remove fields as well as create computed values and sub-documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $project (collection, expr) { - if (isEmpty(expr)) { - return collection - } - - // result collection - let projected = []; - let objKeys = keys(expr); - let idOnlyExcludedExpression = false; - const ID_KEY = idKey(); - - // validate inclusion and exclusion - let check = [false, false]; - each(expr, (v, k) => { - if (k === ID_KEY) return - if (v === 0 || v === false) { - check[0] = true; - } else { - check[1] = true; - } - assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.'); - }); - - if (inArray(objKeys, ID_KEY)) { - let id = expr[ID_KEY]; - if (id === 0 || id === false) { - objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])); - assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key'); - idOnlyExcludedExpression = isEmpty(objKeys); - } - } else { - // if not specified the add the ID field - objKeys.push(ID_KEY); - } - - each(collection, (obj) => { - let cloneObj = {}; - let foundSlice = false; - let foundExclusion = false; - let dropKeys = []; - - if (idOnlyExcludedExpression) { - dropKeys.push(ID_KEY); - } - - each(objKeys, (key) => { - let subExpr = expr[key]; - let value; // final computed value of the key - - if (key !== ID_KEY && subExpr === 0) { - foundExclusion = true; - } - - if (key === ID_KEY && isEmpty(subExpr)) { - // tiny optimization here to skip over id - value = obj[key]; - } else if (isString(subExpr)) { - value = computeValue(obj, subExpr, key); - } else if (subExpr === 1 || subExpr === true) { - // For direct projections, we use the resolved object value - } else if (isObject(subExpr)) { - let operator = keys(subExpr); - operator = operator.length > 1 ? false : operator[0]; - - if (inArray(ops(OP_PROJECTION), operator)) { - // apply the projection operator on the operator expression for the key - if (operator === '$slice') { - // $slice is handled differently for aggregation and projection operations - if (array(subExpr[operator]).every(isNumber)) { - // $slice for projection operation - value = projectionOperators[operator](obj, subExpr[operator], key); - foundSlice = true; - } else { - // $slice for aggregation operation - value = computeValue(obj, subExpr, key); - } - } else { - value = projectionOperators[operator](obj, subExpr[operator], key); - } - } else { - // compute the value for the sub expression for the key - value = computeValue(obj, subExpr, key); - } - } else { - dropKeys.push(key); - return - } - - // clone resolved values - let objValue = clone(resolveObj(obj, key)); - - if (!isUndefined(objValue)) { - Object.assign(cloneObj, objValue); - } - if (!isUndefined(value)) { - setValue(cloneObj, key, clone(value)); - } - - }); - // if projection included $slice operator - // Also if exclusion fields are found or we want to exclude only the id field - // include keys that were not explicitly excluded - if (foundSlice || foundExclusion || idOnlyExcludedExpression) { - cloneObj = Object.assign(clone(obj), cloneObj); - each(dropKeys, (key) => removeValue(cloneObj, key)); - } - projected.push(cloneObj); - }); - - return projected - }, - - /** - * Restricts the number of documents in an aggregation pipeline. - * - * @param collection - * @param value - * @returns {Object|*} - */ - $limit (collection, value) { - return collection.slice(0, value) - }, - - /** - * Skips over a specified number of documents from the pipeline and returns the rest. - * - * @param collection - * @param value - * @returns {*} - */ - $skip (collection, value) { - return collection.slice(value) - }, - - /** - * Takes an array of documents and returns them as a stream of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $unwind (collection, expr) { - let result = []; - let field = expr.substr(1); - each(collection, (obj) => { - // must throw an error if value is not an array - let value = getValue(obj, field); - - assert(isArray(value), "Target field '" + field + "' is not of type Array."); - - each(value, (item) => { - let tmp = clone(obj); - tmp[field] = item; - result.push(tmp); - }); - }); - return result - }, - - /** - * Takes all input documents and returns them in a stream of sorted documents. - * - * @param collection - * @param sortKeys - * @returns {*} - */ - $sort (collection, sortKeys) { - if (!isEmpty(sortKeys) && isObject(sortKeys)) { - let modifiers = keys(sortKeys); - each(modifiers.reverse(), (key) => { - let grouped = groupBy(collection, (obj) => resolve(obj, key)); - let sortedIndex = {}; - let getIndex = (k) => sortedIndex[getHash(k)]; - - let indexKeys = sortBy(grouped.keys, (item, i) => { - sortedIndex[getHash(item)] = i; - return item - }); - - if (sortKeys[key] === -1) { - indexKeys.reverse(); - } - collection = []; - each(indexKeys, (item) => into(collection, grouped.groups[getIndex(item)])); - }); - } - return collection - }, - - /** - * Groups incoming documents based on the value of a specified expression, - * then computes the count of documents in each distinct group. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sortByCount (collection, expr) { - let newExpr = { count: { $sum: 1 } }; - newExpr[idKey()] = expr; - - return this.$sort( - this.$group(collection, newExpr), - { count: -1 } - ) - }, - - /** - * Randomly selects the specified number of documents from its input. - * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sample (collection, expr) { - let size = expr.size; - assert(isNumber(size), '$sample size must be a positive integer'); - - let result = []; - let len = collection.length; - for (let i = 0; i < size; i++) { - let n = Math.floor(Math.random() * len); - result.push(collection[n]); - } - return result - }, - - /** - * Returns a document that contains a count of the number of documents input to the stage. - * @param {Array} collection - * @param {String} expr - * @return {Object} - */ - $count (collection, expr) { - assert( - isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', - 'Invalid expression value for $count' - ); - - let result = {}; - result[expr] = collection.length; - return result - }, - - /** - * Replaces a document with the specified embedded document or new one. - * The replacement document can be any valid expression that resolves to a document. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $replaceRoot (collection, expr) { - let newRoot = expr.newRoot; - let result = []; - each(collection, (obj) => { - obj = computeValue(obj, newRoot); - assert(isObject(obj), '$replaceRoot expression must return a valid JS object'); - result.push(obj); - }); - return result - }, - - /** - * Restricts the contents of the documents based on information stored in the documents themselves. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ - */ - $redact (collection, expr) { - return collection.map((obj) => { - return redactObj(clone(obj), expr) - }) - }, - - /** - * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ - */ - $bucket (collection, expr) { - let boundaries = expr.boundaries; - let defaultKey = expr.default; - let lower = boundaries[0]; // inclusive - let upper = boundaries[boundaries.length - 1]; // exclusive - let outputExpr = expr.output || { 'count': { '$sum': 1 } }; - - assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements"); - let boundType = getType(lower); - - for (let i = 0, len = boundaries.length - 1; i < len; i++) { - assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type"); - assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order"); - } - - if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { - assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range"); - } - - let grouped = {}; - each(boundaries, (k) => grouped[k] = []); - - // add default key if provided - if (!isNil(defaultKey)) grouped[defaultKey] = []; - - each(collection, (obj) => { - let key = computeValue(obj, expr.groupBy); - - if (isNil(key) || key < lower || key >= upper) { - assert(!isNil(defaultKey), '$bucket require a default for out of range values'); - grouped[defaultKey].push(obj); - } else if (key >= lower && key < upper) { - let index = findInsertIndex(boundaries, key); - let boundKey = boundaries[Math.max(0, index - 1)]; - grouped[boundKey].push(obj); - } else { - err("$bucket 'groupBy' expression must resolve to a value in range of boundaries"); - } - }); - - // upper bound is exclusive so we remove it - boundaries.pop(); - if (!isNil(defaultKey)) boundaries.push(defaultKey); - - return map(boundaries, (key) => { - let acc = accumulate(grouped[key], null, outputExpr); - return Object.assign(acc, { '_id': key }) - }) - }, - - $bucketAuto (collection, expr) { - let outputExpr = expr.output || { 'count': { '$sum': 1 } }; - let groupByExpr = expr.groupBy; - let bucketCount = expr.buckets; - - assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount); - - let approxBucketSize = Math.round(collection.length / bucketCount); - if (approxBucketSize < 1) { - approxBucketSize = 1; - } - - let computeValueOptimized = memoize(computeValue); - let grouped = {}; - let remaining = []; - let sorted = sortBy(collection, (o) => { - let key = computeValueOptimized(o, groupByExpr); - if (isNil(key)) { - remaining.push(o); - } else { - grouped[key] || (grouped[key] = []); - grouped[key].push(o); - } - return key - }); - - const ID_KEY = idKey(); - let result = []; - let index = 0; // counter for sorted collection - - for (let i = 0, len = sorted.length; i < bucketCount && index < len; i++) { - let boundaries = {}; - let bucketItems = []; - - for (let j = 0; j < approxBucketSize && index < len; j++) { - let key = computeValueOptimized(sorted[index], groupByExpr); - - if (isNil(key)) key = null; - - // populate current bucket with all values for current key - into(bucketItems, isNil(key) ? remaining : grouped[key]); - - // increase sort index by number of items added - index += (isNil(key) ? remaining.length : grouped[key].length); - - // set the min key boundary if not already present - if (!has(boundaries, 'min')) boundaries.min = key; - - if (result.length > 0) { - let lastBucket = result[result.length - 1]; - lastBucket[ID_KEY].max = boundaries.min; - } - } - - // if is last bucket add remaining items - if (i == bucketCount - 1) { - into(bucketItems, sorted.slice(index)); - } - - result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })); - } - - if (result.length > 0) { - result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr); - } - - return result - }, - - /** - * Processes multiple aggregation pipelines within a single stage on the same set of input documents. - * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. - */ - $facet (collection, expr) { - return map(expr, (pipeline) => aggregate(collection, pipeline)) - } -}; - -/** - * Returns the result of evaluating a $group operation over a collection - * - * @param collection - * @param field the name of the aggregate operator or field - * @param expr the expression of the aggregate operator for the field - * @returns {*} - */ -function accumulate (collection, field, expr) { - if (inArray(ops(OP_GROUP), field)) { - return groupOperators[field](collection, expr) - } - - if (isObject(expr)) { - let result = {}; - each(expr, (val, key) => { - result[key] = accumulate(collection, key, expr[key]); - // must run ONLY one group operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_GROUP), key)) { - result = result[key]; - // if there are more keys in expression this is bad - assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'"); - return false // break - } - }); - return result - } - - return undefined -} - -/** - * Aggregator for defining filter using mongoDB aggregation pipeline syntax - * - * @param operators an Array of pipeline operators - * @constructor - */ -class Aggregator { - - constructor (operators) { - this.__operators = operators; - } - - /** - * Apply the pipeline operations over the collection by order of the sequence added - * - * @param collection an array of objects to process - * @param query the `Query` object to use as context - * @returns {Array} - */ - run (collection, query) { - if (!isEmpty(this.__operators)) { - // run aggregation pipeline - each(this.__operators, (operator) => { - let key = keys(operator); - assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), `Invalid aggregation operator ${key}`); - key = key[0]; - if (query && query instanceof Query) { - collection = pipelineOperators[key].call(query, collection, operator[key]); - } else { - collection = pipelineOperators[key](collection, operator[key]); - } - }); - } - return collection - } -} - -/** - * Return the result collection after running the aggregation pipeline for the given collection - * - * @param collection - * @param pipeline - * @returns {Array} - */ -function aggregate (collection, pipeline) { - assert(isArray(pipeline), 'Aggregation pipeline must be an array'); - return (new Aggregator(pipeline)).run(collection) -} - -/** - * Cursor to iterate and perform filtering on matched objects - * @param collection - * @param query - * @param projection - * @constructor - */ -class Cursor { - - constructor (collection, query, projection) { - this.__query = query; - this.__collection = collection; - this.__projection = projection || query.__projection; - this.__operators = {}; - this.__result = false; - this.__position = 0; - } - - _fetch () { - - if (this.__result !== false) { - return this.__result - } - - // inject projection operator - if (isObject(this.__projection)) { - Object.assign(this.__operators, { '$project': this.__projection }); - } - - assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); - - // filter collection - this.__result = this.__collection.filter(this.__query.test, this.__query); - let pipeline = []; - - each(['$sort', '$skip', '$limit', '$project'], (op) => { - if (has(this.__operators, op)) { - let selected = {}; - selected[op] = this.__operators[op]; - pipeline.push(selected); - } - }); - - if (pipeline.length > 0) { - let aggregator = new Aggregator(pipeline); - this.__result = aggregator.run(this.__result, this.__query); - } - return this.__result - } - - /** - * Fetch and return all matched results - * @returns {Array} - */ - all () { - return this._fetch() - } - - /** - * Fetch and return the first matching result - * @returns {Object} - */ - first () { - return this.count() > 0 ? this._fetch()[0] : null - } - - /** - * Fetch and return the last matching object from the result - * @returns {Object} - */ - last () { - return this.count() > 0 ? this._fetch()[this.count() - 1] : null - } - - /** - * Counts the number of matched objects found - * @returns {Number} - */ - count () { - return this._fetch().length - } - - /** - * Returns a cursor that begins returning results only after passing or skipping a number of documents. - * @param {Number} n the number of results to skip. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - skip (n) { - Object.assign(this.__operators, { '$skip': n }); - return this - } - - /** - * Constrains the size of a cursor's result set. - * @param {Number} n the number of results to limit to. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - limit (n) { - Object.assign(this.__operators, { '$limit': n }); - return this - } - - /** - * Returns results ordered according to a sort specification. - * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - sort (modifier) { - Object.assign(this.__operators, { '$sort': modifier }); - return this - } - - /** - * Returns the next document in a cursor. - * @returns {Object | Boolean} - */ - next () { - if (this.hasNext()) { - return this._fetch()[this.__position++] - } - return null - } - - /** - * Returns true if the cursor has documents and can be iterated. - * @returns {boolean} - */ - hasNext () { - return this.count() > this.__position - } - - /** - * Specifies the exclusive upper bound for a specific field - * @param expr - * @returns {Number} - */ - max (expr) { - return groupOperators.$max(this._fetch(), expr) - } - - /** - * Specifies the inclusive lower bound for a specific field - * @param expr - * @returns {Number} - */ - min (expr) { - return groupOperators.$min(this._fetch(), expr) - } - - /** - * Applies a function to each document in a cursor and collects the return values in an array. - * @param callback - * @returns {Array} - */ - map (callback) { - return this._fetch().map(callback) - } - - /** - * Applies a JavaScript function for every document in a cursor. - * @param callback - */ - forEach (callback) { - each(this._fetch(), callback); - } - - /** - * Applies an [ES2015 Iteration protocol][] compatible implementation - * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols - * @returns {Object} - */ - [Symbol.iterator] () { - let self = this; - return { - next () { - if (!self.hasNext()) { - return { done: true } - } - return { - done: false, - value: self.next() - } - } - } - } -} - -/** - * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ - */ -const simpleOperators = { - - /** - * Checks that two values are equal. - * - * @param a The lhs operand as resolved from the object by the given selector - * @param b The rhs operand provided by the user - * @returns {*} - */ - $eq (a, b) { - // start with simple equality check - if (isEqual(a, b)) return true - - // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ - if (isNil(a) && isNil(b)) return true - - if (isArray(a)) { - // is multi-valued lhs so we check each separately - if (hasMeta(a, { isMulti: true })) { - try { - for (let i = 0; i < a.length; i++) { - if (this.$eq(a[i], b)) { - return true; - } - } - } finally { - dropMeta(a); - } - } else { - // check one level deep - return a.findIndex(isEqual.bind(null, b)) !== -1 - } - } - return false; - }, - - /** - * Matches all values that are not equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $ne (a, b) { - return !this.$eq(a, b) - }, - - /** - * Matches any of the values that exist in an array specified in the query. - * - * @param a - * @param b - * @returns {*} - */ - $in (a, b) { - a = array(a); - return intersection(a, b).length > 0 - }, - - /** - * Matches values that do not exist in an array specified to the query. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $nin (a, b) { - return isNil(a) || !this.$in(a, b) - }, - - /** - * Matches values that are less than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lt (a, b) { - a = array(a).find((val) => val < b); - return a !== undefined - }, - - /** - * Matches values that are less than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lte (a, b) { - a = array(a).find((val) => val <= b); - return a !== undefined - }, - - /** - * Matches values that are greater than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gt (a, b) { - a = array(a).find((val) => val > b); - return a !== undefined - }, - - /** - * Matches values that are greater than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gte (a, b) { - a = array(a).find((val) => val >= b); - return a !== undefined - }, - - /** - * Performs a modulo operation on the value of a field and selects documents with a specified result. - * - * @param a - * @param b - * @returns {boolean} - */ - $mod (a, b) { - a = array(a).find((val) => isNumber(val) && isArray(b) && b.length === 2 && (val % b[0]) === b[1]); - return a !== undefined - }, - - /** - * Selects documents where values match a specified regular expression. - * - * @param a - * @param b - * @returns {boolean} - */ - $regex (a, b) { - a = array(a).find((val) => isString(val) && isRegExp(b) && (!!val.match(b))); - return a !== undefined - }, - - /** - * Matches documents that have the specified field. - * - * @param a - * @param b - * @returns {boolean} - */ - $exists (a, b) { - return ((b === false || b === 0) && isNil(a)) || ((b === true || b === 1) && !isNil(a)) - }, - - /** - * Matches arrays that contain all elements specified in the query. - * - * @param a - * @param b - * @returns boolean - */ - $all (a, b) { - let matched = false; - if (isArray(a) && isArray(b)) { - for (let i = 0, len = b.length; i < len; i++) { - if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { - matched = matched || this.$elemMatch(a, b[i].$elemMatch); - } else { - // order of arguments matter - return intersection(b, a).length === len - } - } - } - return matched - }, - - /** - * Selects documents if the array field is a specified size. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $size (a, b) { - return isArray(a) && isNumber(b) && (a.length === b) - }, - - /** - * Selects documents if element in the array field matches all the specified $elemMatch condition. - * - * @param a - * @param b - */ - $elemMatch (a, b) { - if (isArray(a) && !isEmpty(a)) { - let query = new Query(b); - for (let i = 0, len = a.length; i < len; i++) { - if (query.test(a[i])) { - return true - } - } - } - return false - }, - - /** - * Selects documents if a field is of the specified type. - * - * @param a - * @param b - * @returns {boolean} - */ - $type (a, b) { - switch (b) { - case 1: - case 'double': - return isNumber(a) && (a + '').indexOf('.') !== -1 - case 2: - case T_STRING: - return isString(a) - case 3: - case T_OBJECT: - return isObject(a) - case 4: - case T_ARRAY: - return isArray(a) - case 6: - case T_UNDEFINED: - return isNil(a) - case 8: - case T_BOOL: - return isBoolean(a) - case 9: - case T_DATE: - return isDate(a) - case 10: - case T_NULL: - return isNull(a) - case 11: - case T_REGEX: - return isRegExp(a) - case 16: - case 'int': - return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1 - case 18: - case 'long': - return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1 - case 19: - case 'decimal': - return isNumber(a) - default: - return false - } - } -}; - -const queryOperators = { - - /** - * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $and (selector, value) { - assert(isArray(value), 'Invalid expression: $and expects value to be an Array'); - - let queries = []; - each(value, (expr) => queries.push(new Query(expr))); - - return { - test (obj) { - for (let i = 0; i < queries.length; i++) { - if (!queries[i].test(obj)) { - return false - } - } - return true - } - } - }, - - /** - * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $or (selector, value) { - assert(isArray(value),'Invalid expression. $or expects value to be an Array'); - - let queries = []; - each(value, (expr) => queries.push(new Query(expr))); - - return { - test (obj) { - for (let i = 0; i < queries.length; i++) { - if (queries[i].test(obj)) { - return true - } - } - return false - } - } - }, - - /** - * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $nor (selector, value) { - assert(isArray(value),'Invalid expression. $nor expects value to be an Array'); - let query = this.$or('$or', value); - return { - test (obj) { - return !query.test(obj) - } - } - }, - - /** - * Inverts the effect of a query expression and returns documents that do not match the query expression. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $not (selector, value) { - let criteria = {}; - criteria[selector] = normalize(value); - let query = new Query(criteria); - return { - test (obj) { - return !query.test(obj) - } - } - }, - - /** - * Matches documents that satisfy a JavaScript expression. - * - * @param selector - * @param value - * @returns {{test: test}} - */ - $where (selector, value) { - if (!isFunction(value)) { - value = new Function('return ' + value + ';'); - } - return { - test (obj) { - return value.call(obj) === true - } - } - } -}; - -// add simple query operators -each(simpleOperators, (fn, op) => { - queryOperators[op] = ((f, ctx) => { - return (selector, value) => { - return { - test (obj) { - // value of field must be fully resolved. - let lhs = resolve(obj, selector); - return f.call(ctx, lhs, value) - } - } - } - })(fn, simpleOperators); -}); - -/** - * Query object to test collection elements with - * @param criteria the pass criteria for the query - * @param projection optional projection specifiers - * @constructor - */ -class Query { - - constructor (criteria, projection = {}) { - this.__criteria = criteria; - this.__projection = projection; - this.__compiled = []; - this._compile(); - } - - _compile () { - if (isEmpty(this.__criteria)) return - - assert(isObject(this.__criteria), 'Criteria must be of type Object'); - - let whereOperator; - - each(this.__criteria, (expr, field) => { - // save $where operators to be executed after other operators - if ('$where' === field) { - whereOperator = { field: field, expr: expr }; - } else if (inArray(['$and', '$or', '$nor'], field)) { - this._processOperator(field, field, expr); - } else { - // normalize expression - expr = normalize(expr); - each(expr, (val, op) => { - this._processOperator(field, op, val); - }); - } - - if (isObject(whereOperator)) { - this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); - } - }); - } - - _processOperator (field, operator, value) { - if (inArray(ops(OP_QUERY), operator)) { - this.__compiled.push(queryOperators[operator](field, value)); - } else { - err("Invalid query operator '" + operator + "' detected"); - } - } - - /** - * Checks if the object passes the query criteria. Returns true if so, false otherwise. - * @param obj - * @returns {boolean} - */ - test (obj) { - for (let i = 0, len = this.__compiled.length; i < len; i++) { - if (!this.__compiled[i].test(obj)) { - return false - } - } - return true - } - - /** - * Performs a query on a collection and returns a cursor object. - * @param collection - * @param projection - * @returns {Cursor} - */ - find (collection, projection) { - return new Cursor(collection, this, projection) - } - - /** - * Remove matched documents from the collection returning the remainder - * @param collection - * @returns {Array} - */ - remove (collection) { - return reduce(collection, (acc, obj) => { - if (!this.test(obj)) acc.push(obj); - return acc - }, []) - } -} - -/** - * Performs a query on a collection and returns a cursor object. - * - * @param collection - * @param criteria - * @param projection - * @returns {Cursor} - */ -function find (collection, criteria, projection) { - return new Query(criteria).find(collection, projection) -} - -/** - * Returns a new array without objects which match the criteria - * - * @param collection - * @param criteria - * @returns {Array} - */ -function remove (collection, criteria) { - return new Query(criteria).remove(collection) -} - -const arithmeticOperators = { - - /** - * Returns the absolute value of a number. - * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs - * @param obj - * @param expr - * @return {Number|null|NaN} - */ - $abs (obj, expr) { - let val = computeValue(obj, expr); - return (val === null || val === undefined) ? null : Math.abs(val) - }, - - /** - * Computes the sum of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $add (obj, expr) { - let args = computeValue(obj, expr); - return reduce(args, (acc, num) => acc + num, 0) - }, - - /** - * Returns the smallest integer greater than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $ceil (obj, expr) { - let arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.'); - return Math.ceil(arg) - }, - - /** - * Takes two numbers and divides the first number by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $divide (obj, expr) { - let args = computeValue(obj, expr); - return args[0] / args[1] - }, - - /** - * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {number} - */ - $exp (obj, expr) { - let arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.'); - return Math.exp(arg) - }, - - /** - * Returns the largest integer less than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $floor (obj, expr) { - let arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.'); - return Math.floor(arg) - }, - - /** - * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $ln (obj, expr) { - let arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.'); - return Math.log(arg) - }, - - /** - * Calculates the log of a number in the specified base and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log (obj, expr) { - let args = computeValue(obj, expr); - assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items'); - if (args.some(isNaN)) return NaN - if (args.some(isNil)) return null - assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers'); - return Math.log10(args[0]) / Math.log10(args[1]) - }, - - /** - * Calculates the log base 10 of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log10 (obj, expr) { - let arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.'); - return Math.log10(arg) - }, - - /** - * Takes two numbers and calculates the modulo of the first number divided by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $mod (obj, expr) { - let args = computeValue(obj, expr); - return args[0] % args[1] - }, - - /** - * Computes the product of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $multiply (obj, expr) { - let args = computeValue(obj, expr); - return reduce(args, (acc, num) => acc * num, 1) - }, - - /** - * Raises a number to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {Object} - */ - $pow (obj, expr) { - let args = computeValue(obj, expr); - - assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers'); - assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent'); - - return Math.pow(args[0], args[1]) - }, - - /** - * Calculates the square root of a positive number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $sqrt (obj, expr) { - let n = computeValue(obj, expr); - if (isNaN(n)) return NaN - if (isNil(n)) return null - assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.'); - return Math.sqrt(n) - }, - - /** - * Takes an array that contains two numbers or two dates and subtracts the second value from the first. - * - * @param obj - * @param expr - * @returns {number} - */ - $subtract (obj, expr) { - let args = computeValue(obj, expr); - return args[0] - args[1] - }, - - /** - * Truncates a number to its integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $trunc (obj, expr) { - let n = computeValue(obj, expr); - if (isNaN(n)) return NaN - if (isNil(n)) return null - assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.'); - return Math.trunc(n) - } -}; - -const arrayOperators = { - /** - * Returns the element at the specified array index. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $arrayElemAt (obj, expr) { - let arr = computeValue(obj, expr); - assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements'); - assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array'); - assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer'); - let idx = arr[1]; - arr = arr[0]; - if (idx < 0 && Math.abs(idx) <= arr.length) { - return arr[idx + arr.length] - } else if (idx >= 0 && idx < arr.length) { - return arr[idx] - } - return undefined - }, - - /** - * Converts an array of key value pairs to a document. - */ - $arrayToObject (obj, expr) { - let arr = computeValue(obj, expr); - assert(isArray(arr), '$arrayToObject expression must resolve to an array'); - return reduce(arr, (newObj, val) => { - if (isArray(val) && val.length == 2) newObj[val[0]] = val[1]; - else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v; - else err('$arrayToObject expression is invalid.'); - return newObj - }, {}) - }, - - /** - * Concatenates arrays to return the concatenated array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $concatArrays (obj, expr) { - let arr = computeValue(obj, expr, null); - assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements'); - - if (arr.some(isNil)) return null - - return arr[0].concat(arr[1]) - }, - - /** - * Selects a subset of the array to return an array with only the elements that match the filter condition. - * - * @param {Object} obj [description] - * @param {*} expr [description] - * @return {*} [description] - */ - $filter (obj, expr) { - let input = computeValue(obj, expr.input); - let asVar = expr['as']; - let condExpr = expr['cond']; - - assert(isArray(input), "$filter 'input' expression must resolve to an array"); - - return input.filter((o) => { - // inject variable - let tempObj = {}; - tempObj['$' + asVar] = o; - return computeValue(tempObj, condExpr) === true - }) - }, - - /** - * Returns a boolean indicating whether a specified value is in an array. - * - * @param {Object} obj - * @param {Array} expr - */ - $in (obj, expr) { - let val = computeValue(obj, expr[0]); - let arr = computeValue(obj, expr[1]); - assert(isArray(arr), '$in second argument must be an array'); - return inArray(arr, val) - }, - - /** - * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfArray (obj, expr) { - let args = computeValue(obj, expr); - if (isNil(args)) return null - - let arr = args[0]; - if (isNil(arr)) return null - - assert(isArray(arr), '$indexOfArray expression must resolve to an array.'); - - let searchValue = args[1]; - if (isNil(searchValue)) return null - - let start = args[2] || 0; - let end = args[3] || arr.length; - - if (end < arr.length) { - arr = arr.slice(start, end); - } - - return arr.indexOf(searchValue, start) - }, - - /** - * Determines if the operand is an array. Returns a boolean. - * - * @param {Object} obj - * @param {*} expr - * @return {Boolean} - */ - $isArray (obj, expr) { - return isArray(computeValue(obj, expr)) - }, - - /** - * Applies a sub-expression to each element of an array and returns the array of resulting values in order. - * - * @param obj - * @param expr - * @returns {Array|*} - */ - $map (obj, expr) { - let inputExpr = computeValue(obj, expr.input); - assert(isArray(inputExpr), `$map 'input' expression must resolve to an array`); - - let asExpr = expr['as']; - let inExpr = expr['in']; - - // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" - // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". - // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. - let tempKey = '$' + asExpr; - // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) - let original = obj[tempKey]; - return map(inputExpr, (item) => { - obj[tempKey] = item; - let value = computeValue(obj, inExpr); - // cleanup and restore - if (isUndefined(original)) { - delete obj[tempKey]; - } else { - obj[tempKey] = original; - } - return value - }) - }, - - /** - * Converts a document to an array of documents representing key-value pairs. - */ - $objectToArray (obj, expr) { - let val = computeValue(obj, expr); - assert(isObject(val), '$objectToArray expression must resolve to an object'); - let arr = []; - each(val, (v,k) => arr.push({k,v})); - return arr - }, - - /** - * Returns an array whose elements are a generated sequence of numbers. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $range (obj, expr) { - let arr = computeValue(obj, expr); - let start = arr[0]; - let end = arr[1]; - let step = arr[2] || 1; - - let result = []; - - while ((start < end && step > 0) || (start > end && step < 0)) { - result.push(start); - start += step; - } - - return result - }, - - /** - * Applies an expression to each element in an array and combines them into a single value. - * - * @param {Object} obj - * @param {*} expr - */ - $reduce (obj, expr) { - let input = computeValue(obj, expr.input); - let initialValue = computeValue(obj, expr.initialValue); - let inExpr = expr['in']; - - if (isNil(input)) return null - assert(isArray(input), "$reduce 'input' expression must resolve to an array"); - return reduce(input, (acc, n) => computeValue({ '$value': acc, '$this': n }, inExpr), initialValue) - }, - - /** - * Returns an array with the elements in reverse order. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $reverseArray (obj, expr) { - let arr = computeValue(obj, expr); - - if (isNil(arr)) return null - assert(isArray(arr), '$reverseArray expression must resolve to an array'); - - let result = []; - into(result, arr); - result.reverse(); - return result - }, - - /** - * Counts and returns the total the number of items in an array. - * - * @param obj - * @param expr - */ - $size (obj, expr) { - let value = computeValue(obj, expr); - return isArray(value) ? value.length : undefined - }, - - /** - * Returns a subset of an array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $slice (obj, expr) { - let arr = computeValue(obj, expr); - return slice(arr[0], arr[1], arr[2]) - }, - - /** - * Merge two lists together. - * - * Transposes an array of input arrays so that the first element of the output array would be an array containing, - * the first element of the first input array, the first element of the second input array, etc. - * - * @param {Obj} obj - * @param {*} expr - * @return {*} - */ - $zip (obj, expr) { - let inputs = computeValue(obj, expr.inputs); - let useLongestLength = expr.useLongestLength || false; - - assert(isArray(inputs), "'inputs' expression must resolve to an array"); - assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean"); - - if (isArray(expr.defaults)) { - assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'"); - } - - let zipCount = 0; - - for (let i = 0, len = inputs.length; i < len; i++) { - let arr = inputs[i]; - - if (isNil(arr)) return null - - assert(isArray(arr), "'inputs' expression values must resolve to an array or null"); - - zipCount = useLongestLength - ? Math.max(zipCount, arr.length) - : Math.min(zipCount || arr.length, arr.length); - } - - let result = []; - let defaults = expr.defaults || []; - - for (let i = 0; i < zipCount; i++) { - let temp = inputs.map((val, index) => { - return isNil(val[i]) ? (defaults[index] || null) : val[i] - }); - result.push(temp); - } - - return result - } -}; - -const booleanOperators = { - /** - * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $and: (obj, expr) => { - let value = computeValue(obj, expr); - return truthy(value) && value.every(truthy) - }, - - /** - * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $or: (obj, expr) => { - let value = computeValue(obj, expr); - return truthy(value) && value.some(truthy) - }, - - /** - * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $not: (obj, expr) => { - return !computeValue(obj, expr[0]) - } -}; - -const comparisonOperators = { - /** - * Compares two values and returns the result of the comparison as an integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $cmp (obj, expr) { - let args = computeValue(obj, expr); - if (args[0] > args[1]) return 1 - if (args[0] < args[1]) return -1 - return 0 - } -}; -// mixin comparison operators -each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], (op) => { - comparisonOperators[op] = (obj, expr) => { - let args = computeValue(obj, expr); - return simpleOperators[op](args[0], args[1]) - }; -}); - -/** - * Conditional operators - */ - -const conditionalOperators = { - - /** - * A ternary operator that evaluates one expression, - * and depending on the result returns the value of one following expressions. - * - * @param obj - * @param expr - */ - $cond (obj, expr) { - let ifExpr, thenExpr, elseExpr; - if (isArray(expr)) { - assert(expr.length === 3, 'Invalid arguments for $cond operator'); - ifExpr = expr[0]; - thenExpr = expr[1]; - elseExpr = expr[2]; - } else if (isObject(expr)) { - ifExpr = expr['if']; - thenExpr = expr['then']; - elseExpr = expr['else']; - } - let condition = computeValue(obj, ifExpr); - return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr) - }, - - /** - * An operator that evaluates a series of case expressions. When it finds an expression which - * evaluates to true, it returns the resulting expression for that case. If none of the cases - * evaluate to true, it returns the default expression. - * - * @param obj - * @param expr - */ - $switch (obj, expr) { - assert(expr.branches, 'Invalid arguments for $switch operator'); - - let validBranch = expr.branches.find((branch) => { - assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator'); - return computeValue(obj, branch['case']) - }); - - if (validBranch) { - return computeValue(obj, validBranch.then) - } else if (!expr.default) { - err('Invalid arguments for $switch operator'); - } else { - return computeValue(obj, expr.default) - } - }, - - /** - * Evaluates an expression and returns the first expression if it evaluates to a non-null value. - * Otherwise, $ifNull returns the second expression's value. - * - * @param obj - * @param expr - * @returns {*} - */ - $ifNull (obj, expr) { - assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator'); - let args = computeValue(obj, expr); - return (args[0] === null || args[0] === undefined) ? args[1] : args[0] - } -}; - -// used for formatting dates in $dateToString operator -let DATE_SYM_TABLE = { - '%Y': ['$year', 4], - '%m': ['$month', 2], - '%d': ['$dayOfMonth', 2], - '%H': ['$hour', 2], - '%M': ['$minute', 2], - '%S': ['$second', 2], - '%L': ['$millisecond', 3], - '%j': ['$dayOfYear', 3], - '%w': ['$dayOfWeek', 1], - '%U': ['$week', 2], - '%%': '%' -}; - -const dateOperators = { - /** - * Returns the day of the year for a date as a number between 1 and 366 (leap year). - * @param obj - * @param expr - */ - $dayOfYear (obj, expr) { - let d = computeValue(obj, expr); - if (isDate(d)) { - let start = new Date(d.getFullYear(), 0, 0); - let diff = d - start; - let oneDay = 1000 * 60 * 60 * 24; - return Math.round(diff / oneDay) - } - return undefined - }, - - /** - * Returns the day of the month for a date as a number between 1 and 31. - * @param obj - * @param expr - */ - $dayOfMonth (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getDate() : undefined - }, - - /** - * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). - * @param obj - * @param expr - */ - $dayOfWeek (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getDay() + 1 : undefined - }, - - /** - * Returns the year for a date as a number (e.g. 2014). - * @param obj - * @param expr - */ - $year (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getFullYear() : undefined - }, - - /** - * Returns the month for a date as a number between 1 (January) and 12 (December). - * @param obj - * @param expr - */ - $month (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getMonth() + 1 : undefined - }, - - /** - * Returns the week number for a date as a number between 0 - * (the partial week that precedes the first Sunday of the year) and 53 (leap year). - * @param obj - * @param expr - */ - $week (obj, expr) { - // source: http://stackoverflow.com/a/6117889/1370481 - let d = computeValue(obj, expr); - - // Copy date so don't modify original - d = new Date(+d); - d.setHours(0, 0, 0); - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - d.setDate(d.getDate() + 4 - (d.getDay() || 7)); - // Get first day of year - let yearStart = new Date(d.getFullYear(), 0, 1); - // Calculate full weeks to nearest Thursday - return Math.floor((((d - yearStart) / 8.64e7) + 1) / 7) - }, - - /** - * Returns the hour for a date as a number between 0 and 23. - * @param obj - * @param expr - */ - $hour (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getUTCHours() : undefined - }, - - /** - * Returns the minute for a date as a number between 0 and 59. - * @param obj - * @param expr - */ - $minute (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getMinutes() : undefined - }, - - /** - * Returns the seconds for a date as a number between 0 and 60 (leap seconds). - * @param obj - * @param expr - */ - $second (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getSeconds() : undefined - }, - - /** - * Returns the milliseconds of a date as a number between 0 and 999. - * @param obj - * @param expr - */ - $millisecond (obj, expr) { - let d = computeValue(obj, expr); - return isDate(d) ? d.getMilliseconds() : undefined - }, - - /** - * Returns the date as a formatted string. - * - * %Y Year (4 digits, zero padded) 0000-9999 - * %m Month (2 digits, zero padded) 01-12 - * %d Day of Month (2 digits, zero padded) 01-31 - * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 - * %M Minute (2 digits, zero padded) 00-59 - * %S Second (2 digits, zero padded) 00-60 - * %L Millisecond (3 digits, zero padded) 000-999 - * %j Day of year (3 digits, zero padded) 001-366 - * %w Day of week (1-Sunday, 7-Saturday) 1-7 - * %U Week of year (2 digits, zero padded) 00-53 - * %% Percent Character as a Literal % - * - * @param obj current object - * @param expr operator expression - */ - $dateToString (obj, expr) { - let fmt = expr['format']; - let date = computeValue(obj, expr['date']); - let matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g); - - for (let i = 0, len = matches.length; i < len; i++) { - let hdlr = DATE_SYM_TABLE[matches[i]]; - let value = hdlr; - - if (isArray(hdlr)) { - // reuse date operators - let fn = this[hdlr[0]]; - let pad = hdlr[1]; - value = padDigits(fn.call(this, obj, date), pad); - } - // replace the match with resolved value - fmt = fmt.replace(matches[i], value); - } - - return fmt - } -}; - -function padDigits (number, digits) { - return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number -} - -const literalOperators = { - /** - * Return a value without parsing. - * @param obj - * @param expr - */ - $literal (obj, expr) { - return expr - } -}; - -const setOperators = { - /** - * Returns true if two sets have the same elements. - * @param obj - * @param expr - */ - $setEquals (obj, expr) { - let args = computeValue(obj, expr); - let xs = unique(args[0]); - let ys = unique(args[1]); - return xs.length === ys.length && xs.length === intersection(xs, ys).length - }, - - /** - * Returns the common elements of the input sets. - * @param obj - * @param expr - */ - $setIntersection (obj, expr) { - let args = computeValue(obj, expr); - return intersection(args[0], args[1]) - }, - - /** - * Returns elements of a set that do not appear in a second set. - * @param obj - * @param expr - */ - $setDifference (obj, expr) { - let args = computeValue(obj, expr); - return args[0].filter(notInArray.bind(null, args[1])) - }, - - /** - * Returns a set that holds all elements of the input sets. - * @param obj - * @param expr - */ - $setUnion (obj, expr) { - let args = computeValue(obj, expr); - return union(args[0], args[1]) - }, - - /** - * Returns true if all elements of a set appear in a second set. - * @param obj - * @param expr - */ - $setIsSubset (obj, expr) { - let args = computeValue(obj, expr); - return intersection(args[0], args[1]).length === args[0].length - }, - - /** - * Returns true if any elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $anyElementTrue (obj, expr) { - // mongodb nests the array expression in another - let args = computeValue(obj, expr)[0]; - return args.some(truthy) - }, - - /** - * Returns true if all elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $allElementsTrue (obj, expr) { - // mongodb nests the array expression in another - let args = computeValue(obj, expr)[0]; - return args.every(truthy) - } -}; - -const stringOperators = { - - /** - * Concatenates two strings. - * - * @param obj - * @param expr - * @returns {string|*} - */ - $concat (obj, expr) { - let args = computeValue(obj, expr); - // does not allow concatenation with nulls - if ([null, undefined].some(inArray.bind(null, args))) { - return null - } - return args.join('') - }, - - /** - * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfBytes (obj, expr) { - let arr = computeValue(obj, expr); - - if (isNil(arr[0])) return null - - assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string'); - assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string'); - - let str = arr[0]; - let searchStr = arr[1]; - let start = arr[2]; - let end = arr[3]; - - assert( - isNil(start) || (isNumber(start) && start >= 0 && Math.round(start) === start), - '$indexOfBytes third operand must resolve to a non-negative integer' - ); - start = start || 0; - - assert( - isNil(end) || (isNumber(end) && end >= 0 && Math.round(end) === end), - '$indexOfBytes fourth operand must resolve to a non-negative integer' - ); - end = end || str.length; - - if (start > end) return -1 - - let index = str.substring(start, end).indexOf(searchStr); - return (index > -1) - ? index + start - : index - }, - - /** - * Splits a string into substrings based on a delimiter. - * If the delimiter is not found within the string, returns an array containing the original string. - * - * @param {Object} obj - * @param {Array} expr - * @return {Array} Returns an array of substrings. - */ - $split (obj, expr) { - let args = computeValue(obj, expr); - assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])); - assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])); - return args[0].split(args[1]) - }, - - /** - * Compares two strings and returns an integer that reflects the comparison. - * - * @param obj - * @param expr - * @returns {number} - */ - $strcasecmp (obj, expr) { - let args = computeValue(obj, expr); - args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase(); - args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase(); - if (args[0] > args[1]) { - return 1 - } - return (args[0] < args[1]) ? -1 : 0 - }, - - /** - * Returns a substring of a string, starting at a specified index position and including the specified number of characters. - * The index is zero-based. - * - * @param obj - * @param expr - * @returns {string} - */ - $substr (obj, expr) { - let args = computeValue(obj, expr); - if (isString(args[0])) { - if (args[1] < 0) { - return '' - } else if (args[2] < 0) { - return args[0].substr(args[1]) - } else { - return args[0].substr(args[1], args[2]) - } - } - return '' - }, - - /** - * Converts a string to lowercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toLower (obj, expr) { - let value = computeValue(obj, expr); - return isEmpty(value) ? '' : value.toLowerCase() - }, - - /** - * Converts a string to uppercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toUpper (obj, expr) { - let value = computeValue(obj, expr); - return isEmpty(value) ? '' : value.toUpperCase() - } -}; - -/** - * Aggregation framework variable operators - */ - -const variableOperators = { - /** - * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. - * - * @param obj - * @param expr - * @returns {*} - */ - $let (obj, expr) { - let varsExpr = expr['vars']; - let inExpr = expr['in']; - - // resolve vars - let originals = {}; - let varsKeys = keys(varsExpr); - each(varsKeys, (key) => { - let val = computeValue(obj, varsExpr[key]); - let tempKey = '$' + key; - // set value on object using same technique as in "$map" - originals[tempKey] = obj[tempKey]; - obj[tempKey] = val; - }); - - let value = computeValue(obj, inExpr); - - // cleanup and restore - each(varsKeys, (key) => { - let tempKey = '$' + key; - if (isUndefined(originals[tempKey])) { - delete obj[tempKey]; - } else { - obj[tempKey] = originals[tempKey]; - } - }); - - return value - } -}; - -// combine aggregate operators -const aggregateOperators = Object.assign( - {}, - arithmeticOperators, - arrayOperators, - booleanOperators, - comparisonOperators, - conditionalOperators, - dateOperators, - literalOperators, - setOperators, - stringOperators, - variableOperators -); - -// operator definitions -const OPERATORS = { - 'aggregate': aggregateOperators, - 'group': groupOperators, - 'pipeline': pipelineOperators, - 'projection': projectionOperators, - 'query': queryOperators -}; - -/** - * Returns the operators defined for the given operator classes - */ -function ops () { - return reduce(arguments, (acc, cls) => into(acc, keys(OPERATORS[cls])), []) -} - -/** - * Add new operators - * - * @param opClass the operator class to extend - * @param fn a function returning an object of new operators - */ -function addOperators (opClass, fn) { - - const newOperators = fn(_internal()); - - // ensure correct type specified - assert(has(OPERATORS, opClass), `Invalid operator class ${opClass}`); - - let operators = OPERATORS[opClass]; - - // check for existing operators - each(newOperators, (fn, op) => { - assert(/^\$\w+$/.test(op), `Invalid operator name ${op}`); - assert(!has(operators, op), `${op} already exists for '${opClass}' operators`); - }); - - let wrapped = {}; - - switch (opClass) { - case OP_QUERY: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (selector, value) => { - return { - test: (obj) => { - // value of field must be fully resolved. - let lhs = resolve(obj, selector); - let result = f.call(ctx, selector, lhs, value); - if (isBoolean(result)) { - return result - } else if (result instanceof Query) { - return result.test(obj) - } else { - err("Invalid return type for '" + op + "'. Must return a Boolean or Query"); - } - } - } - } - })(fn, newOperators); - }); - break - case OP_PROJECTION: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (obj, expr, selector) => { - let lhs = resolve(obj, selector); - return f.call(ctx, selector, lhs, expr) - } - })(fn, newOperators); - }); - break - default: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (...args) => { - return f.apply(ctx, args) - } - })(fn, newOperators); - }); - } - - // toss the operator salad :) - Object.assign(OPERATORS[opClass], wrapped); -} - -/** - * Internal functions - */ - -// Settings used by Mingo internally -const settings = { - key: '_id' -}; - -/** - * Setup default settings for Mingo - * @param options - */ -function setup (options) { - Object.assign(settings, options || {}); -} - -/** - * Implementation of system variables - * @type {Object} - */ -const systemVariables = { - '$$ROOT' (obj, expr, opt) { - return opt.root - }, - '$$CURRENT' (obj, expr, opt) { - return obj - } -}; - -/** - * Implementation of $redact variables - * - * Each function accepts 3 arguments (obj, expr, opt) - * - * @type {Object} - */ -const redactVariables = { - '$$KEEP' (obj) { - return obj - }, - '$$PRUNE' () { - return undefined - }, - '$$DESCEND' (obj, expr, opt) { - // traverse nested documents iff there is a $cond - if (!has(expr, '$cond')) return obj - - let result; - - each(obj, (current, key) => { - if (isObjectLike(current)) { - if (isArray(current)) { - result = []; - each(current, (elem) => { - if (isObject(elem)) { - elem = redactObj(elem, expr, opt); - } - if (!isNil(elem)) result.push(elem); - }); - } else { - result = redactObj(current, expr, opt); - } - - if (isNil(result)) { - delete obj[key]; // pruned result - } else { - obj[key] = result; - } - } - }); - return obj - } -}; - -// system variables -const SYS_VARS = keys(systemVariables); -const REDACT_VARS = keys(redactVariables); - -/** - * Returns the key used as the collection's objects ids - */ -function idKey () { - return settings.key -} - -/** - * Retrieve the value of a given key on an object - * @param obj - * @param field - * @returns {*} - * @private - */ -function getValue (obj, field) { - return obj[field] -} - -/** - * Resolve the value of the field (dot separated) on the given object - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) - * @returns {*} - */ -function resolve (obj, selector, deepFlag = false) { - let names = selector.split('.'); - let value = obj; - - for (let i = 0; i < names.length; i++) { - let isText = names[i].match(/^\d+$/) === null; - - if (isText && isArray(value)) { - // On the first iteration, we check if we received a stop flag. - // If so, we stop to prevent iterating over a nested array value - // on consecutive object keys in the selector. - if (deepFlag === true && i === 0) { - return value - } - - value = value.map((item) => resolve(item, names[i], true)); - - // we mark this value as being multi-valued - addMeta(value, { isMulti: true }); - - // we unwrap for arrays of unit length - // this avoids excess wrapping when resolving deeply nested arrays - if (value.length === 1) { - value = value[0]; - } - } else { - value = getValue(value, names[i]); - deepFlag = false; // reset stop flag when we do a direct lookup - } - - if (isNil(value)) break - } - - return value -} - -/** - * Returns the full object to the resolved value given by the selector. - * This function excludes empty values as they aren't practically useful. - * - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - */ -function resolveObj (obj, selector) { - if (isNil(obj)) return - - let names = selector.split('.'); - let key = names[0]; - // get the next part of the selector - let next = names.length === 1 || names.slice(1).join('.'); - let isIndex = key.match(/^\d+$/) !== null; - let hasNext = names.length > 1; - let result; - let value; - - try { - if (isArray(obj)) { - if (isIndex) { - result = getValue(obj, key); - if (hasNext) { - result = resolveObj(result, next); - } - assert(!isUndefined(result)); - result = [result]; - } else { - result = []; - each(obj, (item) => { - value = resolveObj(item, selector); - if (!isNil(value)) result.push(value); - }); - assert(result.length > 0); - } - } else { - value = getValue(obj, key); - if (hasNext) { - value = resolveObj(value, next); - } - assert(!isUndefined(value)); - result = {}; - result[key] = value; - } - } catch (e) { - result = undefined; - } - - return result -} - -/** - * Walk the object graph and execute the given transform function - * @param {Object|Array} obj The object to traverse - * @param {String} selector The selector - * @param {Function} fn Function to execute for value at the end the traversal - * @param {Boolean} force Force generating missing parts of object graph - * @return {*} - */ -function traverse (obj, selector, fn, force = false) { - let names = selector.split('.'); - let key = names[0]; - let next = names.length === 1 || names.slice(1).join('.'); - - if (names.length === 1) { - fn(obj, key); - } else { // nested objects - if (isArray(obj) && !/^\d+$/.test(key)) { - each(obj, (item) => { - traverse(item, selector, fn, force); - }); - } else { - // force the rest of the graph while traversing - if (force === true) { - let exists = has(obj, key); - if (!exists || isNil(obj[key])) { - obj[key] = {}; - } - } - traverse(obj[key], next, fn, force); - } - } -} - -/** - * Set the value of the given object field - * - * @param obj {Object|Array} the object context - * @param selector {String} path to field - * @param value {*} the value to set - */ -function setValue (obj, selector, value) { - traverse(obj, selector, (item, key) => { - item[key] = value; - }, true); -} - -function removeValue (obj, selector) { - traverse(obj, selector, (item, key) => { - if (isArray(item) && /^\d+$/.test(key)) { - item.splice(parseInt(key), 1); - } else if (isObject(item)) { - delete item[key]; - } - }); -} - -/** - * Simplify expression for easy evaluation with query operators map - * @param expr - * @returns {*} - */ -function normalize (expr) { - // normalized primitives - if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { - return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr } - } - - // normalize object expression - if (isObjectLike(expr)) { - let exprKeys = keys(expr); - let noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0; - - // no valid query operator found, so we do simple comparison - if (noQuery) { - return { '$eq': expr } - } - - // ensure valid regex - if (inArray(exprKeys, '$regex')) { - let regex = expr['$regex']; - let options = expr['$options'] || ''; - let modifiers = ''; - if (isString(regex)) { - modifiers += (regex.ignoreCase || options.indexOf('i') >= 0) ? 'i' : ''; - modifiers += (regex.multiline || options.indexOf('m') >= 0) ? 'm' : ''; - modifiers += (regex.global || options.indexOf('g') >= 0) ? 'g' : ''; - regex = new RegExp(regex, modifiers); - } - expr['$regex'] = regex; - delete expr['$options']; - } - } - - return expr -} - -/** - * Computes the actual value of the expression using the given object as context - * - * @param obj the current object from the collection - * @param expr the expression for the given field - * @param field the field name (may also be an aggregate operator) - * @param opt {Object} extra options - * @returns {*} - */ -function computeValue (obj, expr, field = null, opt = {}) { - opt.root = opt.root || obj; - - // if the field of the object is a valid operator - if (inArray(ops(OP_AGGREGATE), field)) { - return aggregateOperators[field](obj, expr, opt) - } - - // we also handle $group accumulator operators - if (inArray(ops(OP_GROUP), field)) { - // we first fully resolve the expression - obj = computeValue(obj, expr, null, opt); - assert(isArray(obj), field + ' expression must resolve to an array'); - // we pass a null expression because all values have been resolved - return groupOperators[field](obj, null, opt) - } - - // if expr is a variable for an object field - // field not used in this case - if (isString(expr) && expr.length > 0 && expr[0] === '$') { - // we return system variables as literals - if (inArray(SYS_VARS, expr)) { - return systemVariables[expr](obj, null, opt) - } else if (inArray(REDACT_VARS, expr)) { - return expr - } - - // handle selectors with explicit prefix - let sysVar = SYS_VARS.filter((v) => expr.indexOf(v + '.') === 0); - - if (sysVar.length === 1) { - sysVar = sysVar[0]; - if (sysVar === '$$ROOT') { - obj = opt.root; - } - expr = expr.substr(sysVar.length); // '.' prefix will be sliced off below - } - - return resolve(obj, expr.slice(1)) - } - - // check and return value if already in a resolved state - switch (jsType(expr)) { - case T_ARRAY: - return expr.map((item) => computeValue(obj, item)) - case T_OBJECT: - let result = {}; - each(expr, (val, key) => { - result[key] = computeValue(obj, val, key, opt); - // must run ONLY one aggregate operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { - // there should be only one operator - assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'"); - result = result[key]; - return false // break - } - }); - return result - default: - return expr - } -} - -/** - * Returns a slice of the array - * - * @param {Array} xs - * @param {Number} skip - * @param {Number} limit - * @return {Array} - */ -function slice (xs, skip, limit = null) { - // MongoDB $slice works a bit differently from Array.slice - // Uses single argument for 'limit' and array argument [skip, limit] - if (isNil(limit)) { - if (skip < 0) { - skip = Math.max(0, xs.length + skip); - limit = xs.length - skip + 1; - } else { - limit = skip; - skip = 0; - } - } else { - if (skip < 0) { - skip = Math.max(0, xs.length + skip); - } - assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number'); - limit += skip; - } - return Array.prototype.slice.apply(xs, [skip, limit]) -} - -/** - * Compute the standard deviation of the data set - * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". - * @return {Number} - */ -function stddev (ctx) { - let sum = reduce(ctx.data, (acc, n) => acc + n, 0); - let N = ctx.data.length || 1; - let correction = ctx.sampled === true ? 1 : 0; - let avg = sum / (N - correction); - return Math.sqrt(reduce(ctx.data, (acc, n) => acc + Math.pow(n - avg, 2), 0) / N) -} - -/** - * Redact an object - * @param {Object} obj The object to redact - * @param {*} expr The redact expression - * @param {*} opt Options for value - * @return {*} Returns the redacted value - */ -function redactObj (obj, expr, opt = {}) { - opt.root = opt.root || obj; - - let result = computeValue(obj, expr, null, opt); - return inArray(REDACT_VARS, result) - ? redactVariables[result](obj, expr, opt) - : result -} - -/** - * Exported to the users to allow writing custom operators - */ -function _internal () { - return { - computeValue, - idKey, - ops, - resolve, - assert, - clone, - each, - err, - getType, - has, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isRegExp, - isString, - isUndefined, - keys, - map - } -} - -/** - * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` - */ -const CollectionMixin = { - - /** - * Runs a query and returns a cursor to the result - * @param criteria - * @param projection - * @returns {Cursor} - */ - query (criteria, projection) { - return new Query(criteria).find(this.toJSON(), projection) - }, - - /** - * Runs the given aggregation operators on this collection - * @params pipeline - * @returns {Array} - */ - aggregate (pipeline) { - return new Aggregator(pipeline).run(this.toJSON()) - } -}; - -const VERSION = '1.3.3'; - -// mingo! -var index = { - _internal, - Aggregator, - CollectionMixin, - Cursor, - OP_AGGREGATE, - OP_GROUP, - OP_PIPELINE, - OP_PROJECTION, - OP_QUERY, - Query, - VERSION, - addOperators, - aggregate, - find, - remove, - setup -}; - -export default index; diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js deleted file mode 100644 index c830940..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.js +++ /dev/null @@ -1,4212 +0,0 @@ -// mingo.js 1.3.3 -// Copyright (c) 2017 Francis Asante -// https://github.com/kofrasa/mingo -// MIT - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.mingo = factory()); -}(this, (function () { 'use strict'; - -/** - * Polyfill to add native methods for non-supported environments. - */ - -// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new Error('Function.prototype.bind - what is trying to be bound is not callable'); - } - - var aArgs = Array.prototype.slice.call(arguments, 1); - var fToBind = this; - var fNOP = function fNOP() {}; - var fBound = function fBound() { - return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - if (this.prototype) { - // Function.prototype doesn't have a prototype property - fNOP.prototype = this.prototype; - } - fBound.prototype = new fNOP(); - - return fBound; - }; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find -if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function value(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this); - var len = o.length >>> 0; - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - - var thisArg = arguments[1]; - var k = 0; - - while (k < len) { - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return kValue; - } - k++; - } - return undefined; - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex -if (!Array.prototype.findIndex) { - Object.defineProperty(Array.prototype, 'findIndex', { - value: function value(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this); - var len = o.length >>> 0; - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - - var thisArg = arguments[1]; - var k = 0; - while (k < len) { - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return k; - } - k++; - } - return -1; - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes -if (!Array.prototype.includes) { - Object.defineProperty(Array.prototype, 'includes', { - value: function value(searchElement, fromIndex) { - if (this == null) { - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this); - var len = o.length >>> 0; - - if (len === 0) { - return false; - } - var n = fromIndex | 0; - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); - - function sameValueZero(x, y) { - return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); - } - - while (k < len) { - if (sameValueZero(o[k], searchElement)) { - return true; - } - k++; - } - return false; - } - }); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign -if (typeof Object.assign != 'function') { - Object.assign = function (target, varArgs) { - // .length of function is 2 - - if (target == null) { - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - var args = Array.prototype.slice.call(arguments); - - for (var index = 1; index < args.length; index++) { - var nextSource = args[index]; - - if (nextSource != null) { - // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (nextSource.hasOwnProperty(nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }; -} - -// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html -if (!Object.keys) { - Object.keys = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.keys called on a non-object'); - } - - var result = []; - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(k); - } - } - return result; - }; -} - -// https://github.com/es-shims/Object.values/blob/master/implementation.js -if (!Object.values) { - Object.values = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.values called on a non-object'); - } - var result = []; - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(o[k]); - } - } - return result; - }; -} - -// Javascript native types -var T_NULL = 'null'; -var T_UNDEFINED = 'undefined'; -var T_BOOL = 'bool'; -var T_BOOLEAN = 'boolean'; -var T_NUMBER = 'number'; -var T_STRING = 'string'; -var T_DATE = 'date'; -var T_REGEX = 'regex'; -var T_REGEXP = 'regexp'; -var T_ARRAY = 'array'; -var T_OBJECT = 'object'; -var T_FUNCTION = 'function'; - -// no array, object, or function types -var JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP]; - -// operator classes -var OP_AGGREGATE = 'aggregate'; -var OP_GROUP = 'group'; -var OP_PIPELINE = 'pipeline'; -var OP_PROJECTION = 'projection'; -var OP_QUERY = 'query'; - -/** - * Utility functions - */ - -function assert(condition, message) { - if (falsey(condition)) err(message); -} - -/** - * Deep clone an object - * @param obj - * @returns {*} - */ -function clone(obj) { - switch (jsType(obj)) { - case T_ARRAY: - return obj.map(clone); - case T_OBJECT: - return map(obj, clone); - default: - return obj; - } -} - -function getType(v) { - if (v === null) return 'Null'; - if (v === undefined) return 'Undefined'; - return v.constructor.name; -} -function jsType(v) { - return getType(v).toLowerCase(); -} -function isBoolean(v) { - return jsType(v) === T_BOOLEAN; -} -function isString(v) { - return jsType(v) === T_STRING; -} -function isNumber(v) { - return jsType(v) === T_NUMBER; -} -function isArray(v) { - return jsType(v) === T_ARRAY; -} -function isArrayLike(v) { - return !isNil(v) && has(v, 'length'); -} -function isObject(v) { - return jsType(v) === T_OBJECT; -} -function isObjectLike(v) { - return v === Object(v); -} // objects, arrays, functions, date, custom object -function isDate(v) { - return jsType(v) === T_DATE; -} -function isRegExp(v) { - return jsType(v) === T_REGEXP; -} -function isFunction(v) { - return jsType(v) === T_FUNCTION; -} -function isNil(v) { - return isNull(v) || isUndefined(v); -} -function isNull(v) { - return jsType(v) === T_NULL; -} -function isUndefined(v) { - return jsType(v) === T_UNDEFINED; -} -function inArray(arr, item) { - return arr.includes(item); -} -function notInArray(arr, item) { - return !arr.includes(item); -} -function truthy(arg) { - return !!arg; -} -function falsey(arg) { - return !arg; -} -function isEmpty(x) { - return isNil(x) || isArray(x) && x.length === 0 || isObject(x) && keys(x).length === 0 || !x; -} -// ensure a value is an array -function array(x) { - return isArray(x) ? x : [x]; -} -function has(obj, prop) { - return obj.hasOwnProperty(prop); -} -function err(s) { - throw new Error(s); -} -function keys(o) { - return Object.keys(o); -} - -// ////////////////// UTILS //////////////////// - -// internal constants -var __MINGO_META = '__mingo__'; - -function addMeta(obj, value) { - obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value); -} - -function hasMeta(obj, value) { - return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]); -} - -function dropMeta(obj) { - if (has(obj, __MINGO_META)) delete obj[__MINGO_META]; -} - -/** - * Iterate over an array or object - * @param {Array|Object} obj An object-like value - * @param {Function} fn The callback to run per item - * @param {*} ctx The object to use a context - * @return {void} - */ -function each(obj, fn) { - var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - - assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'"); - - if (isArrayLike(obj)) { - for (var i = 0, len = obj.length; i < len; i++) { - if (fn.call(ctx, obj[i], i, obj) === false) break; - } - } else { - for (var k in obj) { - if (has(obj, k)) { - if (fn.call(ctx, obj[k], k, obj) === false) break; - } - } - } -} - -/** - * Transform values in a collection - * - * @param {Array|Object} obj An array/object whose values to transform - * @param {Function} fn The transform function - * @param {*} ctx The value to use as the "this" context for the transform - * @return {Array|Object} Result object after applying the transform - */ -function map(obj, fn) { - var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - - if (isArray(obj)) { - return obj.map(fn, ctx); - } else if (isObject(obj)) { - var o = {}; - each(obj, function (v, k) { - return o[k] = fn.call(ctx, v, k); - }, obj); - return o; - } -} - -/** - * Reduce any array-like object - * @param collection - * @param fn - * @param accumulator - * @returns {*} - */ -function reduce(collection, fn, accumulator) { - if (isArray(collection)) return collection.reduce(fn, accumulator); - // array-like objects - each(collection, function (v, k) { - return accumulator = fn(accumulator, v, k, collection); - }); - return accumulator; -} - -/** - * Returns the intersection between two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} Result array - */ -function intersection(xs, ys) { - return xs.filter(inArray.bind(null, ys)); -} - -/** - * Returns the union of two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} The result array - */ -function union(xs, ys) { - return into(into([], xs), ys.filter(notInArray.bind(null, xs))); -} - -/** - * Flatten the array - * - * @param {Array} xs The array to flatten - * @param {Number} depth The number of nested lists to iterate - */ - - -/** - * Determine whether two values are the same or strictly equivalent - * - * @param {*} a The first value - * @param {*} b The second value - * @return {Boolean} Result of comparison - */ -function isEqual(a, b) { - // strictly equal must be equal. - if (a === b) return true; - - // unequal types and functions cannot be equal. - var type = jsType(a); - if (type !== jsType(b) || type === T_FUNCTION) return false; - - // we treat NaN as the same - if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true; - - // leverage toString for Date and RegExp types - if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString(); - - if (type === T_ARRAY) { - if (a.length === b.length && a.length === 0) return true; - if (a.length !== b.length) return false; - for (var i = 0, len = a.length; i < len; i++) { - if (!isEqual(a[i], b[i])) return false; - } - } else if (type === T_OBJECT) { - // deep compare objects - var ka = keys(a); - var kb = keys(b); - - // check length of keys early - if (ka.length !== kb.length) return false; - - // we know keys are strings so we sort before comparing - ka.sort(); - kb.sort(); - - // compare keys - if (!isEqual(ka, kb)) return false; - - // back to the drawing board - for (var _i = 0, _len = ka.length; _i < _len; _i++) { - var temp = ka[_i]; - if (!isEqual(a[temp], b[temp])) return false; - } - } else { - // we do not know how to compare custom types so we guess - return getHash(a) === getHash(b); - } - // best effort says values are equal :) - return true; -} - -/** - * Return a new unique version of the collection - * @param {Array} xs The input collection - * @return {Array} A new collection with unique values - */ -function unique(xs) { - var h = {}; - var arr = []; - each(xs, function (item) { - var k = getHash(item); - if (!has(h, k)) { - arr.push(item); - h[k] = 0; - } - }); - return arr; -} - -/** - * Generates a random string of max length range [24,27] - * @param n Size of string to return - * @returns {*} - */ -function randomString(n) { - return (Math.E + Math.random()).toString(36).slice(2, n + 2); -} - -/** - * Encode value using a simple optimistic stable scheme. - * @param value - * @returns {*} - */ -function encode(value) { - var type = jsType(value); - switch (type) { - case T_FUNCTION: - return randomString(7); - case T_BOOLEAN: - case T_NUMBER: - case T_REGEXP: - return value.toString(); - case T_STRING: - return JSON.stringify(value); - case T_DATE: - return value.toISOString(); - case T_NULL: - case T_UNDEFINED: - return type; - case T_ARRAY: - return '[' + map(value, function (v) { - return '' + encode(v); - }) + ']'; - default: - var prefix = type === T_OBJECT ? '' : getType(value) + '|'; - var objKeys = keys(value); - objKeys.sort(); - return prefix + '{' + map(objKeys, function (k) { - return encode(k) + ':' + encode(value[k]); - }) + '}'; - } -} - -/** - * Generate hash code - * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery - * - * @param value - * @returns {*} - */ -function getHash(value) { - var hash = 0, - i = void 0, - chr = void 0, - len = void 0, - s = encode(value); - if (s.length === 0) return hash; - for (i = 0, len = s.length; i < len; i++) { - chr = s.charCodeAt(i); - hash = (hash << 5) - hash + chr; - hash |= 0; // Convert to 32bit integer - } - return hash.toString(); -} - -/** - * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee - * - * This implementation treats null/undefined sort keys as less than every other type - * - * @param {Array} collection - * @param {Function} fn The function used to resolve sort keys - * @param {Object} ctx The context to use for calling `fn` - * @return {Array} Returns a new sorted array by the given iteratee - */ -function sortBy(collection, fn) { - var ctx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - - var sortKeys = {}; - var sorted = []; - var len = collection.length; - var result = []; - - for (var i = 0; i < len; i++) { - var obj = collection[i]; - var key = fn.call(ctx, obj, i); - if (isNil(key)) { - // objects with null keys will go in first - result.push(obj); - } else { - var hash = getHash(obj); - if (!has(sortKeys, hash)) { - sortKeys[hash] = [key, i]; - } - sorted.push(obj); - } - } - // use native array sorting but enforce stableness - sorted.sort(function (a, b) { - var A = sortKeys[getHash(a)]; - var B = sortKeys[getHash(b)]; - if (A[0] < B[0]) return -1; - if (A[0] > B[0]) return 1; - if (A[1] < B[1]) return -1; - if (A[1] > B[1]) return 1; - return 0; - }); - return into(result, sorted); -} - -/** - * Groups the collection into sets by the returned key - * - * @param collection - * @param fn {Function} to compute the group key of an item in the collection - * @param ctx {Object} The context to use for calling `fn` - * @returns {{keys: Array, groups: Array}} - */ -function groupBy(collection, fn, ctx) { - var result = { - 'keys': [], - 'groups': [] - }; - var lookup = {}; - each(collection, function (obj) { - var key = fn.call(ctx, obj); - var hash = getHash(key); - var index = -1; - - if (isUndefined(lookup[hash])) { - index = result.keys.length; - lookup[hash] = index; - result.keys.push(key); - result.groups.push([]); - } - index = lookup[hash]; - result.groups[index].push(obj); - }); - return result; -} - -/** - * Push elements in given array into target array - * - * @param {*} target The array to push into - * @param {*} xs The array of elements to push - */ -function into(target, xs) { - Array.prototype.push.apply(target, xs); - return target; -} - -/** - * Find the insert index for the given key in a sorted array. - * - * @param {*} array The sorted array to search - * @param {*} key The search key - */ -function findInsertIndex(array, key) { - // uses binary search - var lo = 0; - var hi = array.length - 1; - while (lo <= hi) { - var mid = Math.round(lo + (hi - lo) / 2); - if (key < array[mid]) { - hi = mid - 1; - } else if (key > array[mid]) { - lo = mid + 1; - } else { - return mid; - } - } - return lo; -} - -/** - * This is a generic memoization function - * - * This implementation uses a cache independent of the function being memoized - * to allow old values to be garbage collected when the memoized function goes out of scope. - * - * @param {*} fn The function object to memoize - */ -function memoize(fn) { - var _this = this; - - return function (cache) { - return function () { - for (var _len2 = arguments.length, args = Array(_len2), _key = 0; _key < _len2; _key++) { - args[_key] = arguments[_key]; - } - - var key = getHash(args); - if (!has(cache, key)) { - cache[key] = fn.apply(_this, args); - } - return cache[key]; - }; - }({/* storage */}); -} - -/** - * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ - */ - -var groupOperators = { - - /** - * Returns an array of all the unique values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {*} - */ - $addToSet: function $addToSet(collection, expr) { - return unique(this.$push(collection, expr)); - }, - - - /** - * Returns the sum of all the values in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $sum: function $sum(collection, expr) { - if (!isArray(collection)) return 0; - - if (isNumber(expr)) { - // take a short cut if expr is number literal - return collection.length * expr; - } - return reduce(this.$push(collection, expr).filter(isNumber), function (acc, n) { - return acc + n; - }, 0); - }, - - - /** - * Returns the highest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $max: function $max(collection, expr) { - var mapped = this.$push(collection, expr); - return reduce(mapped, function (acc, n) { - return isNil(acc) || n > acc ? n : acc; - }, undefined); - }, - - - /** - * Returns the lowest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $min: function $min(collection, expr) { - var mapped = this.$push(collection, expr); - return reduce(mapped, function (acc, n) { - return isNil(acc) || n < acc ? n : acc; - }, undefined); - }, - - - /** - * Returns an average of all the values in a group. - * - * @param collection - * @param expr - * @returns {number} - */ - $avg: function $avg(collection, expr) { - var data = this.$push(collection, expr).filter(isNumber); - var sum = reduce(data, function (acc, n) { - return acc + n; - }, 0); - return sum / (data.length || 1); - }, - - - /** - * Returns an array of all values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $push: function $push(collection, expr) { - if (isNil(expr)) return collection; - return map(collection, function (obj) { - return computeValue(obj, expr); - }); - }, - - - /** - * Returns the first value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $first: function $first(collection, expr) { - return collection.length > 0 ? computeValue(collection[0], expr) : undefined; - }, - - - /** - * Returns the last value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $last: function $last(collection, expr) { - return collection.length > 0 ? computeValue(collection[collection.length - 1], expr) : undefined; - }, - - - /** - * Returns the population standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number} - */ - $stdDevPop: function $stdDevPop(collection, expr) { - var data = this.$push(collection, expr).filter(isNumber); - return stddev({ data: data, sampled: false }); - }, - - - /** - * Returns the sample standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number|null} - */ - $stdDevSamp: function $stdDevSamp(collection, expr) { - var data = this.$push(collection, expr).filter(isNumber); - return stddev({ data: data, sampled: true }); - } -}; - -/** - * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ - */ -var projectionOperators = { - - /** - * Projects the first element in an array that matches the query condition. - * - * @param obj - * @param field - * @param expr - */ - $: function $(obj, expr, field) { - err('$ not implemented'); - }, - - - /** - * Projects only the first element from an array that matches the specified $elemMatch condition. - * - * @param obj - * @param field - * @param expr - * @returns {*} - */ - $elemMatch: function $elemMatch(obj, expr, field) { - var arr = resolve(obj, field); - var query = new Query(expr); - - if (isNil(arr) || !isArray(arr)) { - return undefined; - } - - for (var i = 0; i < arr.length; i++) { - if (query.test(arr[i])) { - return [arr[i]]; - } - } - - return undefined; - }, - - - /** - * Limits the number of elements projected from an array. Supports skip and limit slices. - * - * @param obj - * @param field - * @param expr - */ - $slice: function $slice(obj, expr, field) { - var xs = resolve(obj, field); - - if (!isArray(xs)) return xs; - - if (isArray(expr)) { - return slice(xs, expr[0], expr[1]); - } else if (isNumber(expr)) { - return slice(xs, expr); - } else { - err('Invalid argument type for $slice projection operator'); - } - }, - - - /** - * Returns the population standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number} - */ - $stdDevPop: function $stdDevPop(obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: false - }); - }, - - - /** - * Returns the sample standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number|null} - */ - $stdDevSamp: function $stdDevSamp(obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: true - }); - } -}; - -/** - * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ - */ -var pipelineOperators = { - - /** - * Adds new fields to documents. - * Outputs documents that contain all existing fields from the input documents and newly added fields. - * - * @param {Array} collection - * @param {*} expr - */ - $addFields: function $addFields(collection, expr) { - var newFields = keys(expr); - - return collection.map(function (obj) { - obj = clone(obj); - each(newFields, function (field) { - var subExpr = expr[field]; - var newValue = computeValue(obj, subExpr); - traverse(obj, field, function (o, key) { - o[key] = newValue; - }, true); - }); - return obj; - }); - }, - - - /** - * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $group: function $group(collection, expr) { - // lookup key for grouping - var ID_KEY = idKey(); - var objectId = expr[ID_KEY]; - - var partitions = groupBy(collection, function (obj) { - return computeValue(obj, objectId, objectId); - }); - - var result = []; - - // remove the group key - delete expr[ID_KEY]; - - each(partitions.keys, function (value, i) { - var obj = {}; - - // exclude undefined key value - if (!isUndefined(value)) { - obj[ID_KEY] = value; - } - - // compute remaining keys in expression - each(expr, function (val, key) { - obj[key] = accumulate(partitions.groups[i], key, val); - }); - result.push(obj); - }); - - return result; - }, - - - /** - * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. - * - * @param collection - * @param expr - */ - $lookup: function $lookup(collection, expr) { - var joinColl = expr.from; - var localField = expr.localField; - var foreignField = expr.foreignField; - var asField = expr.as; - - var errorMsg = "Invalid $lookup expression. "; - assert(isArray(joinColl), errorMsg + "'from' must be an array"); - assert(isString(foreignField), errorMsg + "'foreignField' must be a string"); - assert(isString(localField), errorMsg + "'localField' must be a string"); - assert(isString(asField), errorMsg + "'as' must be a string"); - - var result = []; - var hash = {}; - - function hashCode(v) { - return getHash(isNil(v) ? null : v); - } - - if (joinColl.length <= collection.length) { - each(joinColl, function (obj, i) { - var k = hashCode(obj[foreignField]); - hash[k] = hash[k] || []; - hash[k].push(i); - }); - - each(collection, function (obj) { - var k = hashCode(obj[localField]); - var indexes = hash[k] || []; - var newObj = clone(obj); - newObj[asField] = indexes.map(function (i) { - return clone(joinColl[i]); - }); - result.push(newObj); - }); - } else { - - each(collection, function (obj, i) { - var k = hashCode(obj[localField]); - hash[k] = hash[k] || []; - hash[k].push(i); - }); - - var tempResult = {}; - each(joinColl, function (obj) { - var k = hashCode(obj[foreignField]); - var indexes = hash[k] || []; - each(indexes, function (i) { - var newObj = tempResult[i] || clone(collection[i]); - newObj[asField] = newObj[asField] || []; - newObj[asField].push(clone(obj)); - tempResult[i] = newObj; - }); - }); - for (var i = 0, len = keys(tempResult).length; i < len; i++) { - result.push(tempResult[i]); - } - } - - return result; - }, - - - /** - * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. - * $match uses standard MongoDB queries. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $match: function $match(collection, expr) { - return new Query(expr).find(collection).all(); - }, - - - /** - * Reshapes a document stream. - * $project can rename, add, or remove fields as well as create computed values and sub-documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $project: function $project(collection, expr) { - if (isEmpty(expr)) { - return collection; - } - - // result collection - var projected = []; - var objKeys = keys(expr); - var idOnlyExcludedExpression = false; - var ID_KEY = idKey(); - - // validate inclusion and exclusion - var check = [false, false]; - each(expr, function (v, k) { - if (k === ID_KEY) return; - if (v === 0 || v === false) { - check[0] = true; - } else { - check[1] = true; - } - assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.'); - }); - - if (inArray(objKeys, ID_KEY)) { - var id = expr[ID_KEY]; - if (id === 0 || id === false) { - objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])); - assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key'); - idOnlyExcludedExpression = isEmpty(objKeys); - } - } else { - // if not specified the add the ID field - objKeys.push(ID_KEY); - } - - each(collection, function (obj) { - var cloneObj = {}; - var foundSlice = false; - var foundExclusion = false; - var dropKeys = []; - - if (idOnlyExcludedExpression) { - dropKeys.push(ID_KEY); - } - - each(objKeys, function (key) { - var subExpr = expr[key]; - var value = void 0; // final computed value of the key - - if (key !== ID_KEY && subExpr === 0) { - foundExclusion = true; - } - - if (key === ID_KEY && isEmpty(subExpr)) { - // tiny optimization here to skip over id - value = obj[key]; - } else if (isString(subExpr)) { - value = computeValue(obj, subExpr, key); - } else if (subExpr === 1 || subExpr === true) { - // For direct projections, we use the resolved object value - } else if (isObject(subExpr)) { - var operator = keys(subExpr); - operator = operator.length > 1 ? false : operator[0]; - - if (inArray(ops(OP_PROJECTION), operator)) { - // apply the projection operator on the operator expression for the key - if (operator === '$slice') { - // $slice is handled differently for aggregation and projection operations - if (array(subExpr[operator]).every(isNumber)) { - // $slice for projection operation - value = projectionOperators[operator](obj, subExpr[operator], key); - foundSlice = true; - } else { - // $slice for aggregation operation - value = computeValue(obj, subExpr, key); - } - } else { - value = projectionOperators[operator](obj, subExpr[operator], key); - } - } else { - // compute the value for the sub expression for the key - value = computeValue(obj, subExpr, key); - } - } else { - dropKeys.push(key); - return; - } - - // clone resolved values - var objValue = clone(resolveObj(obj, key)); - - if (!isUndefined(objValue)) { - Object.assign(cloneObj, objValue); - } - if (!isUndefined(value)) { - setValue(cloneObj, key, clone(value)); - } - }); - // if projection included $slice operator - // Also if exclusion fields are found or we want to exclude only the id field - // include keys that were not explicitly excluded - if (foundSlice || foundExclusion || idOnlyExcludedExpression) { - cloneObj = Object.assign(clone(obj), cloneObj); - each(dropKeys, function (key) { - return removeValue(cloneObj, key); - }); - } - projected.push(cloneObj); - }); - - return projected; - }, - - - /** - * Restricts the number of documents in an aggregation pipeline. - * - * @param collection - * @param value - * @returns {Object|*} - */ - $limit: function $limit(collection, value) { - return collection.slice(0, value); - }, - - - /** - * Skips over a specified number of documents from the pipeline and returns the rest. - * - * @param collection - * @param value - * @returns {*} - */ - $skip: function $skip(collection, value) { - return collection.slice(value); - }, - - - /** - * Takes an array of documents and returns them as a stream of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $unwind: function $unwind(collection, expr) { - var result = []; - var field = expr.substr(1); - each(collection, function (obj) { - // must throw an error if value is not an array - var value = getValue(obj, field); - - assert(isArray(value), "Target field '" + field + "' is not of type Array."); - - each(value, function (item) { - var tmp = clone(obj); - tmp[field] = item; - result.push(tmp); - }); - }); - return result; - }, - - - /** - * Takes all input documents and returns them in a stream of sorted documents. - * - * @param collection - * @param sortKeys - * @returns {*} - */ - $sort: function $sort(collection, sortKeys) { - if (!isEmpty(sortKeys) && isObject(sortKeys)) { - var modifiers = keys(sortKeys); - each(modifiers.reverse(), function (key) { - var grouped = groupBy(collection, function (obj) { - return resolve(obj, key); - }); - var sortedIndex = {}; - var getIndex = function getIndex(k) { - return sortedIndex[getHash(k)]; - }; - - var indexKeys = sortBy(grouped.keys, function (item, i) { - sortedIndex[getHash(item)] = i; - return item; - }); - - if (sortKeys[key] === -1) { - indexKeys.reverse(); - } - collection = []; - each(indexKeys, function (item) { - return into(collection, grouped.groups[getIndex(item)]); - }); - }); - } - return collection; - }, - - - /** - * Groups incoming documents based on the value of a specified expression, - * then computes the count of documents in each distinct group. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sortByCount: function $sortByCount(collection, expr) { - var newExpr = { count: { $sum: 1 } }; - newExpr[idKey()] = expr; - - return this.$sort(this.$group(collection, newExpr), { count: -1 }); - }, - - - /** - * Randomly selects the specified number of documents from its input. - * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sample: function $sample(collection, expr) { - var size = expr.size; - assert(isNumber(size), '$sample size must be a positive integer'); - - var result = []; - var len = collection.length; - for (var i = 0; i < size; i++) { - var n = Math.floor(Math.random() * len); - result.push(collection[n]); - } - return result; - }, - - - /** - * Returns a document that contains a count of the number of documents input to the stage. - * @param {Array} collection - * @param {String} expr - * @return {Object} - */ - $count: function $count(collection, expr) { - assert(isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', 'Invalid expression value for $count'); - - var result = {}; - result[expr] = collection.length; - return result; - }, - - - /** - * Replaces a document with the specified embedded document or new one. - * The replacement document can be any valid expression that resolves to a document. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $replaceRoot: function $replaceRoot(collection, expr) { - var newRoot = expr.newRoot; - var result = []; - each(collection, function (obj) { - obj = computeValue(obj, newRoot); - assert(isObject(obj), '$replaceRoot expression must return a valid JS object'); - result.push(obj); - }); - return result; - }, - - - /** - * Restricts the contents of the documents based on information stored in the documents themselves. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ - */ - $redact: function $redact(collection, expr) { - return collection.map(function (obj) { - return redactObj(clone(obj), expr); - }); - }, - - - /** - * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ - */ - $bucket: function $bucket(collection, expr) { - var boundaries = expr.boundaries; - var defaultKey = expr.default; - var lower = boundaries[0]; // inclusive - var upper = boundaries[boundaries.length - 1]; // exclusive - var outputExpr = expr.output || { 'count': { '$sum': 1 } }; - - assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements"); - var boundType = getType(lower); - - for (var i = 0, len = boundaries.length - 1; i < len; i++) { - assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type"); - assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order"); - } - - if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { - assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range"); - } - - var grouped = {}; - each(boundaries, function (k) { - return grouped[k] = []; - }); - - // add default key if provided - if (!isNil(defaultKey)) grouped[defaultKey] = []; - - each(collection, function (obj) { - var key = computeValue(obj, expr.groupBy); - - if (isNil(key) || key < lower || key >= upper) { - assert(!isNil(defaultKey), '$bucket require a default for out of range values'); - grouped[defaultKey].push(obj); - } else if (key >= lower && key < upper) { - var index = findInsertIndex(boundaries, key); - var boundKey = boundaries[Math.max(0, index - 1)]; - grouped[boundKey].push(obj); - } else { - err("$bucket 'groupBy' expression must resolve to a value in range of boundaries"); - } - }); - - // upper bound is exclusive so we remove it - boundaries.pop(); - if (!isNil(defaultKey)) boundaries.push(defaultKey); - - return map(boundaries, function (key) { - var acc = accumulate(grouped[key], null, outputExpr); - return Object.assign(acc, { '_id': key }); - }); - }, - $bucketAuto: function $bucketAuto(collection, expr) { - var outputExpr = expr.output || { 'count': { '$sum': 1 } }; - var groupByExpr = expr.groupBy; - var bucketCount = expr.buckets; - - assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount); - - var approxBucketSize = Math.round(collection.length / bucketCount); - if (approxBucketSize < 1) { - approxBucketSize = 1; - } - - var computeValueOptimized = memoize(computeValue); - var grouped = {}; - var remaining = []; - var sorted = sortBy(collection, function (o) { - var key = computeValueOptimized(o, groupByExpr); - if (isNil(key)) { - remaining.push(o); - } else { - grouped[key] || (grouped[key] = []); - grouped[key].push(o); - } - return key; - }); - - var ID_KEY = idKey(); - var result = []; - var index = 0; // counter for sorted collection - - for (var i = 0, len = sorted.length; i < bucketCount && index < len; i++) { - var boundaries = {}; - var bucketItems = []; - - for (var j = 0; j < approxBucketSize && index < len; j++) { - var key = computeValueOptimized(sorted[index], groupByExpr); - - if (isNil(key)) key = null; - - // populate current bucket with all values for current key - into(bucketItems, isNil(key) ? remaining : grouped[key]); - - // increase sort index by number of items added - index += isNil(key) ? remaining.length : grouped[key].length; - - // set the min key boundary if not already present - if (!has(boundaries, 'min')) boundaries.min = key; - - if (result.length > 0) { - var lastBucket = result[result.length - 1]; - lastBucket[ID_KEY].max = boundaries.min; - } - } - - // if is last bucket add remaining items - if (i == bucketCount - 1) { - into(bucketItems, sorted.slice(index)); - } - - result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })); - } - - if (result.length > 0) { - result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr); - } - - return result; - }, - - - /** - * Processes multiple aggregation pipelines within a single stage on the same set of input documents. - * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. - */ - $facet: function $facet(collection, expr) { - return map(expr, function (pipeline) { - return aggregate(collection, pipeline); - }); - } -}; - -/** - * Returns the result of evaluating a $group operation over a collection - * - * @param collection - * @param field the name of the aggregate operator or field - * @param expr the expression of the aggregate operator for the field - * @returns {*} - */ -function accumulate(collection, field, expr) { - if (inArray(ops(OP_GROUP), field)) { - return groupOperators[field](collection, expr); - } - - if (isObject(expr)) { - var result = {}; - each(expr, function (val, key) { - result[key] = accumulate(collection, key, expr[key]); - // must run ONLY one group operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_GROUP), key)) { - result = result[key]; - // if there are more keys in expression this is bad - assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'"); - return false; // break - } - }); - return result; - } - - return undefined; -} - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; -} : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; -}; - - - - - - - - - - - -var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -}; - -var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -}(); - -/** - * Aggregator for defining filter using mongoDB aggregation pipeline syntax - * - * @param operators an Array of pipeline operators - * @constructor - */ -var Aggregator = function () { - function Aggregator(operators) { - classCallCheck(this, Aggregator); - - this.__operators = operators; - } - - /** - * Apply the pipeline operations over the collection by order of the sequence added - * - * @param collection an array of objects to process - * @param query the `Query` object to use as context - * @returns {Array} - */ - - - createClass(Aggregator, [{ - key: 'run', - value: function run(collection, query) { - if (!isEmpty(this.__operators)) { - // run aggregation pipeline - each(this.__operators, function (operator) { - var key = keys(operator); - assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), 'Invalid aggregation operator ' + key); - key = key[0]; - if (query && query instanceof Query) { - collection = pipelineOperators[key].call(query, collection, operator[key]); - } else { - collection = pipelineOperators[key](collection, operator[key]); - } - }); - } - return collection; - } - }]); - return Aggregator; -}(); - -/** - * Return the result collection after running the aggregation pipeline for the given collection - * - * @param collection - * @param pipeline - * @returns {Array} - */ -function aggregate(collection, pipeline) { - assert(isArray(pipeline), 'Aggregation pipeline must be an array'); - return new Aggregator(pipeline).run(collection); -} - -/** - * Cursor to iterate and perform filtering on matched objects - * @param collection - * @param query - * @param projection - * @constructor - */ -var Cursor = function () { - function Cursor(collection, query, projection) { - classCallCheck(this, Cursor); - - this.__query = query; - this.__collection = collection; - this.__projection = projection || query.__projection; - this.__operators = {}; - this.__result = false; - this.__position = 0; - } - - createClass(Cursor, [{ - key: '_fetch', - value: function _fetch() { - var _this = this; - - if (this.__result !== false) { - return this.__result; - } - - // inject projection operator - if (isObject(this.__projection)) { - Object.assign(this.__operators, { '$project': this.__projection }); - } - - assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); - - // filter collection - this.__result = this.__collection.filter(this.__query.test, this.__query); - var pipeline = []; - - each(['$sort', '$skip', '$limit', '$project'], function (op) { - if (has(_this.__operators, op)) { - var selected = {}; - selected[op] = _this.__operators[op]; - pipeline.push(selected); - } - }); - - if (pipeline.length > 0) { - var aggregator = new Aggregator(pipeline); - this.__result = aggregator.run(this.__result, this.__query); - } - return this.__result; - } - - /** - * Fetch and return all matched results - * @returns {Array} - */ - - }, { - key: 'all', - value: function all() { - return this._fetch(); - } - - /** - * Fetch and return the first matching result - * @returns {Object} - */ - - }, { - key: 'first', - value: function first() { - return this.count() > 0 ? this._fetch()[0] : null; - } - - /** - * Fetch and return the last matching object from the result - * @returns {Object} - */ - - }, { - key: 'last', - value: function last() { - return this.count() > 0 ? this._fetch()[this.count() - 1] : null; - } - - /** - * Counts the number of matched objects found - * @returns {Number} - */ - - }, { - key: 'count', - value: function count() { - return this._fetch().length; - } - - /** - * Returns a cursor that begins returning results only after passing or skipping a number of documents. - * @param {Number} n the number of results to skip. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - - }, { - key: 'skip', - value: function skip(n) { - Object.assign(this.__operators, { '$skip': n }); - return this; - } - - /** - * Constrains the size of a cursor's result set. - * @param {Number} n the number of results to limit to. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - - }, { - key: 'limit', - value: function limit(n) { - Object.assign(this.__operators, { '$limit': n }); - return this; - } - - /** - * Returns results ordered according to a sort specification. - * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - - }, { - key: 'sort', - value: function sort(modifier) { - Object.assign(this.__operators, { '$sort': modifier }); - return this; - } - - /** - * Returns the next document in a cursor. - * @returns {Object | Boolean} - */ - - }, { - key: 'next', - value: function next() { - if (this.hasNext()) { - return this._fetch()[this.__position++]; - } - return null; - } - - /** - * Returns true if the cursor has documents and can be iterated. - * @returns {boolean} - */ - - }, { - key: 'hasNext', - value: function hasNext() { - return this.count() > this.__position; - } - - /** - * Specifies the exclusive upper bound for a specific field - * @param expr - * @returns {Number} - */ - - }, { - key: 'max', - value: function max(expr) { - return groupOperators.$max(this._fetch(), expr); - } - - /** - * Specifies the inclusive lower bound for a specific field - * @param expr - * @returns {Number} - */ - - }, { - key: 'min', - value: function min(expr) { - return groupOperators.$min(this._fetch(), expr); - } - - /** - * Applies a function to each document in a cursor and collects the return values in an array. - * @param callback - * @returns {Array} - */ - - }, { - key: 'map', - value: function map$$1(callback) { - return this._fetch().map(callback); - } - - /** - * Applies a JavaScript function for every document in a cursor. - * @param callback - */ - - }, { - key: 'forEach', - value: function forEach(callback) { - each(this._fetch(), callback); - } - - /** - * Applies an [ES2015 Iteration protocol][] compatible implementation - * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols - * @returns {Object} - */ - - }, { - key: Symbol.iterator, - value: function value() { - var self = this; - return { - next: function next() { - if (!self.hasNext()) { - return { done: true }; - } - return { - done: false, - value: self.next() - }; - } - }; - } - }]); - return Cursor; -}(); - -/** - * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ - */ -var simpleOperators = { - - /** - * Checks that two values are equal. - * - * @param a The lhs operand as resolved from the object by the given selector - * @param b The rhs operand provided by the user - * @returns {*} - */ - $eq: function $eq(a, b) { - // start with simple equality check - if (isEqual(a, b)) return true; - - // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ - if (isNil(a) && isNil(b)) return true; - - if (isArray(a)) { - // is multi-valued lhs so we check each separately - if (hasMeta(a, { isMulti: true })) { - try { - for (var i = 0; i < a.length; i++) { - if (this.$eq(a[i], b)) { - return true; - } - } - } finally { - dropMeta(a); - } - } else { - // check one level deep - return a.findIndex(isEqual.bind(null, b)) !== -1; - } - } - return false; - }, - - - /** - * Matches all values that are not equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $ne: function $ne(a, b) { - return !this.$eq(a, b); - }, - - - /** - * Matches any of the values that exist in an array specified in the query. - * - * @param a - * @param b - * @returns {*} - */ - $in: function $in(a, b) { - a = array(a); - return intersection(a, b).length > 0; - }, - - - /** - * Matches values that do not exist in an array specified to the query. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $nin: function $nin(a, b) { - return isNil(a) || !this.$in(a, b); - }, - - - /** - * Matches values that are less than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lt: function $lt(a, b) { - a = array(a).find(function (val) { - return val < b; - }); - return a !== undefined; - }, - - - /** - * Matches values that are less than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lte: function $lte(a, b) { - a = array(a).find(function (val) { - return val <= b; - }); - return a !== undefined; - }, - - - /** - * Matches values that are greater than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gt: function $gt(a, b) { - a = array(a).find(function (val) { - return val > b; - }); - return a !== undefined; - }, - - - /** - * Matches values that are greater than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gte: function $gte(a, b) { - a = array(a).find(function (val) { - return val >= b; - }); - return a !== undefined; - }, - - - /** - * Performs a modulo operation on the value of a field and selects documents with a specified result. - * - * @param a - * @param b - * @returns {boolean} - */ - $mod: function $mod(a, b) { - a = array(a).find(function (val) { - return isNumber(val) && isArray(b) && b.length === 2 && val % b[0] === b[1]; - }); - return a !== undefined; - }, - - - /** - * Selects documents where values match a specified regular expression. - * - * @param a - * @param b - * @returns {boolean} - */ - $regex: function $regex(a, b) { - a = array(a).find(function (val) { - return isString(val) && isRegExp(b) && !!val.match(b); - }); - return a !== undefined; - }, - - - /** - * Matches documents that have the specified field. - * - * @param a - * @param b - * @returns {boolean} - */ - $exists: function $exists(a, b) { - return (b === false || b === 0) && isNil(a) || (b === true || b === 1) && !isNil(a); - }, - - - /** - * Matches arrays that contain all elements specified in the query. - * - * @param a - * @param b - * @returns boolean - */ - $all: function $all(a, b) { - var matched = false; - if (isArray(a) && isArray(b)) { - for (var i = 0, len = b.length; i < len; i++) { - if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { - matched = matched || this.$elemMatch(a, b[i].$elemMatch); - } else { - // order of arguments matter - return intersection(b, a).length === len; - } - } - } - return matched; - }, - - - /** - * Selects documents if the array field is a specified size. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $size: function $size(a, b) { - return isArray(a) && isNumber(b) && a.length === b; - }, - - - /** - * Selects documents if element in the array field matches all the specified $elemMatch condition. - * - * @param a - * @param b - */ - $elemMatch: function $elemMatch(a, b) { - if (isArray(a) && !isEmpty(a)) { - var query = new Query(b); - for (var i = 0, len = a.length; i < len; i++) { - if (query.test(a[i])) { - return true; - } - } - } - return false; - }, - - - /** - * Selects documents if a field is of the specified type. - * - * @param a - * @param b - * @returns {boolean} - */ - $type: function $type(a, b) { - switch (b) { - case 1: - case 'double': - return isNumber(a) && (a + '').indexOf('.') !== -1; - case 2: - case T_STRING: - return isString(a); - case 3: - case T_OBJECT: - return isObject(a); - case 4: - case T_ARRAY: - return isArray(a); - case 6: - case T_UNDEFINED: - return isNil(a); - case 8: - case T_BOOL: - return isBoolean(a); - case 9: - case T_DATE: - return isDate(a); - case 10: - case T_NULL: - return isNull(a); - case 11: - case T_REGEX: - return isRegExp(a); - case 16: - case 'int': - return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1; - case 18: - case 'long': - return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1; - case 19: - case 'decimal': - return isNumber(a); - default: - return false; - } - } -}; - -var queryOperators = { - - /** - * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $and: function $and(selector, value) { - assert(isArray(value), 'Invalid expression: $and expects value to be an Array'); - - var queries = []; - each(value, function (expr) { - return queries.push(new Query(expr)); - }); - - return { - test: function test(obj) { - for (var i = 0; i < queries.length; i++) { - if (!queries[i].test(obj)) { - return false; - } - } - return true; - } - }; - }, - - - /** - * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $or: function $or(selector, value) { - assert(isArray(value), 'Invalid expression. $or expects value to be an Array'); - - var queries = []; - each(value, function (expr) { - return queries.push(new Query(expr)); - }); - - return { - test: function test(obj) { - for (var i = 0; i < queries.length; i++) { - if (queries[i].test(obj)) { - return true; - } - } - return false; - } - }; - }, - - - /** - * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $nor: function $nor(selector, value) { - assert(isArray(value), 'Invalid expression. $nor expects value to be an Array'); - var query = this.$or('$or', value); - return { - test: function test(obj) { - return !query.test(obj); - } - }; - }, - - - /** - * Inverts the effect of a query expression and returns documents that do not match the query expression. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $not: function $not(selector, value) { - var criteria = {}; - criteria[selector] = normalize(value); - var query = new Query(criteria); - return { - test: function test(obj) { - return !query.test(obj); - } - }; - }, - - - /** - * Matches documents that satisfy a JavaScript expression. - * - * @param selector - * @param value - * @returns {{test: test}} - */ - $where: function $where(selector, value) { - if (!isFunction(value)) { - value = new Function('return ' + value + ';'); - } - return { - test: function test(obj) { - return value.call(obj) === true; - } - }; - } -}; - -// add simple query operators -each(simpleOperators, function (fn, op) { - queryOperators[op] = function (f, ctx) { - return function (selector, value) { - return { - test: function test(obj) { - // value of field must be fully resolved. - var lhs = resolve(obj, selector); - return f.call(ctx, lhs, value); - } - }; - }; - }(fn, simpleOperators); -}); - -/** - * Query object to test collection elements with - * @param criteria the pass criteria for the query - * @param projection optional projection specifiers - * @constructor - */ -var Query = function () { - function Query(criteria) { - var projection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - classCallCheck(this, Query); - - this.__criteria = criteria; - this.__projection = projection; - this.__compiled = []; - this._compile(); - } - - createClass(Query, [{ - key: '_compile', - value: function _compile() { - var _this = this; - - if (isEmpty(this.__criteria)) return; - - assert(isObject(this.__criteria), 'Criteria must be of type Object'); - - var whereOperator = void 0; - - each(this.__criteria, function (expr, field) { - // save $where operators to be executed after other operators - if ('$where' === field) { - whereOperator = { field: field, expr: expr }; - } else if (inArray(['$and', '$or', '$nor'], field)) { - _this._processOperator(field, field, expr); - } else { - // normalize expression - expr = normalize(expr); - each(expr, function (val, op) { - _this._processOperator(field, op, val); - }); - } - - if (isObject(whereOperator)) { - _this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); - } - }); - } - }, { - key: '_processOperator', - value: function _processOperator(field, operator, value) { - if (inArray(ops(OP_QUERY), operator)) { - this.__compiled.push(queryOperators[operator](field, value)); - } else { - err("Invalid query operator '" + operator + "' detected"); - } - } - - /** - * Checks if the object passes the query criteria. Returns true if so, false otherwise. - * @param obj - * @returns {boolean} - */ - - }, { - key: 'test', - value: function test(obj) { - for (var i = 0, len = this.__compiled.length; i < len; i++) { - if (!this.__compiled[i].test(obj)) { - return false; - } - } - return true; - } - - /** - * Performs a query on a collection and returns a cursor object. - * @param collection - * @param projection - * @returns {Cursor} - */ - - }, { - key: 'find', - value: function find(collection, projection) { - return new Cursor(collection, this, projection); - } - - /** - * Remove matched documents from the collection returning the remainder - * @param collection - * @returns {Array} - */ - - }, { - key: 'remove', - value: function remove(collection) { - var _this2 = this; - - return reduce(collection, function (acc, obj) { - if (!_this2.test(obj)) acc.push(obj); - return acc; - }, []); - } - }]); - return Query; -}(); - -/** - * Performs a query on a collection and returns a cursor object. - * - * @param collection - * @param criteria - * @param projection - * @returns {Cursor} - */ -function find(collection, criteria, projection) { - return new Query(criteria).find(collection, projection); -} - -/** - * Returns a new array without objects which match the criteria - * - * @param collection - * @param criteria - * @returns {Array} - */ -function remove(collection, criteria) { - return new Query(criteria).remove(collection); -} - -var arithmeticOperators = { - - /** - * Returns the absolute value of a number. - * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs - * @param obj - * @param expr - * @return {Number|null|NaN} - */ - $abs: function $abs(obj, expr) { - var val = computeValue(obj, expr); - return val === null || val === undefined ? null : Math.abs(val); - }, - - - /** - * Computes the sum of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $add: function $add(obj, expr) { - var args = computeValue(obj, expr); - return reduce(args, function (acc, num) { - return acc + num; - }, 0); - }, - - - /** - * Returns the smallest integer greater than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $ceil: function $ceil(obj, expr) { - var arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN; - if (isNil(arg)) return null; - assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.'); - return Math.ceil(arg); - }, - - - /** - * Takes two numbers and divides the first number by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $divide: function $divide(obj, expr) { - var args = computeValue(obj, expr); - return args[0] / args[1]; - }, - - - /** - * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {number} - */ - $exp: function $exp(obj, expr) { - var arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN; - if (isNil(arg)) return null; - assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.'); - return Math.exp(arg); - }, - - - /** - * Returns the largest integer less than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $floor: function $floor(obj, expr) { - var arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN; - if (isNil(arg)) return null; - assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.'); - return Math.floor(arg); - }, - - - /** - * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $ln: function $ln(obj, expr) { - var arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN; - if (isNil(arg)) return null; - assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.'); - return Math.log(arg); - }, - - - /** - * Calculates the log of a number in the specified base and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log: function $log(obj, expr) { - var args = computeValue(obj, expr); - assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items'); - if (args.some(isNaN)) return NaN; - if (args.some(isNil)) return null; - assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers'); - return Math.log10(args[0]) / Math.log10(args[1]); - }, - - - /** - * Calculates the log base 10 of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log10: function $log10(obj, expr) { - var arg = computeValue(obj, expr); - if (isNaN(arg)) return NaN; - if (isNil(arg)) return null; - assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.'); - return Math.log10(arg); - }, - - - /** - * Takes two numbers and calculates the modulo of the first number divided by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $mod: function $mod(obj, expr) { - var args = computeValue(obj, expr); - return args[0] % args[1]; - }, - - - /** - * Computes the product of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $multiply: function $multiply(obj, expr) { - var args = computeValue(obj, expr); - return reduce(args, function (acc, num) { - return acc * num; - }, 1); - }, - - - /** - * Raises a number to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {Object} - */ - $pow: function $pow(obj, expr) { - var args = computeValue(obj, expr); - - assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers'); - assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent'); - - return Math.pow(args[0], args[1]); - }, - - - /** - * Calculates the square root of a positive number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $sqrt: function $sqrt(obj, expr) { - var n = computeValue(obj, expr); - if (isNaN(n)) return NaN; - if (isNil(n)) return null; - assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.'); - return Math.sqrt(n); - }, - - - /** - * Takes an array that contains two numbers or two dates and subtracts the second value from the first. - * - * @param obj - * @param expr - * @returns {number} - */ - $subtract: function $subtract(obj, expr) { - var args = computeValue(obj, expr); - return args[0] - args[1]; - }, - - - /** - * Truncates a number to its integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $trunc: function $trunc(obj, expr) { - var n = computeValue(obj, expr); - if (isNaN(n)) return NaN; - if (isNil(n)) return null; - assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.'); - return Math.trunc(n); - } -}; - -var arrayOperators = { - /** - * Returns the element at the specified array index. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $arrayElemAt: function $arrayElemAt(obj, expr) { - var arr = computeValue(obj, expr); - assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements'); - assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array'); - assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer'); - var idx = arr[1]; - arr = arr[0]; - if (idx < 0 && Math.abs(idx) <= arr.length) { - return arr[idx + arr.length]; - } else if (idx >= 0 && idx < arr.length) { - return arr[idx]; - } - return undefined; - }, - - - /** - * Converts an array of key value pairs to a document. - */ - $arrayToObject: function $arrayToObject(obj, expr) { - var arr = computeValue(obj, expr); - assert(isArray(arr), '$arrayToObject expression must resolve to an array'); - return reduce(arr, function (newObj, val) { - if (isArray(val) && val.length == 2) newObj[val[0]] = val[1];else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v;else err('$arrayToObject expression is invalid.'); - return newObj; - }, {}); - }, - - - /** - * Concatenates arrays to return the concatenated array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $concatArrays: function $concatArrays(obj, expr) { - var arr = computeValue(obj, expr, null); - assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements'); - - if (arr.some(isNil)) return null; - - return arr[0].concat(arr[1]); - }, - - - /** - * Selects a subset of the array to return an array with only the elements that match the filter condition. - * - * @param {Object} obj [description] - * @param {*} expr [description] - * @return {*} [description] - */ - $filter: function $filter(obj, expr) { - var input = computeValue(obj, expr.input); - var asVar = expr['as']; - var condExpr = expr['cond']; - - assert(isArray(input), "$filter 'input' expression must resolve to an array"); - - return input.filter(function (o) { - // inject variable - var tempObj = {}; - tempObj['$' + asVar] = o; - return computeValue(tempObj, condExpr) === true; - }); - }, - - - /** - * Returns a boolean indicating whether a specified value is in an array. - * - * @param {Object} obj - * @param {Array} expr - */ - $in: function $in(obj, expr) { - var val = computeValue(obj, expr[0]); - var arr = computeValue(obj, expr[1]); - assert(isArray(arr), '$in second argument must be an array'); - return inArray(arr, val); - }, - - - /** - * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfArray: function $indexOfArray(obj, expr) { - var args = computeValue(obj, expr); - if (isNil(args)) return null; - - var arr = args[0]; - if (isNil(arr)) return null; - - assert(isArray(arr), '$indexOfArray expression must resolve to an array.'); - - var searchValue = args[1]; - if (isNil(searchValue)) return null; - - var start = args[2] || 0; - var end = args[3] || arr.length; - - if (end < arr.length) { - arr = arr.slice(start, end); - } - - return arr.indexOf(searchValue, start); - }, - - - /** - * Determines if the operand is an array. Returns a boolean. - * - * @param {Object} obj - * @param {*} expr - * @return {Boolean} - */ - $isArray: function $isArray(obj, expr) { - return isArray(computeValue(obj, expr)); - }, - - - /** - * Applies a sub-expression to each element of an array and returns the array of resulting values in order. - * - * @param obj - * @param expr - * @returns {Array|*} - */ - $map: function $map(obj, expr) { - var inputExpr = computeValue(obj, expr.input); - assert(isArray(inputExpr), '$map \'input\' expression must resolve to an array'); - - var asExpr = expr['as']; - var inExpr = expr['in']; - - // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" - // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". - // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. - var tempKey = '$' + asExpr; - // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) - var original = obj[tempKey]; - return map(inputExpr, function (item) { - obj[tempKey] = item; - var value = computeValue(obj, inExpr); - // cleanup and restore - if (isUndefined(original)) { - delete obj[tempKey]; - } else { - obj[tempKey] = original; - } - return value; - }); - }, - - - /** - * Converts a document to an array of documents representing key-value pairs. - */ - $objectToArray: function $objectToArray(obj, expr) { - var val = computeValue(obj, expr); - assert(isObject(val), '$objectToArray expression must resolve to an object'); - var arr = []; - each(val, function (v, k) { - return arr.push({ k: k, v: v }); - }); - return arr; - }, - - - /** - * Returns an array whose elements are a generated sequence of numbers. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $range: function $range(obj, expr) { - var arr = computeValue(obj, expr); - var start = arr[0]; - var end = arr[1]; - var step = arr[2] || 1; - - var result = []; - - while (start < end && step > 0 || start > end && step < 0) { - result.push(start); - start += step; - } - - return result; - }, - - - /** - * Applies an expression to each element in an array and combines them into a single value. - * - * @param {Object} obj - * @param {*} expr - */ - $reduce: function $reduce(obj, expr) { - var input = computeValue(obj, expr.input); - var initialValue = computeValue(obj, expr.initialValue); - var inExpr = expr['in']; - - if (isNil(input)) return null; - assert(isArray(input), "$reduce 'input' expression must resolve to an array"); - return reduce(input, function (acc, n) { - return computeValue({ '$value': acc, '$this': n }, inExpr); - }, initialValue); - }, - - - /** - * Returns an array with the elements in reverse order. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $reverseArray: function $reverseArray(obj, expr) { - var arr = computeValue(obj, expr); - - if (isNil(arr)) return null; - assert(isArray(arr), '$reverseArray expression must resolve to an array'); - - var result = []; - into(result, arr); - result.reverse(); - return result; - }, - - - /** - * Counts and returns the total the number of items in an array. - * - * @param obj - * @param expr - */ - $size: function $size(obj, expr) { - var value = computeValue(obj, expr); - return isArray(value) ? value.length : undefined; - }, - - - /** - * Returns a subset of an array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $slice: function $slice(obj, expr) { - var arr = computeValue(obj, expr); - return slice(arr[0], arr[1], arr[2]); - }, - - - /** - * Merge two lists together. - * - * Transposes an array of input arrays so that the first element of the output array would be an array containing, - * the first element of the first input array, the first element of the second input array, etc. - * - * @param {Obj} obj - * @param {*} expr - * @return {*} - */ - $zip: function $zip(obj, expr) { - var inputs = computeValue(obj, expr.inputs); - var useLongestLength = expr.useLongestLength || false; - - assert(isArray(inputs), "'inputs' expression must resolve to an array"); - assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean"); - - if (isArray(expr.defaults)) { - assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'"); - } - - var zipCount = 0; - - for (var i = 0, len = inputs.length; i < len; i++) { - var arr = inputs[i]; - - if (isNil(arr)) return null; - - assert(isArray(arr), "'inputs' expression values must resolve to an array or null"); - - zipCount = useLongestLength ? Math.max(zipCount, arr.length) : Math.min(zipCount || arr.length, arr.length); - } - - var result = []; - var defaults = expr.defaults || []; - - var _loop = function _loop(_i) { - var temp = inputs.map(function (val, index) { - return isNil(val[_i]) ? defaults[index] || null : val[_i]; - }); - result.push(temp); - }; - - for (var _i = 0; _i < zipCount; _i++) { - _loop(_i); - } - - return result; - } -}; - -var booleanOperators = { - /** - * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $and: function $and(obj, expr) { - var value = computeValue(obj, expr); - return truthy(value) && value.every(truthy); - }, - - /** - * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $or: function $or(obj, expr) { - var value = computeValue(obj, expr); - return truthy(value) && value.some(truthy); - }, - - /** - * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $not: function $not(obj, expr) { - return !computeValue(obj, expr[0]); - } -}; - -var comparisonOperators = { - /** - * Compares two values and returns the result of the comparison as an integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $cmp: function $cmp(obj, expr) { - var args = computeValue(obj, expr); - if (args[0] > args[1]) return 1; - if (args[0] < args[1]) return -1; - return 0; - } -}; -// mixin comparison operators -each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], function (op) { - comparisonOperators[op] = function (obj, expr) { - var args = computeValue(obj, expr); - return simpleOperators[op](args[0], args[1]); - }; -}); - -/** - * Conditional operators - */ - -var conditionalOperators = { - - /** - * A ternary operator that evaluates one expression, - * and depending on the result returns the value of one following expressions. - * - * @param obj - * @param expr - */ - $cond: function $cond(obj, expr) { - var ifExpr = void 0, - thenExpr = void 0, - elseExpr = void 0; - if (isArray(expr)) { - assert(expr.length === 3, 'Invalid arguments for $cond operator'); - ifExpr = expr[0]; - thenExpr = expr[1]; - elseExpr = expr[2]; - } else if (isObject(expr)) { - ifExpr = expr['if']; - thenExpr = expr['then']; - elseExpr = expr['else']; - } - var condition = computeValue(obj, ifExpr); - return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr); - }, - - - /** - * An operator that evaluates a series of case expressions. When it finds an expression which - * evaluates to true, it returns the resulting expression for that case. If none of the cases - * evaluate to true, it returns the default expression. - * - * @param obj - * @param expr - */ - $switch: function $switch(obj, expr) { - assert(expr.branches, 'Invalid arguments for $switch operator'); - - var validBranch = expr.branches.find(function (branch) { - assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator'); - return computeValue(obj, branch['case']); - }); - - if (validBranch) { - return computeValue(obj, validBranch.then); - } else if (!expr.default) { - err('Invalid arguments for $switch operator'); - } else { - return computeValue(obj, expr.default); - } - }, - - - /** - * Evaluates an expression and returns the first expression if it evaluates to a non-null value. - * Otherwise, $ifNull returns the second expression's value. - * - * @param obj - * @param expr - * @returns {*} - */ - $ifNull: function $ifNull(obj, expr) { - assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator'); - var args = computeValue(obj, expr); - return args[0] === null || args[0] === undefined ? args[1] : args[0]; - } -}; - -// used for formatting dates in $dateToString operator -var DATE_SYM_TABLE = { - '%Y': ['$year', 4], - '%m': ['$month', 2], - '%d': ['$dayOfMonth', 2], - '%H': ['$hour', 2], - '%M': ['$minute', 2], - '%S': ['$second', 2], - '%L': ['$millisecond', 3], - '%j': ['$dayOfYear', 3], - '%w': ['$dayOfWeek', 1], - '%U': ['$week', 2], - '%%': '%' -}; - -var dateOperators = { - /** - * Returns the day of the year for a date as a number between 1 and 366 (leap year). - * @param obj - * @param expr - */ - $dayOfYear: function $dayOfYear(obj, expr) { - var d = computeValue(obj, expr); - if (isDate(d)) { - var start = new Date(d.getFullYear(), 0, 0); - var diff = d - start; - var oneDay = 1000 * 60 * 60 * 24; - return Math.round(diff / oneDay); - } - return undefined; - }, - - - /** - * Returns the day of the month for a date as a number between 1 and 31. - * @param obj - * @param expr - */ - $dayOfMonth: function $dayOfMonth(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getDate() : undefined; - }, - - - /** - * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). - * @param obj - * @param expr - */ - $dayOfWeek: function $dayOfWeek(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getDay() + 1 : undefined; - }, - - - /** - * Returns the year for a date as a number (e.g. 2014). - * @param obj - * @param expr - */ - $year: function $year(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getFullYear() : undefined; - }, - - - /** - * Returns the month for a date as a number between 1 (January) and 12 (December). - * @param obj - * @param expr - */ - $month: function $month(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getMonth() + 1 : undefined; - }, - - - /** - * Returns the week number for a date as a number between 0 - * (the partial week that precedes the first Sunday of the year) and 53 (leap year). - * @param obj - * @param expr - */ - $week: function $week(obj, expr) { - // source: http://stackoverflow.com/a/6117889/1370481 - var d = computeValue(obj, expr); - - // Copy date so don't modify original - d = new Date(+d); - d.setHours(0, 0, 0); - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - d.setDate(d.getDate() + 4 - (d.getDay() || 7)); - // Get first day of year - var yearStart = new Date(d.getFullYear(), 0, 1); - // Calculate full weeks to nearest Thursday - return Math.floor(((d - yearStart) / 8.64e7 + 1) / 7); - }, - - - /** - * Returns the hour for a date as a number between 0 and 23. - * @param obj - * @param expr - */ - $hour: function $hour(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getUTCHours() : undefined; - }, - - - /** - * Returns the minute for a date as a number between 0 and 59. - * @param obj - * @param expr - */ - $minute: function $minute(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getMinutes() : undefined; - }, - - - /** - * Returns the seconds for a date as a number between 0 and 60 (leap seconds). - * @param obj - * @param expr - */ - $second: function $second(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getSeconds() : undefined; - }, - - - /** - * Returns the milliseconds of a date as a number between 0 and 999. - * @param obj - * @param expr - */ - $millisecond: function $millisecond(obj, expr) { - var d = computeValue(obj, expr); - return isDate(d) ? d.getMilliseconds() : undefined; - }, - - - /** - * Returns the date as a formatted string. - * - * %Y Year (4 digits, zero padded) 0000-9999 - * %m Month (2 digits, zero padded) 01-12 - * %d Day of Month (2 digits, zero padded) 01-31 - * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 - * %M Minute (2 digits, zero padded) 00-59 - * %S Second (2 digits, zero padded) 00-60 - * %L Millisecond (3 digits, zero padded) 000-999 - * %j Day of year (3 digits, zero padded) 001-366 - * %w Day of week (1-Sunday, 7-Saturday) 1-7 - * %U Week of year (2 digits, zero padded) 00-53 - * %% Percent Character as a Literal % - * - * @param obj current object - * @param expr operator expression - */ - $dateToString: function $dateToString(obj, expr) { - var fmt = expr['format']; - var date = computeValue(obj, expr['date']); - var matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g); - - for (var i = 0, len = matches.length; i < len; i++) { - var hdlr = DATE_SYM_TABLE[matches[i]]; - var value = hdlr; - - if (isArray(hdlr)) { - // reuse date operators - var fn = this[hdlr[0]]; - var pad = hdlr[1]; - value = padDigits(fn.call(this, obj, date), pad); - } - // replace the match with resolved value - fmt = fmt.replace(matches[i], value); - } - - return fmt; - } -}; - -function padDigits(number, digits) { - return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number; -} - -var literalOperators = { - /** - * Return a value without parsing. - * @param obj - * @param expr - */ - $literal: function $literal(obj, expr) { - return expr; - } -}; - -var setOperators = { - /** - * Returns true if two sets have the same elements. - * @param obj - * @param expr - */ - $setEquals: function $setEquals(obj, expr) { - var args = computeValue(obj, expr); - var xs = unique(args[0]); - var ys = unique(args[1]); - return xs.length === ys.length && xs.length === intersection(xs, ys).length; - }, - - - /** - * Returns the common elements of the input sets. - * @param obj - * @param expr - */ - $setIntersection: function $setIntersection(obj, expr) { - var args = computeValue(obj, expr); - return intersection(args[0], args[1]); - }, - - - /** - * Returns elements of a set that do not appear in a second set. - * @param obj - * @param expr - */ - $setDifference: function $setDifference(obj, expr) { - var args = computeValue(obj, expr); - return args[0].filter(notInArray.bind(null, args[1])); - }, - - - /** - * Returns a set that holds all elements of the input sets. - * @param obj - * @param expr - */ - $setUnion: function $setUnion(obj, expr) { - var args = computeValue(obj, expr); - return union(args[0], args[1]); - }, - - - /** - * Returns true if all elements of a set appear in a second set. - * @param obj - * @param expr - */ - $setIsSubset: function $setIsSubset(obj, expr) { - var args = computeValue(obj, expr); - return intersection(args[0], args[1]).length === args[0].length; - }, - - - /** - * Returns true if any elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $anyElementTrue: function $anyElementTrue(obj, expr) { - // mongodb nests the array expression in another - var args = computeValue(obj, expr)[0]; - return args.some(truthy); - }, - - - /** - * Returns true if all elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $allElementsTrue: function $allElementsTrue(obj, expr) { - // mongodb nests the array expression in another - var args = computeValue(obj, expr)[0]; - return args.every(truthy); - } -}; - -var stringOperators = { - - /** - * Concatenates two strings. - * - * @param obj - * @param expr - * @returns {string|*} - */ - $concat: function $concat(obj, expr) { - var args = computeValue(obj, expr); - // does not allow concatenation with nulls - if ([null, undefined].some(inArray.bind(null, args))) { - return null; - } - return args.join(''); - }, - - - /** - * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfBytes: function $indexOfBytes(obj, expr) { - var arr = computeValue(obj, expr); - - if (isNil(arr[0])) return null; - - assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string'); - assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string'); - - var str = arr[0]; - var searchStr = arr[1]; - var start = arr[2]; - var end = arr[3]; - - assert(isNil(start) || isNumber(start) && start >= 0 && Math.round(start) === start, '$indexOfBytes third operand must resolve to a non-negative integer'); - start = start || 0; - - assert(isNil(end) || isNumber(end) && end >= 0 && Math.round(end) === end, '$indexOfBytes fourth operand must resolve to a non-negative integer'); - end = end || str.length; - - if (start > end) return -1; - - var index = str.substring(start, end).indexOf(searchStr); - return index > -1 ? index + start : index; - }, - - - /** - * Splits a string into substrings based on a delimiter. - * If the delimiter is not found within the string, returns an array containing the original string. - * - * @param {Object} obj - * @param {Array} expr - * @return {Array} Returns an array of substrings. - */ - $split: function $split(obj, expr) { - var args = computeValue(obj, expr); - assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])); - assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])); - return args[0].split(args[1]); - }, - - - /** - * Compares two strings and returns an integer that reflects the comparison. - * - * @param obj - * @param expr - * @returns {number} - */ - $strcasecmp: function $strcasecmp(obj, expr) { - var args = computeValue(obj, expr); - args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase(); - args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase(); - if (args[0] > args[1]) { - return 1; - } - return args[0] < args[1] ? -1 : 0; - }, - - - /** - * Returns a substring of a string, starting at a specified index position and including the specified number of characters. - * The index is zero-based. - * - * @param obj - * @param expr - * @returns {string} - */ - $substr: function $substr(obj, expr) { - var args = computeValue(obj, expr); - if (isString(args[0])) { - if (args[1] < 0) { - return ''; - } else if (args[2] < 0) { - return args[0].substr(args[1]); - } else { - return args[0].substr(args[1], args[2]); - } - } - return ''; - }, - - - /** - * Converts a string to lowercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toLower: function $toLower(obj, expr) { - var value = computeValue(obj, expr); - return isEmpty(value) ? '' : value.toLowerCase(); - }, - - - /** - * Converts a string to uppercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toUpper: function $toUpper(obj, expr) { - var value = computeValue(obj, expr); - return isEmpty(value) ? '' : value.toUpperCase(); - } -}; - -/** - * Aggregation framework variable operators - */ - -var variableOperators = { - /** - * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. - * - * @param obj - * @param expr - * @returns {*} - */ - $let: function $let(obj, expr) { - var varsExpr = expr['vars']; - var inExpr = expr['in']; - - // resolve vars - var originals = {}; - var varsKeys = keys(varsExpr); - each(varsKeys, function (key) { - var val = computeValue(obj, varsExpr[key]); - var tempKey = '$' + key; - // set value on object using same technique as in "$map" - originals[tempKey] = obj[tempKey]; - obj[tempKey] = val; - }); - - var value = computeValue(obj, inExpr); - - // cleanup and restore - each(varsKeys, function (key) { - var tempKey = '$' + key; - if (isUndefined(originals[tempKey])) { - delete obj[tempKey]; - } else { - obj[tempKey] = originals[tempKey]; - } - }); - - return value; - } -}; - -// combine aggregate operators -var aggregateOperators = Object.assign({}, arithmeticOperators, arrayOperators, booleanOperators, comparisonOperators, conditionalOperators, dateOperators, literalOperators, setOperators, stringOperators, variableOperators); - -// operator definitions -var OPERATORS = { - 'aggregate': aggregateOperators, - 'group': groupOperators, - 'pipeline': pipelineOperators, - 'projection': projectionOperators, - 'query': queryOperators - - /** - * Returns the operators defined for the given operator classes - */ -};function ops() { - return reduce(arguments, function (acc, cls) { - return into(acc, keys(OPERATORS[cls])); - }, []); -} - -/** - * Add new operators - * - * @param opClass the operator class to extend - * @param fn a function returning an object of new operators - */ -function addOperators(opClass, fn) { - - var newOperators = fn(_internal()); - - // ensure correct type specified - assert(has(OPERATORS, opClass), 'Invalid operator class ' + opClass); - - var operators = OPERATORS[opClass]; - - // check for existing operators - each(newOperators, function (fn, op) { - assert(/^\$\w+$/.test(op), 'Invalid operator name ' + op); - assert(!has(operators, op), op + ' already exists for \'' + opClass + '\' operators'); - }); - - var wrapped = {}; - - switch (opClass) { - case OP_QUERY: - each(newOperators, function (fn, op) { - wrapped[op] = function (f, ctx) { - return function (selector, value) { - return { - test: function test(obj) { - // value of field must be fully resolved. - var lhs = resolve(obj, selector); - var result = f.call(ctx, selector, lhs, value); - if (isBoolean(result)) { - return result; - } else if (result instanceof Query) { - return result.test(obj); - } else { - err("Invalid return type for '" + op + "'. Must return a Boolean or Query"); - } - } - }; - }; - }(fn, newOperators); - }); - break; - case OP_PROJECTION: - each(newOperators, function (fn, op) { - wrapped[op] = function (f, ctx) { - return function (obj, expr, selector) { - var lhs = resolve(obj, selector); - return f.call(ctx, selector, lhs, expr); - }; - }(fn, newOperators); - }); - break; - default: - each(newOperators, function (fn, op) { - wrapped[op] = function (f, ctx) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return f.apply(ctx, args); - }; - }(fn, newOperators); - }); - } - - // toss the operator salad :) - Object.assign(OPERATORS[opClass], wrapped); -} - -/** - * Internal functions - */ - -// Settings used by Mingo internally -var settings = { - key: '_id' - - /** - * Setup default settings for Mingo - * @param options - */ -};function setup(options) { - Object.assign(settings, options || {}); -} - -/** - * Implementation of system variables - * @type {Object} - */ -var systemVariables = { - '$$ROOT': function $$ROOT(obj, expr, opt) { - return opt.root; - }, - '$$CURRENT': function $$CURRENT(obj, expr, opt) { - return obj; - } -}; - -/** - * Implementation of $redact variables - * - * Each function accepts 3 arguments (obj, expr, opt) - * - * @type {Object} - */ -var redactVariables = { - '$$KEEP': function $$KEEP(obj) { - return obj; - }, - '$$PRUNE': function $$PRUNE() { - return undefined; - }, - '$$DESCEND': function $$DESCEND(obj, expr, opt) { - // traverse nested documents iff there is a $cond - if (!has(expr, '$cond')) return obj; - - var result = void 0; - - each(obj, function (current, key) { - if (isObjectLike(current)) { - if (isArray(current)) { - result = []; - each(current, function (elem) { - if (isObject(elem)) { - elem = redactObj(elem, expr, opt); - } - if (!isNil(elem)) result.push(elem); - }); - } else { - result = redactObj(current, expr, opt); - } - - if (isNil(result)) { - delete obj[key]; // pruned result - } else { - obj[key] = result; - } - } - }); - return obj; - } -}; - -// system variables -var SYS_VARS = keys(systemVariables); -var REDACT_VARS = keys(redactVariables); - -/** - * Returns the key used as the collection's objects ids - */ -function idKey() { - return settings.key; -} - -/** - * Retrieve the value of a given key on an object - * @param obj - * @param field - * @returns {*} - * @private - */ -function getValue(obj, field) { - return obj[field]; -} - -/** - * Resolve the value of the field (dot separated) on the given object - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) - * @returns {*} - */ -function resolve(obj, selector) { - var deepFlag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var names = selector.split('.'); - var value = obj; - - var _loop = function _loop(i) { - var isText = names[i].match(/^\d+$/) === null; - - if (isText && isArray(value)) { - // On the first iteration, we check if we received a stop flag. - // If so, we stop to prevent iterating over a nested array value - // on consecutive object keys in the selector. - if (deepFlag === true && i === 0) { - return { - v: value - }; - } - - value = value.map(function (item) { - return resolve(item, names[i], true); - }); - - // we mark this value as being multi-valued - addMeta(value, { isMulti: true }); - - // we unwrap for arrays of unit length - // this avoids excess wrapping when resolving deeply nested arrays - if (value.length === 1) { - value = value[0]; - } - } else { - value = getValue(value, names[i]); - deepFlag = false; // reset stop flag when we do a direct lookup - } - - if (isNil(value)) return 'break'; - }; - - _loop2: for (var i = 0; i < names.length; i++) { - var _ret = _loop(i); - - switch (_ret) { - case 'break': - break _loop2; - - default: - if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; - } - } - - return value; -} - -/** - * Returns the full object to the resolved value given by the selector. - * This function excludes empty values as they aren't practically useful. - * - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - */ -function resolveObj(obj, selector) { - if (isNil(obj)) return; - - var names = selector.split('.'); - var key = names[0]; - // get the next part of the selector - var next = names.length === 1 || names.slice(1).join('.'); - var isIndex = key.match(/^\d+$/) !== null; - var hasNext = names.length > 1; - var result = void 0; - var value = void 0; - - try { - if (isArray(obj)) { - if (isIndex) { - result = getValue(obj, key); - if (hasNext) { - result = resolveObj(result, next); - } - assert(!isUndefined(result)); - result = [result]; - } else { - result = []; - each(obj, function (item) { - value = resolveObj(item, selector); - if (!isNil(value)) result.push(value); - }); - assert(result.length > 0); - } - } else { - value = getValue(obj, key); - if (hasNext) { - value = resolveObj(value, next); - } - assert(!isUndefined(value)); - result = {}; - result[key] = value; - } - } catch (e) { - result = undefined; - } - - return result; -} - -/** - * Walk the object graph and execute the given transform function - * @param {Object|Array} obj The object to traverse - * @param {String} selector The selector - * @param {Function} fn Function to execute for value at the end the traversal - * @param {Boolean} force Force generating missing parts of object graph - * @return {*} - */ -function traverse(obj, selector, fn) { - var force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - - var names = selector.split('.'); - var key = names[0]; - var next = names.length === 1 || names.slice(1).join('.'); - - if (names.length === 1) { - fn(obj, key); - } else { - // nested objects - if (isArray(obj) && !/^\d+$/.test(key)) { - each(obj, function (item) { - traverse(item, selector, fn, force); - }); - } else { - // force the rest of the graph while traversing - if (force === true) { - var exists = has(obj, key); - if (!exists || isNil(obj[key])) { - obj[key] = {}; - } - } - traverse(obj[key], next, fn, force); - } - } -} - -/** - * Set the value of the given object field - * - * @param obj {Object|Array} the object context - * @param selector {String} path to field - * @param value {*} the value to set - */ -function setValue(obj, selector, value) { - traverse(obj, selector, function (item, key) { - item[key] = value; - }, true); -} - -function removeValue(obj, selector) { - traverse(obj, selector, function (item, key) { - if (isArray(item) && /^\d+$/.test(key)) { - item.splice(parseInt(key), 1); - } else if (isObject(item)) { - delete item[key]; - } - }); -} - -/** - * Simplify expression for easy evaluation with query operators map - * @param expr - * @returns {*} - */ -function normalize(expr) { - // normalized primitives - if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { - return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr }; - } - - // normalize object expression - if (isObjectLike(expr)) { - var exprKeys = keys(expr); - var noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0; - - // no valid query operator found, so we do simple comparison - if (noQuery) { - return { '$eq': expr }; - } - - // ensure valid regex - if (inArray(exprKeys, '$regex')) { - var regex = expr['$regex']; - var options = expr['$options'] || ''; - var modifiers = ''; - if (isString(regex)) { - modifiers += regex.ignoreCase || options.indexOf('i') >= 0 ? 'i' : ''; - modifiers += regex.multiline || options.indexOf('m') >= 0 ? 'm' : ''; - modifiers += regex.global || options.indexOf('g') >= 0 ? 'g' : ''; - regex = new RegExp(regex, modifiers); - } - expr['$regex'] = regex; - delete expr['$options']; - } - } - - return expr; -} - -/** - * Computes the actual value of the expression using the given object as context - * - * @param obj the current object from the collection - * @param expr the expression for the given field - * @param field the field name (may also be an aggregate operator) - * @param opt {Object} extra options - * @returns {*} - */ -function computeValue(obj, expr) { - var field = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var opt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - - opt.root = opt.root || obj; - - // if the field of the object is a valid operator - if (inArray(ops(OP_AGGREGATE), field)) { - return aggregateOperators[field](obj, expr, opt); - } - - // we also handle $group accumulator operators - if (inArray(ops(OP_GROUP), field)) { - // we first fully resolve the expression - obj = computeValue(obj, expr, null, opt); - assert(isArray(obj), field + ' expression must resolve to an array'); - // we pass a null expression because all values have been resolved - return groupOperators[field](obj, null, opt); - } - - // if expr is a variable for an object field - // field not used in this case - if (isString(expr) && expr.length > 0 && expr[0] === '$') { - // we return system variables as literals - if (inArray(SYS_VARS, expr)) { - return systemVariables[expr](obj, null, opt); - } else if (inArray(REDACT_VARS, expr)) { - return expr; - } - - // handle selectors with explicit prefix - var sysVar = SYS_VARS.filter(function (v) { - return expr.indexOf(v + '.') === 0; - }); - - if (sysVar.length === 1) { - sysVar = sysVar[0]; - if (sysVar === '$$ROOT') { - obj = opt.root; - } - expr = expr.substr(sysVar.length); // '.' prefix will be sliced off below - } - - return resolve(obj, expr.slice(1)); - } - - // check and return value if already in a resolved state - switch (jsType(expr)) { - case T_ARRAY: - return expr.map(function (item) { - return computeValue(obj, item); - }); - case T_OBJECT: - var result = {}; - each(expr, function (val, key) { - result[key] = computeValue(obj, val, key, opt); - // must run ONLY one aggregate operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { - // there should be only one operator - assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'"); - result = result[key]; - return false; // break - } - }); - return result; - default: - return expr; - } -} - -/** - * Returns a slice of the array - * - * @param {Array} xs - * @param {Number} skip - * @param {Number} limit - * @return {Array} - */ -function slice(xs, skip) { - var limit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - - // MongoDB $slice works a bit differently from Array.slice - // Uses single argument for 'limit' and array argument [skip, limit] - if (isNil(limit)) { - if (skip < 0) { - skip = Math.max(0, xs.length + skip); - limit = xs.length - skip + 1; - } else { - limit = skip; - skip = 0; - } - } else { - if (skip < 0) { - skip = Math.max(0, xs.length + skip); - } - assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number'); - limit += skip; - } - return Array.prototype.slice.apply(xs, [skip, limit]); -} - -/** - * Compute the standard deviation of the data set - * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". - * @return {Number} - */ -function stddev(ctx) { - var sum = reduce(ctx.data, function (acc, n) { - return acc + n; - }, 0); - var N = ctx.data.length || 1; - var correction = ctx.sampled === true ? 1 : 0; - var avg = sum / (N - correction); - return Math.sqrt(reduce(ctx.data, function (acc, n) { - return acc + Math.pow(n - avg, 2); - }, 0) / N); -} - -/** - * Redact an object - * @param {Object} obj The object to redact - * @param {*} expr The redact expression - * @param {*} opt Options for value - * @return {*} Returns the redacted value - */ -function redactObj(obj, expr) { - var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - opt.root = opt.root || obj; - - var result = computeValue(obj, expr, null, opt); - return inArray(REDACT_VARS, result) ? redactVariables[result](obj, expr, opt) : result; -} - -/** - * Exported to the users to allow writing custom operators - */ -function _internal() { - return { - computeValue: computeValue, - idKey: idKey, - ops: ops, - resolve: resolve, - assert: assert, - clone: clone, - each: each, - err: err, - getType: getType, - has: has, - isArray: isArray, - isBoolean: isBoolean, - isDate: isDate, - isEmpty: isEmpty, - isEqual: isEqual, - isFunction: isFunction, - isNil: isNil, - isNull: isNull, - isNumber: isNumber, - isObject: isObject, - isRegExp: isRegExp, - isString: isString, - isUndefined: isUndefined, - keys: keys, - map: map - }; -} - -/** - * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` - */ -var CollectionMixin = { - - /** - * Runs a query and returns a cursor to the result - * @param criteria - * @param projection - * @returns {Cursor} - */ - query: function query(criteria, projection) { - return new Query(criteria).find(this.toJSON(), projection); - }, - - - /** - * Runs the given aggregation operators on this collection - * @params pipeline - * @returns {Array} - */ - aggregate: function aggregate$$1(pipeline) { - return new Aggregator(pipeline).run(this.toJSON()); - } -}; - -var VERSION = '1.3.3'; - -// mingo! -var index = { - _internal: _internal, - Aggregator: Aggregator, - CollectionMixin: CollectionMixin, - Cursor: Cursor, - OP_AGGREGATE: OP_AGGREGATE, - OP_GROUP: OP_GROUP, - OP_PIPELINE: OP_PIPELINE, - OP_PROJECTION: OP_PROJECTION, - OP_QUERY: OP_QUERY, - Query: Query, - VERSION: VERSION, - addOperators: addOperators, - aggregate: aggregate, - find: find, - remove: remove, - setup: setup -}; - -return index; - -}))); diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map deleted file mode 100644 index 7ef3a22..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["dist/mingo.js"],"names":["global","factory","exports","module","define","amd","mingo","this","assert","condition","message","falsey","err","clone","obj","jsType","T_ARRAY","map","T_OBJECT","getType","v","undefined","constructor","name","toLowerCase","isBoolean","T_BOOLEAN","isString","T_STRING","isNumber","T_NUMBER","isArray","isArrayLike","isNil","has","isObject","isObjectLike","Object","isDate","T_DATE","isRegExp","T_REGEXP","isFunction","T_FUNCTION","isNull","isUndefined","T_NULL","T_UNDEFINED","inArray","arr","item","includes","notInArray","truthy","arg","isEmpty","x","length","keys","array","prop","hasOwnProperty","s","Error","o","addMeta","value","__MINGO_META","assign","hasMeta","isEqual","dropMeta","each","fn","ctx","arguments","i","len","call","k","reduce","collection","accumulator","intersection","xs","ys","filter","bind","union","into","a","b","type","isNaN","toString","getHash","ka","kb","sort","_i","_len","temp","unique","h","push","randomString","n","Math","E","random","slice","encode","JSON","stringify","toISOString","prefix","objKeys","hash","chr","charCodeAt","sortBy","sortKeys","sorted","result","key","A","B","groupBy","groups","lookup","index","target","Array","prototype","apply","findInsertIndex","lo","hi","mid","round","memoize","_this","cache","_len2","args","_key","accumulate","field","expr","ops","OP_GROUP","groupOperators","val","aggregate","pipeline","Aggregator","run","find","criteria","projection","Query","remove","padDigits","number","digits","max","String","join","acc","cls","OPERATORS","addOperators","opClass","newOperators","_internal","operators","op","test","wrapped","OP_QUERY","f","selector","lhs","resolve","OP_PROJECTION","setup","options","settings","idKey","getValue","deepFlag","names","split","_loop2","_ret","match","isMulti","_typeof","resolveObj","next","isIndex","hasNext","e","traverse","force","exists","setValue","removeValue","splice","parseInt","normalize","JS_SIMPLE_TYPES","$regex","$eq","exprKeys","regex","modifiers","ignoreCase","indexOf","multiline","RegExp","computeValue","opt","root","OP_AGGREGATE","aggregateOperators","SYS_VARS","systemVariables","REDACT_VARS","sysVar","substr","skip","limit","stddev","sum","data","N","correction","sampled","avg","sqrt","pow","redactObj","redactVariables","Function","oThis","aArgs","fToBind","fNOP","fBound","concat","defineProperty","predicate","TypeError","thisArg","kValue","findIndex","searchElement","fromIndex","abs","y","varArgs","to","nextSource","nextKey","values","$addToSet","$push","$sum","$max","$min","$avg","$first","$last","$stdDevPop","$stdDevSamp","projectionOperators","$","$elemMatch","query","$slice","pipelineOperators","$addFields","newFields","subExpr","newValue","$group","ID_KEY","objectId","partitions","$lookup","hashCode","joinColl","from","localField","foreignField","asField","as","errorMsg","indexes","newObj","tempResult","$match","all","$project","projected","idOnlyExcludedExpression","check","id","cloneObj","foundSlice","foundExclusion","dropKeys","operator","every","objValue","$limit","$skip","$unwind","tmp","$sort","reverse","grouped","sortedIndex","getIndex","indexKeys","$sortByCount","newExpr","count","$sample","size","floor","$count","trim","$replaceRoot","newRoot","$redact","$bucket","boundaries","defaultKey","default","lower","upper","outputExpr","output","boundType","boundKey","pop","_id","$bucketAuto","groupByExpr","bucketCount","buckets","approxBucketSize","computeValueOptimized","remaining","bucketItems","j","min","$facet","Symbol","iterator","classCallCheck","instance","Constructor","createClass","defineProperties","props","descriptor","enumerable","configurable","writable","protoProps","staticProps","__operators","Cursor","__query","__collection","__projection","__result","__position","selected","aggregator","_fetch","modifier","callback","self","done","simpleOperators","$ne","$in","$nin","$lt","$lte","$gt","$gte","$mod","$exists","$all","matched","$size","$type","queryOperators","$and","queries","$or","$nor","$not","$where","__criteria","__compiled","_compile","whereOperator","_processOperator","_this2","arithmeticOperators","$abs","$add","num","$ceil","NaN","ceil","$divide","$exp","exp","$floor","$ln","log","$log","some","log10","$log10","$multiply","$pow","$sqrt","$subtract","$trunc","trunc","arrayOperators","$arrayElemAt","idx","$arrayToObject","$concatArrays","$filter","input","asVar","condExpr","tempObj","$indexOfArray","searchValue","start","end","$isArray","$map","inputExpr","asExpr","inExpr","tempKey","original","$objectToArray","$range","step","$reduce","initialValue","$value","$this","$reverseArray","$zip","inputs","useLongestLength","defaults","zipCount","booleanOperators","comparisonOperators","$cmp","conditionalOperators","$cond","ifExpr","thenExpr","elseExpr","$switch","branches","validBranch","branch","then","$ifNull","DATE_SYM_TABLE","%Y","%m","%d","%H","%M","%S","%L","%j","%w","%U","%%","dateOperators","$dayOfYear","d","Date","getFullYear","diff","$dayOfMonth","getDate","$dayOfWeek","getDay","$year","$month","getMonth","$week","setHours","setDate","yearStart","$hour","getUTCHours","$minute","getMinutes","$second","getSeconds","$millisecond","getMilliseconds","$dateToString","fmt","date","matches","hdlr","pad","replace","literalOperators","$literal","setOperators","$setEquals","$setIntersection","$setDifference","$setUnion","$setIsSubset","$anyElementTrue","$allElementsTrue","stringOperators","$concat","$indexOfBytes","str","searchStr","substring","$split","$strcasecmp","toUpperCase","$substr","$toLower","$toUpper","variableOperators","$let","varsExpr","originals","varsKeys","group","$$ROOT","$$CURRENT","$$KEEP","$$PRUNE","$$DESCEND","current","elem","CollectionMixin","toJSON","OP_PIPELINE","VERSION"],"mappings":"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"} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js b/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js deleted file mode 100644 index 42f2b9a..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/dist/mingo.min.js +++ /dev/null @@ -1,7 +0,0 @@ -// mingo.js 1.3.3 -// Copyright (c) 2017 Francis Asante -// https://github.com/kofrasa/mingo -// MIT -!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.mingo=t()}(this,function(){"use strict";function n(n,t){b(n)&&w(t)}function t(n){switch(e(n)){case mn:return n.map(t);case bn:return E(n,t);default:return n}}function r(n){return null===n?"Null":void 0===n?"Undefined":n.constructor.name}function e(n){return r(n).toLowerCase()}function u(n){return e(n)===pn}function i(n){return e(n)===gn}function o(n){return e(n)===dn}function a(n){return e(n)===mn}function s(n){return!p(n)&&O(n,"length")}function c(n){return e(n)===bn}function f(n){return n===Object(n)}function l(n){return e(n)===$n}function v(n){return e(n)===yn}function h(n){return e(n)===_n}function p(n){return d(n)||g(n)}function d(n){return e(n)===vn}function g(n){return e(n)===hn}function $(n,t){return n.includes(t)}function y(n,t){return!n.includes(t)}function m(n){return!!n}function b(n){return!n}function _(n){return p(n)||a(n)&&0===n.length||c(n)&&0===j(n).length||!n}function x(n){return a(n)?n:[n]}function O(n,t){return n.hasOwnProperty(t)}function w(n){throw new Error(n)}function j(n){return Object.keys(n)}function k(n,t){n[Nn]=Object.assign(n[Nn]||{},t)}function N(n,t){return O(n,Nn)&&c(t)&&q(Object.assign({},n[Nn],t),n[Nn])}function M(n){O(n,Nn)&&delete n[Nn]}function A(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(n(t===Object(t),"Cannot iterate over object of type '"+e(t)+"'"),s(t))for(var i=0,o=t.length;i2&&void 0!==arguments[2]?arguments[2]:null;if(a(n))return n.map(t,r);if(c(n)){var e={};return A(n,function(n,u){return e[u]=t.call(r,n,u)},n),e}}function S(n,t,r){return a(n)?n.reduce(t,r):(A(n,function(e,u){return r=t(r,e,u,n)}),r)}function I(n,t){return n.filter($.bind(null,t))}function T(n,t){return L(L([],n),t.filter(y.bind(null,n)))}function q(n,t){if(n===t)return!0;var r=e(n);if(r!==e(t)||r===_n)return!1;if(r===dn&&isNaN(n)&&isNaN(t))return!0;if($([$n,yn],r))return n.toString()===t.toString();if(r===mn){if(n.length===t.length&&0===n.length)return!0;if(n.length!==t.length)return!1;for(var u=0,i=n.length;u2&&void 0!==arguments[2]?arguments[2]:null,e={},u=[],i=n.length,o=[],a=0;au[0]?1:r[1]u[1]?1:0}),L(o,u)}function U(n,t,r){var e={keys:[],groups:[]},u={};return A(n,function(n){var i=t.call(r,n),o=R(i),a=-1;g(u[o])&&(a=e.keys.length,u[o]=a,e.keys.push(i),e.groups.push([])),a=u[o],e.groups[a].push(n)}),e}function L(n,t){return Array.prototype.push.apply(n,t),n}function B(n,t){for(var r=0,e=n.length-1;r<=e;){var u=Math.round(r+(e-r)/2);if(tn[u]))return u;r=u+1}}return r}function Y(n){var t=this;return function(r){return function(){for(var e=arguments.length,u=Array(e),i=0;i2&&void 0!==arguments[2]&&arguments[2],e=t.split("."),u=n;n:for(var i=0;i1,c=void 0,f=void 0;try{a(t)?o?(c=Z(t,u),s&&(c=tn(c,i)),n(!g(c)),c=[c]):(c=[],A(t,function(n){f=tn(n,r),p(f)||c.push(f)}),n(c.length>0)):(f=Z(t,u),s&&(f=tn(f,i)),n(!g(f)),c={},c[u]=f)}catch(n){c=void 0}return c}}function rn(n,t,r){var e=arguments.length>3&&void 0!==arguments[3]&&arguments[3],u=t.split("."),i=u[0],o=1===u.length||u.slice(1).join(".");if(1===u.length)r(n,i);else if(a(n)&&!/^\d+$/.test(i))A(n,function(n){rn(n,t,r,e)});else{if(!0===e){var s=O(n,i);s&&!p(n[i])||(n[i]={})}rn(n[i],o,r,e)}}function en(n,t,r){rn(n,t,function(n,t){n[t]=r},!0)}function un(n,t){rn(n,t,function(n,t){a(n)&&/^\d+$/.test(t)?n.splice(parseInt(t),1):c(n)&&delete n[t]})}function on(n){if($(xn,e(n)))return v(n)?{$regex:n}:{$eq:n};if(f(n)){var t=j(n);if(0===I(V(kn),t).length)return{$eq:n};if($(t,"$regex")){var r=n.$regex,u=n.$options||"",o="";i(r)&&(o+=r.ignoreCase||u.indexOf("i")>=0?"i":"",o+=r.multiline||u.indexOf("m")>=0?"m":"",o+=r.global||u.indexOf("g")>=0?"g":"",r=new RegExp(r,o)),n.$regex=r,delete n.$options}}return n}function an(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(o.root=o.root||t,$(V(On),u))return Kn[u](t,r,o);if($(V(wn),u))return t=an(t,r,null,o),n(a(t),u+" expression must resolve to an array"),Mn[u](t,null,o);if(i(r)&&r.length>0&&"$"===r[0]){if($(tt,r))return Zn[r](t,null,o);if($(rt,r))return r;var s=tt.filter(function(n){return 0===r.indexOf(n+".")});return 1===s.length&&(s=s[0],"$$ROOT"===s&&(t=o.root),r=r.substr(s.length)),nn(t,r.slice(1))}switch(e(r)){case mn:return r.map(function(n){return an(t,n)});case bn:var c={};return A(r,function(e,u){if(c[u]=an(t,e,u,o),$(V(On,wn),u))return n(1===j(r).length,"Invalid aggregation expression '"+JSON.stringify(r)+"'"),c=c[u],!1}),c;default:return r}}function sn(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return p(e)?r<0?(r=Math.max(0,t.length+r),e=t.length-r+1):(e=r,r=0):(r<0&&(r=Math.max(0,t.length+r)),n(e>0,"Invalid argument value for $slice operator. Limit must be a positive number"),e+=r),Array.prototype.slice.apply(t,[r,e])}function cn(n){var t=S(n.data,function(n,t){return n+t},0),r=n.data.length||1,e=!0===n.sampled?1:0,u=t/(r-e);return Math.sqrt(S(n.data,function(n,t){return n+Math.pow(t-u,2)},0)/r)}function fn(n,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};r.root=r.root||n;var e=an(n,t,null,r);return $(rt,e)?nt[e](n,t,r):e}function ln(){return{computeValue:an,idKey:X,ops:V,resolve:nn,assert:n,clone:t,each:A,err:w,getType:r,has:O,isArray:a,isBoolean:u,isDate:l,isEmpty:_,isEqual:q,isFunction:h,isNil:p,isNull:d,isNumber:o,isObject:c,isRegExp:v,isString:i,isUndefined:g,keys:j,map:E}}Function.prototype.bind||(Function.prototype.bind=function(n){if("function"!=typeof this)throw new Error("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),r=this,e=function(){},u=function(){return r.apply(this instanceof e?this:n,t.concat(Array.prototype.slice.call(arguments)))};return this.prototype&&(e.prototype=this.prototype),u.prototype=new e,u}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),r=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u>>0;if(0===e)return!1;for(var u=0|t,i=Math.max(u>=0?u:e-Math.abs(u),0);in?t:n},void 0)},$min:function(n,t){return S(this.$push(n,t),function(n,t){return p(n)||t0?an(n[0],t):void 0},$last:function(n,t){return n.length>0?an(n[n.length-1],t):void 0},$stdDevPop:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!1})},$stdDevSamp:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!0})}},An={$:function(n,t,r){w("$ not implemented")},$elemMatch:function(n,t,r){var e=nn(n,r),u=new Rn(t);if(!p(e)&&a(e))for(var i=0;i1)&&p[0],$(V(jn),p)?"$slice"===p?x(a[p]).every(o)?(s=An[p](n,a[p],u),l=!0):s=an(n,a,u):s=An[p](n,a[p],u):s=an(n,a,u)}var d=t(tn(n,u));g(d)||Object.assign(r,d),g(s)||en(r,u,t(s))}),(l||v||s)&&(r=Object.assign(t(n),r),A(h,function(n){return un(r,n)})),u.push(r)}),u},$limit:function(n,t){return n.slice(0,t)},$skip:function(n,t){return n.slice(t)},$unwind:function(r,e){var u=[],i=e.substr(1);return A(r,function(r){var e=Z(r,i);n(a(e),"Target field '"+i+"' is not of type Array."),A(e,function(n){var e=t(r);e[i]=n,u.push(e)})}),u},$sort:function(n,t){if(!_(t)&&c(t)){A(j(t).reverse(),function(r){var e=U(n,function(n){return nn(n,r)}),u={},i=function(n){return u[R(n)]},o=F(e.keys,function(n,t){return u[R(n)]=t,n});-1===t[r]&&o.reverse(),n=[],A(o,function(t){return L(n,e.groups[i(t)])})})}return n},$sortByCount:function(n,t){var r={count:{$sum:1}};return r[X()]=t,this.$sort(this.$group(n,r),{count:-1})},$sample:function(t,r){var e=r.size;n(o(e),"$sample size must be a positive integer");for(var u=[],i=t.length,a=0;a2,"$bucket 'boundaries' expression must have at least 3 elements");for(var c=r(o),f=0,l=u.length-1;fe.default||a=a)n(!p(i),"$bucket require a default for out of range values"),v[i].push(t);else if(r>=o&&r0,"The $bucketAuto 'buckets' field must be greater than 0, but found: "+i);var o=Math.round(t.length/i);o<1&&(o=1);for(var a=Y(an),s={},c=[],f=F(t,function(n){var t=a(n,u);return p(t)?c.push(n):(s[t]||(s[t]=[]),s[t].push(n)),t}),l=X(),v=[],h=0,d=0,g=f.length;d0){v[v.length-1][l].max=$.min}}d==i-1&&L(y,f.slice(h)),v.push(Object.assign(J(y,null,e),{_id:$}))}return v.length>0&&(v[v.length-1][l].max=a(f[f.length-1],u)),v},$facet:function(n,t){return E(t,function(t){return z(n,t)})}},Sn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},In=function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")},Tn=function(){function n(n,t){for(var r=0;r0){var e=new qn(r);this.__result=e.run(this.__result,this.__query)}return this.__result}},{key:"all",value:function(){return this._fetch()}},{key:"first",value:function(){return this.count()>0?this._fetch()[0]:null}},{key:"last",value:function(){return this.count()>0?this._fetch()[this.count()-1]:null}},{key:"count",value:function(){return this._fetch().length}},{key:"skip",value:function(n){return Object.assign(this.__operators,{$skip:n}),this}},{key:"limit",value:function(n){return Object.assign(this.__operators,{$limit:n}),this}},{key:"sort",value:function(n){return Object.assign(this.__operators,{$sort:n}),this}},{key:"next",value:function(){return this.hasNext()?this._fetch()[this.__position++]:null}},{key:"hasNext",value:function(){return this.count()>this.__position}},{key:"max",value:function(n){return Mn.$max(this._fetch(),n)}},{key:"min",value:function(n){return Mn.$min(this._fetch(),n)}},{key:"map",value:function(n){return this._fetch().map(n)}},{key:"forEach",value:function(n){A(this._fetch(),n)}},{key:Symbol.iterator,value:function(){var n=this;return{next:function(){return n.hasNext()?{done:!1,value:n.next()}:{done:!0}}}}}]),t}(),Cn={$eq:function(n,t){if(q(n,t))return!0;if(p(n)&&p(t))return!0;if(a(n)){if(!N(n,{isMulti:!0}))return-1!==n.findIndex(q.bind(null,t));try{for(var r=0;r0},$nin:function(n,t){return p(n)||!this.$in(n,t)},$lt:function(n,t){return void 0!==(n=x(n).find(function(n){return nt}))},$gte:function(n,t){return void 0!==(n=x(n).find(function(n){return n>=t}))},$mod:function(n,t){return void 0!==(n=x(n).find(function(n){return o(n)&&a(t)&&2===t.length&&n%t[0]===t[1]}))},$regex:function(n,t){return void 0!==(n=x(n).find(function(n){return i(n)&&v(t)&&!!n.match(t)}))},$exists:function(n,t){return(!1===t||0===t)&&p(n)||(!0===t||1===t)&&!p(n)},$all:function(n,t){var r=!1;if(a(n)&&a(t))for(var e=0,u=t.length;e2147483647&&n<=0x8000000000000000&&-1===(n+"").indexOf(".");case 19:case"decimal":return o(n);default:return!1}}},Dn={$and:function(t,r){n(a(r),"Invalid expression: $and expects value to be an Array");var e=[];return A(r,function(n){return e.push(new Rn(n))}),{test:function(n){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:{};In(this,t),this.__criteria=n,this.__projection=r,this.__compiled=[],this._compile()}return Tn(t,[{key:"_compile",value:function(){var t=this;if(!_(this.__criteria)){n(c(this.__criteria),"Criteria must be of type Object");var r=void 0;A(this.__criteria,function(n,e){"$where"===e?r={field:e,expr:n}:$(["$and","$or","$nor"],e)?t._processOperator(e,e,n):(n=on(n),A(n,function(n,r){t._processOperator(e,r,n)})),c(r)&&t._processOperator(r.field,r.field,r.expr)})}}},{key:"_processOperator",value:function(n,t,r){$(V(kn),t)?this.__compiled.push(Dn[t](n,r)):w("Invalid query operator '"+t+"' detected")}},{key:"test",value:function(n){for(var t=0,r=this.__compiled.length;t0,"$sqrt expression must resolve to non-negative number."),Math.sqrt(e))},$subtract:function(n,t){var r=an(n,t);return r[0]-r[1]},$trunc:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e)&&e>0,"$trunc must be a valid expression that resolves to a non-negative number."),Math.trunc(e))}},Un={$arrayElemAt:function(t,r){var e=an(t,r);n(a(e)&&2===e.length,"$arrayElemAt expression must resolve to an array of 2 elements"),n(a(e[0]),"First operand to $arrayElemAt must resolve to an array"),n(o(e[1]),"Second operand to $arrayElemAt must resolve to an integer");var u=e[1];return e=e[0],u<0&&Math.abs(u)<=e.length?e[u+e.length]:u>=0&&u0||e>u&&i<0;)o.push(e),e+=i;return o},$reduce:function(t,r){var e=an(t,r.input),u=an(t,r.initialValue),i=r.in;return p(e)?null:(n(a(e),"$reduce 'input' expression must resolve to an array"),S(e,function(n,t){return an({$value:n,$this:t},i)},u))},$reverseArray:function(t,r){var e=an(t,r);if(p(e))return null;n(a(e),"$reverseArray expression must resolve to an array");var u=[];return L(u,e),u.reverse(),u},$size:function(n,t){var r=an(n,t);return a(r)?r.length:void 0},$slice:function(n,t){var r=an(n,t);return sn(r[0],r[1],r[2])},$zip:function(t,r){var e=an(t,r.inputs),i=r.useLongestLength||!1;n(a(e),"'inputs' expression must resolve to an array"),n(u(i),"'useLongestLength' must be a boolean"),a(r.defaults)&&n(m(i),"'useLongestLength' must be set to true to use 'defaults'");for(var o=0,s=0,c=e.length;sr[1]?1:r[0]=0&&Math.round(s)===s,"$indexOfBytes third operand must resolve to a non-negative integer"),s=s||0,n(p(c)||o(c)&&c>=0&&Math.round(c)===c,"$indexOfBytes fourth operand must resolve to a non-negative integer"),c=c||u.length,s>c)return-1;var f=u.substring(s,c).indexOf(a);return f>-1?f+s:f},$split:function(t,e){var u=an(t,e);return n(i(u[0]),"$split requires an expression that evaluates to a string as a first argument, found: "+r(u[0])),n(i(u[1]),"$split requires an expression that evaluates to a string as a second argument, found: "+r(u[1])),u[0].split(u[1])},$strcasecmp:function(n,t){var r=an(n,t);return r[0]=_(r[0])?"":r[0].toUpperCase(),r[1]=_(r[1])?"":r[1].toUpperCase(),r[0]>r[1]?1:r[0]KlRa{%mHTXWk+mVTdK0isw8FoG!3sokjp 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 { - let key = keys(operator) - assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), `Invalid aggregation operator ${key}`) - key = key[0] - if (query && query instanceof Query) { - collection = pipelineOperators[key].call(query, collection, operator[key]) - } else { - collection = pipelineOperators[key](collection, operator[key]) - } - }) - } - return collection - } -} - -/** - * Return the result collection after running the aggregation pipeline for the given collection - * - * @param collection - * @param pipeline - * @returns {Array} - */ -export function aggregate (collection, pipeline) { - assert(isArray(pipeline), 'Aggregation pipeline must be an array') - return (new Aggregator(pipeline)).run(collection) -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js deleted file mode 100644 index a49df18..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/constants.js +++ /dev/null @@ -1,24 +0,0 @@ - -// Javascript native types -export const T_NULL = 'null' -export const T_UNDEFINED = 'undefined' -export const T_BOOL = 'bool' -export const T_BOOLEAN = 'boolean' -export const T_NUMBER = 'number' -export const T_STRING = 'string' -export const T_DATE = 'date' -export const T_REGEX = 'regex' -export const T_REGEXP = 'regexp' -export const T_ARRAY = 'array' -export const T_OBJECT = 'object' -export const T_FUNCTION = 'function' - -// no array, object, or function types -export const JS_SIMPLE_TYPES = [T_NULL, T_UNDEFINED, T_BOOLEAN, T_NUMBER, T_STRING, T_DATE, T_REGEXP] - -// operator classes -export const OP_AGGREGATE = 'aggregate' -export const OP_GROUP = 'group' -export const OP_PIPELINE = 'pipeline' -export const OP_PROJECTION = 'projection' -export const OP_QUERY = 'query' \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js deleted file mode 100644 index 00bccc7..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/cursor.js +++ /dev/null @@ -1,191 +0,0 @@ -import { assert, each, has, isArray, isObject } from './util' -import { Aggregator } from './aggregator' -import { groupOperators } from './operators/group.js' - -/** - * Cursor to iterate and perform filtering on matched objects - * @param collection - * @param query - * @param projection - * @constructor - */ -export class Cursor { - - constructor (collection, query, projection) { - this.__query = query - this.__collection = collection - this.__projection = projection || query.__projection - this.__operators = {} - this.__result = false - this.__position = 0 - } - - _fetch () { - - if (this.__result !== false) { - return this.__result - } - - // inject projection operator - if (isObject(this.__projection)) { - Object.assign(this.__operators, { '$project': this.__projection }) - } - - assert(isArray(this.__collection), 'Input collection is not of valid type. Must be an Array.'); - - // filter collection - this.__result = this.__collection.filter(this.__query.test, this.__query) - let pipeline = [] - - each(['$sort', '$skip', '$limit', '$project'], (op) => { - if (has(this.__operators, op)) { - let selected = {} - selected[op] = this.__operators[op] - pipeline.push(selected) - } - }) - - if (pipeline.length > 0) { - let aggregator = new Aggregator(pipeline) - this.__result = aggregator.run(this.__result, this.__query) - } - return this.__result - } - - /** - * Fetch and return all matched results - * @returns {Array} - */ - all () { - return this._fetch() - } - - /** - * Fetch and return the first matching result - * @returns {Object} - */ - first () { - return this.count() > 0 ? this._fetch()[0] : null - } - - /** - * Fetch and return the last matching object from the result - * @returns {Object} - */ - last () { - return this.count() > 0 ? this._fetch()[this.count() - 1] : null - } - - /** - * Counts the number of matched objects found - * @returns {Number} - */ - count () { - return this._fetch().length - } - - /** - * Returns a cursor that begins returning results only after passing or skipping a number of documents. - * @param {Number} n the number of results to skip. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - skip (n) { - Object.assign(this.__operators, { '$skip': n }) - return this - } - - /** - * Constrains the size of a cursor's result set. - * @param {Number} n the number of results to limit to. - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - limit (n) { - Object.assign(this.__operators, { '$limit': n }) - return this - } - - /** - * Returns results ordered according to a sort specification. - * @param {Object} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending - * @return {Cursor} Returns the cursor, so you can chain this call. - */ - sort (modifier) { - Object.assign(this.__operators, { '$sort': modifier }) - return this - } - - /** - * Returns the next document in a cursor. - * @returns {Object | Boolean} - */ - next () { - if (this.hasNext()) { - return this._fetch()[this.__position++] - } - return null - } - - /** - * Returns true if the cursor has documents and can be iterated. - * @returns {boolean} - */ - hasNext () { - return this.count() > this.__position - } - - /** - * Specifies the exclusive upper bound for a specific field - * @param expr - * @returns {Number} - */ - max (expr) { - return groupOperators.$max(this._fetch(), expr) - } - - /** - * Specifies the inclusive lower bound for a specific field - * @param expr - * @returns {Number} - */ - min (expr) { - return groupOperators.$min(this._fetch(), expr) - } - - /** - * Applies a function to each document in a cursor and collects the return values in an array. - * @param callback - * @returns {Array} - */ - map (callback) { - return this._fetch().map(callback) - } - - /** - * Applies a JavaScript function for every document in a cursor. - * @param callback - */ - forEach (callback) { - each(this._fetch(), callback) - } - - /** - * Applies an [ES2015 Iteration protocol][] compatible implementation - * [ES2015 Iteration protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols - * @returns {Object} - */ - [Symbol.iterator] () { - let self = this - return { - next () { - if (!self.hasNext()) { - return { done: true } - } - return { - done: false, - value: self.next() - } - } - } - } -} - diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js deleted file mode 100644 index 297e0c6..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import './polyfill' -import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' -import { _internal, setup } from './internal' -import { Query, find, remove } from './query' -import { Aggregator, aggregate } from './aggregator' -import { CollectionMixin } from './mixin' -import { Cursor } from './cursor' -import { addOperators } from './operators/index' - -const VERSION = '1.3.3' - -// mingo! -export default { - _internal, - Aggregator, - CollectionMixin, - Cursor, - OP_AGGREGATE, - OP_GROUP, - OP_PIPELINE, - OP_PROJECTION, - OP_QUERY, - Query, - VERSION, - addOperators, - aggregate, - find, - remove, - setup -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js deleted file mode 100644 index edea20f..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/internal.js +++ /dev/null @@ -1,496 +0,0 @@ -import { - T_ARRAY, - T_OBJECT, - JS_SIMPLE_TYPES, - OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY -} from './constants' -import { - addMeta, - assert, - clone, - dropMeta, - each, - err, - getHash, - getType, - has, - hasMeta, - inArray, - intersection, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isObjectLike, - isRegExp, - isString, - isUndefined, - jsType, - keys, - map, - notInArray, - reduce, - truthy -} from './util' -import { groupOperators } from './operators/group.js' -import { ops } from './operators/index.js' -import { aggregateOperators } from './operators/aggregation/index.js' - - -/** - * Internal functions - */ - -// Settings used by Mingo internally -const settings = { - key: '_id' -} - -/** - * Setup default settings for Mingo - * @param options - */ -export function setup (options) { - Object.assign(settings, options || {}) -} - -/** - * Implementation of system variables - * @type {Object} - */ -export const systemVariables = { - '$$ROOT' (obj, expr, opt) { - return opt.root - }, - '$$CURRENT' (obj, expr, opt) { - return obj - } -} - -/** - * Implementation of $redact variables - * - * Each function accepts 3 arguments (obj, expr, opt) - * - * @type {Object} - */ -export const redactVariables = { - '$$KEEP' (obj) { - return obj - }, - '$$PRUNE' () { - return undefined - }, - '$$DESCEND' (obj, expr, opt) { - // traverse nested documents iff there is a $cond - if (!has(expr, '$cond')) return obj - - let result - - each(obj, (current, key) => { - if (isObjectLike(current)) { - if (isArray(current)) { - result = [] - each(current, (elem) => { - if (isObject(elem)) { - elem = redactObj(elem, expr, opt) - } - if (!isNil(elem)) result.push(elem) - }) - } else { - result = redactObj(current, expr, opt) - } - - if (isNil(result)) { - delete obj[key] // pruned result - } else { - obj[key] = result - } - } - }) - return obj - } -} - -// system variables -export const SYS_VARS = keys(systemVariables) -export const REDACT_VARS = keys(redactVariables) - -/** - * Returns the key used as the collection's objects ids - */ -export function idKey () { - return settings.key -} - -/** - * Retrieve the value of a given key on an object - * @param obj - * @param field - * @returns {*} - * @private - */ -export function getValue (obj, field) { - return obj[field] -} - -/** - * Resolve the value of the field (dot separated) on the given object - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - * @param deepFlag {Boolean} flag whether to iterate deeply (default: false) - * @returns {*} - */ -export function resolve (obj, selector, deepFlag = false) { - let names = selector.split('.') - let value = obj - - for (let i = 0; i < names.length; i++) { - let isText = names[i].match(/^\d+$/) === null - - if (isText && isArray(value)) { - // On the first iteration, we check if we received a stop flag. - // If so, we stop to prevent iterating over a nested array value - // on consecutive object keys in the selector. - if (deepFlag === true && i === 0) { - return value - } - - value = value.map((item) => resolve(item, names[i], true)) - - // we mark this value as being multi-valued - addMeta(value, { isMulti: true }) - - // we unwrap for arrays of unit length - // this avoids excess wrapping when resolving deeply nested arrays - if (value.length === 1) { - value = value[0] - } - } else { - value = getValue(value, names[i]) - deepFlag = false // reset stop flag when we do a direct lookup - } - - if (isNil(value)) break - } - - return value -} - -/** - * Returns the full object to the resolved value given by the selector. - * This function excludes empty values as they aren't practically useful. - * - * @param obj {Object} the object context - * @param selector {String} dot separated path to field - */ -export function resolveObj (obj, selector) { - if (isNil(obj)) return - - let names = selector.split('.') - let key = names[0] - // get the next part of the selector - let next = names.length === 1 || names.slice(1).join('.') - let isIndex = key.match(/^\d+$/) !== null - let hasNext = names.length > 1 - let result - let value - - try { - if (isArray(obj)) { - if (isIndex) { - result = getValue(obj, key) - if (hasNext) { - result = resolveObj(result, next) - } - assert(!isUndefined(result)) - result = [result] - } else { - result = [] - each(obj, (item) => { - value = resolveObj(item, selector) - if (!isNil(value)) result.push(value) - }) - assert(result.length > 0) - } - } else { - value = getValue(obj, key) - if (hasNext) { - value = resolveObj(value, next) - } - assert(!isUndefined(value)) - result = {} - result[key] = value - } - } catch (e) { - result = undefined - } - - return result -} - -/** - * Walk the object graph and execute the given transform function - * @param {Object|Array} obj The object to traverse - * @param {String} selector The selector - * @param {Function} fn Function to execute for value at the end the traversal - * @param {Boolean} force Force generating missing parts of object graph - * @return {*} - */ -export function traverse (obj, selector, fn, force = false) { - let names = selector.split('.') - let key = names[0] - let next = names.length === 1 || names.slice(1).join('.') - - if (names.length === 1) { - fn(obj, key) - } else { // nested objects - if (isArray(obj) && !/^\d+$/.test(key)) { - each(obj, (item) => { - traverse(item, selector, fn, force) - }) - } else { - // force the rest of the graph while traversing - if (force === true) { - let exists = has(obj, key) - if (!exists || isNil(obj[key])) { - obj[key] = {} - } - } - traverse(obj[key], next, fn, force) - } - } -} - -/** - * Set the value of the given object field - * - * @param obj {Object|Array} the object context - * @param selector {String} path to field - * @param value {*} the value to set - */ -export function setValue (obj, selector, value) { - traverse(obj, selector, (item, key) => { - item[key] = value - }, true) -} - -export function removeValue (obj, selector) { - traverse(obj, selector, (item, key) => { - if (isArray(item) && /^\d+$/.test(key)) { - item.splice(parseInt(key), 1) - } else if (isObject(item)) { - delete item[key] - } - }) -} - -/** - * Simplify expression for easy evaluation with query operators map - * @param expr - * @returns {*} - */ -export function normalize (expr) { - // normalized primitives - if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { - return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr } - } - - // normalize object expression - if (isObjectLike(expr)) { - let exprKeys = keys(expr) - let noQuery = intersection(ops(OP_QUERY), exprKeys).length === 0 - - // no valid query operator found, so we do simple comparison - if (noQuery) { - return { '$eq': expr } - } - - // ensure valid regex - if (inArray(exprKeys, '$regex')) { - let regex = expr['$regex'] - let options = expr['$options'] || '' - let modifiers = '' - if (isString(regex)) { - modifiers += (regex.ignoreCase || options.indexOf('i') >= 0) ? 'i' : '' - modifiers += (regex.multiline || options.indexOf('m') >= 0) ? 'm' : '' - modifiers += (regex.global || options.indexOf('g') >= 0) ? 'g' : '' - regex = new RegExp(regex, modifiers) - } - expr['$regex'] = regex - delete expr['$options'] - } - } - - return expr -} - -/** - * Computes the actual value of the expression using the given object as context - * - * @param obj the current object from the collection - * @param expr the expression for the given field - * @param field the field name (may also be an aggregate operator) - * @param opt {Object} extra options - * @returns {*} - */ -export function computeValue (obj, expr, field = null, opt = {}) { - opt.root = opt.root || obj - - // if the field of the object is a valid operator - if (inArray(ops(OP_AGGREGATE), field)) { - return aggregateOperators[field](obj, expr, opt) - } - - // we also handle $group accumulator operators - if (inArray(ops(OP_GROUP), field)) { - // we first fully resolve the expression - obj = computeValue(obj, expr, null, opt) - assert(isArray(obj), field + ' expression must resolve to an array') - // we pass a null expression because all values have been resolved - return groupOperators[field](obj, null, opt) - } - - // if expr is a variable for an object field - // field not used in this case - if (isString(expr) && expr.length > 0 && expr[0] === '$') { - // we return system variables as literals - if (inArray(SYS_VARS, expr)) { - return systemVariables[expr](obj, null, opt) - } else if (inArray(REDACT_VARS, expr)) { - return expr - } - - // handle selectors with explicit prefix - let sysVar = SYS_VARS.filter((v) => expr.indexOf(v + '.') === 0) - - if (sysVar.length === 1) { - sysVar = sysVar[0] - if (sysVar === '$$ROOT') { - obj = opt.root - } - expr = expr.substr(sysVar.length) // '.' prefix will be sliced off below - } - - return resolve(obj, expr.slice(1)) - } - - // check and return value if already in a resolved state - switch (jsType(expr)) { - case T_ARRAY: - return expr.map((item) => computeValue(obj, item)) - case T_OBJECT: - let result = {} - each(expr, (val, key) => { - result[key] = computeValue(obj, val, key, opt) - // must run ONLY one aggregate operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { - // there should be only one operator - assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'") - result = result[key] - return false // break - } - }) - return result - default: - return expr - } -} - -/** - * Returns a slice of the array - * - * @param {Array} xs - * @param {Number} skip - * @param {Number} limit - * @return {Array} - */ -export function slice (xs, skip, limit = null) { - // MongoDB $slice works a bit differently from Array.slice - // Uses single argument for 'limit' and array argument [skip, limit] - if (isNil(limit)) { - if (skip < 0) { - skip = Math.max(0, xs.length + skip) - limit = xs.length - skip + 1 - } else { - limit = skip - skip = 0 - } - } else { - if (skip < 0) { - skip = Math.max(0, xs.length + skip) - } - assert(limit > 0, 'Invalid argument value for $slice operator. Limit must be a positive number') - limit += skip - } - return Array.prototype.slice.apply(xs, [skip, limit]) -} - -/** - * Compute the standard deviation of the data set - * @param {Object} ctx An object of the context. Includes "data:Array" and "sampled:Boolean". - * @return {Number} - */ -export function stddev (ctx) { - let sum = reduce(ctx.data, (acc, n) => acc + n, 0) - let N = ctx.data.length || 1 - let correction = ctx.sampled === true ? 1 : 0 - let avg = sum / (N - correction) - return Math.sqrt(reduce(ctx.data, (acc, n) => acc + Math.pow(n - avg, 2), 0) / N) -} - -/** - * Redact an object - * @param {Object} obj The object to redact - * @param {*} expr The redact expression - * @param {*} opt Options for value - * @return {*} Returns the redacted value - */ -export function redactObj (obj, expr, opt = {}) { - opt.root = opt.root || obj - - let result = computeValue(obj, expr, null, opt) - return inArray(REDACT_VARS, result) - ? redactVariables[result](obj, expr, opt) - : result -} - -/** - * Exported to the users to allow writing custom operators - */ -export function _internal () { - return { - computeValue, - idKey, - ops, - resolve, - assert, - clone, - each, - err, - getType, - has, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isRegExp, - isString, - isUndefined, - keys, - map - } -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js deleted file mode 100644 index 72eb7d4..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/mixin.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Aggregator } from './aggregator' -import { Query } from './query' - -/** - * Mixin for Collection types that provide a method `toJSON() -> Array[Object]` - */ -export const CollectionMixin = { - - /** - * Runs a query and returns a cursor to the result - * @param criteria - * @param projection - * @returns {Cursor} - */ - query (criteria, projection) { - return new Query(criteria).find(this.toJSON(), projection) - }, - - /** - * Runs the given aggregation operators on this collection - * @params pipeline - * @returns {Array} - */ - aggregate (pipeline) { - return new Aggregator(pipeline).run(this.toJSON()) - } -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js deleted file mode 100644 index edde5e7..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/arithmetic.js +++ /dev/null @@ -1,214 +0,0 @@ -import { assert, err, isNil, isNumber, isArray, reduce } from '../../util.js' -import { computeValue } from '../../internal.js' - -export const arithmeticOperators = { - - /** - * Returns the absolute value of a number. - * https://docs.mongodb.com/manual/reference/operator/aggregation/abs/#exp._S_abs - * @param obj - * @param expr - * @return {Number|null|NaN} - */ - $abs (obj, expr) { - let val = computeValue(obj, expr) - return (val === null || val === undefined) ? null : Math.abs(val) - }, - - /** - * Computes the sum of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $add (obj, expr) { - let args = computeValue(obj, expr) - return reduce(args, (acc, num) => acc + num, 0) - }, - - /** - * Returns the smallest integer greater than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $ceil (obj, expr) { - let arg = computeValue(obj, expr) - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$ceil must be a valid expression that resolves to a number.') - return Math.ceil(arg) - }, - - /** - * Takes two numbers and divides the first number by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $divide (obj, expr) { - let args = computeValue(obj, expr) - return args[0] / args[1] - }, - - /** - * Raises Euler’s number (i.e. e ) to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {number} - */ - $exp (obj, expr) { - let arg = computeValue(obj, expr) - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$exp must be a valid expression that resolves to a number.') - return Math.exp(arg) - }, - - /** - * Returns the largest integer less than or equal to the specified number. - * - * @param obj - * @param expr - * @returns {number} - */ - $floor (obj, expr) { - let arg = computeValue(obj, expr) - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$floor must be a valid expression that resolves to a number.') - return Math.floor(arg) - }, - - /** - * Calculates the natural logarithm ln (i.e loge) of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $ln (obj, expr) { - let arg = computeValue(obj, expr) - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$ln must be a valid expression that resolves to a number.') - return Math.log(arg) - }, - - /** - * Calculates the log of a number in the specified base and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log (obj, expr) { - let args = computeValue(obj, expr) - assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items') - if (args.some(isNaN)) return NaN - if (args.some(isNil)) return null - assert(args.every(isNumber), '$log expression must resolve to array of 2 numbers') - return Math.log10(args[0]) / Math.log10(args[1]) - }, - - /** - * Calculates the log base 10 of a number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $log10 (obj, expr) { - let arg = computeValue(obj, expr) - if (isNaN(arg)) return NaN - if (isNil(arg)) return null - assert(isNumber(arg), '$log10 must be a valid expression that resolves to a number.') - return Math.log10(arg) - }, - - /** - * Takes two numbers and calculates the modulo of the first number divided by the second. - * - * @param obj - * @param expr - * @returns {number} - */ - $mod (obj, expr) { - let args = computeValue(obj, expr) - return args[0] % args[1] - }, - - /** - * Computes the product of an array of numbers. - * - * @param obj - * @param expr - * @returns {Object} - */ - $multiply (obj, expr) { - let args = computeValue(obj, expr) - return reduce(args, (acc, num) => acc * num, 1) - }, - - /** - * Raises a number to the specified exponent and returns the result. - * - * @param obj - * @param expr - * @returns {Object} - */ - $pow (obj, expr) { - let args = computeValue(obj, expr) - - assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers') - assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent') - - return Math.pow(args[0], args[1]) - }, - - /** - * Calculates the square root of a positive number and returns the result as a double. - * - * @param obj - * @param expr - * @returns {number} - */ - $sqrt (obj, expr) { - let n = computeValue(obj, expr) - if (isNaN(n)) return NaN - if (isNil(n)) return null - assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.') - return Math.sqrt(n) - }, - - /** - * Takes an array that contains two numbers or two dates and subtracts the second value from the first. - * - * @param obj - * @param expr - * @returns {number} - */ - $subtract (obj, expr) { - let args = computeValue(obj, expr) - return args[0] - args[1] - }, - - /** - * Truncates a number to its integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $trunc (obj, expr) { - let n = computeValue(obj, expr) - if (isNaN(n)) return NaN - if (isNil(n)) return null - assert(isNumber(n) && n > 0, '$trunc must be a valid expression that resolves to a non-negative number.') - return Math.trunc(n) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js deleted file mode 100644 index 51ceddf..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/array.js +++ /dev/null @@ -1,322 +0,0 @@ -import { - assert, - each, - err, - has, - into, - inArray, - isArray, - isObject, - isNumber, - isBoolean, - isNil, - isUndefined, - keys, - map, - reduce, - truthy -} from '../../util.js' -import { computeValue, slice } from '../../internal.js' - -export const arrayOperators = { - /** - * Returns the element at the specified array index. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $arrayElemAt (obj, expr) { - let arr = computeValue(obj, expr) - assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements') - assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array') - assert(isNumber(arr[1]), 'Second operand to $arrayElemAt must resolve to an integer') - let idx = arr[1] - arr = arr[0] - if (idx < 0 && Math.abs(idx) <= arr.length) { - return arr[idx + arr.length] - } else if (idx >= 0 && idx < arr.length) { - return arr[idx] - } - return undefined - }, - - /** - * Converts an array of key value pairs to a document. - */ - $arrayToObject (obj, expr) { - let arr = computeValue(obj, expr) - assert(isArray(arr), '$arrayToObject expression must resolve to an array') - return reduce(arr, (newObj, val) => { - if (isArray(val) && val.length == 2) newObj[val[0]] = val[1] - else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v - else err('$arrayToObject expression is invalid.') - return newObj - }, {}) - }, - - /** - * Concatenates arrays to return the concatenated array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $concatArrays (obj, expr) { - let arr = computeValue(obj, expr, null) - assert(isArray(arr) && arr.length === 2, '$concatArrays expression must resolve to an array of 2 elements') - - if (arr.some(isNil)) return null - - return arr[0].concat(arr[1]) - }, - - /** - * Selects a subset of the array to return an array with only the elements that match the filter condition. - * - * @param {Object} obj [description] - * @param {*} expr [description] - * @return {*} [description] - */ - $filter (obj, expr) { - let input = computeValue(obj, expr.input) - let asVar = expr['as'] - let condExpr = expr['cond'] - - assert(isArray(input), "$filter 'input' expression must resolve to an array") - - return input.filter((o) => { - // inject variable - let tempObj = {} - tempObj['$' + asVar] = o - return computeValue(tempObj, condExpr) === true - }) - }, - - /** - * Returns a boolean indicating whether a specified value is in an array. - * - * @param {Object} obj - * @param {Array} expr - */ - $in (obj, expr) { - let val = computeValue(obj, expr[0]) - let arr = computeValue(obj, expr[1]) - assert(isArray(arr), '$in second argument must be an array') - return inArray(arr, val) - }, - - /** - * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfArray (obj, expr) { - let args = computeValue(obj, expr) - if (isNil(args)) return null - - let arr = args[0] - if (isNil(arr)) return null - - assert(isArray(arr), '$indexOfArray expression must resolve to an array.') - - let searchValue = args[1] - if (isNil(searchValue)) return null - - let start = args[2] || 0 - let end = args[3] || arr.length - - if (end < arr.length) { - arr = arr.slice(start, end) - } - - return arr.indexOf(searchValue, start) - }, - - /** - * Determines if the operand is an array. Returns a boolean. - * - * @param {Object} obj - * @param {*} expr - * @return {Boolean} - */ - $isArray (obj, expr) { - return isArray(computeValue(obj, expr)) - }, - - /** - * Applies a sub-expression to each element of an array and returns the array of resulting values in order. - * - * @param obj - * @param expr - * @returns {Array|*} - */ - $map (obj, expr) { - let inputExpr = computeValue(obj, expr.input) - assert(isArray(inputExpr), `$map 'input' expression must resolve to an array`) - - let asExpr = expr['as'] - let inExpr = expr['in'] - - // HACK: add the "as" expression as a value on the object to take advantage of "resolve()" - // which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". - // But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. - let tempKey = '$' + asExpr - // let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) - let original = obj[tempKey] - return map(inputExpr, (item) => { - obj[tempKey] = item - let value = computeValue(obj, inExpr) - // cleanup and restore - if (isUndefined(original)) { - delete obj[tempKey] - } else { - obj[tempKey] = original - } - return value - }) - }, - - /** - * Converts a document to an array of documents representing key-value pairs. - */ - $objectToArray (obj, expr) { - let val = computeValue(obj, expr) - assert(isObject(val), '$objectToArray expression must resolve to an object') - let arr = [] - each(val, (v,k) => arr.push({k,v})) - return arr - }, - - /** - * Returns an array whose elements are a generated sequence of numbers. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $range (obj, expr) { - let arr = computeValue(obj, expr) - let start = arr[0] - let end = arr[1] - let step = arr[2] || 1 - - let result = [] - - while ((start < end && step > 0) || (start > end && step < 0)) { - result.push(start) - start += step - } - - return result - }, - - /** - * Applies an expression to each element in an array and combines them into a single value. - * - * @param {Object} obj - * @param {*} expr - */ - $reduce (obj, expr) { - let input = computeValue(obj, expr.input) - let initialValue = computeValue(obj, expr.initialValue) - let inExpr = expr['in'] - - if (isNil(input)) return null - assert(isArray(input), "$reduce 'input' expression must resolve to an array") - return reduce(input, (acc, n) => computeValue({ '$value': acc, '$this': n }, inExpr), initialValue) - }, - - /** - * Returns an array with the elements in reverse order. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $reverseArray (obj, expr) { - let arr = computeValue(obj, expr) - - if (isNil(arr)) return null - assert(isArray(arr), '$reverseArray expression must resolve to an array') - - let result = [] - into(result, arr) - result.reverse() - return result - }, - - /** - * Counts and returns the total the number of items in an array. - * - * @param obj - * @param expr - */ - $size (obj, expr) { - let value = computeValue(obj, expr) - return isArray(value) ? value.length : undefined - }, - - /** - * Returns a subset of an array. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $slice (obj, expr) { - let arr = computeValue(obj, expr) - return slice(arr[0], arr[1], arr[2]) - }, - - /** - * Merge two lists together. - * - * Transposes an array of input arrays so that the first element of the output array would be an array containing, - * the first element of the first input array, the first element of the second input array, etc. - * - * @param {Obj} obj - * @param {*} expr - * @return {*} - */ - $zip (obj, expr) { - let inputs = computeValue(obj, expr.inputs) - let useLongestLength = expr.useLongestLength || false - - assert(isArray(inputs), "'inputs' expression must resolve to an array") - assert(isBoolean(useLongestLength), "'useLongestLength' must be a boolean") - - if (isArray(expr.defaults)) { - assert(truthy(useLongestLength), "'useLongestLength' must be set to true to use 'defaults'") - } - - let zipCount = 0 - - for (let i = 0, len = inputs.length; i < len; i++) { - let arr = inputs[i] - - if (isNil(arr)) return null - - assert(isArray(arr), "'inputs' expression values must resolve to an array or null") - - zipCount = useLongestLength - ? Math.max(zipCount, arr.length) - : Math.min(zipCount || arr.length, arr.length) - } - - let result = [] - let defaults = expr.defaults || [] - - for (let i = 0; i < zipCount; i++) { - let temp = inputs.map((val, index) => { - return isNil(val[i]) ? (defaults[index] || null) : val[i] - }) - result.push(temp) - } - - return result - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js deleted file mode 100644 index 5cc96e7..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/boolean.js +++ /dev/null @@ -1,39 +0,0 @@ -import { computeValue } from '../../internal' -import { truthy } from '../../util' - -export const booleanOperators = { - /** - * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $and: (obj, expr) => { - let value = computeValue(obj, expr) - return truthy(value) && value.every(truthy) - }, - - /** - * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $or: (obj, expr) => { - let value = computeValue(obj, expr) - return truthy(value) && value.some(truthy) - }, - - /** - * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. - * - * @param obj - * @param expr - * @returns {boolean} - */ - $not: (obj, expr) => { - return !computeValue(obj, expr[0]) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js deleted file mode 100644 index 0abe23d..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/comparison.js +++ /dev/null @@ -1,26 +0,0 @@ -import { each } from '../../util.js' -import { computeValue } from '../../internal.js' -import { simpleOperators } from '../query.js' - -export const comparisonOperators = { - /** - * Compares two values and returns the result of the comparison as an integer. - * - * @param obj - * @param expr - * @returns {number} - */ - $cmp (obj, expr) { - let args = computeValue(obj, expr) - if (args[0] > args[1]) return 1 - if (args[0] < args[1]) return -1 - return 0 - } -} -// mixin comparison operators -each(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin'], (op) => { - comparisonOperators[op] = (obj, expr) => { - let args = computeValue(obj, expr) - return simpleOperators[op](args[0], args[1]) - } -}) diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js deleted file mode 100644 index af02ebe..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/conditional.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Conditional operators - */ - -import { assert, err, isArray, isObject } from '../../util.js' -import { computeValue, resolve } from '../../internal.js' - -export const conditionalOperators = { - - /** - * A ternary operator that evaluates one expression, - * and depending on the result returns the value of one following expressions. - * - * @param obj - * @param expr - */ - $cond (obj, expr) { - let ifExpr, thenExpr, elseExpr - if (isArray(expr)) { - assert(expr.length === 3, 'Invalid arguments for $cond operator') - ifExpr = expr[0] - thenExpr = expr[1] - elseExpr = expr[2] - } else if (isObject(expr)) { - ifExpr = expr['if'] - thenExpr = expr['then'] - elseExpr = expr['else'] - } - let condition = computeValue(obj, ifExpr) - return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr) - }, - - /** - * An operator that evaluates a series of case expressions. When it finds an expression which - * evaluates to true, it returns the resulting expression for that case. If none of the cases - * evaluate to true, it returns the default expression. - * - * @param obj - * @param expr - */ - $switch (obj, expr) { - assert(expr.branches, 'Invalid arguments for $switch operator') - - let validBranch = expr.branches.find((branch) => { - assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator') - return computeValue(obj, branch['case']) - }) - - if (validBranch) { - return computeValue(obj, validBranch.then) - } else if (!expr.default) { - err('Invalid arguments for $switch operator') - } else { - return computeValue(obj, expr.default) - } - }, - - /** - * Evaluates an expression and returns the first expression if it evaluates to a non-null value. - * Otherwise, $ifNull returns the second expression's value. - * - * @param obj - * @param expr - * @returns {*} - */ - $ifNull (obj, expr) { - assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator') - let args = computeValue(obj, expr) - return (args[0] === null || args[0] === undefined) ? args[1] : args[0] - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js deleted file mode 100644 index fae518a..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/date.js +++ /dev/null @@ -1,182 +0,0 @@ - -import { isDate, isArray } from '../../util.js' -import { computeValue } from '../../internal.js' - -// used for formatting dates in $dateToString operator -let DATE_SYM_TABLE = { - '%Y': ['$year', 4], - '%m': ['$month', 2], - '%d': ['$dayOfMonth', 2], - '%H': ['$hour', 2], - '%M': ['$minute', 2], - '%S': ['$second', 2], - '%L': ['$millisecond', 3], - '%j': ['$dayOfYear', 3], - '%w': ['$dayOfWeek', 1], - '%U': ['$week', 2], - '%%': '%' -} - -export const dateOperators = { - /** - * Returns the day of the year for a date as a number between 1 and 366 (leap year). - * @param obj - * @param expr - */ - $dayOfYear (obj, expr) { - let d = computeValue(obj, expr) - if (isDate(d)) { - let start = new Date(d.getFullYear(), 0, 0) - let diff = d - start - let oneDay = 1000 * 60 * 60 * 24 - return Math.round(diff / oneDay) - } - return undefined - }, - - /** - * Returns the day of the month for a date as a number between 1 and 31. - * @param obj - * @param expr - */ - $dayOfMonth (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getDate() : undefined - }, - - /** - * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). - * @param obj - * @param expr - */ - $dayOfWeek (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getDay() + 1 : undefined - }, - - /** - * Returns the year for a date as a number (e.g. 2014). - * @param obj - * @param expr - */ - $year (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getFullYear() : undefined - }, - - /** - * Returns the month for a date as a number between 1 (January) and 12 (December). - * @param obj - * @param expr - */ - $month (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getMonth() + 1 : undefined - }, - - /** - * Returns the week number for a date as a number between 0 - * (the partial week that precedes the first Sunday of the year) and 53 (leap year). - * @param obj - * @param expr - */ - $week (obj, expr) { - // source: http://stackoverflow.com/a/6117889/1370481 - let d = computeValue(obj, expr) - - // Copy date so don't modify original - d = new Date(+d) - d.setHours(0, 0, 0) - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - d.setDate(d.getDate() + 4 - (d.getDay() || 7)) - // Get first day of year - let yearStart = new Date(d.getFullYear(), 0, 1) - // Calculate full weeks to nearest Thursday - return Math.floor((((d - yearStart) / 8.64e7) + 1) / 7) - }, - - /** - * Returns the hour for a date as a number between 0 and 23. - * @param obj - * @param expr - */ - $hour (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getUTCHours() : undefined - }, - - /** - * Returns the minute for a date as a number between 0 and 59. - * @param obj - * @param expr - */ - $minute (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getMinutes() : undefined - }, - - /** - * Returns the seconds for a date as a number between 0 and 60 (leap seconds). - * @param obj - * @param expr - */ - $second (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getSeconds() : undefined - }, - - /** - * Returns the milliseconds of a date as a number between 0 and 999. - * @param obj - * @param expr - */ - $millisecond (obj, expr) { - let d = computeValue(obj, expr) - return isDate(d) ? d.getMilliseconds() : undefined - }, - - /** - * Returns the date as a formatted string. - * - * %Y Year (4 digits, zero padded) 0000-9999 - * %m Month (2 digits, zero padded) 01-12 - * %d Day of Month (2 digits, zero padded) 01-31 - * %H Hour (2 digits, zero padded, 24-hour clock) 00-23 - * %M Minute (2 digits, zero padded) 00-59 - * %S Second (2 digits, zero padded) 00-60 - * %L Millisecond (3 digits, zero padded) 000-999 - * %j Day of year (3 digits, zero padded) 001-366 - * %w Day of week (1-Sunday, 7-Saturday) 1-7 - * %U Week of year (2 digits, zero padded) 00-53 - * %% Percent Character as a Literal % - * - * @param obj current object - * @param expr operator expression - */ - $dateToString (obj, expr) { - let fmt = expr['format'] - let date = computeValue(obj, expr['date']) - let matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g) - - for (let i = 0, len = matches.length; i < len; i++) { - let hdlr = DATE_SYM_TABLE[matches[i]] - let value = hdlr - - if (isArray(hdlr)) { - // reuse date operators - let fn = this[hdlr[0]] - let pad = hdlr[1] - value = padDigits(fn.call(this, obj, date), pad) - } - // replace the match with resolved value - fmt = fmt.replace(matches[i], value) - } - - return fmt - } -} - -function padDigits (number, digits) { - return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js deleted file mode 100644 index d39a41d..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import { arithmeticOperators } from './arithmetic.js' -import { arrayOperators } from './array.js' -import { booleanOperators } from './boolean.js' -import { comparisonOperators } from './comparison.js' -import { conditionalOperators } from './conditional.js' -import { dateOperators } from './date.js' -import { literalOperators } from './literal.js' -import { setOperators } from './set.js' -import { stringOperators } from './string.js' -import { variableOperators } from './variable.js' - -// combine aggregate operators -export const aggregateOperators = Object.assign( - {}, - arithmeticOperators, - arrayOperators, - booleanOperators, - comparisonOperators, - conditionalOperators, - dateOperators, - literalOperators, - setOperators, - stringOperators, - variableOperators -) diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js deleted file mode 100644 index 0788cf0..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/literal.js +++ /dev/null @@ -1,11 +0,0 @@ - -export const literalOperators = { - /** - * Return a value without parsing. - * @param obj - * @param expr - */ - $literal (obj, expr) { - return expr - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js deleted file mode 100644 index d992786..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/set.js +++ /dev/null @@ -1,78 +0,0 @@ -import { union, unique, intersection, notInArray, inArray, truthy } from '../../util.js' -import { computeValue, resolve } from '../../internal.js' - -export const setOperators = { - /** - * Returns true if two sets have the same elements. - * @param obj - * @param expr - */ - $setEquals (obj, expr) { - let args = computeValue(obj, expr) - let xs = unique(args[0]) - let ys = unique(args[1]) - return xs.length === ys.length && xs.length === intersection(xs, ys).length - }, - - /** - * Returns the common elements of the input sets. - * @param obj - * @param expr - */ - $setIntersection (obj, expr) { - let args = computeValue(obj, expr) - return intersection(args[0], args[1]) - }, - - /** - * Returns elements of a set that do not appear in a second set. - * @param obj - * @param expr - */ - $setDifference (obj, expr) { - let args = computeValue(obj, expr) - return args[0].filter(notInArray.bind(null, args[1])) - }, - - /** - * Returns a set that holds all elements of the input sets. - * @param obj - * @param expr - */ - $setUnion (obj, expr) { - let args = computeValue(obj, expr) - return union(args[0], args[1]) - }, - - /** - * Returns true if all elements of a set appear in a second set. - * @param obj - * @param expr - */ - $setIsSubset (obj, expr) { - let args = computeValue(obj, expr) - return intersection(args[0], args[1]).length === args[0].length - }, - - /** - * Returns true if any elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $anyElementTrue (obj, expr) { - // mongodb nests the array expression in another - let args = computeValue(obj, expr)[0] - return args.some(truthy) - }, - - /** - * Returns true if all elements of a set evaluate to true, and false otherwise. - * @param obj - * @param expr - */ - $allElementsTrue (obj, expr) { - // mongodb nests the array expression in another - let args = computeValue(obj, expr)[0] - return args.every(truthy) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js deleted file mode 100644 index 2362da9..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/string.js +++ /dev/null @@ -1,140 +0,0 @@ -import { assert, err, isString, isNil, isNumber, isEmpty, inArray, getType } from '../../util.js' -import { computeValue, resolve } from '../../internal.js' - -export const stringOperators = { - - /** - * Concatenates two strings. - * - * @param obj - * @param expr - * @returns {string|*} - */ - $concat (obj, expr) { - let args = computeValue(obj, expr) - // does not allow concatenation with nulls - if ([null, undefined].some(inArray.bind(null, args))) { - return null - } - return args.join('') - }, - - /** - * Searches a string for an occurence of a substring and returns the UTF-8 code point index of the first occurence. - * If the substring is not found, returns -1. - * - * @param {Object} obj - * @param {*} expr - * @return {*} - */ - $indexOfBytes (obj, expr) { - let arr = computeValue(obj, expr) - - if (isNil(arr[0])) return null - - assert(isString(arr[0]), '$indexOfBytes first operand must resolve to a string') - assert(isString(arr[1]), '$indexOfBytes second operand must resolve to a string') - - let str = arr[0] - let searchStr = arr[1] - let start = arr[2] - let end = arr[3] - - assert( - isNil(start) || (isNumber(start) && start >= 0 && Math.round(start) === start), - '$indexOfBytes third operand must resolve to a non-negative integer' - ) - start = start || 0 - - assert( - isNil(end) || (isNumber(end) && end >= 0 && Math.round(end) === end), - '$indexOfBytes fourth operand must resolve to a non-negative integer' - ) - end = end || str.length - - if (start > end) return -1 - - let index = str.substring(start, end).indexOf(searchStr) - return (index > -1) - ? index + start - : index - }, - - /** - * Splits a string into substrings based on a delimiter. - * If the delimiter is not found within the string, returns an array containing the original string. - * - * @param {Object} obj - * @param {Array} expr - * @return {Array} Returns an array of substrings. - */ - $split (obj, expr) { - let args = computeValue(obj, expr) - assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])) - assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])) - return args[0].split(args[1]) - }, - - /** - * Compares two strings and returns an integer that reflects the comparison. - * - * @param obj - * @param expr - * @returns {number} - */ - $strcasecmp (obj, expr) { - let args = computeValue(obj, expr) - args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase() - args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase() - if (args[0] > args[1]) { - return 1 - } - return (args[0] < args[1]) ? -1 : 0 - }, - - /** - * Returns a substring of a string, starting at a specified index position and including the specified number of characters. - * The index is zero-based. - * - * @param obj - * @param expr - * @returns {string} - */ - $substr (obj, expr) { - let args = computeValue(obj, expr) - if (isString(args[0])) { - if (args[1] < 0) { - return '' - } else if (args[2] < 0) { - return args[0].substr(args[1]) - } else { - return args[0].substr(args[1], args[2]) - } - } - return '' - }, - - /** - * Converts a string to lowercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toLower (obj, expr) { - let value = computeValue(obj, expr) - return isEmpty(value) ? '' : value.toLowerCase() - }, - - /** - * Converts a string to uppercase. - * - * @param obj - * @param expr - * @returns {string} - */ - $toUpper (obj, expr) { - let value = computeValue(obj, expr) - return isEmpty(value) ? '' : value.toUpperCase() - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js deleted file mode 100644 index a6a93d3..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/aggregation/variable.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Aggregation framework variable operators - */ - -import { assert, each, err, map, isString, isNil, isUndefined, isEmpty, isArray, keys } from '../../util.js' -import { computeValue } from '../../internal.js' - -export const variableOperators = { - /** - * Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. - * - * @param obj - * @param expr - * @returns {*} - */ - $let (obj, expr) { - let varsExpr = expr['vars'] - let inExpr = expr['in'] - - // resolve vars - let originals = {} - let varsKeys = keys(varsExpr) - each(varsKeys, (key) => { - let val = computeValue(obj, varsExpr[key]) - let tempKey = '$' + key - // set value on object using same technique as in "$map" - originals[tempKey] = obj[tempKey] - obj[tempKey] = val - }) - - let value = computeValue(obj, inExpr) - - // cleanup and restore - each(varsKeys, (key) => { - let tempKey = '$' + key - if (isUndefined(originals[tempKey])) { - delete obj[tempKey] - } else { - obj[tempKey] = originals[tempKey] - } - }) - - return value - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js deleted file mode 100644 index d7ac61a..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/group.js +++ /dev/null @@ -1,158 +0,0 @@ -import { - assert, - clone, - each, - err, - getType, - getHash, - has, - inArray, - intersection, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isObjectLike, - isRegExp, - isString, - isUndefined, - map, - notInArray, - reduce, - unique -} from '../util' -import { computeValue, stddev } from '../internal.js' - -/** - * Group stage Accumulator Operators. https://docs.mongodb.com/manual/reference/operator/aggregation-group/ - */ - -export const groupOperators = { - - /** - * Returns an array of all the unique values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {*} - */ - $addToSet (collection, expr) { - return unique(this.$push(collection, expr)) - }, - - /** - * Returns the sum of all the values in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $sum (collection, expr) { - if (!isArray(collection)) return 0 - - if (isNumber(expr)) { - // take a short cut if expr is number literal - return collection.length * expr - } - return reduce(this.$push(collection, expr).filter(isNumber), (acc, n) => acc + n, 0) - }, - - /** - * Returns the highest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $max (collection, expr) { - let mapped = this.$push(collection, expr) - return reduce(mapped, (acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) - }, - - /** - * Returns the lowest value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $min (collection, expr) { - let mapped = this.$push(collection, expr) - return reduce(mapped, (acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) - }, - - /** - * Returns an average of all the values in a group. - * - * @param collection - * @param expr - * @returns {number} - */ - $avg (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber) - let sum = reduce(data, (acc, n) => acc + n, 0) - return sum / (data.length || 1) - }, - - /** - * Returns an array of all values for the selected field among for each document in that group. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $push (collection, expr) { - if (isNil(expr)) return collection - return map(collection, (obj) => computeValue(obj, expr)) - }, - - /** - * Returns the first value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $first (collection, expr) { - return (collection.length > 0) ? computeValue(collection[0], expr) : undefined - }, - - /** - * Returns the last value in a group. - * - * @param collection - * @param expr - * @returns {*} - */ - $last (collection, expr) { - return (collection.length > 0) ? computeValue(collection[collection.length - 1], expr) : undefined - }, - - /** - * Returns the population standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number} - */ - $stdDevPop (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber) - return stddev({ data: data, sampled: false }) - }, - - /** - * Returns the sample standard deviation of the input values. - * @param {Array} collection - * @param {Object} expr - * @return {Number|null} - */ - $stdDevSamp (collection, expr) { - let data = this.$push(collection, expr).filter(isNumber) - return stddev({ data: data, sampled: true }) - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js deleted file mode 100644 index 9e449bb..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/index.js +++ /dev/null @@ -1,95 +0,0 @@ -import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from '../constants' -import { assert, each, err, has, into, isBoolean, keys, reduce } from '../util' -import { _internal, computeValue, idKey, resolve } from '../internal' -import { Query } from '../query.js' -import { aggregateOperators } from './aggregation/index.js' -import { groupOperators } from './group.js' -import { pipelineOperators } from './pipeline.js' -import { projectionOperators } from './projection.js' -import { queryOperators } from './query.js' - -// operator definitions -const OPERATORS = { - 'aggregate': aggregateOperators, - 'group': groupOperators, - 'pipeline': pipelineOperators, - 'projection': projectionOperators, - 'query': queryOperators -} - -/** - * Returns the operators defined for the given operator classes - */ -export function ops () { - return reduce(arguments, (acc, cls) => into(acc, keys(OPERATORS[cls])), []) -} - -/** - * Add new operators - * - * @param opClass the operator class to extend - * @param fn a function returning an object of new operators - */ -export function addOperators (opClass, fn) { - - const newOperators = fn(_internal()) - - // ensure correct type specified - assert(has(OPERATORS, opClass), `Invalid operator class ${opClass}`) - - let operators = OPERATORS[opClass] - - // check for existing operators - each(newOperators, (fn, op) => { - assert(/^\$\w+$/.test(op), `Invalid operator name ${op}`) - assert(!has(operators, op), `${op} already exists for '${opClass}' operators`) - }) - - let wrapped = {} - - switch (opClass) { - case OP_QUERY: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (selector, value) => { - return { - test: (obj) => { - // value of field must be fully resolved. - let lhs = resolve(obj, selector) - let result = f.call(ctx, selector, lhs, value) - if (isBoolean(result)) { - return result - } else if (result instanceof Query) { - return result.test(obj) - } else { - err("Invalid return type for '" + op + "'. Must return a Boolean or Query") - } - } - } - } - })(fn, newOperators) - }) - break - case OP_PROJECTION: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (obj, expr, selector) => { - let lhs = resolve(obj, selector) - return f.call(ctx, selector, lhs, expr) - } - })(fn, newOperators) - }) - break - default: - each(newOperators, (fn, op) => { - wrapped[op] = ((f, ctx) => { - return (...args) => { - return f.apply(ctx, args) - } - })(fn, newOperators) - }) - } - - // toss the operator salad :) - Object.assign(OPERATORS[opClass], wrapped) -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js deleted file mode 100644 index f38f7e2..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/pipeline.js +++ /dev/null @@ -1,650 +0,0 @@ -import { OP_GROUP, OP_PROJECTION } from '../constants' -import { - array, - assert, - clone, - each, - err, - findInsertIndex, - getHash, - getType, - groupBy, - has, - hasMeta, - inArray, - into, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isObjectLike, - isRegExp, - isString, - isUndefined, - keys, - map, - memoize, - notInArray, - sortBy -} from '../util' -import { - computeValue, - getValue, - idKey, - redactObj, - resolve, - resolveObj, - removeValue, - setValue, - traverse -} from '../internal.js' -import { aggregate } from '../aggregator.js' -import { Query } from '../query.js' -import { ops } from './index.js' -import { groupOperators } from './group.js' -import { projectionOperators } from './projection.js' - -/** - * Pipeline Aggregation Stages. https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ - */ -export const pipelineOperators = { - - /** - * Adds new fields to documents. - * Outputs documents that contain all existing fields from the input documents and newly added fields. - * - * @param {Array} collection - * @param {*} expr - */ - $addFields (collection, expr) { - let newFields = keys(expr) - - return collection.map((obj) => { - obj = clone(obj) - each(newFields, (field) => { - let subExpr = expr[field] - let newValue = computeValue(obj, subExpr) - traverse(obj, field, (o, key) => { - o[key] = newValue - }, true) - }) - return obj - }) - }, - - /** - * Groups documents together for the purpose of calculating aggregate values based on a collection of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $group (collection, expr) { - // lookup key for grouping - const ID_KEY = idKey() - let objectId = expr[ID_KEY] - - let partitions = groupBy(collection, (obj) => { - return computeValue(obj, objectId, objectId) - }) - - let result = [] - - // remove the group key - delete expr[ID_KEY] - - each(partitions.keys, (value, i) => { - let obj = {} - - // exclude undefined key value - if (!isUndefined(value)) { - obj[ID_KEY] = value - } - - // compute remaining keys in expression - each(expr, (val, key) => { - obj[key] = accumulate(partitions.groups[i], key, val) - }) - result.push(obj) - }) - - return result - }, - - /** - * Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing. - * - * @param collection - * @param expr - */ - $lookup (collection, expr) { - let joinColl = expr.from - let localField = expr.localField - let foreignField = expr.foreignField - let asField = expr.as - - let errorMsg = "Invalid $lookup expression. " - assert(isArray(joinColl), errorMsg + "'from' must be an array") - assert(isString(foreignField), errorMsg + "'foreignField' must be a string") - assert(isString(localField), errorMsg + "'localField' must be a string") - assert(isString(asField), errorMsg + "'as' must be a string") - - let result = [] - let hash = {} - - function hashCode (v) { - return getHash(isNil(v) ? null : v) - } - - if (joinColl.length <= collection.length) { - each(joinColl, (obj, i) => { - let k = hashCode(obj[foreignField]) - hash[k] = hash[k] || [] - hash[k].push(i) - }) - - each(collection, (obj) => { - let k = hashCode(obj[localField]) - let indexes = hash[k] || [] - let newObj = clone(obj) - newObj[asField] = indexes.map((i) => clone(joinColl[i])) - result.push(newObj) - }) - - } else { - - each(collection, (obj, i) => { - let k = hashCode(obj[localField]) - hash[k] = hash[k] || [] - hash[k].push(i) - }) - - let tempResult = {} - each(joinColl, (obj) => { - let k = hashCode(obj[foreignField]) - let indexes = hash[k] || [] - each(indexes, (i) => { - let newObj = tempResult[i] || clone(collection[i]) - newObj[asField] = newObj[asField] || [] - newObj[asField].push(clone(obj)) - tempResult[i] = newObj - }) - }) - for (let i = 0, len = keys(tempResult).length; i < len; i++) { - result.push(tempResult[i]) - } - } - - return result - }, - - /** - * Filters the document stream, and only allows matching documents to pass into the next pipeline stage. - * $match uses standard MongoDB queries. - * - * @param collection - * @param expr - * @returns {Array|*} - */ - $match (collection, expr) { - return (new Query(expr)).find(collection).all() - }, - - /** - * Reshapes a document stream. - * $project can rename, add, or remove fields as well as create computed values and sub-documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $project (collection, expr) { - if (isEmpty(expr)) { - return collection - } - - // result collection - let projected = [] - let objKeys = keys(expr) - let idOnlyExcludedExpression = false - const ID_KEY = idKey() - - // validate inclusion and exclusion - let check = [false, false] - each(expr, (v, k) => { - if (k === ID_KEY) return - if (v === 0 || v === false) { - check[0] = true - } else { - check[1] = true - } - assert(check[0] !== check[1], 'Projection cannot have a mix of inclusion and exclusion.') - }) - - if (inArray(objKeys, ID_KEY)) { - let id = expr[ID_KEY] - if (id === 0 || id === false) { - objKeys = objKeys.filter(notInArray.bind(null, [ID_KEY])) - assert(notInArray(objKeys, ID_KEY), 'Must not contain collections id key') - idOnlyExcludedExpression = isEmpty(objKeys) - } - } else { - // if not specified the add the ID field - objKeys.push(ID_KEY) - } - - each(collection, (obj) => { - let cloneObj = {} - let foundSlice = false - let foundExclusion = false - let dropKeys = [] - - if (idOnlyExcludedExpression) { - dropKeys.push(ID_KEY) - } - - each(objKeys, (key) => { - let subExpr = expr[key] - let value // final computed value of the key - - if (key !== ID_KEY && subExpr === 0) { - foundExclusion = true - } - - if (key === ID_KEY && isEmpty(subExpr)) { - // tiny optimization here to skip over id - value = obj[key] - } else if (isString(subExpr)) { - value = computeValue(obj, subExpr, key) - } else if (subExpr === 1 || subExpr === true) { - // For direct projections, we use the resolved object value - } else if (isObject(subExpr)) { - let operator = keys(subExpr) - operator = operator.length > 1 ? false : operator[0] - - if (inArray(ops(OP_PROJECTION), operator)) { - // apply the projection operator on the operator expression for the key - if (operator === '$slice') { - // $slice is handled differently for aggregation and projection operations - if (array(subExpr[operator]).every(isNumber)) { - // $slice for projection operation - value = projectionOperators[operator](obj, subExpr[operator], key) - foundSlice = true - } else { - // $slice for aggregation operation - value = computeValue(obj, subExpr, key) - } - } else { - value = projectionOperators[operator](obj, subExpr[operator], key) - } - } else { - // compute the value for the sub expression for the key - value = computeValue(obj, subExpr, key) - } - } else { - dropKeys.push(key) - return - } - - // clone resolved values - let objValue = clone(resolveObj(obj, key)) - - if (!isUndefined(objValue)) { - Object.assign(cloneObj, objValue) - } - if (!isUndefined(value)) { - setValue(cloneObj, key, clone(value)) - } - - }) - // if projection included $slice operator - // Also if exclusion fields are found or we want to exclude only the id field - // include keys that were not explicitly excluded - if (foundSlice || foundExclusion || idOnlyExcludedExpression) { - cloneObj = Object.assign(clone(obj), cloneObj) - each(dropKeys, (key) => removeValue(cloneObj, key)) - } - projected.push(cloneObj) - }) - - return projected - }, - - /** - * Restricts the number of documents in an aggregation pipeline. - * - * @param collection - * @param value - * @returns {Object|*} - */ - $limit (collection, value) { - return collection.slice(0, value) - }, - - /** - * Skips over a specified number of documents from the pipeline and returns the rest. - * - * @param collection - * @param value - * @returns {*} - */ - $skip (collection, value) { - return collection.slice(value) - }, - - /** - * Takes an array of documents and returns them as a stream of documents. - * - * @param collection - * @param expr - * @returns {Array} - */ - $unwind (collection, expr) { - let result = [] - let field = expr.substr(1) - each(collection, (obj) => { - // must throw an error if value is not an array - let value = getValue(obj, field) - - assert(isArray(value), "Target field '" + field + "' is not of type Array.") - - each(value, (item) => { - let tmp = clone(obj) - tmp[field] = item - result.push(tmp) - }) - }) - return result - }, - - /** - * Takes all input documents and returns them in a stream of sorted documents. - * - * @param collection - * @param sortKeys - * @returns {*} - */ - $sort (collection, sortKeys) { - if (!isEmpty(sortKeys) && isObject(sortKeys)) { - let modifiers = keys(sortKeys) - each(modifiers.reverse(), (key) => { - let grouped = groupBy(collection, (obj) => resolve(obj, key)) - let sortedIndex = {} - let getIndex = (k) => sortedIndex[getHash(k)] - - let indexKeys = sortBy(grouped.keys, (item, i) => { - sortedIndex[getHash(item)] = i - return item - }) - - if (sortKeys[key] === -1) { - indexKeys.reverse() - } - collection = [] - each(indexKeys, (item) => into(collection, grouped.groups[getIndex(item)])) - }) - } - return collection - }, - - /** - * Groups incoming documents based on the value of a specified expression, - * then computes the count of documents in each distinct group. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sortByCount (collection, expr) { - let newExpr = { count: { $sum: 1 } } - newExpr[idKey()] = expr - - return this.$sort( - this.$group(collection, newExpr), - { count: -1 } - ) - }, - - /** - * Randomly selects the specified number of documents from its input. - * https://docs.mongodb.com/manual/reference/operator/aggregation/sample/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $sample (collection, expr) { - let size = expr.size - assert(isNumber(size), '$sample size must be a positive integer') - - let result = [] - let len = collection.length - for (let i = 0; i < size; i++) { - let n = Math.floor(Math.random() * len) - result.push(collection[n]) - } - return result - }, - - /** - * Returns a document that contains a count of the number of documents input to the stage. - * @param {Array} collection - * @param {String} expr - * @return {Object} - */ - $count (collection, expr) { - assert( - isString(expr) && expr.trim() !== '' && expr.indexOf('.') === -1 && expr.trim()[0] !== '$', - 'Invalid expression value for $count' - ) - - let result = {} - result[expr] = collection.length - return result - }, - - /** - * Replaces a document with the specified embedded document or new one. - * The replacement document can be any valid expression that resolves to a document. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/ - * - * @param {Array} collection - * @param {Object} expr - * @return {*} - */ - $replaceRoot (collection, expr) { - let newRoot = expr.newRoot - let result = [] - each(collection, (obj) => { - obj = computeValue(obj, newRoot) - assert(isObject(obj), '$replaceRoot expression must return a valid JS object') - result.push(obj) - }) - return result - }, - - /** - * Restricts the contents of the documents based on information stored in the documents themselves. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ - */ - $redact (collection, expr) { - return collection.map((obj) => { - return redactObj(clone(obj), expr) - }) - }, - - /** - * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. - * - * https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/ - */ - $bucket (collection, expr) { - let boundaries = expr.boundaries - let defaultKey = expr.default - let lower = boundaries[0] // inclusive - let upper = boundaries[boundaries.length - 1] // exclusive - let outputExpr = expr.output || { 'count': { '$sum': 1 } } - - assert(boundaries.length > 2, "$bucket 'boundaries' expression must have at least 3 elements") - let boundType = getType(lower) - - for (let i = 0, len = boundaries.length - 1; i < len; i++) { - assert(boundType === getType(boundaries[i + 1]), "$bucket 'boundaries' must all be of the same type") - assert(boundaries[i] < boundaries[i + 1], "$bucket 'boundaries' must be sorted in ascending order") - } - - if (!isNil(defaultKey) && getType(expr.default) === getType(lower)) { - assert(lower > expr.default || upper < expr.default, "$bucket 'default' expression must be out of boundaries range") - } - - let grouped = {} - each(boundaries, (k) => grouped[k] = []) - - // add default key if provided - if (!isNil(defaultKey)) grouped[defaultKey] = [] - - each(collection, (obj) => { - let key = computeValue(obj, expr.groupBy) - - if (isNil(key) || key < lower || key >= upper) { - assert(!isNil(defaultKey), '$bucket require a default for out of range values') - grouped[defaultKey].push(obj) - } else if (key >= lower && key < upper) { - let index = findInsertIndex(boundaries, key) - let boundKey = boundaries[Math.max(0, index - 1)] - grouped[boundKey].push(obj) - } else { - err("$bucket 'groupBy' expression must resolve to a value in range of boundaries") - } - }) - - // upper bound is exclusive so we remove it - boundaries.pop() - if (!isNil(defaultKey)) boundaries.push(defaultKey) - - return map(boundaries, (key) => { - let acc = accumulate(grouped[key], null, outputExpr) - return Object.assign(acc, { '_id': key }) - }) - }, - - $bucketAuto (collection, expr) { - let outputExpr = expr.output || { 'count': { '$sum': 1 } } - let groupByExpr = expr.groupBy - let bucketCount = expr.buckets - - assert(bucketCount > 0, "The $bucketAuto 'buckets' field must be greater than 0, but found: " + bucketCount) - - let approxBucketSize = Math.round(collection.length / bucketCount) - if (approxBucketSize < 1) { - approxBucketSize = 1 - } - - let computeValueOptimized = memoize(computeValue) - let grouped = {} - let remaining = [] - let sorted = sortBy(collection, (o) => { - let key = computeValueOptimized(o, groupByExpr) - if (isNil(key)) { - remaining.push(o) - } else { - grouped[key] || (grouped[key] = []) - grouped[key].push(o) - } - return key - }) - - const ID_KEY = idKey() - let result = [] - let index = 0 // counter for sorted collection - - for (let i = 0, len = sorted.length; i < bucketCount && index < len; i++) { - let boundaries = {} - let bucketItems = [] - - for (let j = 0; j < approxBucketSize && index < len; j++) { - let key = computeValueOptimized(sorted[index], groupByExpr) - - if (isNil(key)) key = null - - // populate current bucket with all values for current key - into(bucketItems, isNil(key) ? remaining : grouped[key]) - - // increase sort index by number of items added - index += (isNil(key) ? remaining.length : grouped[key].length) - - // set the min key boundary if not already present - if (!has(boundaries, 'min')) boundaries.min = key - - if (result.length > 0) { - let lastBucket = result[result.length - 1] - lastBucket[ID_KEY].max = boundaries.min - } - } - - // if is last bucket add remaining items - if (i == bucketCount - 1) { - into(bucketItems, sorted.slice(index)) - } - - result.push(Object.assign(accumulate(bucketItems, null, outputExpr), { '_id': boundaries })) - } - - if (result.length > 0) { - result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr) - } - - return result - }, - - /** - * Processes multiple aggregation pipelines within a single stage on the same set of input documents. - * Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. - */ - $facet (collection, expr) { - return map(expr, (pipeline) => aggregate(collection, pipeline)) - } -} - -/** - * Returns the result of evaluating a $group operation over a collection - * - * @param collection - * @param field the name of the aggregate operator or field - * @param expr the expression of the aggregate operator for the field - * @returns {*} - */ -function accumulate (collection, field, expr) { - if (inArray(ops(OP_GROUP), field)) { - return groupOperators[field](collection, expr) - } - - if (isObject(expr)) { - let result = {} - each(expr, (val, key) => { - result[key] = accumulate(collection, key, expr[key]) - // must run ONLY one group operator per expression - // if so, return result of the computed value - if (inArray(ops(OP_GROUP), key)) { - result = result[key] - // if there are more keys in expression this is bad - assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'") - return false // break - } - }) - return result - } - - return undefined -} - diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js deleted file mode 100644 index d449c6e..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/projection.js +++ /dev/null @@ -1,119 +0,0 @@ -import { - assert, - each, - err, - getHash, - getType, - has, - inArray, - intersection, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isObjectLike, - isRegExp, - isString, - isUndefined, - keys -} from '../util' -import { computeValue, resolve, resolveObj, traverse, idKey, stddev, slice } from '../internal.js' -import { Query } from '../query.js' - - -/** - * Projection Operators. https://docs.mongodb.com/manual/reference/operator/projection/ - */ -export const projectionOperators = { - - /** - * Projects the first element in an array that matches the query condition. - * - * @param obj - * @param field - * @param expr - */ - $ (obj, expr, field) { - err('$ not implemented') - }, - - /** - * Projects only the first element from an array that matches the specified $elemMatch condition. - * - * @param obj - * @param field - * @param expr - * @returns {*} - */ - $elemMatch (obj, expr, field) { - let arr = resolve(obj, field) - let query = new Query(expr) - - if (isNil(arr) || !isArray(arr)) { - return undefined - } - - for (let i = 0; i < arr.length; i++) { - if (query.test(arr[i])) { - return [arr[i]] - } - } - - return undefined - }, - - /** - * Limits the number of elements projected from an array. Supports skip and limit slices. - * - * @param obj - * @param field - * @param expr - */ - $slice (obj, expr, field) { - let xs = resolve(obj, field) - - if (!isArray(xs)) return xs - - if (isArray(expr)) { - return slice(xs, expr[0], expr[1]) - } else if (isNumber(expr)) { - return slice(xs, expr) - } else { - err('Invalid argument type for $slice projection operator') - } - }, - - /** - * Returns the population standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number} - */ - $stdDevPop (obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: false - }) - }, - - /** - * Returns the sample standard deviation of the input values. - * @param {Object} obj - * @param {Object} expr - * @param {String} field - * @return {Number|null} - */ - $stdDevSamp (obj, expr, field) { - return stddev({ - data: computeValue(obj, expr, field), - sampled: true - }) - } -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js deleted file mode 100644 index cf63442..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/operators/query.js +++ /dev/null @@ -1,419 +0,0 @@ -/** - * Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ - */ -import { - T_ARRAY, - T_BOOL, - T_BOOLEAN, - T_DATE, - T_FUNCTION, - T_NULL, - T_NUMBER, - T_OBJECT, - T_REGEX, - T_REGEXP, - T_STRING, - T_UNDEFINED -} from '../constants' -import { - array, - assert, - clone, - dropMeta, - each, - hasMeta, - inArray, - intersection, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isRegExp, - isString, - isUndefined, - keys -} from '../util' -import { computeValue, resolve, normalize } from '../internal.js' -import { Query } from '../query.js' - -export const simpleOperators = { - - /** - * Checks that two values are equal. - * - * @param a The lhs operand as resolved from the object by the given selector - * @param b The rhs operand provided by the user - * @returns {*} - */ - $eq (a, b) { - // start with simple equality check - if (isEqual(a, b)) return true - - // https://docs.mongodb.com/manual/tutorial/query-for-null-fields/ - if (isNil(a) && isNil(b)) return true - - if (isArray(a)) { - // is multi-valued lhs so we check each separately - if (hasMeta(a, { isMulti: true })) { - try { - for (let i = 0; i < a.length; i++) { - if (this.$eq(a[i], b)) { - return true; - } - } - } finally { - dropMeta(a) - } - } else { - // check one level deep - return a.findIndex(isEqual.bind(null, b)) !== -1 - } - } - return false; - }, - - /** - * Matches all values that are not equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $ne (a, b) { - return !this.$eq(a, b) - }, - - /** - * Matches any of the values that exist in an array specified in the query. - * - * @param a - * @param b - * @returns {*} - */ - $in (a, b) { - a = array(a) - return intersection(a, b).length > 0 - }, - - /** - * Matches values that do not exist in an array specified to the query. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $nin (a, b) { - return isNil(a) || !this.$in(a, b) - }, - - /** - * Matches values that are less than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lt (a, b) { - a = array(a).find((val) => val < b) - return a !== undefined - }, - - /** - * Matches values that are less than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $lte (a, b) { - a = array(a).find((val) => val <= b) - return a !== undefined - }, - - /** - * Matches values that are greater than the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gt (a, b) { - a = array(a).find((val) => val > b) - return a !== undefined - }, - - /** - * Matches values that are greater than or equal to the value specified in the query. - * - * @param a - * @param b - * @returns {boolean} - */ - $gte (a, b) { - a = array(a).find((val) => val >= b) - return a !== undefined - }, - - /** - * Performs a modulo operation on the value of a field and selects documents with a specified result. - * - * @param a - * @param b - * @returns {boolean} - */ - $mod (a, b) { - a = array(a).find((val) => isNumber(val) && isArray(b) && b.length === 2 && (val % b[0]) === b[1]) - return a !== undefined - }, - - /** - * Selects documents where values match a specified regular expression. - * - * @param a - * @param b - * @returns {boolean} - */ - $regex (a, b) { - a = array(a).find((val) => isString(val) && isRegExp(b) && (!!val.match(b))) - return a !== undefined - }, - - /** - * Matches documents that have the specified field. - * - * @param a - * @param b - * @returns {boolean} - */ - $exists (a, b) { - return ((b === false || b === 0) && isNil(a)) || ((b === true || b === 1) && !isNil(a)) - }, - - /** - * Matches arrays that contain all elements specified in the query. - * - * @param a - * @param b - * @returns boolean - */ - $all (a, b) { - let matched = false - if (isArray(a) && isArray(b)) { - for (let i = 0, len = b.length; i < len; i++) { - if (isObject(b[i]) && inArray(keys(b[i]), '$elemMatch')) { - matched = matched || this.$elemMatch(a, b[i].$elemMatch) - } else { - // order of arguments matter - return intersection(b, a).length === len - } - } - } - return matched - }, - - /** - * Selects documents if the array field is a specified size. - * - * @param a - * @param b - * @returns {*|boolean} - */ - $size (a, b) { - return isArray(a) && isNumber(b) && (a.length === b) - }, - - /** - * Selects documents if element in the array field matches all the specified $elemMatch condition. - * - * @param a - * @param b - */ - $elemMatch (a, b) { - if (isArray(a) && !isEmpty(a)) { - let query = new Query(b) - for (let i = 0, len = a.length; i < len; i++) { - if (query.test(a[i])) { - return true - } - } - } - return false - }, - - /** - * Selects documents if a field is of the specified type. - * - * @param a - * @param b - * @returns {boolean} - */ - $type (a, b) { - switch (b) { - case 1: - case 'double': - return isNumber(a) && (a + '').indexOf('.') !== -1 - case 2: - case T_STRING: - return isString(a) - case 3: - case T_OBJECT: - return isObject(a) - case 4: - case T_ARRAY: - return isArray(a) - case 6: - case T_UNDEFINED: - return isNil(a) - case 8: - case T_BOOL: - return isBoolean(a) - case 9: - case T_DATE: - return isDate(a) - case 10: - case T_NULL: - return isNull(a) - case 11: - case T_REGEX: - return isRegExp(a) - case 16: - case 'int': - return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1 - case 18: - case 'long': - return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1 - case 19: - case 'decimal': - return isNumber(a) - default: - return false - } - } -} - -export const queryOperators = { - - /** - * Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $and (selector, value) { - assert(isArray(value), 'Invalid expression: $and expects value to be an Array') - - let queries = [] - each(value, (expr) => queries.push(new Query(expr))) - - return { - test (obj) { - for (let i = 0; i < queries.length; i++) { - if (!queries[i].test(obj)) { - return false - } - } - return true - } - } - }, - - /** - * Joins query clauses with a logical OR returns all documents that match the conditions of either clause. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $or (selector, value) { - assert(isArray(value),'Invalid expression. $or expects value to be an Array') - - let queries = [] - each(value, (expr) => queries.push(new Query(expr))) - - return { - test (obj) { - for (let i = 0; i < queries.length; i++) { - if (queries[i].test(obj)) { - return true - } - } - return false - } - } - }, - - /** - * Joins query clauses with a logical NOR returns all documents that fail to match both clauses. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $nor (selector, value) { - assert(isArray(value),'Invalid expression. $nor expects value to be an Array') - let query = this.$or('$or', value) - return { - test (obj) { - return !query.test(obj) - } - } - }, - - /** - * Inverts the effect of a query expression and returns documents that do not match the query expression. - * - * @param selector - * @param value - * @returns {{test: Function}} - */ - $not (selector, value) { - let criteria = {} - criteria[selector] = normalize(value) - let query = new Query(criteria) - return { - test (obj) { - return !query.test(obj) - } - } - }, - - /** - * Matches documents that satisfy a JavaScript expression. - * - * @param selector - * @param value - * @returns {{test: test}} - */ - $where (selector, value) { - if (!isFunction(value)) { - value = new Function('return ' + value + ';') - } - return { - test (obj) { - return value.call(obj) === true - } - } - } -} - -// add simple query operators -each(simpleOperators, (fn, op) => { - queryOperators[op] = ((f, ctx) => { - return (selector, value) => { - return { - test (obj) { - // value of field must be fully resolved. - let lhs = resolve(obj, selector) - return f.call(ctx, lhs, value) - } - } - } - })(fn, simpleOperators) -}) \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js deleted file mode 100644 index fda3416..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/polyfill.js +++ /dev/null @@ -1,184 +0,0 @@ - -/** - * Polyfill to add native methods for non-supported environments. - */ - -// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new Error('Function.prototype.bind - what is trying to be bound is not callable') - } - - var aArgs = Array.prototype.slice.call(arguments, 1) - var fToBind = this - var fNOP = function () {} - var fBound = function () { - return fToBind.apply( - (this instanceof fNOP) ? this : oThis, - aArgs.concat(Array.prototype.slice.call(arguments)) - ) - } - - if (this.prototype) { - // Function.prototype doesn't have a prototype property - fNOP.prototype = this.prototype - } - fBound.prototype = new fNOP() - - return fBound - } -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find -if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this) - var len = o.length >>> 0 - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function') - } - - var thisArg = arguments[1] - var k = 0 - - while (k < len) { - var kValue = o[k] - if (predicate.call(thisArg, kValue, k, o)) { - return kValue - } - k++ - } - return undefined - } - }) -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex -if (!Array.prototype.findIndex) { - Object.defineProperty(Array.prototype, 'findIndex', { - value: function(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this) - var len = o.length >>> 0 - - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function') - } - - var thisArg = arguments[1] - var k = 0 - while (k < len) { - var kValue = o[k] - if (predicate.call(thisArg, kValue, k, o)) { - return k - } - k++ - } - return -1 - } - }) -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes -if (!Array.prototype.includes) { - Object.defineProperty(Array.prototype, 'includes', { - value: function(searchElement, fromIndex) { - if (this == null) { - throw new TypeError('"this" is null or not defined') - } - - var o = Object(this) - var len = o.length >>> 0 - - if (len === 0) { - return false - } - var n = fromIndex | 0 - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0) - - function sameValueZero(x, y) { - return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) - } - - while (k < len) { - if (sameValueZero(o[k], searchElement)) { - return true - } - k++ - } - return false - } - }) -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign -if (typeof Object.assign != 'function') { - Object.assign = function(target, varArgs) { // .length of function is 2 - - if (target == null) { - throw new TypeError('Cannot convert undefined or null to object') - } - - var to = Object(target) - var args = Array.prototype.slice.call(arguments) - - for (var index = 1; index < args.length; index++) { - var nextSource = args[index] - - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (nextSource.hasOwnProperty(nextKey)) { - to[nextKey] = nextSource[nextKey] - } - } - } - } - return to - } -} - -// http://tokenposts.blogspot.co.za/2012/04/javascript-objectkeys-browser.html -if (!Object.keys) { - Object.keys = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.keys called on a non-object') - } - - var result = [] - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(k) - } - } - return result - } -} - -// https://github.com/es-shims/Object.values/blob/master/implementation.js -if (!Object.values) { - Object.values = function (o) { - if (o !== Object(o)) { - throw new TypeError('Object.values called on a non-object') - } - var result = [] - for (var k in o) { - if (o.hasOwnProperty(k)) { - result.push(o[k]) - } - } - return result - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js deleted file mode 100644 index a0eee43..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/query.js +++ /dev/null @@ -1,142 +0,0 @@ -import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' -import { - assert, - each, - err, - getType, - has, - inArray, - intersection, - isArray, - isBoolean, - isDate, - isEmpty, - isEqual, - isFunction, - isNil, - isNull, - isNumber, - isObject, - isObjectLike, - isRegExp, - isString, - isUndefined, - notInArray, - reduce -} from './util' -import { normalize } from './internal.js' -import { Cursor } from './cursor.js' -import { ops } from './operators/index.js' -import { groupOperators } from './operators/group.js' -import { queryOperators } from './operators/query.js' - -/** - * Query object to test collection elements with - * @param criteria the pass criteria for the query - * @param projection optional projection specifiers - * @constructor - */ -export class Query { - - constructor (criteria, projection = {}) { - this.__criteria = criteria - this.__projection = projection - this.__compiled = [] - this._compile() - } - - _compile () { - if (isEmpty(this.__criteria)) return - - assert(isObject(this.__criteria), 'Criteria must be of type Object') - - let whereOperator; - - each(this.__criteria, (expr, field) => { - // save $where operators to be executed after other operators - if ('$where' === field) { - whereOperator = { field: field, expr: expr }; - } else if (inArray(['$and', '$or', '$nor'], field)) { - this._processOperator(field, field, expr) - } else { - // normalize expression - expr = normalize(expr) - each(expr, (val, op) => { - this._processOperator(field, op, val) - }) - } - - if (isObject(whereOperator)) { - this._processOperator(whereOperator.field, whereOperator.field, whereOperator.expr); - } - }) - } - - _processOperator (field, operator, value) { - if (inArray(ops(OP_QUERY), operator)) { - this.__compiled.push(queryOperators[operator](field, value)) - } else { - err("Invalid query operator '" + operator + "' detected") - } - } - - /** - * Checks if the object passes the query criteria. Returns true if so, false otherwise. - * @param obj - * @returns {boolean} - */ - test (obj) { - for (let i = 0, len = this.__compiled.length; i < len; i++) { - if (!this.__compiled[i].test(obj)) { - return false - } - } - return true - } - - /** - * Performs a query on a collection and returns a cursor object. - * @param collection - * @param projection - * @returns {Cursor} - */ - find (collection, projection) { - return new Cursor(collection, this, projection) - } - - /** - * Remove matched documents from the collection returning the remainder - * @param collection - * @returns {Array} - */ - remove (collection) { - return reduce(collection, (acc, obj) => { - if (!this.test(obj)) acc.push(obj) - return acc - }, []) - } -} - -/** - * Performs a query on a collection and returns a cursor object. - * - * @param collection - * @param criteria - * @param projection - * @returns {Cursor} - */ -export function find (collection, criteria, projection) { - return new Query(criteria).find(collection, projection) -} - -/** - * Returns a new array without objects which match the criteria - * - * @param collection - * @param criteria - * @returns {Array} - */ -export function remove (collection, criteria) { - return new Query(criteria).remove(collection) -} - diff --git a/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js b/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js deleted file mode 100644 index 631a95c..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/lib/util.js +++ /dev/null @@ -1,447 +0,0 @@ -/** - * Utility functions - */ - -import { - T_ARRAY, - T_BOOL, - T_BOOLEAN, - T_DATE, - T_FUNCTION, - T_NULL, - T_NUMBER, - T_OBJECT, - T_REGEX, - T_REGEXP, - T_STRING, - T_UNDEFINED -} from './constants' - -export function assert (condition, message) { - if (falsey(condition)) err(message) -} - -/** - * Deep clone an object - * @param obj - * @returns {*} - */ -export function clone (obj) { - switch (jsType(obj)) { - case T_ARRAY: - return obj.map(clone) - case T_OBJECT: - return map(obj, clone) - default: - return obj - } -} - -export function getType (v) { - if (v === null) return 'Null' - if (v === undefined) return 'Undefined' - return v.constructor.name -} -export function jsType (v) { return getType(v).toLowerCase() } -export function isBoolean (v) { return jsType(v) === T_BOOLEAN } -export function isString (v) { return jsType(v) === T_STRING } -export function isNumber (v) { return jsType(v) === T_NUMBER } -export function isArray (v) { return jsType(v) === T_ARRAY } -export function isArrayLike (v) { return !isNil(v) && has(v, 'length') } -export function isObject (v) { return jsType(v) === T_OBJECT } -export function isObjectLike (v) { return v === Object(v) } // objects, arrays, functions, date, custom object -export function isDate (v) { return jsType(v) === T_DATE } -export function isRegExp (v) { return jsType(v) === T_REGEXP } -export function isFunction (v) { return jsType(v) === T_FUNCTION } -export function isNil (v) { return isNull(v) || isUndefined(v) } -export function isNull (v) { return jsType(v) === T_NULL } -export function isUndefined (v) { return jsType(v) === T_UNDEFINED } -export function inArray (arr, item) { return arr.includes(item) } -export function notInArray (arr, item) { return !arr.includes(item) } -export function truthy (arg) { return !!arg } -export function falsey (arg) { return !arg } -export function isEmpty (x) { - return isNil(x) || - isArray(x) && x.length === 0 || - isObject(x) && keys(x).length === 0 || !x -} -// ensure a value is an array -export function array (x) { return isArray(x) ? x : [x] } -export function has (obj, prop) { return obj.hasOwnProperty(prop) } -export function err (s) { throw new Error(s) } -export function keys (o) { return Object.keys(o) } - -// ////////////////// UTILS //////////////////// - -// internal constants -const __MINGO_META = '__mingo__' - -export function addMeta (obj, value) { - obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value) -} - -export function hasMeta (obj, value) { - return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]) -} - -export function dropMeta (obj) { - if (has(obj, __MINGO_META)) delete obj[__MINGO_META] -} - -/** - * Iterate over an array or object - * @param {Array|Object} obj An object-like value - * @param {Function} fn The callback to run per item - * @param {*} ctx The object to use a context - * @return {void} - */ -export function each (obj, fn, ctx = null) { - assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'") - - if (isArrayLike(obj)) { - for (let i = 0, len = obj.length; i < len; i++) { - if (fn.call(ctx, obj[i], i, obj) === false) break - } - } else { - for (let k in obj) { - if (has(obj, k)) { - if (fn.call(ctx, obj[k], k, obj) === false) break - } - } - } -} - -/** - * Transform values in a collection - * - * @param {Array|Object} obj An array/object whose values to transform - * @param {Function} fn The transform function - * @param {*} ctx The value to use as the "this" context for the transform - * @return {Array|Object} Result object after applying the transform - */ -export function map (obj, fn, ctx = null) { - if (isArray(obj)) { - return obj.map(fn, ctx) - } else if (isObject(obj)) { - let o = {} - each(obj, (v, k) => o[k] = fn.call(ctx, v, k), obj) - return o - } -} - -/** - * Reduce any array-like object - * @param collection - * @param fn - * @param accumulator - * @returns {*} - */ -export function reduce (collection, fn, accumulator) { - if (isArray(collection)) return collection.reduce(fn, accumulator) - // array-like objects - each(collection, (v, k) => accumulator = fn(accumulator, v, k, collection)) - return accumulator -} - -/** - * Returns the intersection between two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} Result array - */ -export function intersection (xs, ys) { - return xs.filter(inArray.bind(null, ys)) -} - -/** - * Returns the union of two arrays - * - * @param {Array} xs The first array - * @param {Array} ys The second array - * @return {Array} The result array - */ -export function union (xs, ys) { - return into(into([], xs), ys.filter(notInArray.bind(null, xs))) -} - -/** - * Flatten the array - * - * @param {Array} xs The array to flatten - * @param {Number} depth The number of nested lists to iterate - */ -export function flatten (xs, depth = -1) { - assert(isArray(xs), 'Input must be an Array') - let arr = [] - function unwrap(ys, iter) { - for (let i = 0, len = ys.length; i < len; i++) { - if (isArray(ys[i]) && (iter > 0 || iter < 0)) { - unwrap(ys[i], Math.max(-1, iter - 1)) - } else { - arr.push(ys[i]) - } - } - } - unwrap(xs, depth) - return arr -} - -/** - * Determine whether two values are the same or strictly equivalent - * - * @param {*} a The first value - * @param {*} b The second value - * @return {Boolean} Result of comparison - */ -export function isEqual (a, b) { - // strictly equal must be equal. - if (a === b) return true - - // unequal types and functions cannot be equal. - let type = jsType(a) - if (type !== jsType(b) || type === T_FUNCTION) return false - - // we treat NaN as the same - if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true - - // leverage toString for Date and RegExp types - if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString() - - if (type === T_ARRAY) { - if (a.length === b.length && a.length === 0) return true - if (a.length !== b.length) return false - for (let i = 0, len = a.length; i < len; i++) { - if (!isEqual(a[i], b[i])) return false - } - } else if (type === T_OBJECT) { - // deep compare objects - let ka = keys(a) - let kb = keys(b) - - // check length of keys early - if (ka.length !== kb.length) return false - - // we know keys are strings so we sort before comparing - ka.sort() - kb.sort() - - // compare keys - if (!isEqual(ka, kb)) return false - - // back to the drawing board - for (let i = 0, len = ka.length; i < len; i++) { - let temp = ka[i] - if (!isEqual(a[temp], b[temp])) return false - } - } else { - // we do not know how to compare custom types so we guess - return getHash(a) === getHash(b) - } - // best effort says values are equal :) - return true -} - -/** - * Return a new unique version of the collection - * @param {Array} xs The input collection - * @return {Array} A new collection with unique values - */ -export function unique (xs) { - let h = {} - let arr = [] - each(xs, (item) => { - let k = getHash(item) - if (!has(h, k)) { - arr.push(item) - h[k] = 0 - } - }) - return arr -} - -/** - * Generates a random string of max length range [24,27] - * @param n Size of string to return - * @returns {*} - */ -function randomString(n) { - return (Math.E + Math.random()).toString(36).slice(2, n+2) -} - -/** - * Encode value using a simple optimistic stable scheme. - * @param value - * @returns {*} - */ -export function encode (value) { - let type = jsType(value) - switch (type) { - case T_FUNCTION: - return randomString(7) - case T_BOOLEAN: - case T_NUMBER: - case T_REGEXP: - return value.toString() - case T_STRING: - return JSON.stringify(value) - case T_DATE: - return value.toISOString() - case T_NULL: - case T_UNDEFINED: - return type - case T_ARRAY: - return '[' + map(value, (v) => `${encode(v)}`) + ']' - default: - let prefix = (type === T_OBJECT)? '' : `${getType(value)}|` - let objKeys = keys(value) - objKeys.sort() - return `${prefix}{` + map(objKeys, (k) => `${encode(k)}:${encode(value[k])}`) + '}' - } -} - -/** - * Generate hash code - * http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery - * - * @param value - * @returns {*} - */ -export function getHash (value) { - let hash = 0, i, chr, len, s = encode(value) - if (s.length === 0) return hash - for (i = 0, len = s.length; i < len; i++) { - chr = s.charCodeAt(i) - hash = ((hash << 5) - hash) + chr - hash |= 0 // Convert to 32bit integer - } - return hash.toString() -} - -/** - * Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee - * - * This implementation treats null/undefined sort keys as less than every other type - * - * @param {Array} collection - * @param {Function} fn The function used to resolve sort keys - * @param {Object} ctx The context to use for calling `fn` - * @return {Array} Returns a new sorted array by the given iteratee - */ -export function sortBy (collection, fn, ctx = null) { - let sortKeys = {} - let sorted = [] - let len = collection.length - let result = [] - - for (let i = 0; i < len; i++) { - let obj = collection[i] - let key = fn.call(ctx, obj, i) - if (isNil(key)) { - // objects with null keys will go in first - result.push(obj) - } else { - let hash = getHash(obj) - if (!has(sortKeys, hash)) { - sortKeys[hash] = [key, i] - } - sorted.push(obj) - } - } - // use native array sorting but enforce stableness - sorted.sort((a, b) => { - let A = sortKeys[getHash(a)] - let B = sortKeys[getHash(b)] - if (A[0] < B[0]) return -1 - if (A[0] > B[0]) return 1 - if (A[1] < B[1]) return -1 - if (A[1] > B[1]) return 1 - return 0 - }) - return into(result, sorted) -} - -/** - * Groups the collection into sets by the returned key - * - * @param collection - * @param fn {Function} to compute the group key of an item in the collection - * @param ctx {Object} The context to use for calling `fn` - * @returns {{keys: Array, groups: Array}} - */ -export function groupBy (collection, fn, ctx) { - let result = { - 'keys': [], - 'groups': [] - } - let lookup = {} - each(collection, (obj) => { - let key = fn.call(ctx, obj) - let hash = getHash(key) - let index = -1 - - if (isUndefined(lookup[hash])) { - index = result.keys.length - lookup[hash] = index - result.keys.push(key) - result.groups.push([]) - } - index = lookup[hash] - result.groups[index].push(obj) - }) - return result -} - -/** - * Push elements in given array into target array - * - * @param {*} target The array to push into - * @param {*} xs The array of elements to push - */ -export function into (target, xs) { - Array.prototype.push.apply(target, xs) - return target -} - -/** - * Find the insert index for the given key in a sorted array. - * - * @param {*} array The sorted array to search - * @param {*} key The search key - */ -export function findInsertIndex (array, key) { - // uses binary search - let lo = 0 - let hi = array.length - 1 - while (lo <= hi) { - let mid = Math.round(lo + (hi - lo) / 2) - if (key < array[mid]) { - hi = mid - 1 - } else if (key > array[mid]) { - lo = mid + 1 - } else { - return mid - } - } - return lo -} - -/** - * This is a generic memoization function - * - * This implementation uses a cache independent of the function being memoized - * to allow old values to be garbage collected when the memoized function goes out of scope. - * - * @param {*} fn The function object to memoize - */ -export function memoize (fn) { - return ((cache) => { - return (...args) => { - let key = getHash(args) - if (!has(cache, key)) { - cache[key] = fn.apply(this, args) - } - return cache[key] - } - })({/* storage */}) -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/mingo/package.json b/Challenge/seokahi/010.star/node_modules/mingo/package.json deleted file mode 100644 index 89714d6..0000000 --- a/Challenge/seokahi/010.star/node_modules/mingo/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "mingo", - "version": "1.3.3", - "description": "JavaScript implementation of MongoDB query language", - "main": "dist/mingo.js", - "module": "lib/index.js", - "scripts": { - "build": "make build", - "prepublishOnly": "make build", - "test": "make test" - }, - "repository": { - "type": "git", - "url": "https://github.com/kofrasa/mingo.git" - }, - "files": [ - "dist", - "lib", - "LICENSE", - "README.md", - "CONTRIBUTORS.md", - "CHANGELOG.md", - "VERSION" - ], - "devDependencies": { - "babel-plugin-external-helpers": "^6.22.0", - "babel-preset-env": "^1.6.0", - "backbone": ">=1.3.x", - "bson": "1.x.x", - "gulp": ">=3.9.x", - "rollup": "^0.45.2", - "rollup-plugin-babel": "^2.7.1", - "rollup-plugin-commonjs": "^8.0.2", - "rollup-plugin-node-resolve": "^3.0.0", - "tape": ">=4.x.x", - "uglify-js": "2.x.x" - }, - "keywords": [ - "util", - "mongo", - "nosql", - "query", - "aggregate", - "filter", - "group", - "project", - "search", - "transform" - ], - "author": "Francis Asante ", - "license": "MIT", - "bugs": { - "url": "https://github.com/kofrasa/mingo/issues" - } -} diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE b/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE deleted file mode 100644 index 19129e3..0000000 --- a/Challenge/seokahi/010.star/node_modules/mute-stream/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/README.md b/Challenge/seokahi/010.star/node_modules/mute-stream/README.md deleted file mode 100644 index 8ab1238..0000000 --- a/Challenge/seokahi/010.star/node_modules/mute-stream/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# mute-stream - -Bytes go in, but they don't come out (when muted). - -This is a basic pass-through stream, but when muted, the bytes are -silently dropped, rather than being passed through. - -## Usage - -```javascript -var MuteStream = require('mute-stream') - -var ms = new MuteStream(options) - -ms.pipe(process.stdout) -ms.write('foo') // writes 'foo' to stdout -ms.mute() -ms.write('bar') // does not write 'bar' -ms.unmute() -ms.write('baz') // writes 'baz' to stdout - -// can also be used to mute incoming data -var ms = new MuteStream -input.pipe(ms) - -ms.on('data', function (c) { - console.log('data: ' + c) -}) - -input.emit('data', 'foo') // logs 'foo' -ms.mute() -input.emit('data', 'bar') // does not log 'bar' -ms.unmute() -input.emit('data', 'baz') // logs 'baz' -``` - -## Options - -All options are optional. - -* `replace` Set to a string to replace each character with the - specified string when muted. (So you can show `****` instead of the - password, for example.) - -* `prompt` If you are using a replacement char, and also using a - prompt with a readline stream (as for a `Password: *****` input), - then specify what the prompt is so that backspace will work - properly. Otherwise, pressing backspace will overwrite the prompt - with the replacement character, which is weird. - -## ms.mute() - -Set `muted` to `true`. Turns `.write()` into a no-op. - -## ms.unmute() - -Set `muted` to `false` - -## ms.isTTY - -True if the pipe destination is a TTY, or if the incoming pipe source is -a TTY. - -## Other stream methods... - -The other standard readable and writable stream methods are all -available. The MuteStream object acts as a facade to its pipe source -and destination. diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js b/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js deleted file mode 100644 index a24fc09..0000000 --- a/Challenge/seokahi/010.star/node_modules/mute-stream/mute.js +++ /dev/null @@ -1,145 +0,0 @@ -var Stream = require('stream') - -module.exports = MuteStream - -// var out = new MuteStream(process.stdout) -// argument auto-pipes -function MuteStream (opts) { - Stream.apply(this) - opts = opts || {} - this.writable = this.readable = true - this.muted = false - this.on('pipe', this._onpipe) - this.replace = opts.replace - - // For readline-type situations - // This much at the start of a line being redrawn after a ctrl char - // is seen (such as backspace) won't be redrawn as the replacement - this._prompt = opts.prompt || null - this._hadControl = false -} - -MuteStream.prototype = Object.create(Stream.prototype) - -Object.defineProperty(MuteStream.prototype, 'constructor', { - value: MuteStream, - enumerable: false -}) - -MuteStream.prototype.mute = function () { - this.muted = true -} - -MuteStream.prototype.unmute = function () { - this.muted = false -} - -Object.defineProperty(MuteStream.prototype, '_onpipe', { - value: onPipe, - enumerable: false, - writable: true, - configurable: true -}) - -function onPipe (src) { - this._src = src -} - -Object.defineProperty(MuteStream.prototype, 'isTTY', { - get: getIsTTY, - set: setIsTTY, - enumerable: true, - configurable: true -}) - -function getIsTTY () { - return( (this._dest) ? this._dest.isTTY - : (this._src) ? this._src.isTTY - : false - ) -} - -// basically just get replace the getter/setter with a regular value -function setIsTTY (isTTY) { - Object.defineProperty(this, 'isTTY', { - value: isTTY, - enumerable: true, - writable: true, - configurable: true - }) -} - -Object.defineProperty(MuteStream.prototype, 'rows', { - get: function () { - return( this._dest ? this._dest.rows - : this._src ? this._src.rows - : undefined ) - }, enumerable: true, configurable: true }) - -Object.defineProperty(MuteStream.prototype, 'columns', { - get: function () { - return( this._dest ? this._dest.columns - : this._src ? this._src.columns - : undefined ) - }, enumerable: true, configurable: true }) - - -MuteStream.prototype.pipe = function (dest, options) { - this._dest = dest - return Stream.prototype.pipe.call(this, dest, options) -} - -MuteStream.prototype.pause = function () { - if (this._src) return this._src.pause() -} - -MuteStream.prototype.resume = function () { - if (this._src) return this._src.resume() -} - -MuteStream.prototype.write = function (c) { - if (this.muted) { - if (!this.replace) return true - if (c.match(/^\u001b/)) { - if(c.indexOf(this._prompt) === 0) { - c = c.substr(this._prompt.length); - c = c.replace(/./g, this.replace); - c = this._prompt + c; - } - this._hadControl = true - return this.emit('data', c) - } else { - if (this._prompt && this._hadControl && - c.indexOf(this._prompt) === 0) { - this._hadControl = false - this.emit('data', this._prompt) - c = c.substr(this._prompt.length) - } - c = c.toString().replace(/./g, this.replace) - } - } - this.emit('data', c) -} - -MuteStream.prototype.end = function (c) { - if (this.muted) { - if (c && this.replace) { - c = c.toString().replace(/./g, this.replace) - } else { - c = null - } - } - if (c) this.emit('data', c) - this.emit('end') -} - -function proxy (fn) { return function () { - var d = this._dest - var s = this._src - if (d && d[fn]) d[fn].apply(d, arguments) - if (s && s[fn]) s[fn].apply(s, arguments) -}} - -MuteStream.prototype.destroy = proxy('destroy') -MuteStream.prototype.destroySoon = proxy('destroySoon') -MuteStream.prototype.close = proxy('close') diff --git a/Challenge/seokahi/010.star/node_modules/mute-stream/package.json b/Challenge/seokahi/010.star/node_modules/mute-stream/package.json deleted file mode 100644 index 56ebb36..0000000 --- a/Challenge/seokahi/010.star/node_modules/mute-stream/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "mute-stream", - "version": "0.0.8", - "main": "mute.js", - "directories": { - "test": "test" - }, - "devDependencies": { - "tap": "^12.1.1" - }, - "scripts": { - "test": "tap test/*.js --cov" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/mute-stream" - }, - "keywords": [ - "mute", - "stream", - "pipe" - ], - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "ISC", - "description": "Bytes go in, but they don't come out (when muted).", - "files": [ - "mute.js" - ] -} diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore b/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore deleted file mode 100644 index 13abef4..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -node_modules/* -npm_debug.log diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE b/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE deleted file mode 100644 index 6a477d4..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/LICENSE +++ /dev/null @@ -1,231 +0,0 @@ -Dual Licensed MIT and Apache 2 - -The MIT License - -Copyright (c) 2013 Dominic Tarr - -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. - - - ----------------------------------------------------------------------- - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (c) 2013 Dominic Tarr - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/index.js b/Challenge/seokahi/010.star/node_modules/pause-stream/index.js deleted file mode 100644 index 0e0bf96..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/index.js +++ /dev/null @@ -1,3 +0,0 @@ -//through@2 handles this by default! -module.exports = require('through') - diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/package.json b/Challenge/seokahi/010.star/node_modules/pause-stream/package.json deleted file mode 100644 index 2a22646..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "pause-stream", - "version": "0.0.11", - "description": "a ThroughStream that strictly buffers all readable events when paused.", - "main": "index.js", - "directories": { - "test": "test" - }, - "devDependencies": { - "stream-tester": "0.0.2", - "stream-spec": "~0.2.0" - }, - "scripts": { - "test": "node test/index.js && node test/pause-end.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/dominictarr/pause-stream.git" - }, - "keywords": [ - "stream", - "pipe", - "pause", - "drain", - "buffer" - ], - "author": "Dominic Tarr (dominictarr.com)", - "license": [ - "MIT", - "Apache2" - ], - "dependencies": { - "through": "~2.3" - } -} diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown b/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown deleted file mode 100644 index 2366939..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/readme.markdown +++ /dev/null @@ -1,29 +0,0 @@ -# PauseStream - -This is a `Stream` that will strictly buffer when paused. -Connect it to anything you need buffered. - -``` js - var ps = require('pause-stream')(); - - badlyBehavedStream.pipe(ps.pause()) - - aLittleLater(function (err, data) { - ps.pipe(createAnotherStream(data)) - ps.resume() - }) -``` - -`PauseStream` will buffer whenever paused. -it will buffer when yau have called `pause` manually. -but also when it's downstream `dest.write()===false`. -it will attempt to drain the buffer when you call resume -or the downstream emits `'drain'` - -`PauseStream` is tested using [stream-spec](https://github.com/dominictarr/stream-spec) -and [stream-tester](https://github.com/dominictarr/stream-tester) - -This is now the default case of -[through](https://github.com/dominictarr/through) - -https://github.com/dominictarr/pause-stream/commit/4a6fe3dc2c11091b1efbfde912e0473719ed9cc0 diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js b/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js deleted file mode 100644 index db8778d..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/test/index.js +++ /dev/null @@ -1,17 +0,0 @@ -var spec = require('stream-spec') -var tester = require('stream-tester') -var ps = require('..')() - -spec(ps) - .through({strict: false}) - .validateOnExit() - -var master = tester.createConsistent - -tester.createRandomStream(1000) //1k random numbers - .pipe(master = tester.createConsistentStream()) - .pipe(tester.createUnpauseStream()) - .pipe(ps) - .pipe(tester.createPauseStream()) - .pipe(master.createSlave()) - diff --git a/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js b/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js deleted file mode 100644 index a6c27ef..0000000 --- a/Challenge/seokahi/010.star/node_modules/pause-stream/test/pause-end.js +++ /dev/null @@ -1,33 +0,0 @@ - -var pause = require('..') -var assert = require('assert') - -var ps = pause() -var read = [], ended = false - -ps.on('data', function (i) { - read.push(i) -}) - -ps.on('end', function () { - ended = true -}) - -assert.deepEqual(read, []) - -ps.write(0) -ps.write(1) -ps.write(2) - -assert.deepEqual(read, [0, 1, 2]) - -ps.pause() - -assert.deepEqual(read, [0, 1, 2]) - -ps.end() -assert.equal(ended, false) -ps.resume() -assert.equal(ended, true) - - diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc b/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc deleted file mode 100644 index 67bc628..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/.eslintrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": [ - "eslint:recommended" - ], - "env": { - "node": true, - "es6": false, - }, - "globals": { - "Promise": true // used only when no callback are passed - }, - "rules": { - "no-control-regex": "warn", - "no-prototype-builtins": "warn", - "indent": ["warn", 2, {"SwitchCase": 1}], - "linebreak-style": ["warn", "unix"], - "quotes": ["warn", "single"], - "no-unused-vars": "warn", - "no-sequences": "error", - "no-unused-expressions": "error", - } -} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc b/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc deleted file mode 100644 index 0d97986..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/.jshintrc +++ /dev/null @@ -1,54 +0,0 @@ -{ - "passfail": false, - "maxerr": 100, - - "browser": false, - "node": true, - "rhino": false, - "couch": true, - "wsh": true, - "jquery": true, - "prototypejs": false, - "mootools": false, - "dojo": false, - - "devel": false, - - "es5": true, - "strict": false, - "globalstrict": false, - - "asi": false, - "lastsemic": true, - "laxbreak": true, - "laxcomma": false, - "bitwise": false, - "boss": false, - "curly": true, - "eqeqeq": true, - "eqnull": false, - "evil": false, - "expr": false, - "forin": false, - "immed": false, - "latedef": false, - "loopfunc": true, - "noarg": true, - "regexp": true, - "regexdash": false, - "scripturl": true, - "shadow": true, - "supernew": true, - "undef": true, - - "newcap": true, - "noempty": true, - "nonew": true, - "nomen": false, - "onevar": true, - "plusplus": false, - "sub": true, - "trailing": true, - "white": false, - "indent": 2 -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml b/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml deleted file mode 100644 index 150a777..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js -node_js: - - "node" - - "0.12" - - "4" - - "5" - -before_script: - - npx eslint . --quiet - -sudo: false diff --git a/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json b/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json deleted file mode 100644 index 9792498..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "editor.formatOnSave": false -} \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md b/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md deleted file mode 100644 index b094c48..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/CHANGELOG.md +++ /dev/null @@ -1,13 +0,0 @@ - -0.2.7 / 2012-08-30 -================== - - * Fixed handling of numeric inputs with parseFloat - * Fixed overwriting of non-string inputs - * Added support for boolean types - -0.2.6 / 2012-08-12 -================== - - * Added allowance of empty default values - diff --git a/Challenge/seokahi/010.star/node_modules/prompt/LICENSE b/Challenge/seokahi/010.star/node_modules/prompt/LICENSE deleted file mode 100644 index 56217ca..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Nodejitsu Inc. - -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. \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/README.md b/Challenge/seokahi/010.star/node_modules/prompt/README.md deleted file mode 100644 index 5980812..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/README.md +++ /dev/null @@ -1,468 +0,0 @@ -# prompt [![Build Status](https://secure.travis-ci.org/flatiron/prompt.svg)](http://travis-ci.org/flatiron/prompt) [![Npm package version](https://img.shields.io/npm/v/prompt.svg?maxAge=2592000)](https://npmjs.com/package/prompt) - - -A beautiful command-line prompt for node.js - -## Features - -* prompts the user for input -* supports validation and defaults -* hides passwords - -## Usage -Using prompt is relatively straight forward. There are two core methods you should be aware of: `prompt.get()` and `prompt.addProperties()`. Their methods take strings representing property names in addition to objects for complex property validation (and more). There are a number of [examples][0] that you should examine for detailed usage. - -### Getting Basic Prompt Information -Getting started with `prompt` is easy. Lets take a look at `examples/simple-prompt.js`: - -``` js - var prompt = require('prompt'); - - // - // Start the prompt - // - prompt.start(); - - // - // Get two properties from the user: username and email - // - prompt.get(['username', 'email'], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' email: ' + result.email); - }); -``` - -This will result in the following command-line output: - -``` - $ node examples/simple-prompt.js - prompt: username: some-user - prompt: email: some-user@some-place.org - Command-line input received: - username: some-user - email: some-user@some-place.org -``` - -If no callback is passed to `prompt.get(schema)`, then it returns a `Promise`, so you can also write: -```js -const {username, email} = await prompt.get(['username', 'email']); -``` - - -### Prompting with Validation, Default Values, and More (Complex Properties) -In addition to prompting the user with simple string prompts, there is a robust API for getting and validating complex information from a command-line prompt. Here's a quick sample: - -``` js - var schema = { - properties: { - name: { - pattern: /^[a-zA-Z\s\-]+$/, - message: 'Name must be only letters, spaces, or dashes', - required: true - }, - password: { - hidden: true - } - } - }; - - // - // Start the prompt - // - prompt.start(); - - // - // Get two properties from the user: name, password - // - prompt.get(schema, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' name: ' + result.name); - console.log(' password: ' + result.password); - }); -``` - -Pretty easy right? The output from the above script is: - -``` - $ node examples/property-prompt.js - prompt: name: nodejitsu000 - error: Invalid input for name - error: Name must be only letters, spaces, or dashes - prompt: name: Nodejitsu Inc - prompt: password: - Command-line input received: - name: Nodejitsu Inc - password: some-password -``` - -## Valid Property Settings -`prompt` understands JSON-schema with a few extra parameters and uses [revalidator](https://github.com/flatiron/revalidator) for validation. - -Here's an overview of the properties that may be used for validation and prompting controls: - -``` js - { - description: 'Enter your password', // Prompt displayed to the user. If not supplied name will be used. - type: 'string', // Specify the type of input to expect. - pattern: /^\w+$/, // Regular expression that input must be valid against. - message: 'Password must be letters', // Warning message to display if validation fails. - hidden: true, // If true, characters entered will either not be output to console or will be outputed using the `replace` string. - replace: '*', // If `hidden` is set it will replace each hidden character with the specified string. - default: 'lamepassword', // Default value to use if no value is entered. - required: true // If true, value entered must be non-empty. - before: function(value) { return 'v' + value; } // Runs before node-prompt callbacks. It modifies user's input - } -``` - -Alternatives to `pattern` include `format` and `conform`, as documented in [revalidator](https://github.com/flatiron/revalidator). - -Supported types are `string`, `boolean`, `number`, `integer`, `array` - -Using `type: 'boolean'` accepts case insensitive values 'true', 't', 'false', 'f' - -Using `type: 'array'` has some special cases. - -- `description` will not work in the schema if `type: 'array'` is defined. -- `maxItems` takes precedence over `minItems`. -- Arrays that do not have `maxItems` defined will require users to `SIGINT` (`^C`) before the array is ended. -- If `SIGINT` (`^C`) is triggered before `minItems` is met, a validation error will appear. This will require users to `SIGEOF` (`^D`) to end the input. - -For more information on things such as `maxItems` and `minItems`, refer to the [revalidator](https://github.com/flatiron/revalidator) repository. - -### Alternate Validation API: - -Prompt, in addition to iterating over JSON-Schema properties, will also happily iterate over an array of validation objects given an extra 'name' property: - -```js - var prompt = require('../lib/prompt'); - - // - // Start the prompt - // - prompt.start(); - - // - // Get two properties from the user: username and password - // - prompt.get([{ - name: 'username', - required: true - }, { - name: 'password', - hidden: true, - conform: function (value) { - return true; - } - }], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' password: ' + result.password); - }); -``` - -### Backward Compatibility - -Note that, while this structure is similar to that used by prompt 0.1.x, that the object properties use the same names as in JSON-Schema. prompt 0.2.x is backward compatible with prompt 0.1.x except for asynchronous validation. - -### Skipping Prompts - -Sometimes power users may wish to skip prompts and specify all data as command line options. -if a value is set as a property of `prompt.override` prompt will use that instead of -prompting the user. - -``` js - //prompt-override.js - - var prompt = require('prompt'), - optimist = require('optimist') - - // - // set the overrides - // - prompt.override = optimist.argv - - // - // Start the prompt - // - prompt.start(); - - // - // Get two properties from the user: username and email - // - prompt.get(['username', 'email'], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' email: ' + result.email); - }) - - //: node prompt-override.js --username USER --email EMAIL -``` - -It is also possible to skip prompts dynamically based on previous prompts. -If an `ask` method is added, prompt will use it to determine if the prompt should be displayed. -If `ask` returns true the prompt is displayed. otherwise, the default value or empty string are used. - -``` js - var schema = { - properties: { - proxy: { - description: 'Proxy url', - }, - proxyCredentials: { - description: 'Proxy credentials', - ask: function() { - // only ask for proxy credentials if a proxy was set - return prompt.history('proxy').value > 0; - } - } - } - }; - - // - // Start the prompt - // - prompt.start(); - - // - // Get one or two properties from the user, depending on - // what the user answered for proxy - // - prompt.get(schema, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' proxy: ' + result.proxy); - console.log(' credentials: ' + result.proxyCredentials); - }); -``` - - -### Adding Properties to an Object -A common use-case for prompting users for data from the command-line is to extend or create a configuration object that is passed onto the entry-point method for your CLI tool. `prompt` exposes a convenience method for doing just this: - -``` js - var obj = { - password: 'lamepassword', - mindset: 'NY' - } - - // - // Log the initial object. - // - console.log('Initial object to be extended:'); - console.dir(obj); - - // - // Add two properties to the empty object: username and email - // - prompt.addProperties(obj, ['username', 'email'], function (err) { - // - // Log the results. - // - console.log('Updated object received:'); - console.dir(obj); - }); -``` - -### Prompt history -You can use the `prompt.history()` method to get access to previous prompt input. - -``` js - prompt.get([{ - name: 'name', - description: 'Your name', - type: 'string', - required: true - }, { - name: 'surname', - description: 'Your surname', - type: 'string', - required: true, - message: 'Please dont use the demo credentials', - conform: function(surname) { - var name = prompt.history('name').value; - return (name !== 'John' || surname !== 'Smith'); - } - }], function(err, results) { - console.log(results); - }); -``` - -## Customizing your prompt -Aside from changing `property.message`, you can also change `prompt.message` -and `prompt.delimiter` to change the appearance of your prompt. - -The basic structure of a prompt is this: - -``` js -prompt.message + prompt.delimiter + property.message + prompt.delimiter; -``` - -The default `prompt.message` is "prompt," the default `prompt.delimiter` is -": ", and the default `property.message` is `property.name`. -Changing these allows you to customize the appearance of your prompts! In -addition, prompt supports ANSI color codes via the -[colors module](https://github.com/DABH/colors.js) for custom colors. For a -very colorful example: - -``` js - var prompt = require("prompt"); - var colors = require("@colors/colors/safe"); - // - // Setting these properties customizes the prompt. - // - prompt.message = colors.rainbow("Question!"); - prompt.delimiter = colors.green("><"); - - prompt.start(); - - prompt.get({ - properties: { - name: { - description: colors.magenta("What is your name?") - } - } - }, function (err, result) { - console.log(colors.cyan("You said your name is: " + result.name)); - }); -``` - -If you don't want colors, you can set - -```js -var prompt = require('prompt'); - -prompt.colors = false; -``` - -## Integration with streamlinejs - -When integrating prompt with projects using streamlinejs such as the following - -``` -prompt.start(); -function test_prompt(_){ - console.log(prompt.get(loadDataValues(), _).output); -} -test_prompt(_); -``` - -This will work, however the process is then stuck with a stdin stream still open. If you setup the traditional way (with callback) such as this - - ``` -prompt.start(); -function test_prompt(){ - prompt.get(loadDataValues(), function(err, data){ - console.log(data.output); - }); -} -test_prompt(); -``` -This works and ends correctly. - -To resolve this we have added a new method to prompt, which will stop the stdin stream - -``` -// -// ### function stop () -// Stops input coming in from stdin -// -prompt.stop = function () { - if (prompt.stopped || !prompt.started) { - return; - } - - stdin.destroy(); - prompt.emit('stop'); - prompt.stopped = true; - prompt.started = false; - prompt.paused = false; - return prompt; -} -``` - -And you can find an example in the example folder `examples/prompt-streamline.js` - -``` -/* - * prompt-streamline._js: Example of how to use prompt with streamlinejs. - * - * calling syntax: _node prompt-streamline._js - * - */ -var prompt = require('../lib/prompt'); - -function getSampleData(){ - return [ - { - name: 'username', - message: 'Enter a username' - } - ]; -}; - -// -// Start the prompt -// -prompt.start(); - -function get_username_prompt(_){ - console.log(prompt.get(getSampleData(), _).username); -} - -get_username_prompt(_); - -// -// Clean the prompt -// -prompt.stop(); -``` - -## Disabling prompt's built-in SIGINT handling - -By default, prompt prompt binds a process-killing event handler to the SIGINT event (CTRL+C). This allows easily exiting from prompts, but can prevent an app from executing other event handlers when an interrupt is received. In order to override this default behavior, pass a `{noHandleSIGINT: true}` option into `prompt.start`. - -``` js - // - // Disable prompt's built-in SIGINT handling: - // - prompt.start({noHandleSIGINT: true}); - - process.on('SIGINT', function() { - console.log("This will execute when you hit CTRL+C"); - process.exit(); - }); -``` - - -## Installation - -``` bash - $ [sudo] npm install prompt -``` - -## Running tests - -``` bash - $ npm test -``` - -#### License: MIT -#### Author: [Charlie Robbins](http://github.com/indexzero) -#### Contributors: [Josh Holbrook](http://github.com/jesusabdullah), [Pavan Kumar Sunkara](http://github.com/pksunkara) - -[0]: https://github.com/flatiron/prompt/tree/master/examples diff --git a/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css b/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css deleted file mode 100644 index bd54134..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/docs/docco.css +++ /dev/null @@ -1,194 +0,0 @@ -/*--------------------- Layout and Typography ----------------------------*/ -body { - font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; - font-size: 15px; - line-height: 22px; - color: #252519; - margin: 0; padding: 0; -} -a { - color: #261a3b; -} - a:visited { - color: #261a3b; - } -p { - margin: 0 0 15px 0; -} -h4, h5, h6 { - color: #333; - margin: 6px 0 6px 0; - font-size: 13px; -} - h2, h3 { - margin-bottom: 0; - color: #000; - } - h1 { - margin-top: 40px; - margin-bottom: 15px; - color: #000; - } -#container { - position: relative; -} -#background { - position: fixed; - top: 0; left: 525px; right: 0; bottom: 0; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - z-index: -1; -} -#jump_to, #jump_page { - background: white; - -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; - -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - font: 10px Arial; - text-transform: uppercase; - cursor: pointer; - text-align: right; -} -#jump_to, #jump_wrapper { - position: fixed; - right: 0; top: 0; - padding: 5px 10px; -} - #jump_wrapper { - padding: 0; - display: none; - } - #jump_to:hover #jump_wrapper { - display: block; - } - #jump_page { - padding: 5px 0 3px; - margin: 0 0 25px 25px; - } - #jump_page .source { - display: block; - padding: 5px 10px; - text-decoration: none; - border-top: 1px solid #eee; - } - #jump_page .source:hover { - background: #f5f5ff; - } - #jump_page .source:first-child { - } -table td { - border: 0; - outline: 0; -} - td.docs, th.docs { - max-width: 450px; - min-width: 450px; - min-height: 5px; - padding: 10px 25px 1px 50px; - overflow-x: hidden; - vertical-align: top; - text-align: left; - } - .docs pre { - margin: 15px 0 15px; - padding-left: 15px; - } - .docs p tt, .docs p code { - background: #f8f8ff; - border: 1px solid #dedede; - font-size: 12px; - padding: 0 0.2em; - } - .pilwrap { - position: relative; - } - .pilcrow { - font: 12px Arial; - text-decoration: none; - color: #454545; - position: absolute; - top: 3px; left: -20px; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; - } - td.docs:hover .pilcrow { - opacity: 1; - } - td.code, th.code { - padding: 14px 15px 16px 25px; - width: 100%; - vertical-align: top; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - } - pre, tt, code { - font-size: 12px; line-height: 18px; - font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; - margin: 0; padding: 0; - } - - -/*---------------------- Syntax Highlighting -----------------------------*/ -td.linenos { background-color: #f0f0f0; padding-right: 10px; } -span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } -body .hll { background-color: #ffffcc } -body .c { color: #408080; font-style: italic } /* Comment */ -body .err { border: 1px solid #FF0000 } /* Error */ -body .k { color: #954121 } /* Keyword */ -body .o { color: #666666 } /* Operator */ -body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -body .cp { color: #BC7A00 } /* Comment.Preproc */ -body .c1 { color: #408080; font-style: italic } /* Comment.Single */ -body .cs { color: #408080; font-style: italic } /* Comment.Special */ -body .gd { color: #A00000 } /* Generic.Deleted */ -body .ge { font-style: italic } /* Generic.Emph */ -body .gr { color: #FF0000 } /* Generic.Error */ -body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -body .gi { color: #00A000 } /* Generic.Inserted */ -body .go { color: #808080 } /* Generic.Output */ -body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -body .gs { font-weight: bold } /* Generic.Strong */ -body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -body .gt { color: #0040D0 } /* Generic.Traceback */ -body .kc { color: #954121 } /* Keyword.Constant */ -body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ -body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ -body .kp { color: #954121 } /* Keyword.Pseudo */ -body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ -body .kt { color: #B00040 } /* Keyword.Type */ -body .m { color: #666666 } /* Literal.Number */ -body .s { color: #219161 } /* Literal.String */ -body .na { color: #7D9029 } /* Name.Attribute */ -body .nb { color: #954121 } /* Name.Builtin */ -body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -body .no { color: #880000 } /* Name.Constant */ -body .nd { color: #AA22FF } /* Name.Decorator */ -body .ni { color: #999999; font-weight: bold } /* Name.Entity */ -body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -body .nf { color: #0000FF } /* Name.Function */ -body .nl { color: #A0A000 } /* Name.Label */ -body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -body .nt { color: #954121; font-weight: bold } /* Name.Tag */ -body .nv { color: #19469D } /* Name.Variable */ -body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -body .w { color: #bbbbbb } /* Text.Whitespace */ -body .mf { color: #666666 } /* Literal.Number.Float */ -body .mh { color: #666666 } /* Literal.Number.Hex */ -body .mi { color: #666666 } /* Literal.Number.Integer */ -body .mo { color: #666666 } /* Literal.Number.Oct */ -body .sb { color: #219161 } /* Literal.String.Backtick */ -body .sc { color: #219161 } /* Literal.String.Char */ -body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ -body .s2 { color: #219161 } /* Literal.String.Double */ -body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -body .sh { color: #219161 } /* Literal.String.Heredoc */ -body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -body .sx { color: #954121 } /* Literal.String.Other */ -body .sr { color: #BB6688 } /* Literal.String.Regex */ -body .s1 { color: #219161 } /* Literal.String.Single */ -body .ss { color: #19469D } /* Literal.String.Symbol */ -body .bp { color: #954121 } /* Name.Builtin.Pseudo */ -body .vc { color: #19469D } /* Name.Variable.Class */ -body .vg { color: #19469D } /* Name.Variable.Global */ -body .vi { color: #19469D } /* Name.Variable.Instance */ -body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html b/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html deleted file mode 100644 index 7776f5b..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/docs/prompt.html +++ /dev/null @@ -1,296 +0,0 @@ - prompt.js

prompt.js

/*
- * prompt.js: Simple prompt for prompting information from the command line 
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var events = require('events'),
-    async = require('async'),
-    colors = require('colors'),
-    winston = require('winston'),
-    stdio = process.binding('stdio');

@private function capitalize (str)

- -

str {string} String to capitalize

- -

Capitalizes the string supplied.

function capitalize(str) {
-  return str.charAt(0).toUpperCase() + str.slice(1);
-}
-
-var prompt = module.exports = Object.create(events.EventEmitter.prototype);
-
-var logger = prompt.logger = new winston.Logger({
-  transports: [
-    new (winston.transports.Console)()
-  ]
-});
-    
-prompt.started    = false;
-prompt.paused     = false;
-prompt.allowEmpty = false; 
-
-var stdin, stdout;

Create an empty object for the properties -known to prompt

prompt.properties = {};

Setup the default winston logger to use -the cli levels and colors.

logger.cli();

function start (options)

- -

@options {Object} Optional Options to consume by prompt

- -

Starts the prompt by listening to the appropriate events on options.stdin -and options.stdout. If no streams are supplied, then process.stdin -and process.stdout are used, respectively.

prompt.start = function (options) {
-  if (prompt.started) {
-    return;
-  }
-  
-  options = options        || {};
-  stdin   = options.stdin  || process.openStdin();
-  stdout  = options.stdout || process.stdout;
-  
-  prompt.allowEmpty = options.allowEmpty || false;
-  
-  process.on('SIGINT', function () {
-    stdout.write('\n');
-    process.exit(1);
-  })
-  
-  prompt.emit('start');
-  prompt.started = true;
-  return prompt;
-};

function pause ()

- -

Pauses input coming in from stdin

prompt.pause = function () {
-  if (!prompt.started || prompt.paused) {
-    return;
-  }
-  
-  stdin.pause();
-  prompt.emit('pause');
-  prompt.paused = true;
-  return prompt;
-};

function resume ()

- -

Resumes input coming in from stdin

prompt.resume = function () {
-  if (!prompt.started || !prompt.paused) {
-    return;
-  }
-  
-  stdin.resume();
-  prompt.emit('resume');
-  prompt.paused = false;
-  return prompt;
-};

function get (msg, [validator,] callback)

- -

@msg {Array|Object|string} Set of variables to get input for.

- -

@callback {function} Continuation to pass control to when complete.

- -

Gets input from the user via stdin for the specified message(s) msg.

prompt.get = function (msg, callback) {
-  var vars = !Array.isArray(msg) ? [msg] : msg,
-      result = {};
-  
-  vars = vars.map(function (v) {
-    if (typeof v === 'string') {
-      v = v.toLowerCase();
-    }
-    
-    return prompt.properties[v] || v;
-  });
-  
-  function get(target, next) {
-    prompt.getInput(target, function (err, line) {
-      if (err) {
-        return next(err);
-      }
-      
-      var name = target.name || target;
-      result[name] = line;
-      next();
-    });
-  }
-  
-  async.forEachSeries(vars, get, function (err) {
-    return err ? callback(err) : callback(null, result);
-  });
-  
-  return prompt;
-};

function getInput (msg, validator, callback)

- -

@msg {Object|string} Variable to get input for.

- -

@callback {function} Continuation to pass control to when complete.

- -

Gets input from the user via stdin for the specified message msg.

prompt.getInput = function (prop, callback) {
-  var name   = prop.message || prop.name || prop,
-      raw    = ['prompt', ': ' + name.grey, ': '.grey],
-      read   = prop.hidden ? prompt.readLineHidden : prompt.readLine,
-      length, msg;
-  
-  if (prop.default) {
-    raw.splice(2, -1, ' (' + prop.default + ')');
-  }
-  

Calculate the raw length and colorize the prompt

  length = raw.join('').length;
-  raw[0] = raw[0];
-  msg = raw.join('');
-  
-  if (prop.help) {
-    prop.help.forEach(function (line) {
-      logger.help(line);
-    });
-  }
-  
-  stdout.write(msg); 
-  prompt.emit('prompt', prop);
-  
-  read.call(null, function (err, line) {
-    if (err) {
-      return callback(err);
-    }
-  
-    if (!line || line === '') {
-      line = prop.default || line;
-    }
-    
-    if (prop.validator || prop.empty === false) {
-      var valid;
-      
-      if (prop.validator) {
-        valid = prop.validator.test 
-         ? prop.validator.test(line)
-         : prop.validator(line);
-      }
-      
-      if (prop.empty === false && valid) {
-        valid = line.length > 0;
-        prop.warning = prop.warning || 'You must supply a value.';
-      }
-      
-      if (!valid) {
-        logger.error('Invalid input for ' + name.grey);
-        if (prop.warning) {
-          logger.error(prop.warning);
-        }
-        
-        prompt.emit('invalid', prop, line);
-        return prompt.getInput(prop, callback);
-      }
-    }
-        
-    logger.input(line.yellow);
-    callback(null, line);
-  });
-
-  return prompt;
-};

function addProperties (obj, properties, callback)

- -

@obj {Object} Object to add properties to

- -

@properties {Array} List of properties to get values for

- -

@callback {function} Continuation to pass control to when complete.

- -

Prompts the user for values each of the properties if obj does not already -have a value for the property. Responds with the modified object.

prompt.addProperties = function (obj, properties, callback) {
-  properties = properties.filter(function (prop) {
-    return typeof obj[prop] === 'undefined';
-  });
-  
-  if (properties.length === 0) {
-    return callback(obj);
-  }
-  
-  prompt.get(properties, function (err, results) {
-    if (err) {
-      return callback(err);
-    }
-    else if (!results) {
-      return callback(null, obj);
-    }
-    
-    function putNested (obj, path, value) {
-      var last = obj, key; 
-      
-      while (path.length > 1) {
-        key = path.shift();
-        if (!last[key]) {
-          last[key] = {};
-        }
-        
-        last = last[key];
-      }
-      
-      last[path.shift()] = value;
-    }
-    
-    Object.keys(results).forEach(function (key) {
-      putNested(obj, key.split('.'), results[key]);
-    });
-    
-    callback(null, obj);
-  });
-  
-  return prompt;
-};

function readLine (callback)

- -

@callback {function} Continuation to respond to when complete

- -

Gets a single line of input from the user.

prompt.readLine = function (callback) {
-  var value = '', buffer = '';
-  prompt.resume();
-  stdin.setEncoding('utf8');
-  stdin.on('error', callback);
-  stdin.on('data', function data (chunk) {
-    value += buffer + chunk;
-    buffer = '';
-    value = value.replace(/\r/g, '');
-    if (value.indexOf('\n') !== -1) {
-      if (value !== '\n') {
-        value = value.replace(/^\n+/, '');
-      }
-      
-      buffer = value.substr(value.indexOf('\n'));
-      val = value.substr(0, value.indexOf('\n'));
-      prompt.pause();
-      stdin.removeListener('data', data);
-      stdin.removeListener('error', callback);
-      value = value.trim();
-      callback(null, value);
-    }
-  });
-  
-  return prompt;
-};

function readLineHidden (callback)

- -

@callback {function} Continuation to respond to when complete

- -

Gets a single line of hidden input (i.e. rawMode = true) from the user.

prompt.readLineHidden = function (callback) {
-  var value = '', buffer = '';
-  stdio.setRawMode(true);
-  prompt.resume();
-  stdin.on('error', callback);
-  stdin.on('data', function data (c) {
-    c = '' + c;
-    switch (c) {
-      case '\n': case '\r': case '\r\n': case '\u0004':
-        stdio.setRawMode(false);
-        stdin.removeListener('data', data);
-        stdin.removeListener('error', callback);
-        value = value.trim();
-        stdout.write('\n');
-        stdout.flush();
-        prompt.pause();
-        return callback(null, value)
-      case '\u0003': case '\0':
-        stdout.write('\n');
-        process.exit(1);
-        break;
-      default:
-        value += buffer + c
-        buffer = '';
-        break;
-    }
-  });
-  
-  return prompt;
-};
-
-
diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js deleted file mode 100644 index 1a56176..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/add-properties.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * add-properties.js: Example of how to add properties to an object using prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -var obj = { - password: 'lamepassword', - mindset: 'NY' -} - -// -// Log the initial object. -// -console.log('Initial object to be extended:'); -console.dir(obj); - -// -// Add two properties to the empty object: username and email -// -prompt.addProperties(obj, ['username', 'email'], function (err) { - // - // Log the results. - // - console.log('Updated object received:'); - console.dir(obj); -}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js deleted file mode 100644 index 0a90b88..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/color.js +++ /dev/null @@ -1,19 +0,0 @@ -var prompt = require("../lib/prompt"); -var colors = require("@colors/colors/safe"); -// -// Setting these properties customizes the prompt. -// -prompt.message = colors.rainbow("Question!"); -prompt.delimiter = colors.green("><"); - -prompt.start(); - -prompt.get({ - properties: { - name: { - description: colors.magenta("What is your name?") - } - } -}, function (err, result) { - console.log(colors.cyan("You said your name is: " + result.name)); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js deleted file mode 100644 index 194e1ef..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/dynamic-ask-prompt.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * dynamic-ask-prompt.js: Dynamically decide whether to display prompt. - */ - -var prompt = require('../lib/prompt'); - -var schema = { - properties: { - proxy: { - description: 'Proxy url' - }, - proxyCredentials: { - description: 'Proxy credentials', - ask: function() { - // only ask for proxy credentials if a proxy was set - return prompt.history('proxy').value > 0; - } - } - } -}; - -// -// Start the prompt -// -prompt.start(); - -// -// Get one or two properties from the user, depending on -// what the user answered for proxy -// -prompt.get(schema, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' proxy: ' + result.proxy); - console.log(' credentials: ' + result.proxyCredentials); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js deleted file mode 100644 index d87503b..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/existing-properties.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * existing-properties.js: Example of using prompt with predefined properties. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -prompt.properties = { - email: { - format: 'email', - message: 'Must be a valid email address' - }, - password: { - hidden: true - } -}; - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: email, password -// -prompt.get(['email', 'password'], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' email: ' + result.email); - console.log(' password: ' + result.password); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js deleted file mode 100644 index fd4369d..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/history.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * history.js: Example of using the prompt history capabilities. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -var properties = { - properties: { - animal: { - description: 'Enter an animal', - default: 'dog', - pattern: /dog|cat/ - }, - sound: { - description: 'What sound does this animal make?', - conform: function (value) { - var animal = prompt.history(0).value; - - return animal === 'dog' && value === 'woof' - || animal === 'cat' && value === 'meow'; - } - } - } -} - -// -// Get two properties from the user -// -prompt.get(properties, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' animal: ' + result.animal); - console.log(' sound: ' + result.sound); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js deleted file mode 100644 index 25106a2..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/nested-properties-prompt.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * property-prompt.js: Example of using prompt with complex properties. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -var schema = { - properties: { - url: { - required: true, - format: 'url' - }, - auth: { - properties: { - username: { - required: true - }, - password: { - required: true, - hidden: true - } - } - } - } -}; - -prompt.start(); - -prompt.get(schema, function (err, result) { - console.log('Command-line input received:'); - console.log(' url: ' + result.url); - console.log(' auth:username: ' + result.auth.username); - console.log(' auth:password: ' + result.auth.password); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js deleted file mode 100644 index 631b7b5..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/old-schema.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * simple-prompt.js: Simple example of using prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: username and email -// -prompt.get([ - { - name: 'username', - validator: /^[a-z]+$/, - warning: 'Username should consist only lowercase alphabets', - empty: false - }, - { - name: 'email', - message: 'Email Address' - } -], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' email: ' + result.email); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js deleted file mode 100644 index 0ca9ddd..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/override-validation.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * override-validation.js: Example of using prompt with complex properties and command-line input. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'), - optimist = require('optimist'); - -var schema = { - properties: { - name: { - pattern: /^[a-zA-Z\s-]+$/, - message: 'Name must be only letters, spaces, or dashes', - required: true - }, - email: { - name: 'email', - format: 'email', - message: 'Must be a valid email address' - } - } -}; - -// -// Set the overrides -// -prompt.override = optimist.argv - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: email, password -// -prompt.get(schema, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' name: ' + result.name); - console.log(' email: ' + result.email); -}); - -// try running -// $ node ./override-validation.js --name USER --email EMAIL -// You will only be asked for email because it's invalid -// $ node ./override-validation.js --name h$acker --email me@example.com -// You will only be asked for name becasue it's invalid diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js deleted file mode 100644 index e8015e6..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/password.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * password.js: Simple example of using prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: username and password and password masked -// -prompt.get([{ - name: 'username', - required: true - }, { - name: 'password', - hidden: true, - conform: function (value) { - return true; - } - }, { - name: 'passwordMasked', - hidden: true, - replace: '*', - conform: function (value) { - return true; - } - }], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' password: ' + result.password); - console.log(' passwordMasked: ' + result.passwordMasked); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js deleted file mode 100644 index 7f2848b..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-override.js +++ /dev/null @@ -1,36 +0,0 @@ -var prompt = require('../lib/prompt'), - optimist; - -try { - optimist = require('optimist'); -} catch (err) { - throw new Error([ - 'You need to install optimist before this example will work!', - 'Try: `npm install optimist`.' - ].join('\n')); -} - -// -// Set the overrides -// -prompt.override = optimist.argv - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: username and email -// -prompt.get(['username', 'email'], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' email: ' + result.email); - prompt.pause(); -}) - -// $ node ./prompt-override.js --username USER --email EMAIL diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js b/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js deleted file mode 100644 index e7fef42..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/prompt-streamline._js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * prompt-streamline._js: Example of how to use prompt with streamlinejs. - * - * calling syntax: _node prompt-streamline._js - * - */ -var prompt = require('../lib/prompt'); - -function getSampleData(){ - return [ - { - name: 'username', - message: 'Enter a username' - } - ]; -}; - -// -// Start the prompt -// -prompt.start(); - -function get_username_prompt(_){ - console.log(prompt.get(getSampleData(), _).username); -} - -get_username_prompt(_); - -// -// Clean the prompt -// -prompt.stop(); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js deleted file mode 100644 index c8b343b..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/property-prompt.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * property-prompt.js: Example of using prompt with complex properties. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -var schema = { - properties: { - name: { - pattern: /^[a-zA-Z\s-]+$/, - message: 'Name must be only letters, spaces, or dashes', - required: true - }, - email: { - name: 'email', - format: 'email', - message: 'Must be a valid email address' - }, - password: { - required: true, - hidden: true - } - } -}; - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: email, password -// -prompt.get(schema, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' name: ' + result.name); - console.log(' email: ' + result.email); - console.log(' password: ' + result.password); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js deleted file mode 100644 index 062e529..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/simple-prompt.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * simple-prompt.js: Simple example of using prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -// -// Get two properties from the user: username and email -// -prompt.get(['username', 'email'], function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' username: ' + result.username); - console.log(' email: ' + result.email); -}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js deleted file mode 100644 index 83f45a6..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/types.js +++ /dev/null @@ -1,20 +0,0 @@ -var prompt = require('../lib/prompt'); - -prompt.start(); - -prompt.get([{ - name: 'integer', - type: 'integer', - required: true - }, { - name: 'number', - type: 'number', - required: true - }, { - name: 'boolean', - type: 'boolean', - required: true - }], function (err, result) { - console.log('Input received:'); - console.log(JSON.stringify(result, null, 2)); -}); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js deleted file mode 100644 index 512b556..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/examples/yes-or-no-prompt.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * yes-or-no-prompt.js: Simple example of using prompt. - * - * (C) 2012, Nodejitsu Inc. - * - */ - -var prompt = require('../lib/prompt'); - -// -// Start the prompt -// -prompt.start(); - -var property = { - name: 'yesno', - message: 'are you sure?', - validator: /y[es]*|n[o]?/, - warning: 'Must respond yes or no', - default: 'no' -}; - -// -// Get the simple yes or no property -// -prompt.get(property, function (err, result) { - // - // Log the results. - // - console.log('Command-line input received:'); - console.log(' result: ' + result.yesno); -}); \ No newline at end of file diff --git a/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js b/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js deleted file mode 100644 index df28f82..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/lib/prompt.js +++ /dev/null @@ -1,822 +0,0 @@ -/* - * prompt.js: Simple prompt for prompting information from the command line - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var events = require('events'), - readline = require('readline'), - eachSeries = require('async/eachSeries'), - rejectSeries = require('async/rejectSeries'), - read = require('read'), - validate = require('revalidator').validate, - winston = require('winston'), - colors = require('@colors/colors/safe'); - -// -// Monkey-patch readline.Interface to work-around -// https://github.com/joyent/node/issues/3860 -// -readline.Interface.prototype.setPrompt = function(prompt, length) { - this._prompt = prompt; - if (length) { - this._promptLength = length; - } else { - var lines = prompt.split(/[\r\n]/); - var lastLine = lines[lines.length - 1]; - this._promptLength = lastLine.replace(/\u001b\[(\d+(;\d+)*)?m/g, '').length; - } -}; - -// -// Expose version using `pkginfo` -// -module.exports.version = require('../package.json').version; - -var stdin, stdout, history = []; -var prompt = module.exports = Object.create(events.EventEmitter.prototype); -var logger = prompt.logger = new winston.Logger({ - transports: [new (winston.transports.Console)()] -}); - -prompt.started = false; -prompt.paused = false; -prompt.stopped = true; -prompt.allowEmpty = false; -prompt.message = 'prompt'; -prompt.delimiter = ': '; -prompt.colors = true; - -// -// Create an empty object for the properties -// known to `prompt` -// -prompt.properties = {}; - -// -// Setup the default winston logger to use -// the `cli` levels and colors. -// -logger.cli(); - -// -// ### function start (options) -// #### @options {Object} **Optional** Options to consume by prompt -// Starts the prompt by listening to the appropriate events on `options.stdin` -// and `options.stdout`. If no streams are supplied, then `process.stdin` -// and `process.stdout` are used, respectively. -// -prompt.start = function (options) { - if (prompt.started) { - return; - } - - options = options || {}; - stdin = options.stdin || process.stdin; - stdout = options.stdout || process.stdout; - - // - // By default: Remember the last `10` prompt property / - // answer pairs and don't allow empty responses globally. - // - prompt.memory = options.memory || 10; - prompt.allowEmpty = options.allowEmpty || false; - prompt.message = options.message || prompt.message; - prompt.delimiter = options.delimiter || prompt.delimiter; - prompt.colors = options.colors || prompt.colors; - - if (!options.noHandleSIGINT) { - if (process.platform !== 'win32') { - // windows falls apart trying to deal with SIGINT - process.on('SIGINT', function () { - stdout.write('\n'); - process.exit(1); - }); - } else { - // listen for the "Ctrl+C" key combination and trigger process event. - // See https://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js - stdin.on('keypress', function(char, key) { - if (key && key.ctrl && key.name == 'c') { - stdout.write('\n'); - process.emit("SIGINT"); - process.exit(1); - } - }); - } - } - - prompt.emit('start'); - prompt.started = true; - prompt.stopped = false; - return prompt; -}; - -// -// ### function pause () -// Pauses input coming in from stdin -// -prompt.pause = function () { - if (!prompt.started || prompt.stopped || prompt.paused) { - return; - } - - stdin.pause(); - prompt.emit('pause'); - prompt.paused = true; - return prompt; -}; - -// -// ### function stop () -// Stops input coming in from stdin -// -prompt.stop = function () { - if (prompt.stopped || !prompt.started) { - return; - } - - stdin.destroy(); - prompt.emit('stop'); - prompt.stopped = true; - prompt.started = false; - prompt.paused = false; - return prompt; -} - -// -// ### function resume () -// Resumes input coming in from stdin -// -prompt.resume = function () { - if (!prompt.started || !prompt.paused) { - return; - } - - stdin.resume(); - prompt.emit('resume'); - prompt.paused = false; - return prompt; -}; - -// -// ### function history (search) -// #### @search {Number|string} Index or property name to find. -// Returns the `property:value` pair from within the prompts -// `history` array. -// -prompt.history = function (search) { - if (typeof search === 'number') { - return history[search] || {}; - } - - var names = history.map(function (pair) { - return typeof pair.property === 'string' - ? pair.property - : pair.property.name; - }); - - if (!~names.indexOf(search)) { - return null; - } - - return history.filter(function (pair) { - return typeof pair.property === 'string' - ? pair.property === search - : pair.property.name === search; - })[0]; -}; - -// -// ### function get (schema, callback) -// #### @schema {Array|Object|string} Set of variables to get input for. -// #### @callback {function} Continuation to pass control to when complete. -// Gets input from the user via stdin for the specified message(s) `msg`. -// -prompt.get = function (schema, callback) { - if (typeof callback === 'function') return prompt._get(schema, callback); - - return new Promise(function (resolve, reject) { - prompt._get(schema, function (err, result) { - return err ? reject(err) : resolve(result); - }); - }); -}; - -prompt._get = function (schema, callback) { - // - // Transforms a full JSON-schema into an array describing path and sub-schemas. - // Used for iteration purposes. - // - function untangle(schema, path) { - var results = []; - path = path || []; - - if (schema.properties) { - // - // Iterate over the properties in the schema and use recursion - // to process sub-properties. - // - Object.keys(schema.properties).forEach(function (key) { - var obj = {}; - obj[key] = schema.properties[key]; - - // - // Concat a sub-untangling to the results. - // - results = results.concat(untangle(obj[key], path.concat(key))); - }); - - // Return the results. - return results; - } - - // - // This is a schema "leaf". - // - return { - path: path, - schema: schema - }; - } - - // - // Iterate over the values in the schema, represented as - // a legit single-property object subschemas. Accepts `schema` - // of the forms: - // - // 'prop-name' - // - // ['string-name', { path: ['or-well-formed-subschema'], properties: ... }] - // - // { path: ['or-well-formed-subschema'], properties: ... ] } - // - // { properties: { 'schema-with-no-path' } } - // - // And transforms them all into - // - // { path: ['path', 'to', 'property'], properties: { path: { to: ...} } } - // - function iterate(schema, get, done) { - var iterator = [], - result = {}; - - if (typeof schema === 'string') { - // - // We can iterate over a single string. - // - iterator.push({ - path: [schema], - schema: prompt.properties[schema.toLowerCase()] || {} - }); - } - else if (Array.isArray(schema)) { - // - // An array of strings and/or single-prop schema and/or no-prop schema. - // - iterator = schema.map(function (element) { - if (typeof element === 'string') { - return { - path: [element], - schema: prompt.properties[element.toLowerCase()] || {} - }; - } - else if (element.properties) { - return { - path: [Object.keys(element.properties)[0]], - schema: element.properties[Object.keys(element.properties)[0]] - }; - } - else if (element.path && element.schema) { - return element; - } - else { - return { - path: [element.name || 'question'], - schema: element - }; - } - }); - } - else if (schema.properties) { - // - // Or a complete schema `untangle` it for use. - // - iterator = untangle(schema); - } - else { - // - // Or a partial schema and path. - // TODO: Evaluate need for this option. - // - iterator = [{ - schema: schema.schema ? schema.schema : schema, - path: schema.path || [schema.name || 'question'] - }]; - } - - // - // Now, iterate and assemble the result. - // - eachSeries(iterator, function (branch, next) { - get(branch, function assembler(err, line) { - if (err) { - return next(err); - } - - function build(path, line) { - var obj = {}; - if (path.length) { - obj[path[0]] = build(path.slice(1), line); - return obj; - } - - return line; - } - - function attach(obj, attr) { - var keys; - if (typeof attr !== 'object' || attr instanceof Array) { - return attr; - } - - keys = Object.keys(attr); - if (keys.length) { - if (!obj[keys[0]]) { - obj[keys[0]] = {}; - } - obj[keys[0]] = attach(obj[keys[0]], attr[keys[0]]); - } - - return obj; - } - - result = attach(result, build(branch.path, line)); - next(); - }); - }, function (err) { - return err ? done(err) : done(null, result); - }); - } - - iterate(schema, function get(target, next) { - prompt.getInput(target, function (err, line) { - return err ? next(err) : next(null, line); - }); - }, callback); - - return prompt; -}; - -// -// ### function confirm (msg, callback) -// #### @msg {Array|Object|string} set of message to confirm -// #### @callback {function} Continuation to pass control to when complete. -// Confirms a single or series of messages by prompting the user for a Y/N response. -// Returns `true` if ALL messages are answered in the affirmative, otherwise `false` -// -// `msg` can be a string, or object (or array of strings/objects). -// An object may have the following properties: -// -// { -// description: 'yes/no' // message to prompt user -// pattern: /^[yntf]{1}/i // optional - regex defining acceptable responses -// yes: /^[yt]{1}/i // optional - regex defining `affirmative` responses -// message: 'yes/no' // optional - message to display for invalid responses -// } -// -prompt.confirm = function (/* msg, options, callback */) { - var args = Array.prototype.slice.call(arguments), - msg = args.shift(), - callback = args.pop(), - opts = args.shift(), - vars = !Array.isArray(msg) ? [msg] : msg, - RX_Y = /^[yt]{1}/i, - RX_YN = /^[yntf]{1}/i; - - function confirm(target, next) { - var yes = target.yes || RX_Y, - options = { - description: typeof target === 'string' ? target : target.description || 'yes/no', - pattern: target.pattern || RX_YN, - name: 'confirm', - message: target.message || 'yes/no' - }; - - for (var k in (opts || {})) { - if (opts.hasOwnProperty(k)) { - options[k] = opts[k]; - } - } - - prompt.get([options], function (err, result) { - next(null, err ? false : yes.test(result[options.name])); - }); - } - - rejectSeries(vars, confirm, function(err, result) { - callback(null, result.length===0); - }); -}; - - -// Variables needed outside of getInput for multiline arrays. -var tmp = []; - - -// ### function getInput (prop, callback) -// #### @prop {Object|string} Variable to get input for. -// #### @callback {function} Continuation to pass control to when complete. -// Gets input from the user via stdin for the specified message `msg`. -// -prompt.getInput = function (prop, callback) { - var schema = prop.schema || prop, - propName = prop.path && prop.path.join(':') || prop, - storedSchema = prompt.properties[propName.toLowerCase()], - delim = prompt.delimiter, - defaultLine, - against, - hidden, - length, - valid, - name, - raw, - msg; - - // - // If there is a stored schema for `propName` in `propmpt.properties` - // then use it. - // - if (schema instanceof Object && !Object.keys(schema).length && - typeof storedSchema !== 'undefined') { - schema = storedSchema; - } - - // - // Build a proper validation schema if we just have a string - // and no `storedSchema`. - // - if (typeof prop === 'string' && !storedSchema) { - schema = {}; - } - - schema = convert(schema); - defaultLine = schema.default; - name = prop.description || schema.description || propName; - raw = prompt.colors - ? [colors.grey(name), colors.grey(delim)] - : [name, delim]; - - if (prompt.message) - raw.unshift(prompt.message, delim); - - prop = { - schema: schema, - path: propName.split(':') - }; - - // - // If the schema has no `properties` value then set - // it to an object containing the current schema - // for `propName`. - // - if (!schema.properties) { - schema = (function () { - var obj = { properties: {} }; - obj.properties[propName] = schema; - return obj; - })(); - } - - // - // Handle overrides here. - // TODO: Make overrides nestable - // - if (prompt.override && prompt.override.hasOwnProperty(propName)) { - if (prompt._performValidation(name, prop, prompt.override, schema, -1, callback)) { - return callback(null, prompt.override[propName]); - } - - delete prompt.override[propName]; - } - - // - // Check if we should skip this prompt - // - if (typeof prop.schema.ask === 'function' && - !prop.schema.ask()) { - return callback(null, prop.schema.default || ''); - } - - var type = (schema.properties && schema.properties[propName] && - schema.properties[propName].type || '').toLowerCase().trim(), - wait = type === 'array'; - - if (type === 'array') { - length = prop.schema.maxItems; - if (length) { - msg = (tmp.length + 1).toString() + '/' + length.toString(); - } - else { - msg = (tmp.length + 1).toString(); - } - msg += delim; - raw.push(prompt.colors ? colors.grey(msg) : msg); - } - - // - // Calculate the raw length and colorize the prompt - // - length = raw.join('').length; - // raw[0] = raw[0]; - msg = raw.join(''); - - if (schema.help) { - schema.help.forEach(function (line) { - logger.help(line); - }); - } - - // - // Emit a "prompting" event - // - prompt.emit('prompt', prop); - - // - // If defaultLine is a function, execute it and store it back to defaultLine - // - if(typeof defaultLine === 'function') { - defaultLine = defaultLine(); - } - - // - // If there is no default line, set it to an empty string - // - if(typeof defaultLine === 'undefined') { - defaultLine = ''; - } - - // - // set to string for readline ( will not accept Numbers ) - // - defaultLine = defaultLine.toString(); - - // - // Make the actual read - // - read({ - prompt: msg, - silent: prop.schema && prop.schema.hidden, - replace: prop.schema && prop.schema.replace, - default: defaultLine, - input: stdin, - output: stdout - }, function (err, line) { - if (err && wait === false) { - return callback(err); - } - - var against = {}, - numericInput, - isValid; - - if (line !== '') { - - if (schema.properties[propName]) { - var type = (schema.properties[propName].type || '').toLowerCase().trim() || undefined; - - // - // If type is some sort of numeric create a Number object to pass to revalidator - // - if (type === 'number' || type === 'integer') { - line = Number(line); - } - - // - // Attempt to parse input as a boolean if the schema expects a boolean - // - if (type == 'boolean') { - if(line.toLowerCase() === "true" || line.toLowerCase() === 't') { - line = true; - } else if(line.toLowerCase() === "false" || line.toLowerCase() === 'f') { - line = false; - } - } - - // - // If the type is an array, wait for the end. Fixes #54 - // - if (type == 'array') { - var length = prop.schema.maxItems; - if (err) { - if (err.message == 'canceled') { - wait = false; - stdout.write('\n'); - } - } - else { - if (length) { - if (tmp.length + 1 < length) { - isValid = false; - wait = true; - } - else { - isValid = true; - wait = false; - } - } - else { - isValid = false; - wait = true; - } - tmp.push(line); - } - line = tmp; - } - } - - against[propName] = line; - } - - if (prop && prop.schema.before) { - line = prop.schema.before(line); - } - - // Validate - if (isValid === undefined) isValid = prompt._performValidation(name, prop, against, schema, line, callback); - - if (!isValid) { - return prompt.getInput(prop, callback); - } - - // - // Log the resulting line, append this `property:value` - // pair to the history for `prompt` and respond to - // the callback. - // - logger.input(line.yellow); - prompt._remember(propName, line); - callback(null, line); - - // Make sure `tmp` is emptied - tmp = []; - }); -}; - -// -// ### function performValidation (name, prop, against, schema, line, callback) -// #### @name {Object} Variable name -// #### @prop {Object|string} Variable to get input for. -// #### @against {Object} Input -// #### @schema {Object} Validation schema -// #### @line {String|Boolean} Input line -// #### @callback {function} Continuation to pass control to when complete. -// Perfoms user input validation, print errors if needed and returns value according to validation -// -prompt._performValidation = function (name, prop, against, schema, line, callback) { - var numericInput, valid, msg; - try { - valid = validate(against, schema); - } - catch (err) { - return (line !== -1) ? callback(err) : false; - } - - if (!valid.valid) { - if (prop.schema.message) { - logger.error(prop.schema.message); - } else { - msg = line !== -1 ? 'Invalid input for ' : 'Invalid command-line input for '; - - if (prompt.colors) { - logger.error(msg + colors.grey(name)); - } - else { - logger.error(msg + name); - } - } - - prompt.emit('invalid', prop, line); - } - - return valid.valid; -}; - -// -// ### function addProperties (obj, properties, callback) -// #### @obj {Object} Object to add properties to -// #### @properties {Array} List of properties to get values for -// #### @callback {function} Continuation to pass control to when complete. -// Prompts the user for values each of the `properties` if `obj` does not already -// have a value for the property. Responds with the modified object. -// -prompt.addProperties = function (obj, properties, callback) { - properties = properties.filter(function (prop) { - return typeof obj[prop] === 'undefined'; - }); - - if (properties.length === 0) { - return callback(null, obj); - } - - prompt.get(properties, function (err, results) { - if (err) { - return callback(err); - } - else if (!results) { - return callback(null, obj); - } - - function putNested (obj, path, value) { - var last = obj, key; - - while (path.length > 1) { - key = path.shift(); - if (!last[key]) { - last[key] = {}; - } - - last = last[key]; - } - - last[path.shift()] = value; - } - - Object.keys(results).forEach(function (key) { - putNested(obj, key.split('.'), results[key]); - }); - - callback(null, obj); - }); - - return prompt; -}; - -// -// ### @private function _remember (property, value) -// #### @property {Object|string} Property that the value is in response to. -// #### @value {string} User input captured by `prompt`. -// Prepends the `property:value` pair into the private `history` Array -// for `prompt` so that it can be accessed later. -// -prompt._remember = function (property, value) { - history.unshift({ - property: property, - value: value - }); - - // - // If the length of the `history` Array - // has exceeded the specified length to remember, - // `prompt.memory`, truncate it. - // - if (history.length > prompt.memory) { - history.splice(prompt.memory, history.length - prompt.memory); - } -}; - -// -// ### @private function convert (schema) -// #### @schema {Object} Schema for a property -// Converts the schema into new format if it is in old format -// -function convert(schema) { - var newProps = Object.keys(validate.messages), - newSchema = false, - key; - - newProps = newProps.concat(['description', 'dependencies']); - - for (key in schema) { - if (newProps.indexOf(key) > 0) { - newSchema = true; - break; - } - } - - if (!newSchema || schema.validator || schema.warning || typeof schema.empty !== 'undefined') { - if(typeof schema.message !== 'undefined'){ - schema.description = schema.message; - } - - if(typeof schema.warning !== 'undefined'){ - schema.message = schema.warning; - } - - if (typeof schema.validator === 'function') { - schema.conform = schema.validator; - } else { - schema.pattern = schema.validator; - } - - if (typeof schema.empty !== 'undefined') { - schema.required = !(schema.empty); - } - - delete schema.warning; - delete schema.validator; - delete schema.empty; - } - - return schema; -} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/package.json b/Challenge/seokahi/010.star/node_modules/prompt/package.json deleted file mode 100644 index f101c6b..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "prompt", - "version": "1.3.0", - "description": "A beautiful command-line prompt for node.js", - "author": "Nodejitsu Inc. ", - "maintainers": [ - "indexzero ", - "jesusabdullah " - ], - "repository": { - "type": "git", - "url": "http://github.com/flatiron/prompt.git" - }, - "keywords": [ - "prompt", - "command-line", - "customize", - "validation" - ], - "dependencies": { - "@colors/colors": "1.5.0", - "async": "3.2.3", - "read": "1.0.x", - "revalidator": "0.1.x", - "winston": "2.x" - }, - "devDependencies": { - "eslint": "^7.32.0", - "vows": "^0.7.0" - }, - "main": "./lib/prompt", - "scripts": { - "test": "vows test/prompt-test.js --spec", - "test-all": "vows --spec" - }, - "license": "MIT", - "engines": { - "node": ">= 6.0.0" - } -} diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js b/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js deleted file mode 100644 index 404ebe8..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/test/helpers.js +++ /dev/null @@ -1,177 +0,0 @@ -/* - * helpers.js: test helpers for the prompt tests. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var stream = require('stream'), - util = require('util'), - prompt = require('../lib/prompt'); - -var helpers = exports; - -var MockReadWriteStream = helpers.MockReadWriteStream = function () { - // - // No need to do anything here, it's just a mock. - // - var self = this; - this.on('pipe', function (src) { - var _emit = src.emit; - src.emit = function () { - //console.dir(arguments); - _emit.apply(src, arguments); - }; - - src.on('data', function (d) { - self.emit('data', d + ''); - }) - }) -}; - -util.inherits(MockReadWriteStream, stream.Stream); - -['resume', 'pause', 'setEncoding', 'flush', 'end'].forEach(function (method) { - MockReadWriteStream.prototype[method] = function () { /* Mock */ }; -}); - -MockReadWriteStream.prototype.write = function (msg) { - this.emit('data', msg); - return true; -}; - -MockReadWriteStream.prototype.writeNextTick = function (msg) { - var self = this - process.nextTick(function () { - self.write(msg); - }); -}; - -// -// Create some mock streams for asserting against -// in our prompt teSts. -// -helpers.stdin = new MockReadWriteStream(); -helpers.stdout = new MockReadWriteStream(); -helpers.stderr = new MockReadWriteStream(); - -// -// Because `read` uses a `process.nextTick` for reading from -// stdin, it is necessary to write sequences of input with extra -// `process.nextTick` calls -// -helpers.stdin.writeSequence = function (lines) { - if (!lines || !lines.length) { - return; - } - - helpers.stdin.writeNextTick(lines.shift()); - prompt.once('prompt', function () { - process.nextTick(function () { - helpers.stdin.writeSequence(lines); - }); - }); -} - -// -// Monkey punch `util.error` to silence console output -// and redirect to helpers.stderr for testing. -// -process.stderr.write = function () { - helpers.stderr.write.apply(helpers.stderr, arguments); -} - -// 1) .properties -// 2) warning --> message -// 3) Name --> description || key -// 4) validator --> conform (fxns), pattern (regexp), format (built-in) -// 5) empty --> required -helpers.schema = { - properties: { - oldschema: { - message: 'Enter your username', - validator: /^[\w|-]+$/, - warning: 'username can only be letters, numbers, and dashes', - empty: false - }, - riffwabbles: { - pattern: /^[\w|-]+$/, - message: 'riffwabbles can only be letters, numbers, and dashes', - default: 'foobizzles' - }, - functiondefaultpluralanimal: { - message: 'function default plural animal', - default: function () { - return prompt.history('animal').value + 's'; - } - }, - functiondefaulttest: { - message: 'function default test', - default: function () { - return 'test'; - } - }, - functiondefaultundefined: { - message: 'function default undefined', - default: function () { } - }, - number: { - type: 'number', - message: 'pick a number, any number', - default: 10 - }, - integer: { - type: 'integer' - }, - boolean: { - type: 'boolean' - }, - username: { - pattern: /^[\w|-]+$/, - message: 'Username can only be letters, numbers, and dashes' - }, - notblank: { - required: true - }, - password: { - hidden: true, - required: true - }, - badValidator: { - pattern: ['cant', 'use', 'array'] - }, - animal: { - description: 'Enter an animal', - default: 'dog', - pattern: /dog|cat/ - }, - sound: { - description: 'What sound does this animal make?', - conform: function (value) { - var animal = prompt.history(0).value; - - return animal === 'dog' && value === 'woof' - || animal === 'cat' && value === 'meow'; - } - }, - fnvalidator: { - name: 'fnvalidator', - validator: function (line) { - return line.slice(0,2) == 'fn'; - }, - message: 'fnvalidator must start with "fn"' - }, - fnconform: { - conform: function (line) { - return line.slice(0,2) == 'fn'; - }, - message: 'fnconform must start with "fn"' - }/*, - cbvalidator: { - conform: function (line, next) { - next(line.slice(0,2) == 'cb'); - }, - message: 'cbvalidator must start with "cb"' - }*/ - } -}; diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js b/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js deleted file mode 100644 index a3032e3..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/test/interactive-prompt-test.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * prompt-test.js: Tests for prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var assert = require('assert'), - vows = require('vows'), - prompt = require('../lib/prompt'), - winston = require('winston').cli(), - helpers = require('./helpers'); - -vows.describe('prompt/interactive').addBatch({ - "When using prompt": { - topic: function () { - // - // Reset the prompt for interactive testing - // - prompt.started = false; - prompt.start(); - winston.info('These prompt tests are interactive'); - winston.info('Not following instructions will result in test failure'); - return null; - }, - "the getInput() method": { - "when passed a complex property with `hidden: true`": { - topic: function () { - winston.info('When prompted, enter: 12345 [backspace] [backspace] [enter]'); - prompt.getInput({ path: ['password'], schema: helpers.schema.properties.password }, this.callback); - }, - "should respond with `123`": function (err, result) { - assert.isNull(err); - assert.equal(result, '123'); - }, - "and then when passed a complex property expecting a number": { - topic: function () { - winston.info('When prompted, enter: 123 [enter]'); - prompt.getInput({ path: ['number'], schema: helpers.schema.properties.number }, this.callback); - }, - "should respond with `123` (as a number)": function (err, result) { - assert.isNull(err); - assert.equal(result, 123); - } - } - } - } - } -}).export(module); diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js b/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js deleted file mode 100644 index 9f58f08..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/test/macros.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * macros.js: Test macros for prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var assert = require('assert'), - helpers = require('./helpers'), - prompt = require('../lib/prompt'); - -exports.shouldConfirm = function (options, mixin) { - var message = options.response.toString().replace(/\n/g, ''), - messages = ["When using prompt", "the confirm() method"], - context = {}, - last = context; - - messages = messages.concat(options.messages || []); - - while (messages.length) { - var text = messages.shift(); - last[text] = {}; - last = last[text]; - } - - last['responding with ' + message] = { - topic: function () { - if(!mixin) - prompt.confirm(options.prop, this.callback); - else - prompt.confirm(options.prop, mixin, this.callback); - - if (!Array.isArray(options.response)) { - helpers.stdin.writeNextTick(options.response + '\n'); - } - else { - helpers.stdin.writeSequence(options.response); - } - }, - "should respond with true" : function(err, result) { - assert.isNull(err); - assert.isTrue(result); - } - } - - return context; -}; - -exports.shouldNotConfirm = function (options) { - var message = options.response.toString().replace(/\n/g, ''), - messages = ["When using prompt", "the confirm() method"], - context = {}, - last = context; - - messages = messages.concat(options.messages || []); - - while (messages.length) { - var text = messages.shift(); - last[text] = {}; - last = last[text]; - } - - last['responding with ' + message] = { - topic: function () { - prompt.confirm(options.prop, this.callback); - - if (!Array.isArray(options.response)) { - helpers.stdin.writeNextTick(options.response + '\n'); - } - else { - helpers.stdin.writeSequence(options.response); - } - }, - "should respond with false" : function(err, result) { - assert.isNull(err); - assert.isFalse(result); - } - }; - - return context; -}; - diff --git a/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js b/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js deleted file mode 100644 index 1e9ab81..0000000 --- a/Challenge/seokahi/010.star/node_modules/prompt/test/prompt-test.js +++ /dev/null @@ -1,960 +0,0 @@ -/* - * prompt-test.js: Tests for prompt. - * - * (C) 2010, Nodejitsu Inc. - * - */ - -var assert = require('assert'), - vows = require('vows'), - prompt = require('../lib/prompt'), - helpers = require('./helpers'), - macros = require('./macros'), - schema = helpers.schema; - -// fix for vows, util.print/puts was removed from node -require('util').print = console.log; -require('util').puts = console.log; - -// A helper to pass fragments of our schema into prompt as full schemas. -function grab () { - var names = [].slice.call(arguments), - complete = { schema: {} }; - - names.forEach(function (name) { - complete.path = [name]; - complete.schema = schema.properties[name]; - }); - return complete; -} - -// -// Reset the prompt for mock testing -// -prompt.started = false; -prompt.start({ - stdin: helpers.stdin, - stdout: helpers.stdout -}); - -vows.describe('prompt').addBatch({ - "When using prompt": { - "the getInput() method": { - "with a simple string prompt": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }) - - prompt.getInput('test input', this.callback); - helpers.stdin.writeNextTick('test value\n'); - }, - "should prompt to stdout and respond with data": function (err, input) { - assert.isNull(err); - assert.equal(input, 'test value'); - assert.isTrue(this.msg.indexOf('test input') !== -1); - } - }, - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with any field that is not supposed to be empty": { - "and we don't provide any input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - helpers.stderr.once('data', function (msg) { - that.errmsg = msg; - }); - - prompt.getInput(grab('notblank'), function () {}); - prompt.once('invalid', this.callback.bind(null, null)) - helpers.stdin.writeNextTick('\n'); - }, - "should prompt with an error": function (_, prop, input) { - assert.isObject(prop); - assert.equal(input, ''); - assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); - assert.isTrue(this.msg.indexOf('notblank') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a hidden field that is not supposed to be empty": { - "and we provide valid input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.getInput('password', this.callback); - helpers.stdin.writeNextTick('trustno1\n'); - }, - - "should prompt to stdout and respond with data": function (err, input) { - assert.isNull(err); - assert.equal(input, 'trustno1'); - assert.isTrue(this.msg.indexOf('password') !== -1); - } - }, - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a hidden field that is not supposed to be empty": { - "and we don't provide an input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - helpers.stderr.once('data', function (msg) { - that.errmsg = msg; - }); - - prompt.getInput(grab('password'), function () {} ); - prompt.once('invalid', this.callback.bind(null, null)) - helpers.stdin.writeNextTick('\n'); - }, - "should prompt with an error": function (ign, prop, input) { - assert.isObject(prop); - assert.equal(input, ''); - assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); - assert.isTrue(this.msg.indexOf('password') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with an integer field": { - "and we provide valid input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.getInput(grab('integer'), this.callback); - helpers.stdin.writeNextTick('42\n'); - }, - "should prompt to stdout and respond with data": function (err, input) { - assert.isNull(err); - assert.equal(input, '42'); - assert.isTrue(this.msg.indexOf('integer') !== -1); - } - }, - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with an integer field": { - "and we don't provide an integer": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - helpers.stderr.once('data', function (msg) { - that.errmsg = msg; - }) - - prompt.getInput(grab('integer'), this.callback); - - prompt.once('invalid', function () { - prompt.once('prompt', function () { - process.nextTick(function () { - helpers.stdin.writeNextTick('42\n'); - }) - }) - }); - - helpers.stdin.writeNextTick('4.2\n'); - }, - "should prompt with an error before completing the operation": function (err, input) { - assert.isNull(err); - assert.equal(input, '42'); - assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); - assert.isTrue(this.msg.indexOf('integer') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a boolean field": { - "and we provide valid input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.getInput(grab('boolean'), this.callback); - helpers.stdin.writeNextTick('true\n'); - }, - "should prompt to stdout and respond with data": function (err, input) { - assert.isNull(err); - assert.equal(input, true); - assert.isTrue(this.msg.indexOf('boolean') !== -1); - } - }, - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a boolean field": { - "and we don't provide an bool": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - helpers.stderr.once('data', function (msg) { - that.errmsg = msg; - }) - - prompt.getInput(grab('boolean'), this.callback); - - prompt.once('invalid', function () { - prompt.once('prompt', function () { - process.nextTick(function () { - helpers.stdin.writeNextTick('F\n'); - }) - }) - }); - - helpers.stdin.writeNextTick('4.2\n'); - }, - "should prompt with an error before completing the operation": function (err, input) { - assert.isNull(err); - assert.equal(input, false); - assert.isTrue(this.errmsg.indexOf('Invalid input') !== -1); - assert.isTrue(this.msg.indexOf('boolean') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a complex property prompt": { - "and a valid input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.getInput(grab('username'), this.callback); - helpers.stdin.writeNextTick('some-user\n'); - }, - "should prompt to stdout and respond with data": function (err, input) { - assert.isNull(err); - assert.equal(input, 'some-user'); - assert.isTrue(this.msg.indexOf('username') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a complex property prompt": { - "and an invalid input": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - helpers.stderr.once('data', function (msg) { - that.errmsg = msg; - }) - - prompt.getInput(grab('username'), this.callback); - - prompt.once('invalid', function () { - prompt.once('prompt', function () { - process.nextTick(function () { - helpers.stdin.writeNextTick('some-user\n'); - }) - }) - }); - - helpers.stdin.writeNextTick('some -user\n'); - }, - "should prompt with an error before completing the operation": function (err, input) { - assert.isNull(err); - assert.equal(input, 'some-user'); - assert.isTrue(this.errmsg.indexOf('Username can only be letters, numbers, and dashes') !== -1); - assert.isTrue(this.msg.indexOf('username') !== -1); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the getInput() method": { - "with a complex property prompt": { - "with an invalid validator (array)": { - topic: function () { - var that = this, - called; - - prompt.getInput(grab('badValidator'), function (err) { - if (!called) { - called = true; - that.callback(err); - } - }); - helpers.stdin.writeNextTick('some-user\n'); - }, - "should respond with an error": function (err, ign) { - assert.isTrue(!!err); - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is not a property in prompt.properties": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }) - - prompt.get('test input', this.callback); - helpers.stdin.writeNextTick('test value\n'); - }, - "should prompt to stdout and respond with the value": function (err, result) { - assert.isNull(err); - assert.include(result, 'test input'); - assert.equal(result['test input'], 'test value'); - assert.isTrue(this.msg.indexOf('test input') !== -1); - } - }, - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a string literal default value": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.properties.riffwabbles = schema.properties.riffwabbles; - prompt.get('riffwabbles', this.callback); - helpers.stdin.writeNextTick('\n'); - }, - "should prompt to stdout and respond with the default value": function (err, result) { - assert.isNull(err); - assert.notStrictEqual(this.msg.indexOf('riffwabbles'), -1); - assert.notStrictEqual(this.msg.indexOf('(foobizzles)'), -1); - assert.include(result, 'riffwabbles'); - assert.equal(result['riffwabbles'], schema.properties['riffwabbles'].default); - } - }, - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a function default returning a string literal": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.properties.functiondefaulttest = schema.properties.functiondefaulttest; - prompt.get('functionDefaultTest', this.callback); - helpers.stdin.writeNextTick('\n'); - }, - "should respond with the default value function's return value": function (err, result) { - assert.isNull(err); - assert.notStrictEqual(this.msg.indexOf('function default test'), -1); - assert.notStrictEqual(this.msg.indexOf('(test)'), -1); - assert.include(result, 'functionDefaultTest'); - assert.strictEqual(result['functionDefaultTest'], 'test'); - } - }, - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a function default returning a string literal": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - // we really need the second message, so we'll - // ignore the first and look out for the second - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }) - }); - - prompt.properties.animal = schema.properties.animal; - prompt.properties.functiondefaultpluralanimal = - schema.properties.functiondefaultpluralanimal; - prompt.get(['animal', 'functiondefaultpluralanimal'], this.callback); - helpers.stdin.writeSequence(['cat\n', '\n']); - }, - "should respond with the default value function's return value": function (err, result) { - assert.isNull(err); - assert.notStrictEqual(this.msg.indexOf('function default plural animal'), -1); - assert.notStrictEqual(this.msg.indexOf('(cats)'), -1); - assert.strictEqual(result['animal'], 'cat'); - assert.include(result, 'functiondefaultpluralanimal'); - assert.strictEqual(result['functiondefaultpluralanimal'], 'cats'); - } - }, - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a function default that returns undefined": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.properties.functiondefaultundefined = - schema.properties.functiondefaultundefined; - prompt.get('functionDefaultUndefined', this.callback); - helpers.stdin.writeNextTick('\n'); - }, - "should prompt without a default value": function (err, result) { - assert.isNull(err); - assert.notStrictEqual(this.msg.indexOf('function default undefined'), -1); - assert.strictEqual(this.msg.indexOf('('), -1); - assert.include(result, 'functionDefaultUndefined'); - assert.strictEqual(result['functionDefaultUndefined'], ''); - } - }, - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "that expects a numeric value": { - "and gets valid input": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.properties.number = schema.properties.number; - prompt.get('number', this.callback); - helpers.stdin.writeNextTick('15\n'); - }, - "should prompt to stdout and respond with a numeric value": function (err, result) { - assert.isNull(err); - assert.include(result, 'number'); - assert.equal(result['number'], 15); - } - } - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a sync function validator (.validator)": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.get(helpers.schema.properties.fnvalidator, this.callback); - helpers.stdin.writeNextTick('fn123\n'); - }, - "should accept a value that is checked": function (err, result) { - assert.isNull(err); - assert.equal(result['fnvalidator'],'fn123'); - } - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a sync function validator (.conform)": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.get(grab('fnconform'), this.callback); - helpers.stdin.writeNextTick('fn123\n'); - }, - "should accept a value that is checked": function (err, result) { - assert.isNull(err); - assert.equal(result['fnconform'],'fn123'); - } - } - // - // Remark Does not work with revalidator - // - // "with a callback validator": { - // topic: function () { - // var that = this; - // - // helpers.stdout.once('data', function (msg) { - // that.msg = msg; - // }); - // - // prompt.get(grab('cbvalidator'), this.callback); - // helpers.stdin.writeNextTick('cb123\n'); - // }, - // "should not accept a value that is correct": function (err, result) { - // assert.isNull(err); - // assert.equal(result['cbvalidator'],'cb123'); - // } - // } - } - }, - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with a simple string prompt": { - "that is a property name in prompt.properties": { - "with a sync function before (.before)": { - topic: function() { - var that = this; - - helpers.stdout.once('data', function(msg) { - that.msg = msg; - }); - - prompt.get({ - properties: { - fnbefore: { - before: function(v) { - return 'v' + v; - } - } - } - }, this.callback); - helpers.stdin.writeNextTick('fn456\n'); - }, - "should modify user's input": function(e, result) { - assert.equal(result.fnbefore, 'vfn456'); - } - } - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "skip prompt with prompt.overide": { - topic: function () { - prompt.override = { coconihet: 'whatever' } - prompt.get('coconihet', this.callback); - }, - "skips prompt and uses overide": function (err, results) { - assert.equal(results.coconihet, 'whatever') - } - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "skip prompt with falsy prompt.overide": { - topic: function () { - prompt.override = { coconihet: false } - prompt.get('coconihet', this.callback); - }, - "skips prompt and uses overide": function (err, results) { - assert.equal(results.coconihet, false) - } - } - } - } -}).addBatch({ - "When using prompt": { - "the addProperties() method": { - topic: function () { - prompt.addProperties({}, ['foo', 'bar'], this.callback); - helpers.stdin.writeSequence(['foo\n', 'bar\n']); - }, - "should add the properties to the object": function (err, obj) { - assert.isNull(err); - assert.isObject(obj); - assert.equal(obj.foo, 'foo'); - assert.equal(obj.bar, 'bar'); - } - } - } -}).addBatch({ - "When using prompt": { - "the addProperties() method": { - topic: function () { - prompt.addProperties({'foo': 'foo', 'bar': 'bar'}, [], this.callback); - }, - "should return the object as-is when no properties provided": function (err, obj) { - assert.isNull(err); - assert.isObject(obj); - assert.equal(obj.foo, 'foo'); - assert.equal(obj.bar, 'bar'); - } - } - } -}).addBatch({ - "When using prompt": { - "the get() method": { - "with old schema": { - topic: function () { - var that = this; - - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.properties.username = schema.properties.oldschema; - prompt.get('username', this.callback); - - helpers.stdin.writeSequence(['\n', 'hell$\n', 'hello\n']); - }, - "should prompt to stdout and respond with the default value": function (err, result) { - assert.isNull(err); - assert.isTrue(this.msg.indexOf('username') !== -1); - assert.include(result, 'username'); - assert.equal(result.username, 'hello'); - } - } - } - } -}).addBatch({ - "When using prompt": { - "the history() method": { - "when used inside of a complex property": { - "with correct value(s)": { - topic: function () { - prompt.get([grab('animal'), grab('sound')], this.callback); - helpers.stdin.writeSequence(['dog\n', 'woof\n']); - }, - "should respond with the values entered": function (err, result) { - assert.isTrue(!err); - assert.equal(result.animal, 'dog'); - assert.equal(result.sound, 'woof'); - assert.equal(prompt.history('nothing'), null); - assert.deepEqual(prompt.history('animal'), { property: 'animal', value: 'dog' }); - } - }, - } - } - } -}).addBatch({ - "When using prompt": { - "the history() method": { - "when used inside of a complex property": { - "with an incorrect value": { - topic: function () { - prompt.get([grab('animal'), grab('sound')], function () {}); - prompt.once('invalid', this.callback.bind(null, null)); - helpers.stdin.writeSequence(['dog\n', 'meow\n']); - }, - "should prompt for the error": function (ign, property, line) { - assert.equal(property.path.join(''), 'sound'); - assert.equal(line, 'meow'); - } - } - } - } - } -}).addBatch({ - "when using prompt": { - "the get() method": { - topic: function () { - prompt.override = { xyz: 468, abc: 123 } - prompt.get(['xyz', 'abc'], this.callback); - }, - "should respond with overrides": function (err, results) { - assert.isNull(err); - assert.deepEqual(results, { xyz: 468, abc: 123 }); - } - } - } -}).addBatch({ - "when using prompt": { - "the get() method also works as a Promise": { - topic: function () { - var that = this; - - prompt.override = { xyz: 468, abc: 123 }; - prompt.get(['xyz', 'abc']) - .then(function (result) { return that.callback(null, result); }); - }, - "should respond with overrides": function (err, results) { - assert.isNull(err); - assert.deepEqual(results, { xyz: 468, abc: 123 }); - } - } - } -}).addBatch({ - "When using prompt": { - "with fancy properties": { - "the get() method": { - topic: function () { - prompt.override = { UVW: 5423, DEF: 64235 } - prompt.get({ - properties: { - 'UVW': { - description: 'a custom message', - default: 6 - }, - 'DEF': { - description: 'a custom message', - default: 6 - } - } - }, this.callback); - }, - "should respond with overrides": function (err, results) { - assert.isNull(err); - assert.deepEqual(results, { UVW: 5423, DEF: 64235 }); - } - } - } - } -}).addBatch({ - "When using prompt": { - "with a type and a description property": { - "the get() method": { - topic: function () { - var that = this; - helpers.stdout.once('data', function (msg) { - that.msg = msg; - }); - - prompt.get({ - name: 'test', - type: 'number', - description: 'Please input a number' - }, this.callback); - helpers.stdin.writeNextTick('42\n'); - }, - "should prompt to stdout and respond with the value": function (err, result) { - assert.isNull(err); - assert.include(result, 'test'); - assert.equal(result['test'], '42'); - assert.isTrue(this.msg.indexOf('Please input a number') !== -1); - } - }, - } - } - }) -.addBatch( - macros.shouldConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'Y' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with an empty string and default yes'], - prop: 'test', - response: '' - }, { - default: 'yes' - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'N' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'YES' - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'NO' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'T' - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'F' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'TRUE' - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with a string message'], - prop: 'test', - response: 'FALSE' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with an object', 'and description set'], - prop: { description: 'a custom message' }, - response: 'Y' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with an object', 'and they forgot the description'], - prop: { description: 'a custom message' }, - response: 'Y' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with an object', 'and custom validators'], - prop: { - description: 'node or jitsu?', - pattern: /^(node|jitsu)/i, - yes: /^node/i - }, - response: 'node' - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with an object', 'and custom validators'], - prop: { - description: 'node or jitsu?', - pattern: /^(node|jitsu)/i, - yes: /^node/i - }, - response: 'jitsu' - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with multiple strings'], - prop: ["test", "test2", "test3"], - response: ['Y\n', 'y\n', 'YES\n'] - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with multiple strings'], - prop: ["test", "test2", "test3"], - response: ['Y\n', 'N\n', 'YES\n'] - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with multiple strings'], - prop: ["test", "test2", "test3"], - response: ['n\n', 'NO\n', 'N\n'] - }) -).addBatch( - macros.shouldConfirm({ - messages: ['with multiple objects'], - prop: [ - { message: "test" }, - { message: "test2" } - ], - response: ['y\n', 'y\n'] - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with multiple objects'], - prop: [ - { message: "test" }, - { message: "test2" } - ], - response: ['n\n', 'n\n'] - }) -).addBatch( - macros.shouldNotConfirm({ - messages: ['with multiple objects'], - prop: [ - { message: "test" }, - { message: "test2" } - ], - response: ['n\n', 'y\n'] - }) -).export(module); diff --git a/Challenge/seokahi/010.star/node_modules/read/LICENSE b/Challenge/seokahi/010.star/node_modules/read/LICENSE deleted file mode 100644 index 19129e3..0000000 --- a/Challenge/seokahi/010.star/node_modules/read/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Challenge/seokahi/010.star/node_modules/read/README.md b/Challenge/seokahi/010.star/node_modules/read/README.md deleted file mode 100644 index 5967fad..0000000 --- a/Challenge/seokahi/010.star/node_modules/read/README.md +++ /dev/null @@ -1,53 +0,0 @@ -## read - -For reading user input from stdin. - -Similar to the `readline` builtin's `question()` method, but with a -few more features. - -## USAGE - -```javascript -var read = require("read") -read(options, callback) -``` - -The callback gets called with either the user input, or the default -specified, or an error, as `callback(error, result, isDefault)` -node style. - -## OPTIONS - -Every option is optional. - -* `prompt` What to write to stdout before reading input. -* `silent` Don't echo the output as the user types it. -* `replace` Replace silenced characters with the supplied character value. -* `timeout` Number of ms to wait for user input before giving up. -* `default` The default value if the user enters nothing. -* `edit` Allow the user to edit the default value. -* `terminal` Treat the output as a TTY, whether it is or not. -* `input` Readable stream to get input data from. (default `process.stdin`) -* `output` Writeable stream to write prompts to. (default: `process.stdout`) - -If silent is true, and the input is a TTY, then read will set raw -mode, and read character by character. - -## COMPATIBILITY - -This module works sort of with node 0.6. It does not work with node -versions less than 0.6. It is best on node 0.8. - -On node version 0.6, it will remove all listeners on the input -stream's `data` and `keypress` events, because the readline module did -not fully clean up after itself in that version of node, and did not -make it possible to clean up after it in a way that has no potential -for side effects. - -Additionally, some of the readline options (like `terminal`) will not -function in versions of node before 0.8, because they were not -implemented in the builtin readline module. - -## CONTRIBUTING - -Patches welcome. diff --git a/Challenge/seokahi/010.star/node_modules/read/lib/read.js b/Challenge/seokahi/010.star/node_modules/read/lib/read.js deleted file mode 100644 index a93d1b3..0000000 --- a/Challenge/seokahi/010.star/node_modules/read/lib/read.js +++ /dev/null @@ -1,113 +0,0 @@ - -module.exports = read - -var readline = require('readline') -var Mute = require('mute-stream') - -function read (opts, cb) { - if (opts.num) { - throw new Error('read() no longer accepts a char number limit') - } - - if (typeof opts.default !== 'undefined' && - typeof opts.default !== 'string' && - typeof opts.default !== 'number') { - throw new Error('default value must be string or number') - } - - var input = opts.input || process.stdin - var output = opts.output || process.stdout - var prompt = (opts.prompt || '').trim() + ' ' - var silent = opts.silent - var editDef = false - var timeout = opts.timeout - - var def = opts.default || '' - if (def) { - if (silent) { - prompt += '(