Pārlūkot izejas kodu

VIP20课程代码

大侠 2 gadi atpakaļ
vecāks
revīzija
73814028ba
100 mainītis faili ar 7540 papildinājumiem un 0 dzēšanām
  1. BIN
      .DS_Store
  2. 152 0
      10_sass/1_style.css
  3. 3 0
      10_sass/1_style.min.css
  4. 167 0
      10_sass/1_style.scss
  5. 12 0
      10_sass/reset.css
  6. 1 0
      10_sass/reset.min.css
  7. 10 0
      10_sass/reset.scss
  8. BIN
      11_ES6/.DS_Store
  9. BIN
      11_ES6/day-1/.DS_Store
  10. 90 0
      11_ES6/day-1/code/1.let.html
  11. 30 0
      11_ES6/day-1/code/2.const.html
  12. 45 0
      11_ES6/day-1/code/3.js
  13. 12 0
      11_ES6/day-1/code/3.数组解构.html
  14. 28 0
      11_ES6/day-1/code/4.js
  15. 12 0
      11_ES6/day-1/code/4.对象解构.html
  16. 39 0
      11_ES6/day-1/code/5.js
  17. 12 0
      11_ES6/day-1/code/5.函数参数解构.html
  18. 45 0
      11_ES6/day-1/code/6.js
  19. 12 0
      11_ES6/day-1/code/6.解构默认值.html
  20. 68 0
      11_ES6/day-1/code/7.js
  21. 12 0
      11_ES6/day-1/code/7函数扩展:rest参数.html
  22. 49 0
      11_ES6/day-1/code/8.js
  23. 12 0
      11_ES6/day-1/code/8.函数扩展:箭头函数.html
  24. BIN
      11_ES6/day-1/note/1.对象解构示意图.png
  25. BIN
      11_ES6/day-2/.DS_Store
  26. 56 0
      11_ES6/day-2/code/1.js
  27. 12 0
      11_ES6/day-2/code/1.数组方法:find&findIndex.html
  28. 15 0
      11_ES6/day-2/code/2.js
  29. 12 0
      11_ES6/day-2/code/2.数组扩展:includes.html
  30. 40 0
      11_ES6/day-2/code/3.js
  31. 20 0
      11_ES6/day-2/code/3.数组扩展:filter方法.html
  32. 56 0
      11_ES6/day-2/code/4.js
  33. 12 0
      11_ES6/day-2/code/4.数组扩展:sort方法.html
  34. 53 0
      11_ES6/day-2/code/5.对象扩展:简洁写法.html
  35. 25 0
      11_ES6/day-2/code/6.对象扩展:计算属性.html
  36. 56 0
      11_ES6/day-2/code/7.js
  37. 12 0
      11_ES6/day-2/code/7.展开运算符.html
  38. 154 0
      11_ES6/day-2/code/8.js
  39. 12 0
      11_ES6/day-2/code/8.promise对象.html
  40. BIN
      11_ES6/day-2/note/promise对象属性.png
  41. BIN
      12_Ajax/.DS_Store
  42. BIN
      12_Ajax/day-1/.DS_Store
  43. BIN
      12_Ajax/day-1/code/.DS_Store
  44. 23 0
      12_Ajax/day-1/code/2.json.html
  45. 38 0
      12_Ajax/day-1/code/client/1.json
  46. 4 0
      12_Ajax/day-1/code/data.json
  47. BIN
      12_Ajax/day-1/note/http-1.png
  48. BIN
      12_Ajax/day-1/note/http-2.png
  49. BIN
      12_Ajax/day-1/note/http-3.png
  50. 97 0
      12_Ajax/day-1/note/json.md
  51. BIN
      12_Ajax/day-1/note/xhr事件作用.png
  52. BIN
      12_Ajax/day-1/note/如何启动我们的server 服务端项目.png
  53. BIN
      12_Ajax/day-2/.DS_Store
  54. BIN
      12_Ajax/day-2/code/.DS_Store
  55. 68 0
      12_Ajax/day-2/code/1.fetch获取所有用户信息.html
  56. 101 0
      12_Ajax/day-2/code/1.js
  57. 34 0
      12_Ajax/day-2/code/2.axios的使用.html
  58. 49 0
      12_Ajax/day-2/code/2.js
  59. 37 0
      12_Ajax/day-2/code/common.css
  60. BIN
      12_Ajax/day-2/note/1.axios响应对象结构.png
  61. BIN
      12_Ajax/day-2/note/2.Vue实例.png
  62. BIN
      12_Ajax/day-2/note/3.Vue响应式.png
  63. BIN
      12_Ajax/day-3/.DS_Store
  64. BIN
      12_Ajax/day-3/code/.DS_Store
  65. BIN
      12_Ajax/day-3/code/case/.DS_Store
  66. 51 0
      12_Ajax/day-3/code/case/index.html
  67. 176 0
      12_Ajax/day-3/code/case/js/index.js
  68. 97 0
      12_Ajax/day-3/code/case/pages/user.insert.html
  69. 70 0
      12_Ajax/day-3/code/case/styles/common.css
  70. 27 0
      12_Ajax/day-3/code/case/styles/iconfont.css
  71. 0 0
      12_Ajax/day-3/code/case/styles/iconfont.js
  72. 23 0
      12_Ajax/day-3/code/case/styles/iconfont.json
  73. BIN
      12_Ajax/day-3/code/case/styles/iconfont.ttf
  74. BIN
      12_Ajax/server/.DS_Store
  75. 117 0
      12_Ajax/server/index.js
  76. 1222 0
      12_Ajax/server/learn-ajax接口文档.html
  77. 109 0
      12_Ajax/server/models/users.js
  78. 1 0
      12_Ajax/server/node_modules/.bin/mime
  79. 572 0
      12_Ajax/server/node_modules/.package-lock.json
  80. 243 0
      12_Ajax/server/node_modules/accepts/HISTORY.md
  81. 23 0
      12_Ajax/server/node_modules/accepts/LICENSE
  82. 140 0
      12_Ajax/server/node_modules/accepts/README.md
  83. 238 0
      12_Ajax/server/node_modules/accepts/index.js
  84. 47 0
      12_Ajax/server/node_modules/accepts/package.json
  85. 21 0
      12_Ajax/server/node_modules/array-flatten/LICENSE
  86. 43 0
      12_Ajax/server/node_modules/array-flatten/README.md
  87. 64 0
      12_Ajax/server/node_modules/array-flatten/array-flatten.js
  88. 39 0
      12_Ajax/server/node_modules/array-flatten/package.json
  89. 651 0
      12_Ajax/server/node_modules/body-parser/HISTORY.md
  90. 23 0
      12_Ajax/server/node_modules/body-parser/LICENSE
  91. 464 0
      12_Ajax/server/node_modules/body-parser/README.md
  92. 25 0
      12_Ajax/server/node_modules/body-parser/SECURITY.md
  93. 157 0
      12_Ajax/server/node_modules/body-parser/index.js
  94. 205 0
      12_Ajax/server/node_modules/body-parser/lib/read.js
  95. 236 0
      12_Ajax/server/node_modules/body-parser/lib/types/json.js
  96. 101 0
      12_Ajax/server/node_modules/body-parser/lib/types/raw.js
  97. 121 0
      12_Ajax/server/node_modules/body-parser/lib/types/text.js
  98. 284 0
      12_Ajax/server/node_modules/body-parser/lib/types/urlencoded.js
  99. 56 0
      12_Ajax/server/node_modules/body-parser/package.json
  100. 97 0
      12_Ajax/server/node_modules/bytes/History.md

BIN
.DS_Store


+ 152 - 0
10_sass/1_style.css

@@ -0,0 +1,152 @@
+@charset "UTF-8";
+* {
+  margin: 0;
+  padding: 0;
+}
+
+li {
+  list-style: none;
+}
+
+body {
+  font-size: 16px;
+}
+
+/* 
+  div 元素
+  多行注释 编译后 .css文件中会保留
+*/
+/*! 
+  强制显示 编译后 .min.css文件中 会保留
+*/
+div {
+  background: #000;
+  color: #eee;
+  width: 100px;
+}
+
+#list {
+  width: 100px;
+  height: 20px;
+}
+
+#list li {
+  font-size: 12px;
+}
+
+#list li p {
+  padding-top: 30px;
+  padding-left: 10px;
+}
+
+#list-inner {
+  color: #000;
+}
+
+.link {
+  color: #000;
+}
+
+.link:hover {
+  color: #eee;
+}
+
+.login-btn {
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  border-radius: 5px;
+  color: #eee;
+  background: #000;
+}
+
+.submit-btn {
+  width: 50px;
+  height: 50px;
+  line-height: 50px;
+  text-align: center;
+  border-radius: 5px;
+  color: #eee;
+  background: #000;
+}
+
+.del-btn {
+  width: 20px;
+  height: 20px;
+  line-height: 20px;
+  text-align: center;
+  border-radius: 5px;
+  color: #eee;
+  background: #000;
+}
+
+.aa-btn {
+  width: 300px;
+  height: 20px;
+  line-height: 20px;
+  text-align: center;
+  border-radius: 5px;
+  color: #eee;
+  background: #000;
+}
+
+.wrapper, .wrapper .inner, #main {
+  width: 100px;
+  height: 100px;
+  font-size: 10px;
+}
+
+.wrapper .inner, #main .inner {
+  padding: 20px;
+}
+
+#main {
+  margin: 10px;
+}
+
+/* 
+  绝对值: abs(-10px)
+  四舍五入:round(5.5)
+  向上取整:ceil(5.5)
+  向下取整:floor(5.5)
+  百分比:percentage(30px / 100px)
+  最小值: min(1,2,3)
+  最大值:max(1,2,3)
+*/
+.content {
+  width: 30%;
+}
+
+div {
+  width: 60px;
+}
+
+p {
+  border: 1px solid #000;
+  background: yellow;
+}
+
+li {
+  font-size: 12px;
+}
+
+.list-1 {
+  width: 100px;
+}
+
+.list-2 {
+  width: 200px;
+}
+
+.list-3 {
+  width: 300px;
+}
+
+.none-1 {
+  width: 50px;
+}
+
+.none-2 {
+  width: 100px;
+}

+ 3 - 0
10_sass/1_style.min.css

@@ -0,0 +1,3 @@
+*{margin:0;padding:0}li{list-style:none}body{font-size:16px}/*! 
+  强制显示 编译后 .min.css文件中 会保留
+*/div{background:#000;color:#eee;width:100px}#list{width:100px;height:20px}#list li{font-size:12px}#list li p{padding-top:30px;padding-left:10px}#list-inner{color:#000}.link{color:#000}.link:hover{color:#eee}.login-btn{width:100px;height:40px;line-height:40px;text-align:center;border-radius:5px;color:#eee;background:#000}.submit-btn{width:50px;height:50px;line-height:50px;text-align:center;border-radius:5px;color:#eee;background:#000}.del-btn{width:20px;height:20px;line-height:20px;text-align:center;border-radius:5px;color:#eee;background:#000}.aa-btn{width:300px;height:20px;line-height:20px;text-align:center;border-radius:5px;color:#eee;background:#000}.wrapper,.wrapper .inner,#main{width:100px;height:100px;font-size:10px}.wrapper .inner,#main .inner{padding:20px}#main{margin:10px}.content{width:30%}div{width:60px}p{border:1px solid #000;background:#ff0}li{font-size:12px}.list-1{width:100px}.list-2{width:200px}.list-3{width:300px}.none-1{width:50px}.none-2{width:100px}

+ 167 - 0
10_sass/1_style.scss

@@ -0,0 +1,167 @@
+@import './reset.scss';
+
+//$定义变量 都放在顶部
+$bgColor: #000;
+$keyName: 'color';
+$whiteColor: #eee;
+/* 
+  div 元素
+  多行注释 编译后 .css文件中会保留
+*/
+/*! 
+  强制显示 编译后 .min.css文件中 会保留
+*/
+div{
+  background: $bgColor;
+  //#{变量}  差值语句 属性名如果是变量 可以使用
+  //一般不建议这样操作
+  #{$keyName}: #eee;
+  width: 100px;
+}
+
+//选择器嵌套
+#list{
+  width: 100px;
+  height: 20px;
+  li{
+    font-size: 12px;
+    p{
+      // padding-top: 30px;
+      // padding-left: 10px;\
+      //属性嵌套 : 和 { 之间要有一个空格
+      padding: {
+        top: 30px;
+        left: 10px;
+      }
+    }
+  }
+  //引用父元素选择器
+  &-inner{
+    color: $bgColor;
+  }
+}
+
+.link{
+  color: $bgColor;
+  &:hover {
+    color: #eee;
+  }
+}
+
+
+// .login-btn{
+//   width: 100px;
+//   height: 40px;
+//   line-height: 40px;
+//   text-align: center;
+//   border-radius: 5px;
+//   color: $whiteColor;
+//   background: $bgColor;
+// }
+// .submit-btn{
+//   width: 50px;
+//   height: 50px;
+//   line-height: 50px;
+//   text-align: center;
+//   border-radius: 5px;
+//   color: $whiteColor;
+//   background: $bgColor;
+// }
+
+//定义一个混合宏
+//定义的时候可以带参数 参数可以设定默认值
+@mixin logo-btn($width:20px,$height:20px,$lineHeight:20px){
+  width: $width;
+  height: $height;
+  line-height: $lineHeight;
+  text-align: center;
+  border-radius: 5px;
+  color: $whiteColor;
+  background: $bgColor;
+}
+//通过@include 去调用设置的混合宏
+.login-btn{
+  @include logo-btn(100px,40px ,40px )
+}
+.submit-btn{
+  @include logo-btn(50px,50px ,50px )
+}
+.del-btn{
+  @include logo-btn()
+}
+//调用 混合宏 传参 可以指定参数的名字和数值
+.aa-btn{
+  @include logo-btn($width: 300px)
+}
+
+.wrapper{
+  width: 100px;
+  height: 100px;
+  font-size: 10px;
+  .inner{
+    //@extend 继承某一个选择器的样式
+    //编译的时候 会将相同的样式 转化成分组选择器
+    //如果继承的选择器 有子选择器  会继承过来
+    @extend .wrapper;
+    padding: 20px;
+  }
+}
+
+#main{
+  @extend .wrapper;
+  margin: 10px;
+}
+/* 
+  绝对值: abs(-10px)
+  四舍五入:round(5.5)
+  向上取整:ceil(5.5)
+  向下取整:floor(5.5)
+  百分比:percentage(30px / 100px)
+  最小值: min(1,2,3)
+  最大值:max(1,2,3)
+*/
+$width: 6;
+.content{
+  width: percentage(30px / 100px);
+}
+//定义函数
+@function changeWidth($width){
+  @return $width * 2
+}
+
+div{
+  width: changeWidth(30px);
+}
+
+$list: 1px solid #000;
+$colorList: blue,red,yellow;
+p{
+  border: $list;
+  //nth($list,index)获取列表第几项
+  background: nth($colorList,3);
+}
+
+//@if 指令 与js相同
+$length: 0;
+li{
+  @if $length < 1{
+    font-size: 12px;
+  } @else if $length > 1 and $length < 4{
+    font-size: 10px;
+  } @else {
+    font-size: 2px;
+  }
+}
+//@for 类似于js中的for循环
+//through 包括
+@for $i from 1 through 3{
+  .list-#{$i}{
+    width: $i * 100px;
+  }
+}
+//to 不包括
+@for $i from 1 to 3{
+  .none-#{$i}{
+    width: $i * 50px;
+  }
+}

+ 12 - 0
10_sass/reset.css

@@ -0,0 +1,12 @@
+* {
+  margin: 0;
+  padding: 0;
+}
+
+li {
+  list-style: none;
+}
+
+body {
+  font-size: 16px;
+}

+ 1 - 0
10_sass/reset.min.css

@@ -0,0 +1 @@
+*{margin:0;padding:0}li{list-style:none}body{font-size:16px}

+ 10 - 0
10_sass/reset.scss

@@ -0,0 +1,10 @@
+*{
+  margin: 0;
+  padding: 0;
+}
+li{
+  list-style: none;
+}
+body{
+  font-size: 16px;
+}

BIN
11_ES6/.DS_Store


BIN
11_ES6/day-1/.DS_Store


+ 90 - 0
11_ES6/day-1/code/1.let.html

@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script>
+      // 变量声明 通过var来实现
+      var a = 10;
+      console.log(a);
+      // ES6 提出两个新的创建变量的关键字 keyword
+      // 分别为 let 和 const
+      let age = 18;
+
+      console.log(age);
+
+      // 对比var : 1 var 声明变量 有提升过程(会给提升的变量初始值 = undefined) 而let没有
+      console.log(b); // undefined
+      var b;
+
+      // let 在定义之前 去使用变量,会报错
+      // console.log(c); // 报错  Uncaught ReferenceError: Cannot access 'c' before initialization
+      let c;
+
+      // console.log(d); //访问不存在的变量 Uncaught ReferenceError: d is not defined
+
+      // 实际工作中,var定义的变量 具有提升的特性。但是实践告诉我们 这个特性并不是好的事情。因为会降低代码的可读性,错误的使用会导致一些意外不可预知的错误。
+      // 实际开发时,代码的实现 要 A:完成特定功能 B;让人看懂你的代码(维护)
+      // 先定义,再使用
+      // 先赋值,再运算
+
+      // 对比var : 2 var 可以重复定义同一变量;而let不可
+      var e;
+      var e;
+
+      // 下面代码 会报错 Uncaught SyntaxError: Identifier 'f' has already been declared
+      // let f;
+      // let f;
+
+      // 对比 var : 3 var 定义的变量只有两种作用域(全局作用域 以及 函数作用域(局部作用域))而 let 具有块级作用域
+      // 在函数中var定义的变量具有函数作用域,只有在函数体中可以被有效的访问到,
+      // 而不在任何函数中var定义的变量具有全局作用域,可以在任何位置被有效的访问到
+      var g; // 全局变量
+      function fn() {
+        var h; // 局部变量
+      }
+
+      // let 定义的变量 具有自己的块级作用域;
+      //  块:代码块 在js中使用 {} 代码代码块
+      {
+        var i; // 全局变量
+        let j = 'j'; // 块级作用域,只有在它定义的代码块中可以被有效的访问到
+
+        console.log(j);
+      }
+
+      console.log(i); // undefined
+      // console.log(j); // 在代码块 外部使用let定义变量 会报错  Uncaught ReferenceError: j is not defined
+
+      if (true) {
+        let k = 'k';
+      }
+      // console.log(k);
+      // 在循环中,通过let定义的变量 同样具有块级作用域,但是与其他的块有区别
+      //  下面代码 会循环3次,因此会产生3个代码块,也就说是 创建3个块级作用域,里面都会定义属于自己作用域的变量l
+      for (let l = 0; l < 3; l++) {
+        console.log(l);
+      }
+      // 下面函数中代码 由于函数体 也是用{}包裹的 因此 即属于块级作用域 也是函数作用域
+      // function foo() {
+      //   var aa;
+
+      //   let aa;
+      // }
+
+      // foo();
+
+      // var bb;
+      // let bb;
+
+      {
+        hh = 10; // 在let定义变量之前的区域,不准许对该变量进行任何的操作。
+        let hh;
+      }
+    </script>
+  </body>
+</html>

+ 30 - 0
11_ES6/day-1/code/2.const.html

@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script>
+      // const 用来定义一个变量,但是不同于let的是,const定义的变量必须在定义时给予一个初始值,同时不许再次修改
+      // 通常 通过const定义的变量 也叫做常量。
+      // 其他方面 等同于 let
+      //  没有变量名提升
+      //  不许重复声明
+      //  具有块级作用域
+      //  具有暂存死区
+
+      // const 定义变量 必须有初识值(在定义的时候赋值,不能单独赋值)
+
+      // const PI; // 定义时没有指定初始值
+
+      // PI = 3.14 // 单独赋值不可以
+
+      const PI = 3.14;
+
+      // PI = 3; // 给const定义的变量重新赋值 会报错:Uncaught TypeError: Assignment to constant variable.
+    </script>
+  </body>
+</html>

+ 45 - 0
11_ES6/day-1/code/3.js

@@ -0,0 +1,45 @@
+//! 数组解构
+
+let arr = [1, 2, 3];
+//  需求:将数组arr中的元素1,2,3分别取出来赋值给对应变量a,b,c
+// a = 1; b = 2; c =3
+
+// var a = arr[0];
+// var b = arr[1];
+// var c = arr[2];
+
+// console.log(a, b, c);
+
+//  使用数组解构 会更简单直接
+// let [a, b, c] = arr;
+// let [c, b, a] = [4, 5, 6];
+// console.log(a, b, c);
+
+// let a, c;
+
+// [a, c] = [1, 3];
+
+let [, , third] = ['foo', 'bar', 'baz'];
+console.log(third); // "baz"
+let [, middle] = ['f', 'b', 'r'];
+
+console.log(middle);
+
+let [first] = [7, 8, 9];
+console.log(first); // 7
+
+let [x, , y] = [1, 2, 3];
+console.log(x, y);
+
+let [head, ...tail] = [1, 2, 3, 4];
+console.log(head, tail);
+
+// 在解构时,如果失败了,变量就会被赋值为undefined,如果...z解构,z确定就是数组,由于解构失败 因此就是空数组. 这里需要注意 ...z这种剩余解构方式,只能写在解构的尾部
+let [f, s, ...z] = ['a'];
+console.log(f, s, z);
+
+//? [1, 2, 3, 4, 5, 6]
+
+let [a, , b] = [1, 2, 3, 4, 5, 6];
+
+console.log(`output->a, b`, a, b);

+ 12 - 0
11_ES6/day-1/code/3.数组解构.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="./3.js"></script>
+  </body>
+</html>

+ 28 - 0
11_ES6/day-1/code/4.js

@@ -0,0 +1,28 @@
+//! 对象解构
+
+var obj = { foo: 'aaa', bar: 'bbb' };
+//TODO 需求:创建两个变量 foo 和 bar;foo = obj.foo; bar = obj.bar
+// var foo = obj.foo;
+// var bar = obj.bar;
+
+//TODO 对象解构
+
+// let { foo: foo, bar: bar } = obj;
+
+//! 上面对象解构的写法 是有简写方式的
+// 由于 我们定义的变量 和 解构对象的属性名 一样,因此可以简写为如下形式:
+let { foo, bar } = { foo: 'foo', bar: 'bar' };
+console.log(foo, bar);
+
+//! 实际工作中,为了使代码更简写通常我们在解构的时候,会定义变量名和其解构对象的属性名一致,这样就可以使用上面的简写语法格式
+
+// 如果 上面已经定义了foo和bar变量,此时就不能在使用简写语法。
+// let { foo, bar } = { foo: 'foo', bar: 'bar' };
+//  我们就可以通过完整语法 对变量进行重命名
+let { foo: foo1, bar: bar1 } = { foo: 'foo', bar: 'bar' };
+
+console.log(foo1, bar1);
+
+//! 同样,如果解构时失败了,那么定义的变量会赋予一个undefined值
+let { baz } = { foo: 'aaa', bar: 'bbb' };
+console.log(baz); // undefined

+ 12 - 0
11_ES6/day-1/code/4.对象解构.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="4.js"></script>
+  </body>
+</html>

+ 39 - 0
11_ES6/day-1/code/5.js

@@ -0,0 +1,39 @@
+//! 函数参数解构
+// 函数fn解构一个数组为参数,数组中包含两个数字,最终函数 返回两数之和
+function fn(nums) {
+  var val1 = nums[0]; // 第一个数
+  var val2 = nums[1]; // 第二个数
+
+  return val1 + val2;
+}
+
+console.log(fn([1, 2]));
+
+//! 函数在调用的时候,会传入实参。实际传入值 就会复制给 函数定义的形参
+//! 那么 也就说 函数参数在实际应用中也可以解构赋值
+//! 函数sum定义两个形参
+function sum([val1, val2]) {
+  return val1 + val2;
+}
+
+console.log(sum([4, 6])); // 10
+
+var user = {
+  name: '大侠', // 郭靖 侠哥
+  age: 18,
+}; // 存储人相关信息
+// 定义函数用来 将指定参数的信息输出到控制台
+function print(user) {
+  var name = user.name;
+  var age = user.age;
+
+  console.log('我的名字叫 ' + name + ',今年我 ' + age + '岁。');
+}
+
+print(user);
+
+function output({ name, age }) {
+  console.log('我的名字叫 ' + name + ',今年我 ' + age + '岁。');
+}
+
+output(user);

+ 12 - 0
11_ES6/day-1/code/5.函数参数解构.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="5.js"></script>
+  </body>
+</html>

+ 45 - 0
11_ES6/day-1/code/6.js

@@ -0,0 +1,45 @@
+//! 实际开发中,解构失败后会给变量一个undefined值。这个值不能参加其他的元素。
+//! 因此,在解构的时候可以指定默认值,这样解构失败后参加运算也不会出现意外的结果
+//! 解构的时候 一定注意:对象的解构赋值 null和undefined值是不可以解构
+//!   基本数据类型 number bool string 可以,底层会将这些基本的数据类型 转换成 对象,在去解构。
+
+var { a } = {};
+
+console.log(a);
+console.log(a + 1);
+console.log(a + 'hehe');
+
+// 下面代码就是在解构时指定变量b的默认值为0,如果解构失败,就会使用该默认值。
+// 只有解构时变量的值 严格等于(===)undefined 才算是解构失败
+var { b = 0 } = {};
+
+console.log(b); // 0
+console.log(b + 1); // 1
+
+var [c = 10] = [];
+var [d = 10] = [0];
+var [e = 20] = [null];
+var [f = 100] = [undefined];
+
+console.log(c); // 10
+console.log(d); // 0
+console.log(e); // null
+console.log(f); // 100
+
+function sum([x = 0, y = 0]) {
+  return x + y;
+}
+
+console.log(sum([])); // 0
+
+//! 基本数据类型 对应 都有自己的 对象类型
+// 数字 number
+var a = 1; // 对应对象类型 new Number(1)
+console.log(new Number(1));
+console.log(new String('string'));
+console.log(new Boolean(true));
+
+//! 扩展:字符串 存储逻辑和数组相似  因此字符串也可以像数组那样解构
+var [a, b] = 'string';
+
+console.log(a, b); // s t

+ 12 - 0
11_ES6/day-1/code/6.解构默认值.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="./6.js"></script>
+  </body>
+</html>

+ 68 - 0
11_ES6/day-1/code/7.js

@@ -0,0 +1,68 @@
+//! 函数扩展:rest参数 也叫剩余参数
+//TODO 功能:接收一些列数字参数,完成求和
+// function sum() {}
+
+// sum(1);
+// sum(1, 2);
+// sum(1, 2, 3);
+// sum(1, 2, 3, 4);
+// ...
+
+//! ES5实现:由于sum函数调用的时候传入的实参个数不定,因此不能通过定义函数的形参就接收所有的参数
+//!   解决方案:使用函数中arguments
+function sum() {
+  console.log(arguments); // arguments是伪数组对象(类数组对象)
+  var total = 0; // 总和
+  for (var i = 0; i < arguments.length; i++) {
+    // 使用for循环去遍历出所有的实参,然后累加到total变量上
+    total += arguments[i];
+  }
+
+  console.log(total);
+}
+
+// sum(1);
+// sum(1, 2);
+// sum(1, 2, 3);
+// sum(1, 2, 3, 4);
+
+//! ES6 推荐使用rest参数 代替 arguments
+//! rest参数 是真数组,那么就可以使用数组对象的所有方法
+// function sum(...rest) {
+//   // console.log(rest);
+//   var total = 0;
+//   rest.forEach(function (v) {
+//     total += v;
+//   });
+
+//   console.log(total);
+// }
+
+// sum(1);
+// sum(1, 2);
+// sum(1, 2, 3);
+// sum(1, 2, 3, 4);
+
+//TODO 功能: 以base为基础值,去累加其他传入的数字参数
+function sum(base, ...rest) {
+  console.log(rest);
+}
+sum(1, 1); // 2 [1]
+sum(10, 2); // 12 [2]
+sum(100, 2, 3); // [2, 3]
+sum(1000, 2, 3, 4); // [2, 3, 4]
+
+//! arguments比较危险,如果手动修改arguments里的数据 会直接影响到传入的实参
+function test1(x) {
+  arguments[0] = 10;
+  console.log(x); // 1? or 10?
+}
+
+test1(1);
+
+function test2(x, ...rest) {
+  rest[0] = 100;
+  console.log(x);
+}
+
+test2(1);

+ 12 - 0
11_ES6/day-1/code/7函数扩展:rest参数.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="7.js"></script>
+  </body>
+</html>

+ 49 - 0
11_ES6/day-1/code/8.js

@@ -0,0 +1,49 @@
+//! 箭头函数
+// ES6 允许使用“箭头”(`=>`)定义函数。
+//TODO 语法: (arg1, arg2, ..., argN) => { statements }
+// 下面就是定义一个箭头函数
+let sum = (x, y) => {
+  return x + y;
+};
+
+// 等价于
+
+function sum1(x, y) {
+  return x + y;
+}
+
+console.log(sum(2, 3)); // 5
+
+//! 仅有一个参数时,定义新参的圆括号可以省略.但是没有参数 圆括号必有有,是语法的一部分。
+
+let f = () => {
+  console.log(v);
+};
+
+//! 在花括号中编写函数体代码,当函数体中只有一个表达式时,可以省略花括号,同时表达式的值会自动作为函数的返回值
+
+let sum2 = (x, y) => x + y;
+console.log(sum2(2, 3)); // 5
+
+//! 箭头函数主要的应用场景:就是替代传统的回调函数
+
+var arr = [1, 2, 3, 4];
+var total = 0;
+
+// arr.forEach(function (v) {
+//   total += v;
+// });
+
+// 使用箭头函数, 使得代码更加简洁
+arr.forEach((v) => (total += v));
+
+console.log(total);
+
+/**
+ *! 面试考点(先背下来)
+ ** 箭头函数与function定义函数的区别:
+ *     1. 箭头函数没有自己的`this`,会从父级作用域中继承下来。
+ *     2. 不可以当作构造函数,也就是说,不可以对箭头函数使用`new`命令,否则会抛出一个错误。
+ *     3. 不可以使用`arguments`对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
+ *     4. 不可以使用`yield`命令,因此箭头函数不能用作 Generator(生成器) 函数。
+ */

+ 12 - 0
11_ES6/day-1/code/8.函数扩展:箭头函数.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="8.js"></script>
+  </body>
+</html>

BIN
11_ES6/day-1/note/1.对象解构示意图.png


BIN
11_ES6/day-2/.DS_Store


+ 56 - 0
11_ES6/day-2/code/1.js

@@ -0,0 +1,56 @@
+//! find 和 findIndex
+// find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
+const array1 = [5, 12, 8, 130, 44];
+
+const found = array1.find((element) => element > 10);
+
+console.log(found);
+
+// array1.find(
+//   (e) => {
+//     console.log(`output->this`, this);
+//     return e > 12;
+//   },
+//   { a: '1' }
+// );
+
+//! 手写find方法
+
+function find(target, callbackFn, thisArg) {
+  // 判断target 是不是数组
+  if (!Array.isArray(target)) {
+    return undefined;
+  }
+
+  for (let i = 0, l = target.length; i < l; i++) {
+    let cur = target[i]; // 当前遍历的元素
+    let ret = callbackFn.call(thisArg, cur, i, target);
+    if (ret) {
+      return cur;
+    }
+  }
+}
+
+// console.log(
+//   find(array1, (e) => {
+//     console.log(`output->this`, this);
+//     return e > 10;
+//   })
+// );
+
+// console.log(
+//   find(
+//     array1,
+//     function (e) {
+//       console.log(`output->this`, this);
+//       return e > 10;
+//     },
+//     { a: 'a' }
+//   )
+// );
+
+//! findIndex
+// findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1。
+
+console.log(array1.findIndex((e) => e > 10)); // 1
+console.log(array1.findIndex((e) => e > 1000)); // 如果没有满足的 就返回 -1

+ 12 - 0
11_ES6/day-2/code/1.数组方法:find&findIndex.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="1.js"></script>
+  </body>
+</html>

+ 15 - 0
11_ES6/day-2/code/2.js

@@ -0,0 +1,15 @@
+//! 数组的includes方法
+// includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
+const array1 = [1, 2, 3];
+
+console.log(array1.includes(2));
+console.log(array1.includes(2, -2));
+// expected output: true
+
+const pets = ['cat', 'dog', 'bat'];
+
+console.log(pets.includes('cat')); // expected output: true
+console.log(pets.includes('cat', 1)); // false
+
+console.log(pets.includes('at'));
+// expected output: false

+ 12 - 0
11_ES6/day-2/code/2.数组扩展:includes.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="2.js"></script>
+  </body>
+</html>

+ 40 - 0
11_ES6/day-2/code/3.js

@@ -0,0 +1,40 @@
+//! filter方法:过滤器
+// 对原数组进行拷贝,同时保留满足回调函数中条件的那些值。
+//  因此,filter方法不对原数组操作,是无害的
+
+const words = [
+  'spray',
+  'limit',
+  'elite',
+  'exuberant',
+  'destruction',
+  'present',
+];
+
+const result = words.filter((word) => word.length > 6);
+
+console.log(result);
+// expected output: Array ["exuberant", "destruction", "present"]
+console.log(words);
+
+// filter示例
+const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
+
+const iptEle = document.getElementById('fruit');
+const dataListEle = document.getElementById('fruit-choose');
+
+// 当text-input的值改变时 会触发input事件
+iptEle.addEventListener('input', function () {
+  let iptVal = iptEle.value; // 获取当前输入框的值
+  let chooseFruits = fruits.filter((f) => f.includes(iptVal));
+  // 每一次添加option的时候 记得清空上次结果
+  dataListEle.innerHTML = '';
+  chooseFruits.forEach((f) => {
+    // 然后再创建新的option标签,并添加给datalist
+    // 下面代码有性能问题?回流 与 重绘
+    // 尽量避免在循环中动态的一个一个的向页面中添加元素,因为会频繁引起回流,引起性能问题
+    let optionEle = document.createElement('option');
+    optionEle.value = f;
+    dataListEle.append(optionEle);
+  });
+});

+ 20 - 0
11_ES6/day-2/code/3.数组扩展:filter方法.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <input
+      type="text"
+      placeholder="输入你爱吃的水果..."
+      id="fruit"
+      list="fruit-choose"
+    />
+    <datalist id="fruit-choose"> </datalist>
+
+    <script src="3.js"></script>
+  </body>
+</html>

+ 56 - 0
11_ES6/day-2/code/4.js

@@ -0,0 +1,56 @@
+//! 数组扩展 sort方法 不是es6新增的方法
+//! 功能 是  对原数组进行排序 sort() 方法用原地算法对数组的元素进行排序,并返回数组。
+
+const array = [11, 2, 8, 10, 1, 5, 3];
+
+//TODO 将array进行升序排序
+// 默认排序顺序是在将元素转换为字符串,在排序后等结果;
+array.sort();
+console.log(array);
+
+//因此下面字符串排序 是没有问题的
+const months = ['March', 'Jan', 'Feb', 'Dec'];
+months.sort();
+console.log(months);
+
+//? 但是 实际排序顺序我们希望是安装数字来排列
+//! 那么 就必须给sort方法传入一个比较函数
+/**
+ * compareFn(a, b) a 和 b 是原数组中要比较的两个值,同时 原位置 a 在 b 前
+ * 返回值	  排序顺序
+   > 0	   a 在 b 后
+   < 0	   a 在 b 前
+   === 0	 保持 a 和 b 的顺序
+ */
+
+// array.sort((a, b) => (a > b ? 1 : -1));
+
+// 由于排序的类型 是数字
+array.sort((a, b) => a - b);
+
+console.log(`output->array`, array);
+
+// 降序
+// 由于排序的类型 是数字
+array.sort((a, b) => b - a);
+console.log(`output->array`, array);
+
+//TODO  对象可以按照某个属性排序:
+const items = [
+  { name: 'Edward', value: 21 },
+  { name: 'Sharpe', value: 37 },
+  { name: 'And', value: 45 },
+  { name: 'The', value: -12 },
+  { name: 'Magnetic', value: 13 },
+  { name: 'Zeros', value: 37 },
+];
+
+// 按照 name 属性 对数组中的对象进行升序排序
+items.sort((a, b) => (a.name > b.name ? 1 : -1));
+
+console.log(items);
+
+// 按照 value 对数组中的对象进行升序排序
+items.sort((a, b) => a.value - b.value);
+
+console.log(items);

+ 12 - 0
11_ES6/day-2/code/4.数组扩展:sort方法.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="4.js"></script>
+  </body>
+</html>

+ 53 - 0
11_ES6/day-2/code/5.对象扩展:简洁写法.html

@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script>
+      var name = '大侠';
+      var age = 18;
+      // 希望 obj对象具有name和age属性 对应值 为name变量以及age变量的值
+      // es5之前
+      var obj1 = {
+        name: name, // 重复出现 name
+        age: age, // 重复出现 age
+      }; // {name: '大侠', age: 18}
+
+      //! ES6 上面写法就可以用 短语法来写
+      var obj2 = {
+        name,
+        age,
+      }; // {name: '大侠', age: 18}
+
+      //! ES6 方法的添加也有短语法
+      // ES5 之前
+      var obj3 = {
+        hi: function () {
+          console.log('obj3:hi');
+        },
+      };
+      // ES6 短语法
+      var obj4 = {
+        hi() {
+          console.log('obj4:hi');
+        },
+      };
+
+      obj3.hi();
+      obj4.hi();
+
+      // 如果属性简洁写法中 不存在该变量 就会报错 sex is not defined
+      var obj5 = {
+        sex,
+      };
+      // 给obj5 添加 sex属性,对应属性值 为 作用域中sex变量的值
+      // 由于 作用域中没有定义sex变量,因此就报错 ReferrenceError:sex is not defined
+
+      //
+    </script>
+  </body>
+</html>

+ 25 - 0
11_ES6/day-2/code/6.对象扩展:计算属性.html

@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script>
+      var prop = 'name';
+
+      // 需求:创建一个对象,对象具有变量prop存储的值属性
+      // 也就是 得到这么个对象 {name}
+
+      // ES5实现
+      var obj1 = {};
+      obj1[prop] = '大侠';
+      // ES6 有短语法 叫做计算属性
+      var obj2 = {
+        [prop]: '大侠',
+      };
+    </script>
+  </body>
+</html>

+ 56 - 0
11_ES6/day-2/code/7.js

@@ -0,0 +1,56 @@
+//! 展开运算符
+//TODO spread ...
+// Math.max() 方法可以返回传输列表中的最大值
+
+console.log(Math.max(1, 56, 25, 68, 30)); // 68
+const array = [1, 56, 25, 68, 30];
+
+//TODO 求数组array中最大值
+
+var maxValue = array[0]; // 默认最大值 为 数组中的第一个元素
+
+array.forEach((v) => {
+  if (v > maxValue) {
+    maxValue = v;
+  }
+});
+
+// 循环结束后 maxValue就是最大值
+console.log(maxValue); // 68
+
+// 通过apply方法去调用max方法 这样就可以将数组元素作为参数传给max
+console.log(Math.max.apply(undefined, array)); // 68
+
+//! 使用展开运算符
+console.log(Math.max(...array)); // 将数组中元素展开依次传入max方法中
+
+function sum(x, y) {
+  console.log(x + y);
+}
+
+// x, y参数值 在一个数组中
+var arr = [2, 3];
+
+sum(...arr);
+
+// 拷贝数组
+var arr1 = [1, 2, 3];
+
+var arr2 = arr1.slice(0);
+
+var arr3 = [...arr1];
+
+// 合并多个数组
+var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+var arr3 = [...arr1, ...arr2];
+
+// 在对象上 也可以使用 spread
+var obj1 = { foo: 'bar', x: 42 };
+var obj2 = { foo: 'baz', y: 13 };
+
+var clonedObj = { ...obj1 };
+// 克隆后的对象:{ foo: "bar", x: 42 }
+
+var mergedObj = { ...obj1, ...obj2 };
+// 合并后的对象:{ foo: "baz", x: 42, y: 13 }

+ 12 - 0
11_ES6/day-2/code/7.展开运算符.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="7.js"></script>
+  </body>
+</html>

+ 154 - 0
11_ES6/day-2/code/8.js

@@ -0,0 +1,154 @@
+//! Promise对象
+// Promise 就是 “承诺”  的意思。代表未来某个时间要发生的事。它的出现是为了更好的处理异步任务。
+
+//! 1. 同步与异步
+
+var a = 10;
+console.log(a);
+var b = 20;
+console.log(b);
+
+//COMMENT 上面代码 都属于 同步代码 即我们所说的同步任务
+//! 同步的特点是,代码 是 自顶向下 一行一行的执行,只有当前行有返回值或者运算完成后,才会执行下一行代码。
+
+var c = 10;
+console.log(c);
+// 定时器中回调函数 就是 异步代码  即我们所说的异步任务
+setTimeout(() => {
+  console.log('timer');
+}, 1000);
+console.log('end');
+
+// 上面代码 输出的顺序为 : 10,'end', 'timer'
+//! 上面代码 中 包含异步任务,特点是 异步任务不会阻塞同步任务的执行,如果下面还有同步任务,继续执行。也就说 同步任务 此时的执行优先级高于 异步任务。
+
+//! 小结:在JavaScript中,常见的异步任务:
+/**
+ * 1. 事件处理函数
+ * 2. 定时器 setTimeout 和 setInterval
+ * 3. 网络请求Ajax
+ * 4. Promise对象
+ * */
+
+//! 2. 创建Promise对象
+// 语法 const promise = new Promise(executor)
+
+const promise = new Promise((resolve, reject) => {
+  // executor 是同步的回调函数,当new Promise的时候executor会立即执行。
+  // 这里就是 要编写的异步任务
+  setTimeout(() => {
+    // 1.5s后 该异步任务会执行
+    // 执行后,要给Promise对象设置状态(成功或者失败),以及异步任务的结果
+    // 在 executor中 会接收两个参数 resolve 和 reject
+    //   resolve(value) 将Promise对象的状态设置为成功的(fulfilled),并将参数value设置为成功的结果值
+    //   reject(reason) 将Promise对象的状态设置为失败的(rejected),并将参数reason设置为失败的原因
+    let n = Math.random(); // 创建一个随件数
+    // 如果n大于 0.5 那么成功,结果值 为 n
+    if (n > 0.5) {
+      resolve(n);
+      reject(); // 这里并不会 将promise状态修改为 失败的。由于上面已经调用resolve了 此reject会被忽略
+    } else {
+      // 否则 失败,失败的原因 为 '你太小了'
+      reject('你太小了');
+    }
+  }, 1500);
+});
+
+console.log(promise);
+
+//! 3. 获取Promise对象结果
+
+// promise.then(
+//   (value) => {
+//     console.log('你成功了,值为:', value);
+//   },
+//   (reason) => {
+//     console.log('你拜拜了,因为:', reason);
+//   }
+// );
+//! promise对象的then方法会返回一个新的Promise对象
+
+//! 4. Promise对象 还有一个 专门用于处理失败的方法 catch
+promise
+  .then((value) => {
+    console.log('你成功了,值为:', value);
+  })
+  .catch((reason) => {
+    console.log('你拜拜了,因为:', reason);
+  });
+
+//COMMENT 上面代码 由于then方法没有传入失败的处理函数,因此一旦promise失败了,就会将状态和结果都交给then返回的新Promise对象上,然后就可以通过新Promise对象调用catch方法去处理失败的情况了。
+
+//! 5 静态方法 就是 构造函数的方法 Promise.resolve(value)
+// 直接返回一个Promise对象,通过状态为 成功的,以及成功的值为value参数。value可以为任何值。
+
+console.log(Promise.resolve(1));
+//! 6 静态方法 就是 构造函数的方法 Promise.reject(reason)
+// 直接返回一个Promise对象,通过状态为 失败的,以及失败的原因为reason参数。reason可以为任何值。
+
+console.log(Promise.reject('我就失败了咋地!!!'));
+
+//! 6 回调地狱
+// 举栗子:
+// 假如 有3个定时器:A - 1s后执行,B - 3s后执行,C - 2s后执行,但是要求 A 执行后 在执行B,B执行后 在执行C。
+
+setTimeout(() => {
+  console.log('任务A完事了');
+  // 开启任务B
+  setTimeout(() => {
+    console.log('任务B完事了');
+    setTimeout(() => {
+      console.log('任务C完事了');
+    }, 2000);
+  }, 3000);
+}, 1000);
+
+//! 在上述代码中的实现 你会发现 setTimeout中的回调函数 一直在嵌套下去,一旦这种异步任务 需要有序的、像同步任务那样一个一个的执行,就会产生一种现象--回调地狱。影响代码的可读性,也就说维护这样的代码会变得困难。
+
+//! 6.1 使用Promsie对象来解决
+function taskA() {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      resolve('任务A完事了');
+    }, 1000);
+  });
+}
+function takB() {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      resolve('任务B完事了');
+    }, 3000);
+  });
+}
+function taskC() {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      resolve('任务C完事了');
+    }, 2000);
+  });
+}
+
+taskA()
+  .then((v) => {
+    console.log(v);
+    return taskB();
+  })
+  .then((v) => {
+    console.log(v);
+    return taskC();
+  })
+  .then((v) => {
+    console.log(v);
+  });
+//! 由于AP.then方法中的回调函数 指定了 返回值 为 一个新的Promise对象BP,因此 AP.then方法它自己返回的Promise对象的状态就和BP关联,同理后面也是一样的道理。
+
+var p1 = Promise.resolve(1).then((v) => {
+  console.log(`output->v`, v);
+});
+
+console.log(p1); // p1 就是 then方法返回值Promise对象
+var p2 = Promise.reject(1).catch((v) => {
+  console.log(`output->v`, v);
+});
+
+console.log(p2); // p2 就是 catch方法返回值Promise对象

+ 12 - 0
11_ES6/day-2/code/8.promise对象.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script src="8.js"></script>
+  </body>
+</html>

BIN
11_ES6/day-2/note/promise对象属性.png


BIN
12_Ajax/.DS_Store


BIN
12_Ajax/day-1/.DS_Store


BIN
12_Ajax/day-1/code/.DS_Store


+ 23 - 0
12_Ajax/day-1/code/2.json.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <script>
+      var obj = {
+        a: 1,
+        s: 'string',
+      };
+
+      var jsonObj = JSON.stringify(obj);
+
+      console.log('json格式: ', jsonObj);
+
+      console.log('js对象: ', JSON.parse(jsonObj));
+    </script>
+  </body>
+</html>

+ 38 - 0
12_Ajax/day-1/code/client/1.json

@@ -0,0 +1,38 @@
+{
+  "code": 200,
+  "msg": "查询成功",
+  "data": [
+    {
+      "name": "admin",
+      "password": "123123",
+      "sex": "0",
+      "age": "18",
+      "id": "1651481065895",
+      "avatar": "https://picsum.photos/100"
+    },
+    {
+      "name": "daxia",
+      "password": "123456",
+      "sex": "1",
+      "age": "24",
+      "id": "1651481065896",
+      "avatar": "https://picsum.photos/100"
+    },
+    {
+      "name": "ronger",
+      "password": "123456",
+      "sex": "0",
+      "age": "20",
+      "id": "1651714181019",
+      "avatar": "https://picsum.photos/100"
+    },
+    {
+      "name": "lihuchong",
+      "age": "20",
+      "password": "123456",
+      "sex": "1",
+      "id": "1652751566952",
+      "avatar": "https://picsum.photos/100"
+    }
+  ]
+}

+ 4 - 0
12_Ajax/day-1/code/data.json

@@ -0,0 +1,4 @@
+{
+  "name": "大侠",
+  "hh": null
+}

BIN
12_Ajax/day-1/note/http-1.png


BIN
12_Ajax/day-1/note/http-2.png


BIN
12_Ajax/day-1/note/http-3.png


+ 97 - 0
12_Ajax/day-1/note/json.md

@@ -0,0 +1,97 @@
+# JSON
+
+## 1. 基本概念
+
+JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
+
+## 2. JSON 语法规则
+
+JSON是一个序列化的对象或数组。
+
+JSON 会有两种形式:
+
+- 第一种: 就是序列化的Object对象
+- 第二种:就是序列化的Array对象
+
+```json
+ {}
+```
+或者
+```json
+ []
+```
+
+JSON 支持以下几种数据类型:
+
+- 字符串
+- 数字
+- bool值
+- {} Object对象
+- [] Array数组
+- null
+
+==注意:JSON表示数据时 所有属性的名称 必须是字符串类型,同时也必须使用双引号来表达一个字符串==
+
+示例1:用一个JSON格式数据 表示 一个用户的信息 {name: '大侠', age: 18, sex: '男'}。
+
+```json
+{
+  "name": "大侠",
+  "age": 18,
+  "sex": "男",
+  "hobby": [
+    "football",
+    "basketball"
+  ]
+}
+```
+
+示例2: 用一个JSON格式数据 表示 一个用户信息列表 [{name: '大侠', age: 18, sex: '男'},{name: '蓉儿', age: 17, sex: '女'}]。
+
+```json
+[
+  {
+    "name": "大侠",
+    "age": 18,
+    "sex": "男",
+    "hobby": [
+      "football",
+      "basketball"
+    ]
+  },
+  {
+    "name": "蓉儿",
+    "age": 17,
+    "sex": "女",
+    "hobby": [
+      "打狗",
+      "睡觉"
+    ]
+  }
+]
+```
+
+
+## 3. JSON 与 JS 对象的关系
+很多人搞不清楚 JSON 和 JS 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:
+JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
+
+```js
+var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
+var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
+```
+
+### 3.1 JSON 和 JS 对象互转
+
+要实现从JSON字符串转换为JS对象,使用 `JSON.parse()` 方法:
+
+```js
+var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
+```
+
+要实现从JS对象转换为JSON字符串,使用 `JSON.stringify()` 方法:
+
+```js
+var json = JSON.stringify({a: 'Hello',b: 'World' });  //结果是 '{"a": "Hello", "b": "World"}'
+```
+

BIN
12_Ajax/day-1/note/xhr事件作用.png


BIN
12_Ajax/day-1/note/如何启动我们的server 服务端项目.png


BIN
12_Ajax/day-2/.DS_Store


BIN
12_Ajax/day-2/code/.DS_Store


+ 68 - 0
12_Ajax/day-2/code/1.fetch获取所有用户信息.html

@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+    <style>
+      .user-list {
+        width: 500px;
+        margin: 0 auto;
+
+        box-shadow: 0 0 2px 5px #ccc;
+        border-radius: 4px;
+
+        padding: 10px;
+      }
+
+      .user-list table {
+        border-collapse: collapse;
+        width: 100%;
+      }
+
+      .user-list table tr {
+        border-top: 1px solid #dedede;
+        height: 32px;
+        line-height: 32px;
+
+        text-align: left;
+      }
+
+      .user-list table thead tr:first-child {
+        border: none;
+      }
+
+      .user-list table td,
+      .user-list table th {
+        padding-left: 10px;
+      }
+
+      .avatar {
+        width: 30px;
+        height: 30px;
+        border-radius: 50%;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="user-list">
+      <table>
+        <!-- thead标签给table定义表头 -->
+        <thead>
+          <tr>
+            <th>头像</th>
+            <th>姓名</th>
+            <th>密码</th>
+            <th>年龄</th>
+            <th>性别</th>
+          </tr>
+        </thead>
+        <tbody id="listBody">
+          <!-- 动态添加数据 -->
+        </tbody>
+      </table>
+    </div>
+    <script src="1.js"></script>
+  </body>
+</html>

+ 101 - 0
12_Ajax/day-2/code/1.js

@@ -0,0 +1,101 @@
+const tBodyEle = document.getElementById('listBody');
+// fetch 的 第一个参数 为 请求的地址;第二个参数为 请求的配置对象
+fetch('http://localhost:3000/users', {
+  method: 'get', // 设置请求的方法
+})
+  .then((res) => {
+    // 请求成功
+    // 这里看一下成功的值 是什么
+    // console.log(res);
+    // res 是 一个 Response对象 我们不能直接处理
+    // 需要使用res.json()方法将响应对象的数据 转换成 js对象才可以
+    return res.json();
+  })
+  .then(({ code, msg, data }) => {
+    // 在这个then方法中 去接收 res.json()的结果
+    // console.log(data);
+    console.log(msg);
+
+    // 2 校验数据的正确性,只有code == 200时 数据是正确的
+    if (code !== 200) {
+      return;
+    }
+
+    var tr, td;
+    data.forEach((user) => {
+      // 每循环一次,就新建一个tr DOM对象
+      tr = document.createElement('tr');
+      // 字符串拼接,在原生js操作dom中会频繁发生,但是存在一个问题 就是代码可读性 太低
+      //  因此 在ES6 对字符串进行了一个扩展。叫做 模板字符串。
+      //   模板字符串 中 可以 换行;也可以通过${}语法 将外部表达式的值 嵌入字符串中的指定位置
+      td = `
+        <td>
+          <img class="avatar" src="${user.avatar}" alt="avatar" />
+        </td>
+        <td>${user.name}</td>
+        <td>${user.password}</td>
+        <td>${user.age}</td>
+        <td>${user.sex === '0' ? '女' : '男'}</td>
+      `; // 这就是模板字符串
+      tr.innerHTML = td;
+      // 下次循环开始前,记得将新建tr添加给tbody元素
+      tBodyEle.append(tr);
+    });
+  })
+  .catch((reason) => {
+    // 当请求失败的时候,输出一下失败的原因
+    console.log(reason);
+  });
+
+// xhr.onload = function () {
+//   let res = xhr.responseText;
+//   // console.log(res);
+//   // res 就是 服务器端 响应给我们的 json字符串类型数据
+//   // 接下来处理 数据
+//   //  就是使用table表格来展示这些数据
+//   //TOOD 将数据 转换成 tr,添加到tbody中
+//   // 1 将json数据 -> js对象
+//   // let data = JSON.parse(res);
+
+//   let { code, msg, data } = JSON.parse(res);
+
+//   console.log(msg);
+
+//   // 2 校验数据的正确性,只有code == 200时 数据是正确的
+//   if (code !== 200) {
+//     return;
+//   }
+
+//   // 3 数据是正确的
+//   //  data 变量 存的就是所有用户信息对象 是一个数组
+//   var tr, td;
+//   data.forEach((user) => {
+//     // 每循环一次,就新建一个tr DOM对象
+//     tr = document.createElement('tr');
+//     td =
+//       '<td><img class="avatar" src="' +
+//       user.avatar +
+//       '" alt="avatar" /></td>' +
+//       '<td>' +
+//       user.name +
+//       '</td>' +
+//       '<td>' +
+//       user.password +
+//       '</td>' +
+//       '<td>' +
+//       user.age +
+//       '</td>' +
+//       '<td>' +
+//       (user.sex === '0' ? '女' : '男') +
+//       '</td>';
+
+//     // console.log(td);
+//     tr.innerHTML = td;
+//     // 下次循环开始前,记得将新建tr添加给tbody元素
+//     tBodyEle.append(tr);
+//   });
+
+//   // console.log(`output->data`, data);
+// };
+
+// xhr.send();

+ 34 - 0
12_Ajax/day-2/code/2.axios的使用.html

@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+    <link rel="stylesheet" href="common.css" />
+  </head>
+  <body>
+    <div class="user-list">
+      <table>
+        <!-- thead标签给table定义表头 -->
+        <thead>
+          <tr>
+            <th>头像</th>
+            <th>姓名</th>
+            <th>密码</th>
+            <th>年龄</th>
+            <th>性别</th>
+          </tr>
+        </thead>
+        <tbody id="listBody">
+          <!-- 动态添加数据 -->
+        </tbody>
+      </table>
+      <button id="btn">获取数据</button>
+    </div>
+
+    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
+    <!-- 上面引入axios库后,会在全局对象上添加一个 axios 函数对象 -->
+    <script src="2.js"></script>
+  </body>
+</html>

+ 49 - 0
12_Ajax/day-2/code/2.js

@@ -0,0 +1,49 @@
+//! 如果想要发起一个http请求 可以调用全局对象中axios函数,同时传入一个配置对象即可
+const btnEle = document.getElementById('btn');
+const tBodyEle = document.getElementById('listBody');
+
+function loadData() {
+  axios({
+    url: 'http://localhost:3000/users', // 请求地址
+    method: 'get', // 请求方法
+  })
+    .then((result) => {
+      // axios 得到的响应 result 是什么
+      console.log(result);
+      let { code, msg, data } = result.data;
+
+      // 2 校验数据的正确性,只有code == 200时 数据是正确的
+      if (code !== 200) {
+        return;
+      }
+
+      var tr, td;
+      data.forEach((user) => {
+        // 每循环一次,就新建一个tr DOM对象
+        tr = document.createElement('tr');
+        // 字符串拼接,在原生js操作dom中会频繁发生,但是存在一个问题 就是代码可读性 太低
+        //  因此 在ES6 对字符串进行了一个扩展。叫做 模板字符串。
+        //   模板字符串 中 可以 换行;也可以通过${}语法 将外部表达式的值 嵌入字符串中的指定位置
+        td = `
+        <td>
+          <img class="avatar" src="${user.avatar}" alt="avatar" />
+        </td>
+        <td>${user.name}</td>
+        <td>${user.password}</td>
+        <td>${user.age}</td>
+        <td>${user.sex === '0' ? '女' : '男'}</td>
+      `; // 这就是模板字符串
+        tr.innerHTML = td;
+        // 下次循环开始前,记得将新建tr添加给tbody元素
+        tBodyEle.append(tr);
+      });
+    })
+    .catch((err) => {
+      console.log(err);
+    });
+}
+
+btnEle.addEventListener('click', function () {
+  console.log('开始加载数据...');
+  loadData();
+});

+ 37 - 0
12_Ajax/day-2/code/common.css

@@ -0,0 +1,37 @@
+.user-list {
+  width: 500px;
+  margin: 0 auto;
+
+  box-shadow: 0 0 2px 5px #ccc;
+  border-radius: 4px;
+
+  padding: 10px;
+}
+
+.user-list table {
+  border-collapse: collapse;
+  width: 100%;
+}
+
+.user-list table tr {
+  border-top: 1px solid #dedede;
+  height: 32px;
+  line-height: 32px;
+
+  text-align: left;
+}
+
+.user-list table thead tr:first-child {
+  border: none;
+}
+
+.user-list table td,
+.user-list table th {
+  padding-left: 10px;
+}
+
+.avatar {
+  width: 30px;
+  height: 30px;
+  border-radius: 50%;
+}

BIN
12_Ajax/day-2/note/1.axios响应对象结构.png


BIN
12_Ajax/day-2/note/2.Vue实例.png


BIN
12_Ajax/day-2/note/3.Vue响应式.png


BIN
12_Ajax/day-3/.DS_Store


BIN
12_Ajax/day-3/code/.DS_Store


BIN
12_Ajax/day-3/code/case/.DS_Store


+ 51 - 0
12_Ajax/day-3/code/case/index.html

@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>主页</title>
+    <link rel="stylesheet" href="./styles/iconfont.css" />
+    <link rel="stylesheet" href="./styles/common.css" />
+  </head>
+  <body>
+    <div class="user-list">
+      <button id="newUserBtn">新增用户</button>
+      <table>
+        <!-- thead标签给table定义表头 -->
+        <thead>
+          <tr>
+            <th>头像</th>
+            <th>姓名</th>
+            <th>密码</th>
+            <th>年龄</th>
+            <th>性别</th>
+            <th>操作</th>
+          </tr>
+        </thead>
+        <tbody id="listBody">
+          <!-- 动态添加数据 -->
+        </tbody>
+        <tfoot>
+          <tr>
+            <td colspan="6" align="right">
+              <span
+                id="prevSp"
+                class="iconfont icon-prev icon"
+                title="上一页"
+              ></span>
+              <span id="totalSp">4 条</span>
+              <span
+                id="nextSp"
+                class="iconfont icon-next icon"
+                title="下一页"
+              ></span>
+            </td>
+          </tr>
+        </tfoot>
+      </table>
+    </div>
+    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
+    <script src="./js/index.js"></script>
+  </body>
+</html>

+ 176 - 0
12_Ajax/day-3/code/case/js/index.js

@@ -0,0 +1,176 @@
+//! 主页
+//TODO 分页显示用户列表
+/**
+ ** 给服务器传递消息,告知 当前页码以及每页显示条目
+ *! 实现方案:2种
+ **  1. 通过search 查询字符串 方式 传递数据
+ **     什么是查询字符串,"?id=1&r=2" 这就是一个查询字符串,其中id 和 r都是查询参数,使用=给其赋予一个参数值。多个查询参数 使用 & 符号拼接。使用时必须拼接到url上,才能将数据传递给服务器。
+ **  2. 通过 请求体request-body 传递数据
+
+ *! get 与 post 请求的区别
+ ** 语义上 
+    1、get是从服务器上获取数据。
+    2、post是向服务器传送数据。
+** 传数据
+   1、 get请求没有 请求体,因此只能通过查询字符串给服务器传递数据,而查询字符串会拼接到请求地址URL中,因此 对任何人数据都是可见
+   2、 post请求,有请求体 可将发送给服务器的数据放到请求体中,这样一般用户是看不见数据的。
+** 数据量
+   1、 get请求传数据时,url地址长度收到浏览器地址栏限制,理论最大值为 4K。实际上不能超过 2K。
+   2、 post传送的数据量较大,一般被默认为不受限制。
+** 安全性
+  1、get安全性非常低。
+  2、post安全性较高。
+** 效率上
+  1、 get 更简单 速度更快
+  2、 post 会复杂一点,效率较低。
+** 缓存
+  1、get可以缓存
+  2、post刷新后数据不会缓存
+ **/
+let page = 1; // 当前页码, 默认第一页
+const pageSize = 2; // 每页条目, 默认每页显示2条数据
+let total = 0; // 数据总数
+let pages = 0; // 总页数
+
+const tBodyEle = document.getElementById('listBody');
+const totalSp = document.querySelector('#totalSp');
+const prevlSp = document.querySelector('#prevlSp');
+const nextSp = document.querySelector('#nextSp');
+const newUserBtn = document.querySelector('#newUserBtn');
+
+function loadData() {
+  axios({
+    url: 'http://localhost:3000/users/page',
+    method: 'get', // method默认值 也是 ‘get’
+    params: {
+      // 属性名 就是 查询参数名
+      // page: page,
+      // pageSize: pageSize,
+      // ES6 对象简洁写法
+      page,
+      pageSize,
+    }, // params 用来指定 查询参数 可以为对象类型。自动拼接到  请求地址
+  })
+    .then((result) => {
+      // 由于是分页显示数据,因此每一次添加数据行时,清空上一次tbody中显示数据
+      tBodyEle.innerHTML = '';
+      // axios 得到的响应 result 是什么
+      console.log(result);
+      let { code, msg, data } = result.data;
+
+      console.log(msg);
+
+      // 2 校验数据的正确性,只有code == 200时 数据是正确的
+      if (code !== 200) {
+        return;
+      }
+
+      var tr, td;
+      data.list.forEach((user) => {
+        // 每循环一次,就新建一个tr DOM对象
+        tr = document.createElement('tr');
+        // 字符串拼接,在原生js操作dom中会频繁发生,但是存在一个问题 就是代码可读性 太低
+        //  因此 在ES6 对字符串进行了一个扩展。叫做 模板字符串。
+        //   模板字符串 中 可以 换行;也可以通过${}语法 将外部表达式的值 嵌入字符串中的指定位置
+        td = `
+          <td>
+            <img class="avatar" src="${user.avatar}" alt="avatar" />
+          </td>
+          <td>${user.name}</td>
+          <td>${user.password}</td>
+          <td>${user.age}</td>
+          <td>${user.sex === '0' ? '女' : '男'}</td>
+          <td data-id="${user.id}">
+            <span
+              class="iconfont icon-edit edit"
+              title="编辑"
+              data-name="edit"
+            ></span>
+            <span
+              class="iconfont icon-delete delete"
+              title="删除"
+              data-name="delete"
+            ></span>
+          </td>
+        `; // 这就是模板字符串
+        tr.innerHTML = td;
+        // 下次循环开始前,记得将新建tr添加给tbody元素
+        // 处理 点击 删除或者编辑按钮
+        tr.addEventListener('click', function (e) {
+          console.log(e.target);
+          // 区分是 点击删除 还是 编辑
+          // data-* 自定义属性,通过DOM对象的dataset属性来获取
+          let { name } = e.target.dataset;
+          let uid = e.target.parentNode.dataset.id;
+
+          // console.log(uid);
+
+          if (name === 'edit') {
+            // 是编辑
+          } else {
+            // 是删除
+            // 为了防止 用户 误触点击
+            if (confirm('您确定删除该行数据吗?')) {
+              // 用户确认了删除操作,接下来就可以 实现删除了
+              // 发起网络请求,将服务器中 数据删除掉
+              axios
+                .delete('http://localhost:3000/users/delete', {
+                  data: {
+                    id: uid,
+                  },
+                })
+                .then((result) => {
+                  let { code, msg } = result.data;
+
+                  alert(msg);
+
+                  if (code == 200) {
+                    // 一旦 删除成功后,要刷新页面数据
+                    loadData();
+                  }
+                });
+            }
+          }
+        });
+        tBodyEle.append(tr);
+      });
+
+      // 将分页信息 保存起来
+      total = data.page.total;
+      totalSp.innerHTML = ` ${total} `;
+      pages = data.page.pages;
+    })
+    .catch((err) => {
+      console.log(err);
+    });
+}
+
+prevSp.addEventListener('click', () => {
+  if (page === 1) {
+    alert('已经在首页了亲!');
+    // 如果是 第一页,这里表示没有上一页
+    return;
+  }
+
+  page--;
+  // 页码 减一后,重新获取数据
+  loadData();
+});
+nextSp.addEventListener('click', () => {
+  if (page === pages) {
+    alert('已经到尾页了亲!');
+    // 如果是 最后页,这里表示没有下一页
+    return;
+  }
+
+  page++;
+  // 页码 加一后,重新获取数据
+  loadData();
+});
+
+newUserBtn.addEventListener('click', () => {
+  // 页面跳转时,此时该js文件被引入到 index.html中,因此下面路径 需要以index.html文件为参照
+  window.location = 'pages/user.insert.html';
+});
+
+loadData();

+ 97 - 0
12_Ajax/day-3/code/case/pages/user.insert.html

@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Document</title>
+  </head>
+  <body>
+    <div class="user-insert">
+      <form id="userForm">
+        <div class="form-item">
+          <label for=""
+            >姓名:
+            <input
+              type="text"
+              name="name"
+              id="name"
+              placeholder="输入姓名..."
+            />
+          </label>
+        </div>
+        <div class="form-item">
+          <label for=""
+            >密码:
+            <input
+              type="password"
+              name="password"
+              id="password"
+              placeholder="输入密码..."
+            />
+          </label>
+        </div>
+        <div class="form-item">
+          <label for=""
+            >年龄:
+            <input
+              type="number"
+              name="age"
+              id="age"
+              placeholder="输入年龄..."
+            />
+          </label>
+        </div>
+        <div class="form-item">
+          <select name="sex" id="sex">
+            <option value="">请选择性别...</option>
+            <option value="1">男</option>
+            <option value="0">女</option>
+          </select>
+        </div>
+        <div class="form-item">
+          <button>新增</button>
+        </div>
+      </form>
+    </div>
+    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
+    <script>
+      // userForm
+      document.querySelector('#userForm').addEventListener('submit', (e) => {
+        // 我们自己提交请求,将数据传给服务器存储。因此这里不需要表单默认行为
+        e.preventDefault(); // 阻止表单 默认的提交行为
+        // e 为 事件对象
+        const formEle = e.target;
+
+        // 实际开发时 可以通过表单输入域的name属性来获取该输入域
+        // 下面代码 就是 通过表单form 来获取 name属性为 name 的标签值
+        // console.log(formEle.name);
+        // console.log(formEle.name.value);
+        const user = {
+          name: formEle.name.value,
+          password: formEle.password.value,
+          age: formEle.age.value,
+          sex: formEle.sex.value,
+        };
+
+        console.log(user);
+
+        // 发起post请求,将用户信息 发送给服务器
+        // post方法 第一个参数 请求地址;第二参数 请求体
+        axios
+          .post('http://localhost:3000/users/insert', user)
+          .then((result) => {
+            let { code, msg } = result.data;
+
+            alert(msg); // 给用户提示
+
+            if (code === 200) {
+              // 新增用户操作成功了,页面跳转到主页
+              window.location = '../index.html';
+            }
+          })
+          .catch((err) => {});
+      });
+    </script>
+  </body>
+</html>

+ 70 - 0
12_Ajax/day-3/code/case/styles/common.css

@@ -0,0 +1,70 @@
+html,
+body {
+  width: 100%;
+  height: 100%;
+}
+
+body {
+  overflow: hidden;
+  box-sizing: border-box;
+  display: flex;
+
+  justify-content: center;
+  align-items: center;
+}
+
+.user-list {
+  width: 500px;
+  margin: 0 auto;
+
+  box-shadow: 0 0 2px 5px #ccc;
+  border-radius: 4px;
+
+  padding: 10px;
+}
+
+.user-list table {
+  border-collapse: collapse;
+  width: 100%;
+}
+
+.user-list table tr {
+  border-top: 1px solid #dedede;
+  height: 32px;
+  line-height: 32px;
+
+  text-align: left;
+}
+
+.user-list table thead tr:first-child {
+  border: none;
+}
+
+.user-list table td,
+.user-list table th {
+  padding-left: 10px;
+}
+
+.avatar {
+  width: 30px;
+  height: 30px;
+  border-radius: 50%;
+}
+
+.icon {
+  transition: color linear 0.3s;
+  padding: 4px;
+}
+
+.icon:hover {
+  color: #00bfff;
+  border: 1px solid #00bfff;
+}
+
+.edit:hover {
+  color: #ff8c00;
+}
+
+.delete:hover {
+  color: #8b1a1a;
+}

+ 27 - 0
12_Ajax/day-3/code/case/styles/iconfont.css

@@ -0,0 +1,27 @@
+@font-face {
+  font-family: 'iconfont'; /* Project id  */
+  src: url('iconfont.ttf?t=1672732706745') format('truetype');
+}
+
+.iconfont {
+  font-family: 'iconfont' !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.icon-edit:before {
+  content: '\e7e1';
+}
+
+.icon-delete:before {
+  content: '\e699';
+}
+
+.icon-next:before {
+  content: '\e605';
+}
+
+.icon-prev:before {
+  content: '\e606';
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
12_Ajax/day-3/code/case/styles/iconfont.js


+ 23 - 0
12_Ajax/day-3/code/case/styles/iconfont.json

@@ -0,0 +1,23 @@
+{
+  "id": "",
+  "name": "",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "879141",
+      "name": "prev",
+      "font_class": "prev",
+      "unicode": "e659",
+      "unicode_decimal": 58969
+    },
+    {
+      "icon_id": "879157",
+      "name": "next",
+      "font_class": "next",
+      "unicode": "e667",
+      "unicode_decimal": 58983
+    }
+  ]
+}

BIN
12_Ajax/day-3/code/case/styles/iconfont.ttf


BIN
12_Ajax/server/.DS_Store


+ 117 - 0
12_Ajax/server/index.js

@@ -0,0 +1,117 @@
+const express = require('express');
+const bodyParser = require('body-parser');
+const userModel = require('./models/users');
+const cors = require('cors');
+
+const app = express();
+
+app.use(cors());
+
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(bodyParser.json());
+
+app.get('/users', (req, res) => {
+  let { name } = req.query;
+  res.json({
+    code: 200,
+    msg: '查询成功',
+    data: userModel.findAll(name),
+  });
+});
+
+app.post('/register', (req, res) => {
+  // console.log(req.body);
+  if (userModel.existUser)
+    return res.json({
+      code: 405,
+      msg: '用户名已存在',
+    });
+  res.json(
+    userModel.insert(req.body)
+      ? { code: 200, msg: '注册成功' }
+      : {
+          code: 400,
+          msg: '注册失败,请检查网络',
+        }
+  );
+});
+
+app.post('/login', (req, res) => {
+  // console.log(req.body);
+  let user = userModel.login(req.body);
+  res.json(
+    user
+      ? { code: 200, msg: '登录成功', data: user }
+      : {
+          code: 400,
+          msg: '用户名或密码错误',
+        }
+  );
+});
+
+app.post('/users/insert', (req, res) => {
+  // console.log(req.body);
+  res.json(
+    userModel.insert(req.body)
+      ? { code: 200, msg: '操作成功' }
+      : {
+          code: 400,
+          msg: '操作失败,请稍后重试',
+        }
+  );
+});
+
+app.get('/users/page', (req, res) => {
+  res.json({
+    code: 200,
+    msg: '操作成功',
+    data: userModel.findByPage(req.query),
+  });
+});
+
+app.delete('/users/delete', (req, res) => {
+  // console.log(req.body);
+  let { id } = req.body;
+  res.json(
+    userModel.remove(id)
+      ? { code: 200, msg: '删除成功' }
+      : { code: 400, msg: '删除失败' }
+  );
+});
+
+app.post('/users/update', (req, res) => {
+  res.json(
+    userModel.update(req.body)
+      ? { code: 200, msg: '修改成功' }
+      : { code: 400, msg: '修改失败,请检查网络' }
+  );
+});
+
+app.get('/users/id', (req, res) => {
+  let { id } = req.query;
+  let user = userModel.findById(id);
+
+  res.json(
+    user
+      ? {
+          code: 200,
+          msg: '成功',
+          data: user,
+        }
+      : {
+          code: 400,
+          msg: '用户不存在',
+        }
+  );
+});
+
+app.use((req, res) => {
+  res.json({
+    code: 404,
+    msg: '没有当前API',
+  });
+});
+
+app.listen(3000, () => {
+  console.log(`Server was started at port <3000>`);
+});

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1222 - 0
12_Ajax/server/learn-ajax接口文档.html


+ 109 - 0
12_Ajax/server/models/users.js

@@ -0,0 +1,109 @@
+const fs = require('fs');
+const { resolve } = require('path');
+
+let from = (path) => {
+  let data;
+  path = resolve(__dirname, '../tables/users.json');
+  try {
+    data = fs.readFileSync(path, {
+      encoding: 'utf-8',
+    });
+    data = JSON.parse(data) || [];
+  } catch (err) {
+    data = [];
+  }
+
+  return {
+    insert(item) {
+      item.id = Date.now() + '';
+      item.avatar = 'https://picsum.photos/100';
+
+      data.push(item);
+      try {
+        fs.writeFileSync(path, JSON.stringify(data));
+      } catch (err) {
+        console.error(err);
+        return false;
+      }
+
+      return true;
+    },
+    findAll(name) {
+      return name ? data.filter((user) => user.name.includes(name)) : data;
+    },
+    findById(id) {
+      return data.filter((item) => item.id === id)[0];
+    },
+    findByName(name) {
+      return data.filter((user) => user.name === name);
+    },
+    findByPage({ page = 1, pageSize = 5 }) {
+      let start = (page - 1) * pageSize;
+
+      return {
+        list: data.slice(start, Number(pageSize) + start),
+        page: {
+          page,
+          pageSize,
+          pages: Math.ceil(data.length / pageSize),
+          total: data.length,
+        },
+      };
+    },
+    remove(id) {
+      data = data.filter((item) => item.id !== id);
+      try {
+        fs.writeFileSync(path, JSON.stringify(data));
+      } catch (err) {
+        return false;
+      }
+
+      return true;
+    },
+    update(v) {
+      let index = data.findIndex((item) => item.id === v.id);
+      data.splice(index, 1, { ...data[index], ...v });
+
+      try {
+        fs.writeFileSync(path, JSON.stringify(data));
+      } catch (err) {
+        return false;
+      }
+
+      return true;
+    },
+    login({ name, password }) {
+      let res = data.filter(
+        (item) => item.name === name && item.password === password
+      );
+      return res.length > 0 ? res[0] : false;
+    },
+  };
+};
+
+module.exports = {
+  insert(user) {
+    return from('../tables/users.json').insert(user);
+  },
+  findAll(name) {
+    return from('../tables/users.json').findAll(name);
+  },
+  findByPage(opts) {
+    return from('../tables/users.json').findByPage(opts);
+  },
+  findById(id) {
+    return from('../tables/users.json').findById(id);
+  },
+  update(user) {
+    return from('../tables/users.json').update(user);
+  },
+  remove(id) {
+    return from('../tables/users.json').remove(id);
+  },
+  login(user) {
+    return from('../tables/users.json').login(user);
+  },
+  existUser(name) {
+    return !!from('../tables/users.json').findByName(name).length;
+  },
+};

+ 1 - 0
12_Ajax/server/node_modules/.bin/mime

@@ -0,0 +1 @@
+../mime/cli.js

+ 572 - 0
12_Ajax/server/node_modules/.package-lock.json

@@ -0,0 +1,572 @@
+{
+  "name": "server",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://r.cnpmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://r2.cnpmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+    },
+    "node_modules/body-parser": {
+      "version": "1.20.0",
+      "resolved": "https://r.cnpmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+      "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.10.3",
+        "raw-body": "2.5.1",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "https://r.cnpmjs.org/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://r2.cnpmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://r2.cnpmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://r2.cnpmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie": {
+      "version": "0.5.0",
+      "resolved": "https://r.cnpmjs.org/cookie/-/cookie-0.5.0.tgz",
+      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://r2.cnpmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+    },
+    "node_modules/cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://r2.cnpmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://r2.cnpmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://r.cnpmjs.org/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://r2.cnpmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://r2.cnpmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://r2.cnpmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://r.cnpmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/express": {
+      "version": "4.18.1",
+      "resolved": "https://r.cnpmjs.org/express/-/express-4.18.1.tgz",
+      "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.0",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.5.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.2.0",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.10.3",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.18.0",
+        "serve-static": "1.15.0",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.2.0",
+      "resolved": "https://r.cnpmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+      "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "statuses": "2.0.1",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://r2.cnpmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://r2.cnpmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://r2.cnpmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://r2.cnpmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://r2.cnpmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://r.cnpmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "https://r2.cnpmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://r2.cnpmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://r2.cnpmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://r2.cnpmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://r2.cnpmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://r2.cnpmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://r2.cnpmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://r2.cnpmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://r.cnpmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://r.cnpmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://r2.cnpmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://r.cnpmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://r2.cnpmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.12.0",
+      "resolved": "https://r2.cnpmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+      "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://r.cnpmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://r2.cnpmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://r2.cnpmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.7",
+      "resolved": "https://r2.cnpmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "dependencies": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.10.3",
+      "resolved": "https://r.cnpmjs.org/qs/-/qs-6.10.3.tgz",
+      "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+      "dependencies": {
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://r2.cnpmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.5.1",
+      "resolved": "https://r.cnpmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+      "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://r2.cnpmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://r2.cnpmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "node_modules/send": {
+      "version": "0.18.0",
+      "resolved": "https://r.cnpmjs.org/send/-/send-0.18.0.tgz",
+      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://r2.cnpmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "node_modules/serve-static": {
+      "version": "1.15.0",
+      "resolved": "https://r.cnpmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+      "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.18.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://r2.cnpmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://r2.cnpmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "https://r2.cnpmjs.org/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://r2.cnpmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://r2.cnpmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://r2.cnpmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://r2.cnpmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://r2.cnpmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    }
+  }
+}

+ 243 - 0
12_Ajax/server/node_modules/accepts/HISTORY.md

@@ -0,0 +1,243 @@
+1.3.8 / 2022-02-02
+==================
+
+  * deps: mime-types@~2.1.34
+    - deps: mime-db@~1.51.0
+  * deps: negotiator@0.6.3
+
+1.3.7 / 2019-04-29
+==================
+
+  * deps: negotiator@0.6.2
+    - Fix sorting charset, encoding, and language with extra parameters
+
+1.3.6 / 2019-04-28
+==================
+
+  * deps: mime-types@~2.1.24
+    - deps: mime-db@~1.40.0
+
+1.3.5 / 2018-02-28
+==================
+
+  * deps: mime-types@~2.1.18
+    - deps: mime-db@~1.33.0
+
+1.3.4 / 2017-08-22
+==================
+
+  * deps: mime-types@~2.1.16
+    - deps: mime-db@~1.29.0
+
+1.3.3 / 2016-05-02
+==================
+
+  * deps: mime-types@~2.1.11
+    - deps: mime-db@~1.23.0
+  * deps: negotiator@0.6.1
+    - perf: improve `Accept` parsing speed
+    - perf: improve `Accept-Charset` parsing speed
+    - perf: improve `Accept-Encoding` parsing speed
+    - perf: improve `Accept-Language` parsing speed
+
+1.3.2 / 2016-03-08
+==================
+
+  * deps: mime-types@~2.1.10
+    - Fix extension of `application/dash+xml`
+    - Update primary extension for `audio/mp4`
+    - deps: mime-db@~1.22.0
+
+1.3.1 / 2016-01-19
+==================
+
+  * deps: mime-types@~2.1.9
+    - deps: mime-db@~1.21.0
+
+1.3.0 / 2015-09-29
+==================
+
+  * deps: mime-types@~2.1.7
+    - deps: mime-db@~1.19.0
+  * deps: negotiator@0.6.0
+    - Fix including type extensions in parameters in `Accept` parsing
+    - Fix parsing `Accept` parameters with quoted equals
+    - Fix parsing `Accept` parameters with quoted semicolons
+    - Lazy-load modules from main entry point
+    - perf: delay type concatenation until needed
+    - perf: enable strict mode
+    - perf: hoist regular expressions
+    - perf: remove closures getting spec properties
+    - perf: remove a closure from media type parsing
+    - perf: remove property delete from media type parsing
+
+1.2.13 / 2015-09-06
+===================
+
+  * deps: mime-types@~2.1.6
+    - deps: mime-db@~1.18.0
+
+1.2.12 / 2015-07-30
+===================
+
+  * deps: mime-types@~2.1.4
+    - deps: mime-db@~1.16.0
+
+1.2.11 / 2015-07-16
+===================
+
+  * deps: mime-types@~2.1.3
+    - deps: mime-db@~1.15.0
+
+1.2.10 / 2015-07-01
+===================
+
+  * deps: mime-types@~2.1.2
+    - deps: mime-db@~1.14.0
+
+1.2.9 / 2015-06-08
+==================
+
+  * deps: mime-types@~2.1.1
+    - perf: fix deopt during mapping
+
+1.2.8 / 2015-06-07
+==================
+
+  * deps: mime-types@~2.1.0
+    - deps: mime-db@~1.13.0
+  * perf: avoid argument reassignment & argument slice
+  * perf: avoid negotiator recursive construction
+  * perf: enable strict mode
+  * perf: remove unnecessary bitwise operator
+
+1.2.7 / 2015-05-10
+==================
+
+  * deps: negotiator@0.5.3
+    - Fix media type parameter matching to be case-insensitive
+
+1.2.6 / 2015-05-07
+==================
+
+  * deps: mime-types@~2.0.11
+    - deps: mime-db@~1.9.1
+  * deps: negotiator@0.5.2
+    - Fix comparing media types with quoted values
+    - Fix splitting media types with quoted commas
+
+1.2.5 / 2015-03-13
+==================
+
+  * deps: mime-types@~2.0.10
+    - deps: mime-db@~1.8.0
+
+1.2.4 / 2015-02-14
+==================
+
+  * Support Node.js 0.6
+  * deps: mime-types@~2.0.9
+    - deps: mime-db@~1.7.0
+  * deps: negotiator@0.5.1
+    - Fix preference sorting to be stable for long acceptable lists
+
+1.2.3 / 2015-01-31
+==================
+
+  * deps: mime-types@~2.0.8
+    - deps: mime-db@~1.6.0
+
+1.2.2 / 2014-12-30
+==================
+
+  * deps: mime-types@~2.0.7
+    - deps: mime-db@~1.5.0
+
+1.2.1 / 2014-12-30
+==================
+
+  * deps: mime-types@~2.0.5
+    - deps: mime-db@~1.3.1
+
+1.2.0 / 2014-12-19
+==================
+
+  * deps: negotiator@0.5.0
+    - Fix list return order when large accepted list
+    - Fix missing identity encoding when q=0 exists
+    - Remove dynamic building of Negotiator class
+
+1.1.4 / 2014-12-10
+==================
+
+  * deps: mime-types@~2.0.4
+    - deps: mime-db@~1.3.0
+
+1.1.3 / 2014-11-09
+==================
+
+  * deps: mime-types@~2.0.3
+    - deps: mime-db@~1.2.0
+
+1.1.2 / 2014-10-14
+==================
+
+  * deps: negotiator@0.4.9
+    - Fix error when media type has invalid parameter
+
+1.1.1 / 2014-09-28
+==================
+
+  * deps: mime-types@~2.0.2
+    - deps: mime-db@~1.1.0
+  * deps: negotiator@0.4.8
+    - Fix all negotiations to be case-insensitive
+    - Stable sort preferences of same quality according to client order
+
+1.1.0 / 2014-09-02
+==================
+
+  * update `mime-types`
+
+1.0.7 / 2014-07-04
+==================
+
+  * Fix wrong type returned from `type` when match after unknown extension
+
+1.0.6 / 2014-06-24
+==================
+
+  * deps: negotiator@0.4.7
+
+1.0.5 / 2014-06-20
+==================
+
+ * fix crash when unknown extension given
+
+1.0.4 / 2014-06-19
+==================
+
+  * use `mime-types`
+
+1.0.3 / 2014-06-11
+==================
+
+  * deps: negotiator@0.4.6
+    - Order by specificity when quality is the same
+
+1.0.2 / 2014-05-29
+==================
+
+  * Fix interpretation when header not in request
+  * deps: pin negotiator@0.4.5
+
+1.0.1 / 2014-01-18
+==================
+
+  * Identity encoding isn't always acceptable
+  * deps: negotiator@~0.4.0
+
+1.0.0 / 2013-12-27
+==================
+
+  * Genesis

+ 23 - 0
12_Ajax/server/node_modules/accepts/LICENSE

@@ -0,0 +1,23 @@
+(The MIT License)
+
+Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
+Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.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.

+ 140 - 0
12_Ajax/server/node_modules/accepts/README.md

@@ -0,0 +1,140 @@
+# accepts
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
+Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
+
+In addition to negotiator, it allows:
+
+- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
+  as well as `('text/html', 'application/json')`.
+- Allows type shorthands such as `json`.
+- Returns `false` when no types match
+- Treats non-existent headers as `*`
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install accepts
+```
+
+## API
+
+```js
+var accepts = require('accepts')
+```
+
+### accepts(req)
+
+Create a new `Accepts` object for the given `req`.
+
+#### .charset(charsets)
+
+Return the first accepted charset. If nothing in `charsets` is accepted,
+then `false` is returned.
+
+#### .charsets()
+
+Return the charsets that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .encoding(encodings)
+
+Return the first accepted encoding. If nothing in `encodings` is accepted,
+then `false` is returned.
+
+#### .encodings()
+
+Return the encodings that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .language(languages)
+
+Return the first accepted language. If nothing in `languages` is accepted,
+then `false` is returned.
+
+#### .languages()
+
+Return the languages that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .type(types)
+
+Return the first accepted type (and it is returned as the same text as what
+appears in the `types` array). If nothing in `types` is accepted, then `false`
+is returned.
+
+The `types` array can contain full MIME types or file extensions. Any value
+that is not a full MIME types is passed to `require('mime-types').lookup`.
+
+#### .types()
+
+Return the types that the request accepts, in the order of the client's
+preference (most preferred first).
+
+## Examples
+
+### Simple type negotiation
+
+This simple example shows how to use `accepts` to return a different typed
+respond body based on what the client wants to accept. The server lists it's
+preferences in order and will get back the best match between the client and
+server.
+
+```js
+var accepts = require('accepts')
+var http = require('http')
+
+function app (req, res) {
+  var accept = accepts(req)
+
+  // the order of this list is significant; should be server preferred order
+  switch (accept.type(['json', 'html'])) {
+    case 'json':
+      res.setHeader('Content-Type', 'application/json')
+      res.write('{"hello":"world!"}')
+      break
+    case 'html':
+      res.setHeader('Content-Type', 'text/html')
+      res.write('<b>hello, world!</b>')
+      break
+    default:
+      // the fallback is text/plain, so no need to specify it above
+      res.setHeader('Content-Type', 'text/plain')
+      res.write('hello, world!')
+      break
+  }
+
+  res.end()
+}
+
+http.createServer(app).listen(3000)
+```
+
+You can test this out with the cURL program:
+```sh
+curl -I -H'Accept: text/html' http://localhost:3000/
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
+[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
+[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
+[node-version-image]: https://badgen.net/npm/node/accepts
+[node-version-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/accepts
+[npm-url]: https://npmjs.org/package/accepts
+[npm-version-image]: https://badgen.net/npm/v/accepts

+ 238 - 0
12_Ajax/server/node_modules/accepts/index.js

@@ -0,0 +1,238 @@
+/*!
+ * accepts
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Negotiator = require('negotiator')
+var mime = require('mime-types')
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = Accepts
+
+/**
+ * Create a new Accepts object for the given req.
+ *
+ * @param {object} req
+ * @public
+ */
+
+function Accepts (req) {
+  if (!(this instanceof Accepts)) {
+    return new Accepts(req)
+  }
+
+  this.headers = req.headers
+  this.negotiator = new Negotiator(req)
+}
+
+/**
+ * Check if the given `type(s)` is acceptable, returning
+ * the best match when true, otherwise `undefined`, in which
+ * case you should respond with 406 "Not Acceptable".
+ *
+ * The `type` value may be a single mime type string
+ * such as "application/json", the extension name
+ * such as "json" or an array `["json", "html", "text/plain"]`. When a list
+ * or array is given the _best_ match, if any is returned.
+ *
+ * Examples:
+ *
+ *     // Accept: text/html
+ *     this.types('html');
+ *     // => "html"
+ *
+ *     // Accept: text/*, application/json
+ *     this.types('html');
+ *     // => "html"
+ *     this.types('text/html');
+ *     // => "text/html"
+ *     this.types('json', 'text');
+ *     // => "json"
+ *     this.types('application/json');
+ *     // => "application/json"
+ *
+ *     // Accept: text/*, application/json
+ *     this.types('image/png');
+ *     this.types('png');
+ *     // => undefined
+ *
+ *     // Accept: text/*;q=.5, application/json
+ *     this.types(['html', 'json']);
+ *     this.types('html', 'json');
+ *     // => "json"
+ *
+ * @param {String|Array} types...
+ * @return {String|Array|Boolean}
+ * @public
+ */
+
+Accepts.prototype.type =
+Accepts.prototype.types = function (types_) {
+  var types = types_
+
+  // support flattened arguments
+  if (types && !Array.isArray(types)) {
+    types = new Array(arguments.length)
+    for (var i = 0; i < types.length; i++) {
+      types[i] = arguments[i]
+    }
+  }
+
+  // no types, return all requested types
+  if (!types || types.length === 0) {
+    return this.negotiator.mediaTypes()
+  }
+
+  // no accept header, return first given type
+  if (!this.headers.accept) {
+    return types[0]
+  }
+
+  var mimes = types.map(extToMime)
+  var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
+  var first = accepts[0]
+
+  return first
+    ? types[mimes.indexOf(first)]
+    : false
+}
+
+/**
+ * Return accepted encodings or best fit based on `encodings`.
+ *
+ * Given `Accept-Encoding: gzip, deflate`
+ * an array sorted by quality is returned:
+ *
+ *     ['gzip', 'deflate']
+ *
+ * @param {String|Array} encodings...
+ * @return {String|Array}
+ * @public
+ */
+
+Accepts.prototype.encoding =
+Accepts.prototype.encodings = function (encodings_) {
+  var encodings = encodings_
+
+  // support flattened arguments
+  if (encodings && !Array.isArray(encodings)) {
+    encodings = new Array(arguments.length)
+    for (var i = 0; i < encodings.length; i++) {
+      encodings[i] = arguments[i]
+    }
+  }
+
+  // no encodings, return all requested encodings
+  if (!encodings || encodings.length === 0) {
+    return this.negotiator.encodings()
+  }
+
+  return this.negotiator.encodings(encodings)[0] || false
+}
+
+/**
+ * Return accepted charsets or best fit based on `charsets`.
+ *
+ * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
+ * an array sorted by quality is returned:
+ *
+ *     ['utf-8', 'utf-7', 'iso-8859-1']
+ *
+ * @param {String|Array} charsets...
+ * @return {String|Array}
+ * @public
+ */
+
+Accepts.prototype.charset =
+Accepts.prototype.charsets = function (charsets_) {
+  var charsets = charsets_
+
+  // support flattened arguments
+  if (charsets && !Array.isArray(charsets)) {
+    charsets = new Array(arguments.length)
+    for (var i = 0; i < charsets.length; i++) {
+      charsets[i] = arguments[i]
+    }
+  }
+
+  // no charsets, return all requested charsets
+  if (!charsets || charsets.length === 0) {
+    return this.negotiator.charsets()
+  }
+
+  return this.negotiator.charsets(charsets)[0] || false
+}
+
+/**
+ * Return accepted languages or best fit based on `langs`.
+ *
+ * Given `Accept-Language: en;q=0.8, es, pt`
+ * an array sorted by quality is returned:
+ *
+ *     ['es', 'pt', 'en']
+ *
+ * @param {String|Array} langs...
+ * @return {Array|String}
+ * @public
+ */
+
+Accepts.prototype.lang =
+Accepts.prototype.langs =
+Accepts.prototype.language =
+Accepts.prototype.languages = function (languages_) {
+  var languages = languages_
+
+  // support flattened arguments
+  if (languages && !Array.isArray(languages)) {
+    languages = new Array(arguments.length)
+    for (var i = 0; i < languages.length; i++) {
+      languages[i] = arguments[i]
+    }
+  }
+
+  // no languages, return all requested languages
+  if (!languages || languages.length === 0) {
+    return this.negotiator.languages()
+  }
+
+  return this.negotiator.languages(languages)[0] || false
+}
+
+/**
+ * Convert extnames to mime.
+ *
+ * @param {String} type
+ * @return {String}
+ * @private
+ */
+
+function extToMime (type) {
+  return type.indexOf('/') === -1
+    ? mime.lookup(type)
+    : type
+}
+
+/**
+ * Check if mime is valid.
+ *
+ * @param {String} type
+ * @return {String}
+ * @private
+ */
+
+function validMime (type) {
+  return typeof type === 'string'
+}

+ 47 - 0
12_Ajax/server/node_modules/accepts/package.json

@@ -0,0 +1,47 @@
+{
+  "name": "accepts",
+  "description": "Higher-level content negotiation",
+  "version": "1.3.8",
+  "contributors": [
+    "Douglas Christopher Wilson <doug@somethingdoug.com>",
+    "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
+  ],
+  "license": "MIT",
+  "repository": "jshttp/accepts",
+  "dependencies": {
+    "mime-types": "~2.1.34",
+    "negotiator": "0.6.3"
+  },
+  "devDependencies": {
+    "deep-equal": "1.0.1",
+    "eslint": "7.32.0",
+    "eslint-config-standard": "14.1.1",
+    "eslint-plugin-import": "2.25.4",
+    "eslint-plugin-markdown": "2.2.1",
+    "eslint-plugin-node": "11.1.0",
+    "eslint-plugin-promise": "4.3.1",
+    "eslint-plugin-standard": "4.1.0",
+    "mocha": "9.2.0",
+    "nyc": "15.1.0"
+  },
+  "files": [
+    "LICENSE",
+    "HISTORY.md",
+    "index.js"
+  ],
+  "engines": {
+    "node": ">= 0.6"
+  },
+  "scripts": {
+    "lint": "eslint .",
+    "test": "mocha --reporter spec --check-leaks --bail test/",
+    "test-ci": "nyc --reporter=lcov --reporter=text npm test",
+    "test-cov": "nyc --reporter=html --reporter=text npm test"
+  },
+  "keywords": [
+    "content",
+    "negotiation",
+    "accept",
+    "accepts"
+  ]
+}

+ 21 - 0
12_Ajax/server/node_modules/array-flatten/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Blake Embrey (hello@blakeembrey.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.

+ 43 - 0
12_Ajax/server/node_modules/array-flatten/README.md

@@ -0,0 +1,43 @@
+# Array Flatten
+
+[![NPM version][npm-image]][npm-url]
+[![NPM downloads][downloads-image]][downloads-url]
+[![Build status][travis-image]][travis-url]
+[![Test coverage][coveralls-image]][coveralls-url]
+
+> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
+
+## Installation
+
+```
+npm install array-flatten --save
+```
+
+## Usage
+
+```javascript
+var flatten = require('array-flatten')
+
+flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
+//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
+//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
+
+(function () {
+  flatten(arguments) //=> [1, 2, 3]
+})(1, [2, 3])
+```
+
+## License
+
+MIT
+
+[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
+[npm-url]: https://npmjs.org/package/array-flatten
+[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
+[downloads-url]: https://npmjs.org/package/array-flatten
+[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
+[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
+[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
+[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master

+ 64 - 0
12_Ajax/server/node_modules/array-flatten/array-flatten.js

@@ -0,0 +1,64 @@
+'use strict'
+
+/**
+ * Expose `arrayFlatten`.
+ */
+module.exports = arrayFlatten
+
+/**
+ * Recursive flatten function with depth.
+ *
+ * @param  {Array}  array
+ * @param  {Array}  result
+ * @param  {Number} depth
+ * @return {Array}
+ */
+function flattenWithDepth (array, result, depth) {
+  for (var i = 0; i < array.length; i++) {
+    var value = array[i]
+
+    if (depth > 0 && Array.isArray(value)) {
+      flattenWithDepth(value, result, depth - 1)
+    } else {
+      result.push(value)
+    }
+  }
+
+  return result
+}
+
+/**
+ * Recursive flatten function. Omitting depth is slightly faster.
+ *
+ * @param  {Array} array
+ * @param  {Array} result
+ * @return {Array}
+ */
+function flattenForever (array, result) {
+  for (var i = 0; i < array.length; i++) {
+    var value = array[i]
+
+    if (Array.isArray(value)) {
+      flattenForever(value, result)
+    } else {
+      result.push(value)
+    }
+  }
+
+  return result
+}
+
+/**
+ * Flatten an array, with the ability to define a depth.
+ *
+ * @param  {Array}  array
+ * @param  {Number} depth
+ * @return {Array}
+ */
+function arrayFlatten (array, depth) {
+  if (depth == null) {
+    return flattenForever(array, [])
+  }
+
+  return flattenWithDepth(array, [], depth)
+}

+ 39 - 0
12_Ajax/server/node_modules/array-flatten/package.json

@@ -0,0 +1,39 @@
+{
+  "name": "array-flatten",
+  "version": "1.1.1",
+  "description": "Flatten an array of nested arrays into a single flat array",
+  "main": "array-flatten.js",
+  "files": [
+    "array-flatten.js",
+    "LICENSE"
+  ],
+  "scripts": {
+    "test": "istanbul cover _mocha -- -R spec"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/blakeembrey/array-flatten.git"
+  },
+  "keywords": [
+    "array",
+    "flatten",
+    "arguments",
+    "depth"
+  ],
+  "author": {
+    "name": "Blake Embrey",
+    "email": "hello@blakeembrey.com",
+    "url": "http://blakeembrey.me"
+  },
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/blakeembrey/array-flatten/issues"
+  },
+  "homepage": "https://github.com/blakeembrey/array-flatten",
+  "devDependencies": {
+    "istanbul": "^0.3.13",
+    "mocha": "^2.2.4",
+    "pre-commit": "^1.0.7",
+    "standard": "^3.7.3"
+  }
+}

+ 651 - 0
12_Ajax/server/node_modules/body-parser/HISTORY.md

@@ -0,0 +1,651 @@
+1.20.0 / 2022-04-02
+===================
+
+  * Fix error message for json parse whitespace in `strict`
+  * Fix internal error when inflated body exceeds limit
+  * Prevent loss of async hooks context
+  * Prevent hanging when request already read
+  * deps: depd@2.0.0
+    - Replace internal `eval` usage with `Function` constructor
+    - Use instance methods on `process` to check for listeners
+  * deps: http-errors@2.0.0
+    - deps: depd@2.0.0
+    - deps: statuses@2.0.1
+  * deps: on-finished@2.4.1
+  * deps: qs@6.10.3
+  * deps: raw-body@2.5.1
+    - deps: http-errors@2.0.0
+
+1.19.2 / 2022-02-15
+===================
+
+  * deps: bytes@3.1.2
+  * deps: qs@6.9.7
+    * Fix handling of `__proto__` keys
+  * deps: raw-body@2.4.3
+    - deps: bytes@3.1.2
+
+1.19.1 / 2021-12-10
+===================
+
+  * deps: bytes@3.1.1
+  * deps: http-errors@1.8.1
+    - deps: inherits@2.0.4
+    - deps: toidentifier@1.0.1
+    - deps: setprototypeof@1.2.0
+  * deps: qs@6.9.6
+  * deps: raw-body@2.4.2
+    - deps: bytes@3.1.1
+    - deps: http-errors@1.8.1
+  * deps: safe-buffer@5.2.1
+  * deps: type-is@~1.6.18
+
+1.19.0 / 2019-04-25
+===================
+
+  * deps: bytes@3.1.0
+    - Add petabyte (`pb`) support
+  * deps: http-errors@1.7.2
+    - Set constructor name when possible
+    - deps: setprototypeof@1.1.1
+    - deps: statuses@'>= 1.5.0 < 2'
+  * deps: iconv-lite@0.4.24
+    - Added encoding MIK
+  * deps: qs@6.7.0
+    - Fix parsing array brackets after index
+  * deps: raw-body@2.4.0
+    - deps: bytes@3.1.0
+    - deps: http-errors@1.7.2
+    - deps: iconv-lite@0.4.24
+  * deps: type-is@~1.6.17
+    - deps: mime-types@~2.1.24
+    - perf: prevent internal `throw` on invalid type
+
+1.18.3 / 2018-05-14
+===================
+
+  * Fix stack trace for strict json parse error
+  * deps: depd@~1.1.2
+    - perf: remove argument reassignment
+  * deps: http-errors@~1.6.3
+    - deps: depd@~1.1.2
+    - deps: setprototypeof@1.1.0
+    - deps: statuses@'>= 1.3.1 < 2'
+  * deps: iconv-lite@0.4.23
+    - Fix loading encoding with year appended
+    - Fix deprecation warnings on Node.js 10+
+  * deps: qs@6.5.2
+  * deps: raw-body@2.3.3
+    - deps: http-errors@1.6.3
+    - deps: iconv-lite@0.4.23
+  * deps: type-is@~1.6.16
+    - deps: mime-types@~2.1.18
+
+1.18.2 / 2017-09-22
+===================
+
+  * deps: debug@2.6.9
+  * perf: remove argument reassignment
+
+1.18.1 / 2017-09-12
+===================
+
+  * deps: content-type@~1.0.4
+    - perf: remove argument reassignment
+    - perf: skip parameter parsing when no parameters
+  * deps: iconv-lite@0.4.19
+    - Fix ISO-8859-1 regression
+    - Update Windows-1255
+  * deps: qs@6.5.1
+    - Fix parsing & compacting very deep objects
+  * deps: raw-body@2.3.2
+    - deps: iconv-lite@0.4.19
+
+1.18.0 / 2017-09-08
+===================
+
+  * Fix JSON strict violation error to match native parse error
+  * Include the `body` property on verify errors
+  * Include the `type` property on all generated errors
+  * Use `http-errors` to set status code on errors
+  * deps: bytes@3.0.0
+  * deps: debug@2.6.8
+  * deps: depd@~1.1.1
+    - Remove unnecessary `Buffer` loading
+  * deps: http-errors@~1.6.2
+    - deps: depd@1.1.1
+  * deps: iconv-lite@0.4.18
+    - Add support for React Native
+    - Add a warning if not loaded as utf-8
+    - Fix CESU-8 decoding in Node.js 8
+    - Improve speed of ISO-8859-1 encoding
+  * deps: qs@6.5.0
+  * deps: raw-body@2.3.1
+    - Use `http-errors` for standard emitted errors
+    - deps: bytes@3.0.0
+    - deps: iconv-lite@0.4.18
+    - perf: skip buffer decoding on overage chunk
+  * perf: prevent internal `throw` when missing charset
+
+1.17.2 / 2017-05-17
+===================
+
+  * deps: debug@2.6.7
+    - Fix `DEBUG_MAX_ARRAY_LENGTH`
+    - deps: ms@2.0.0
+  * deps: type-is@~1.6.15
+    - deps: mime-types@~2.1.15
+
+1.17.1 / 2017-03-06
+===================
+
+  * deps: qs@6.4.0
+    - Fix regression parsing keys starting with `[`
+
+1.17.0 / 2017-03-01
+===================
+
+  * deps: http-errors@~1.6.1
+    - Make `message` property enumerable for `HttpError`s
+    - deps: setprototypeof@1.0.3
+  * deps: qs@6.3.1
+    - Fix compacting nested arrays
+
+1.16.1 / 2017-02-10
+===================
+
+  * deps: debug@2.6.1
+    - Fix deprecation messages in WebStorm and other editors
+    - Undeprecate `DEBUG_FD` set to `1` or `2`
+
+1.16.0 / 2017-01-17
+===================
+
+  * deps: debug@2.6.0
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable
+    - Fix error when running under React Native
+    - Use same color for same namespace
+    - deps: ms@0.7.2
+  * deps: http-errors@~1.5.1
+    - deps: inherits@2.0.3
+    - deps: setprototypeof@1.0.2
+    - deps: statuses@'>= 1.3.1 < 2'
+  * deps: iconv-lite@0.4.15
+    - Added encoding MS-31J
+    - Added encoding MS-932
+    - Added encoding MS-936
+    - Added encoding MS-949
+    - Added encoding MS-950
+    - Fix GBK/GB18030 handling of Euro character
+  * deps: qs@6.2.1
+    - Fix array parsing from skipping empty values
+  * deps: raw-body@~2.2.0
+    - deps: iconv-lite@0.4.15
+  * deps: type-is@~1.6.14
+    - deps: mime-types@~2.1.13
+
+1.15.2 / 2016-06-19
+===================
+
+  * deps: bytes@2.4.0
+  * deps: content-type@~1.0.2
+    - perf: enable strict mode
+  * deps: http-errors@~1.5.0
+    - Use `setprototypeof` module to replace `__proto__` setting
+    - deps: statuses@'>= 1.3.0 < 2'
+    - perf: enable strict mode
+  * deps: qs@6.2.0
+  * deps: raw-body@~2.1.7
+    - deps: bytes@2.4.0
+    - perf: remove double-cleanup on happy path
+  * deps: type-is@~1.6.13
+    - deps: mime-types@~2.1.11
+
+1.15.1 / 2016-05-05
+===================
+
+  * deps: bytes@2.3.0
+    - Drop partial bytes on all parsed units
+    - Fix parsing byte string that looks like hex
+  * deps: raw-body@~2.1.6
+    - deps: bytes@2.3.0
+  * deps: type-is@~1.6.12
+    - deps: mime-types@~2.1.10
+
+1.15.0 / 2016-02-10
+===================
+
+  * deps: http-errors@~1.4.0
+    - Add `HttpError` export, for `err instanceof createError.HttpError`
+    - deps: inherits@2.0.1
+    - deps: statuses@'>= 1.2.1 < 2'
+  * deps: qs@6.1.0
+  * deps: type-is@~1.6.11
+    - deps: mime-types@~2.1.9
+
+1.14.2 / 2015-12-16
+===================
+
+  * deps: bytes@2.2.0
+  * deps: iconv-lite@0.4.13
+  * deps: qs@5.2.0
+  * deps: raw-body@~2.1.5
+    - deps: bytes@2.2.0
+    - deps: iconv-lite@0.4.13
+  * deps: type-is@~1.6.10
+    - deps: mime-types@~2.1.8
+
+1.14.1 / 2015-09-27
+===================
+
+  * Fix issue where invalid charset results in 400 when `verify` used
+  * deps: iconv-lite@0.4.12
+    - Fix CESU-8 decoding in Node.js 4.x
+  * deps: raw-body@~2.1.4
+    - Fix masking critical errors from `iconv-lite`
+    - deps: iconv-lite@0.4.12
+  * deps: type-is@~1.6.9
+    - deps: mime-types@~2.1.7
+
+1.14.0 / 2015-09-16
+===================
+
+  * Fix JSON strict parse error to match syntax errors
+  * Provide static `require` analysis in `urlencoded` parser
+  * deps: depd@~1.1.0
+    - Support web browser loading
+  * deps: qs@5.1.0
+  * deps: raw-body@~2.1.3
+    - Fix sync callback when attaching data listener causes sync read
+  * deps: type-is@~1.6.8
+    - Fix type error when given invalid type to match against
+    - deps: mime-types@~2.1.6
+
+1.13.3 / 2015-07-31
+===================
+
+  * deps: type-is@~1.6.6
+    - deps: mime-types@~2.1.4
+
+1.13.2 / 2015-07-05
+===================
+
+  * deps: iconv-lite@0.4.11
+  * deps: qs@4.0.0
+    - Fix dropping parameters like `hasOwnProperty`
+    - Fix user-visible incompatibilities from 3.1.0
+    - Fix various parsing edge cases
+  * deps: raw-body@~2.1.2
+    - Fix error stack traces to skip `makeError`
+    - deps: iconv-lite@0.4.11
+  * deps: type-is@~1.6.4
+    - deps: mime-types@~2.1.2
+    - perf: enable strict mode
+    - perf: remove argument reassignment
+
+1.13.1 / 2015-06-16
+===================
+
+  * deps: qs@2.4.2
+    - Downgraded from 3.1.0 because of user-visible incompatibilities
+
+1.13.0 / 2015-06-14
+===================
+
+  * Add `statusCode` property on `Error`s, in addition to `status`
+  * Change `type` default to `application/json` for JSON parser
+  * Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
+  * Provide static `require` analysis
+  * Use the `http-errors` module to generate errors
+  * deps: bytes@2.1.0
+    - Slight optimizations
+  * deps: iconv-lite@0.4.10
+    - The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails
+    - Leading BOM is now removed when decoding
+  * deps: on-finished@~2.3.0
+    - Add defined behavior for HTTP `CONNECT` requests
+    - Add defined behavior for HTTP `Upgrade` requests
+    - deps: ee-first@1.1.1
+  * deps: qs@3.1.0
+    - Fix dropping parameters like `hasOwnProperty`
+    - Fix various parsing edge cases
+    - Parsed object now has `null` prototype
+  * deps: raw-body@~2.1.1
+    - Use `unpipe` module for unpiping requests
+    - deps: iconv-lite@0.4.10
+  * deps: type-is@~1.6.3
+    - deps: mime-types@~2.1.1
+    - perf: reduce try block size
+    - perf: remove bitwise operations
+  * perf: enable strict mode
+  * perf: remove argument reassignment
+  * perf: remove delete call
+
+1.12.4 / 2015-05-10
+===================
+
+  * deps: debug@~2.2.0
+  * deps: qs@2.4.2
+    - Fix allowing parameters like `constructor`
+  * deps: on-finished@~2.2.1
+  * deps: raw-body@~2.0.1
+    - Fix a false-positive when unpiping in Node.js 0.8
+    - deps: bytes@2.0.1
+  * deps: type-is@~1.6.2
+    - deps: mime-types@~2.0.11
+
+1.12.3 / 2015-04-15
+===================
+
+  * Slight efficiency improvement when not debugging
+  * deps: depd@~1.0.1
+  * deps: iconv-lite@0.4.8
+    - Add encoding alias UNICODE-1-1-UTF-7
+  * deps: raw-body@1.3.4
+    - Fix hanging callback if request aborts during read
+    - deps: iconv-lite@0.4.8
+
+1.12.2 / 2015-03-16
+===================
+
+  * deps: qs@2.4.1
+    - Fix error when parameter `hasOwnProperty` is present
+
+1.12.1 / 2015-03-15
+===================
+
+  * deps: debug@~2.1.3
+    - Fix high intensity foreground color for bold
+    - deps: ms@0.7.0
+  * deps: type-is@~1.6.1
+    - deps: mime-types@~2.0.10
+
+1.12.0 / 2015-02-13
+===================
+
+  * add `debug` messages
+  * accept a function for the `type` option
+  * use `content-type` to parse `Content-Type` headers
+  * deps: iconv-lite@0.4.7
+    - Gracefully support enumerables on `Object.prototype`
+  * deps: raw-body@1.3.3
+    - deps: iconv-lite@0.4.7
+  * deps: type-is@~1.6.0
+    - fix argument reassignment
+    - fix false-positives in `hasBody` `Transfer-Encoding` check
+    - support wildcard for both type and subtype (`*/*`)
+    - deps: mime-types@~2.0.9
+
+1.11.0 / 2015-01-30
+===================
+
+  * make internal `extended: true` depth limit infinity
+  * deps: type-is@~1.5.6
+    - deps: mime-types@~2.0.8
+
+1.10.2 / 2015-01-20
+===================
+
+  * deps: iconv-lite@0.4.6
+    - Fix rare aliases of single-byte encodings
+  * deps: raw-body@1.3.2
+    - deps: iconv-lite@0.4.6
+
+1.10.1 / 2015-01-01
+===================
+
+  * deps: on-finished@~2.2.0
+  * deps: type-is@~1.5.5
+    - deps: mime-types@~2.0.7
+
+1.10.0 / 2014-12-02
+===================
+
+  * make internal `extended: true` array limit dynamic
+
+1.9.3 / 2014-11-21
+==================
+
+  * deps: iconv-lite@0.4.5
+    - Fix Windows-31J and X-SJIS encoding support
+  * deps: qs@2.3.3
+    - Fix `arrayLimit` behavior
+  * deps: raw-body@1.3.1
+    - deps: iconv-lite@0.4.5
+  * deps: type-is@~1.5.3
+    - deps: mime-types@~2.0.3
+
+1.9.2 / 2014-10-27
+==================
+
+  * deps: qs@2.3.2
+    - Fix parsing of mixed objects and values
+
+1.9.1 / 2014-10-22
+==================
+
+  * deps: on-finished@~2.1.1
+    - Fix handling of pipelined requests
+  * deps: qs@2.3.0
+    - Fix parsing of mixed implicit and explicit arrays
+  * deps: type-is@~1.5.2
+    - deps: mime-types@~2.0.2
+
+1.9.0 / 2014-09-24
+==================
+
+  * include the charset in "unsupported charset" error message
+  * include the encoding in "unsupported content encoding" error message
+  * deps: depd@~1.0.0
+
+1.8.4 / 2014-09-23
+==================
+
+  * fix content encoding to be case-insensitive
+
+1.8.3 / 2014-09-19
+==================
+
+  * deps: qs@2.2.4
+    - Fix issue with object keys starting with numbers truncated
+
+1.8.2 / 2014-09-15
+==================
+
+  * deps: depd@0.4.5
+
+1.8.1 / 2014-09-07
+==================
+
+  * deps: media-typer@0.3.0
+  * deps: type-is@~1.5.1
+
+1.8.0 / 2014-09-05
+==================
+
+  * make empty-body-handling consistent between chunked requests
+    - empty `json` produces `{}`
+    - empty `raw` produces `new Buffer(0)`
+    - empty `text` produces `''`
+    - empty `urlencoded` produces `{}`
+  * deps: qs@2.2.3
+    - Fix issue where first empty value in array is discarded
+  * deps: type-is@~1.5.0
+    - fix `hasbody` to be true for `content-length: 0`
+
+1.7.0 / 2014-09-01
+==================
+
+  * add `parameterLimit` option to `urlencoded` parser
+  * change `urlencoded` extended array limit to 100
+  * respond with 413 when over `parameterLimit` in `urlencoded`
+
+1.6.7 / 2014-08-29
+==================
+
+  * deps: qs@2.2.2
+    - Remove unnecessary cloning
+
+1.6.6 / 2014-08-27
+==================
+
+  * deps: qs@2.2.0
+    - Array parsing fix
+    - Performance improvements
+
+1.6.5 / 2014-08-16
+==================
+
+  * deps: on-finished@2.1.0
+
+1.6.4 / 2014-08-14
+==================
+
+  * deps: qs@1.2.2
+
+1.6.3 / 2014-08-10
+==================
+
+  * deps: qs@1.2.1
+
+1.6.2 / 2014-08-07
+==================
+
+  * deps: qs@1.2.0
+    - Fix parsing array of objects
+
+1.6.1 / 2014-08-06
+==================
+
+  * deps: qs@1.1.0
+    - Accept urlencoded square brackets
+    - Accept empty values in implicit array notation
+
+1.6.0 / 2014-08-05
+==================
+
+  * deps: qs@1.0.2
+    - Complete rewrite
+    - Limits array length to 20
+    - Limits object depth to 5
+    - Limits parameters to 1,000
+
+1.5.2 / 2014-07-27
+==================
+
+  * deps: depd@0.4.4
+    - Work-around v8 generating empty stack traces
+
+1.5.1 / 2014-07-26
+==================
+
+  * deps: depd@0.4.3
+    - Fix exception when global `Error.stackTraceLimit` is too low
+
+1.5.0 / 2014-07-20
+==================
+
+  * deps: depd@0.4.2
+    - Add `TRACE_DEPRECATION` environment variable
+    - Remove non-standard grey color from color output
+    - Support `--no-deprecation` argument
+    - Support `--trace-deprecation` argument
+  * deps: iconv-lite@0.4.4
+    - Added encoding UTF-7
+  * deps: raw-body@1.3.0
+    - deps: iconv-lite@0.4.4
+    - Added encoding UTF-7
+    - Fix `Cannot switch to old mode now` error on Node.js 0.10+
+  * deps: type-is@~1.3.2
+
+1.4.3 / 2014-06-19
+==================
+
+  * deps: type-is@1.3.1
+    - fix global variable leak
+
+1.4.2 / 2014-06-19
+==================
+
+  * deps: type-is@1.3.0
+    - improve type parsing
+
+1.4.1 / 2014-06-19
+==================
+
+  * fix urlencoded extended deprecation message
+
+1.4.0 / 2014-06-19
+==================
+
+  * add `text` parser
+  * add `raw` parser
+  * check accepted charset in content-type (accepts utf-8)
+  * check accepted encoding in content-encoding (accepts identity)
+  * deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed
+  * deprecate `urlencoded()` without provided `extended` option
+  * lazy-load urlencoded parsers
+  * parsers split into files for reduced mem usage
+  * support gzip and deflate bodies
+    - set `inflate: false` to turn off
+  * deps: raw-body@1.2.2
+    - Support all encodings from `iconv-lite`
+
+1.3.1 / 2014-06-11
+==================
+
+  * deps: type-is@1.2.1
+    - Switch dependency from mime to mime-types@1.0.0
+
+1.3.0 / 2014-05-31
+==================
+
+  * add `extended` option to urlencoded parser
+
+1.2.2 / 2014-05-27
+==================
+
+  * deps: raw-body@1.1.6
+    - assert stream encoding on node.js 0.8
+    - assert stream encoding on node.js < 0.10.6
+    - deps: bytes@1
+
+1.2.1 / 2014-05-26
+==================
+
+  * invoke `next(err)` after request fully read
+    - prevents hung responses and socket hang ups
+
+1.2.0 / 2014-05-11
+==================
+
+  * add `verify` option
+  * deps: type-is@1.2.0
+    - support suffix matching
+
+1.1.2 / 2014-05-11
+==================
+
+  * improve json parser speed
+
+1.1.1 / 2014-05-11
+==================
+
+  * fix repeated limit parsing with every request
+
+1.1.0 / 2014-05-10
+==================
+
+  * add `type` option
+  * deps: pin for safety and consistency
+
+1.0.2 / 2014-04-14
+==================
+
+  * use `type-is` module
+
+1.0.1 / 2014-03-20
+==================
+
+  * lower default limits to 100kb

+ 23 - 0
12_Ajax/server/node_modules/body-parser/LICENSE

@@ -0,0 +1,23 @@
+(The MIT License)
+
+Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
+Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.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.

+ 464 - 0
12_Ajax/server/node_modules/body-parser/README.md

@@ -0,0 +1,464 @@
+# body-parser
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+  * [busboy](https://www.npmjs.org/package/busboy#readme) and
+    [connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)
+  * [multiparty](https://www.npmjs.org/package/multiparty#readme) and
+    [connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)
+  * [formidable](https://www.npmjs.org/package/formidable#readme)
+  * [multer](https://www.npmjs.org/package/multer#readme)
+
+This module provides the following parsers:
+
+  * [JSON body parser](#bodyparserjsonoptions)
+  * [Raw body parser](#bodyparserrawoptions)
+  * [Text body parser](#bodyparsertextoptions)
+  * [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.org/package/body#readme)
+- [co-body](https://www.npmjs.org/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+var bodyParser = require('body-parser')
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option, or an empty
+object (`{}`) if there was no body to parse, the `Content-Type` was not matched,
+or an error occurred.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip` and
+`deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip` and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.org/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip` and `deflate` encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip` and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The `extended` option allows to choose between parsing the URL-encoded data
+with the `querystring` library (when `false`) or the `qs` library (when
+`true`). The "extended" syntax allows for rich objects and arrays to be
+encoded into the URL-encoded format, allowing for a JSON-like experience
+with URL-encoded. For more information, please
+[see the qs library](https://www.npmjs.org/package/qs#readme).
+
+Defaults to `true`, but using the default has been deprecated. Please
+research into the difference between `qs` and `querystring` and choose the
+appropriate setting.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the reqest body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+var express = require('express')
+var bodyParser = require('body-parser')
+
+var app = express()
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded({ extended: false }))
+
+// parse application/json
+app.use(bodyParser.json())
+
+app.use(function (req, res) {
+  res.setHeader('Content-Type', 'text/plain')
+  res.write('you posted:\n')
+  res.end(JSON.stringify(req.body, null, 2))
+})
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+var express = require('express')
+var bodyParser = require('body-parser')
+
+var app = express()
+
+// create application/json parser
+var jsonParser = bodyParser.json()
+
+// create application/x-www-form-urlencoded parser
+var urlencodedParser = bodyParser.urlencoded({ extended: false })
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+  res.send('welcome, ' + req.body.username)
+})
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+  // create user in req.body
+})
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+var express = require('express')
+var bodyParser = require('body-parser')
+
+var app = express()
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }))
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }))
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/body-parser.svg
+[npm-url]: https://npmjs.org/package/body-parser
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/body-parser/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/body-parser.svg
+[downloads-url]: https://npmjs.org/package/body-parser
+[github-actions-ci-image]: https://img.shields.io/github/workflow/status/expressjs/body-parser/ci/master?label=ci
+[github-actions-ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml

+ 25 - 0
12_Ajax/server/node_modules/body-parser/SECURITY.md

@@ -0,0 +1,25 @@
+# Security Policies and Procedures
+
+## Reporting a Bug
+
+The Express team and community take all security bugs seriously. Thank you
+for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing the current owner(s) of `body-parser`. This
+information can be found in the npm registry using the command
+`npm owner ls body-parser`.
+If unsure or unable to get the information from the above, open an issue
+in the [project issue tracker](https://github.com/expressjs/body-parser/issues)
+asking for the current contact information.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+At least one owner will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the owners will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.

+ 157 - 0
12_Ajax/server/node_modules/body-parser/index.js

@@ -0,0 +1,157 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var deprecate = require('depd')('body-parser')
+
+/**
+ * Cache of loaded parsers.
+ * @private
+ */
+
+var parsers = Object.create(null)
+
+/**
+ * @typedef Parsers
+ * @type {function}
+ * @property {function} json
+ * @property {function} raw
+ * @property {function} text
+ * @property {function} urlencoded
+ */
+
+/**
+ * Module exports.
+ * @type {Parsers}
+ */
+
+exports = module.exports = deprecate.function(bodyParser,
+  'bodyParser: use individual json/urlencoded middlewares')
+
+/**
+ * JSON parser.
+ * @public
+ */
+
+Object.defineProperty(exports, 'json', {
+  configurable: true,
+  enumerable: true,
+  get: createParserGetter('json')
+})
+
+/**
+ * Raw parser.
+ * @public
+ */
+
+Object.defineProperty(exports, 'raw', {
+  configurable: true,
+  enumerable: true,
+  get: createParserGetter('raw')
+})
+
+/**
+ * Text parser.
+ * @public
+ */
+
+Object.defineProperty(exports, 'text', {
+  configurable: true,
+  enumerable: true,
+  get: createParserGetter('text')
+})
+
+/**
+ * URL-encoded parser.
+ * @public
+ */
+
+Object.defineProperty(exports, 'urlencoded', {
+  configurable: true,
+  enumerable: true,
+  get: createParserGetter('urlencoded')
+})
+
+/**
+ * Create a middleware to parse json and urlencoded bodies.
+ *
+ * @param {object} [options]
+ * @return {function}
+ * @deprecated
+ * @public
+ */
+
+function bodyParser (options) {
+  var opts = {}
+
+  // exclude type option
+  if (options) {
+    for (var prop in options) {
+      if (prop !== 'type') {
+        opts[prop] = options[prop]
+      }
+    }
+  }
+
+  var _urlencoded = exports.urlencoded(opts)
+  var _json = exports.json(opts)
+
+  return function bodyParser (req, res, next) {
+    _json(req, res, function (err) {
+      if (err) return next(err)
+      _urlencoded(req, res, next)
+    })
+  }
+}
+
+/**
+ * Create a getter for loading a parser.
+ * @private
+ */
+
+function createParserGetter (name) {
+  return function get () {
+    return loadParser(name)
+  }
+}
+
+/**
+ * Load a parser module.
+ * @private
+ */
+
+function loadParser (parserName) {
+  var parser = parsers[parserName]
+
+  if (parser !== undefined) {
+    return parser
+  }
+
+  // this uses a switch for static require analysis
+  switch (parserName) {
+    case 'json':
+      parser = require('./lib/types/json')
+      break
+    case 'raw':
+      parser = require('./lib/types/raw')
+      break
+    case 'text':
+      parser = require('./lib/types/text')
+      break
+    case 'urlencoded':
+      parser = require('./lib/types/urlencoded')
+      break
+  }
+
+  // store to prevent invoking require()
+  return (parsers[parserName] = parser)
+}

+ 205 - 0
12_Ajax/server/node_modules/body-parser/lib/read.js

@@ -0,0 +1,205 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var createError = require('http-errors')
+var destroy = require('destroy')
+var getBody = require('raw-body')
+var iconv = require('iconv-lite')
+var onFinished = require('on-finished')
+var unpipe = require('unpipe')
+var zlib = require('zlib')
+
+/**
+ * Module exports.
+ */
+
+module.exports = read
+
+/**
+ * Read a request into a buffer and parse.
+ *
+ * @param {object} req
+ * @param {object} res
+ * @param {function} next
+ * @param {function} parse
+ * @param {function} debug
+ * @param {object} options
+ * @private
+ */
+
+function read (req, res, next, parse, debug, options) {
+  var length
+  var opts = options
+  var stream
+
+  // flag as parsed
+  req._body = true
+
+  // read options
+  var encoding = opts.encoding !== null
+    ? opts.encoding
+    : null
+  var verify = opts.verify
+
+  try {
+    // get the content stream
+    stream = contentstream(req, debug, opts.inflate)
+    length = stream.length
+    stream.length = undefined
+  } catch (err) {
+    return next(err)
+  }
+
+  // set raw-body options
+  opts.length = length
+  opts.encoding = verify
+    ? null
+    : encoding
+
+  // assert charset is supported
+  if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
+    return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
+      charset: encoding.toLowerCase(),
+      type: 'charset.unsupported'
+    }))
+  }
+
+  // read body
+  debug('read body')
+  getBody(stream, opts, function (error, body) {
+    if (error) {
+      var _error
+
+      if (error.type === 'encoding.unsupported') {
+        // echo back charset
+        _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
+          charset: encoding.toLowerCase(),
+          type: 'charset.unsupported'
+        })
+      } else {
+        // set status code on error
+        _error = createError(400, error)
+      }
+
+      // unpipe from stream and destroy
+      if (stream !== req) {
+        unpipe(req)
+        destroy(stream, true)
+      }
+
+      // read off entire request
+      dump(req, function onfinished () {
+        next(createError(400, _error))
+      })
+      return
+    }
+
+    // verify
+    if (verify) {
+      try {
+        debug('verify body')
+        verify(req, res, body, encoding)
+      } catch (err) {
+        next(createError(403, err, {
+          body: body,
+          type: err.type || 'entity.verify.failed'
+        }))
+        return
+      }
+    }
+
+    // parse
+    var str = body
+    try {
+      debug('parse body')
+      str = typeof body !== 'string' && encoding !== null
+        ? iconv.decode(body, encoding)
+        : body
+      req.body = parse(str)
+    } catch (err) {
+      next(createError(400, err, {
+        body: str,
+        type: err.type || 'entity.parse.failed'
+      }))
+      return
+    }
+
+    next()
+  })
+}
+
+/**
+ * Get the content stream of the request.
+ *
+ * @param {object} req
+ * @param {function} debug
+ * @param {boolean} [inflate=true]
+ * @return {object}
+ * @api private
+ */
+
+function contentstream (req, debug, inflate) {
+  var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
+  var length = req.headers['content-length']
+  var stream
+
+  debug('content-encoding "%s"', encoding)
+
+  if (inflate === false && encoding !== 'identity') {
+    throw createError(415, 'content encoding unsupported', {
+      encoding: encoding,
+      type: 'encoding.unsupported'
+    })
+  }
+
+  switch (encoding) {
+    case 'deflate':
+      stream = zlib.createInflate()
+      debug('inflate body')
+      req.pipe(stream)
+      break
+    case 'gzip':
+      stream = zlib.createGunzip()
+      debug('gunzip body')
+      req.pipe(stream)
+      break
+    case 'identity':
+      stream = req
+      stream.length = length
+      break
+    default:
+      throw createError(415, 'unsupported content encoding "' + encoding + '"', {
+        encoding: encoding,
+        type: 'encoding.unsupported'
+      })
+  }
+
+  return stream
+}
+
+/**
+ * Dump the contents of a request.
+ *
+ * @param {object} req
+ * @param {function} callback
+ * @api private
+ */
+
+function dump (req, callback) {
+  if (onFinished.isFinished(req)) {
+    callback(null)
+  } else {
+    onFinished(req, callback)
+    req.resume()
+  }
+}

+ 236 - 0
12_Ajax/server/node_modules/body-parser/lib/types/json.js

@@ -0,0 +1,236 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var bytes = require('bytes')
+var contentType = require('content-type')
+var createError = require('http-errors')
+var debug = require('debug')('body-parser:json')
+var read = require('../read')
+var typeis = require('type-is')
+
+/**
+ * Module exports.
+ */
+
+module.exports = json
+
+/**
+ * RegExp to match the first non-space in a string.
+ *
+ * Allowed whitespace is defined in RFC 7159:
+ *
+ *    ws = *(
+ *            %x20 /              ; Space
+ *            %x09 /              ; Horizontal tab
+ *            %x0A /              ; Line feed or New line
+ *            %x0D )              ; Carriage return
+ */
+
+var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex
+
+/**
+ * Create a middleware to parse JSON bodies.
+ *
+ * @param {object} [options]
+ * @return {function}
+ * @public
+ */
+
+function json (options) {
+  var opts = options || {}
+
+  var limit = typeof opts.limit !== 'number'
+    ? bytes.parse(opts.limit || '100kb')
+    : opts.limit
+  var inflate = opts.inflate !== false
+  var reviver = opts.reviver
+  var strict = opts.strict !== false
+  var type = opts.type || 'application/json'
+  var verify = opts.verify || false
+
+  if (verify !== false && typeof verify !== 'function') {
+    throw new TypeError('option verify must be function')
+  }
+
+  // create the appropriate type checking function
+  var shouldParse = typeof type !== 'function'
+    ? typeChecker(type)
+    : type
+
+  function parse (body) {
+    if (body.length === 0) {
+      // special-case empty json body, as it's a common client-side mistake
+      // TODO: maybe make this configurable or part of "strict" option
+      return {}
+    }
+
+    if (strict) {
+      var first = firstchar(body)
+
+      if (first !== '{' && first !== '[') {
+        debug('strict violation')
+        throw createStrictSyntaxError(body, first)
+      }
+    }
+
+    try {
+      debug('parse json')
+      return JSON.parse(body, reviver)
+    } catch (e) {
+      throw normalizeJsonSyntaxError(e, {
+        message: e.message,
+        stack: e.stack
+      })
+    }
+  }
+
+  return function jsonParser (req, res, next) {
+    if (req._body) {
+      debug('body already parsed')
+      next()
+      return
+    }
+
+    req.body = req.body || {}
+
+    // skip requests without bodies
+    if (!typeis.hasBody(req)) {
+      debug('skip empty body')
+      next()
+      return
+    }
+
+    debug('content-type %j', req.headers['content-type'])
+
+    // determine if request should be parsed
+    if (!shouldParse(req)) {
+      debug('skip parsing')
+      next()
+      return
+    }
+
+    // assert charset per RFC 7159 sec 8.1
+    var charset = getCharset(req) || 'utf-8'
+    if (charset.slice(0, 4) !== 'utf-') {
+      debug('invalid charset')
+      next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
+        charset: charset,
+        type: 'charset.unsupported'
+      }))
+      return
+    }
+
+    // read
+    read(req, res, next, parse, debug, {
+      encoding: charset,
+      inflate: inflate,
+      limit: limit,
+      verify: verify
+    })
+  }
+}
+
+/**
+ * Create strict violation syntax error matching native error.
+ *
+ * @param {string} str
+ * @param {string} char
+ * @return {Error}
+ * @private
+ */
+
+function createStrictSyntaxError (str, char) {
+  var index = str.indexOf(char)
+  var partial = index !== -1
+    ? str.substring(0, index) + '#'
+    : ''
+
+  try {
+    JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation')
+  } catch (e) {
+    return normalizeJsonSyntaxError(e, {
+      message: e.message.replace('#', char),
+      stack: e.stack
+    })
+  }
+}
+
+/**
+ * Get the first non-whitespace character in a string.
+ *
+ * @param {string} str
+ * @return {function}
+ * @private
+ */
+
+function firstchar (str) {
+  var match = FIRST_CHAR_REGEXP.exec(str)
+
+  return match
+    ? match[1]
+    : undefined
+}
+
+/**
+ * Get the charset of a request.
+ *
+ * @param {object} req
+ * @api private
+ */
+
+function getCharset (req) {
+  try {
+    return (contentType.parse(req).parameters.charset || '').toLowerCase()
+  } catch (e) {
+    return undefined
+  }
+}
+
+/**
+ * Normalize a SyntaxError for JSON.parse.
+ *
+ * @param {SyntaxError} error
+ * @param {object} obj
+ * @return {SyntaxError}
+ */
+
+function normalizeJsonSyntaxError (error, obj) {
+  var keys = Object.getOwnPropertyNames(error)
+
+  for (var i = 0; i < keys.length; i++) {
+    var key = keys[i]
+    if (key !== 'stack' && key !== 'message') {
+      delete error[key]
+    }
+  }
+
+  // replace stack before message for Node.js 0.10 and below
+  error.stack = obj.stack.replace(error.message, obj.message)
+  error.message = obj.message
+
+  return error
+}
+
+/**
+ * Get the simple type checker.
+ *
+ * @param {string} type
+ * @return {function}
+ */
+
+function typeChecker (type) {
+  return function checkType (req) {
+    return Boolean(typeis(req, type))
+  }
+}

+ 101 - 0
12_Ajax/server/node_modules/body-parser/lib/types/raw.js

@@ -0,0 +1,101 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ */
+
+var bytes = require('bytes')
+var debug = require('debug')('body-parser:raw')
+var read = require('../read')
+var typeis = require('type-is')
+
+/**
+ * Module exports.
+ */
+
+module.exports = raw
+
+/**
+ * Create a middleware to parse raw bodies.
+ *
+ * @param {object} [options]
+ * @return {function}
+ * @api public
+ */
+
+function raw (options) {
+  var opts = options || {}
+
+  var inflate = opts.inflate !== false
+  var limit = typeof opts.limit !== 'number'
+    ? bytes.parse(opts.limit || '100kb')
+    : opts.limit
+  var type = opts.type || 'application/octet-stream'
+  var verify = opts.verify || false
+
+  if (verify !== false && typeof verify !== 'function') {
+    throw new TypeError('option verify must be function')
+  }
+
+  // create the appropriate type checking function
+  var shouldParse = typeof type !== 'function'
+    ? typeChecker(type)
+    : type
+
+  function parse (buf) {
+    return buf
+  }
+
+  return function rawParser (req, res, next) {
+    if (req._body) {
+      debug('body already parsed')
+      next()
+      return
+    }
+
+    req.body = req.body || {}
+
+    // skip requests without bodies
+    if (!typeis.hasBody(req)) {
+      debug('skip empty body')
+      next()
+      return
+    }
+
+    debug('content-type %j', req.headers['content-type'])
+
+    // determine if request should be parsed
+    if (!shouldParse(req)) {
+      debug('skip parsing')
+      next()
+      return
+    }
+
+    // read
+    read(req, res, next, parse, debug, {
+      encoding: null,
+      inflate: inflate,
+      limit: limit,
+      verify: verify
+    })
+  }
+}
+
+/**
+ * Get the simple type checker.
+ *
+ * @param {string} type
+ * @return {function}
+ */
+
+function typeChecker (type) {
+  return function checkType (req) {
+    return Boolean(typeis(req, type))
+  }
+}

+ 121 - 0
12_Ajax/server/node_modules/body-parser/lib/types/text.js

@@ -0,0 +1,121 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ */
+
+var bytes = require('bytes')
+var contentType = require('content-type')
+var debug = require('debug')('body-parser:text')
+var read = require('../read')
+var typeis = require('type-is')
+
+/**
+ * Module exports.
+ */
+
+module.exports = text
+
+/**
+ * Create a middleware to parse text bodies.
+ *
+ * @param {object} [options]
+ * @return {function}
+ * @api public
+ */
+
+function text (options) {
+  var opts = options || {}
+
+  var defaultCharset = opts.defaultCharset || 'utf-8'
+  var inflate = opts.inflate !== false
+  var limit = typeof opts.limit !== 'number'
+    ? bytes.parse(opts.limit || '100kb')
+    : opts.limit
+  var type = opts.type || 'text/plain'
+  var verify = opts.verify || false
+
+  if (verify !== false && typeof verify !== 'function') {
+    throw new TypeError('option verify must be function')
+  }
+
+  // create the appropriate type checking function
+  var shouldParse = typeof type !== 'function'
+    ? typeChecker(type)
+    : type
+
+  function parse (buf) {
+    return buf
+  }
+
+  return function textParser (req, res, next) {
+    if (req._body) {
+      debug('body already parsed')
+      next()
+      return
+    }
+
+    req.body = req.body || {}
+
+    // skip requests without bodies
+    if (!typeis.hasBody(req)) {
+      debug('skip empty body')
+      next()
+      return
+    }
+
+    debug('content-type %j', req.headers['content-type'])
+
+    // determine if request should be parsed
+    if (!shouldParse(req)) {
+      debug('skip parsing')
+      next()
+      return
+    }
+
+    // get charset
+    var charset = getCharset(req) || defaultCharset
+
+    // read
+    read(req, res, next, parse, debug, {
+      encoding: charset,
+      inflate: inflate,
+      limit: limit,
+      verify: verify
+    })
+  }
+}
+
+/**
+ * Get the charset of a request.
+ *
+ * @param {object} req
+ * @api private
+ */
+
+function getCharset (req) {
+  try {
+    return (contentType.parse(req).parameters.charset || '').toLowerCase()
+  } catch (e) {
+    return undefined
+  }
+}
+
+/**
+ * Get the simple type checker.
+ *
+ * @param {string} type
+ * @return {function}
+ */
+
+function typeChecker (type) {
+  return function checkType (req) {
+    return Boolean(typeis(req, type))
+  }
+}

+ 284 - 0
12_Ajax/server/node_modules/body-parser/lib/types/urlencoded.js

@@ -0,0 +1,284 @@
+/*!
+ * body-parser
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var bytes = require('bytes')
+var contentType = require('content-type')
+var createError = require('http-errors')
+var debug = require('debug')('body-parser:urlencoded')
+var deprecate = require('depd')('body-parser')
+var read = require('../read')
+var typeis = require('type-is')
+
+/**
+ * Module exports.
+ */
+
+module.exports = urlencoded
+
+/**
+ * Cache of parser modules.
+ */
+
+var parsers = Object.create(null)
+
+/**
+ * Create a middleware to parse urlencoded bodies.
+ *
+ * @param {object} [options]
+ * @return {function}
+ * @public
+ */
+
+function urlencoded (options) {
+  var opts = options || {}
+
+  // notice because option default will flip in next major
+  if (opts.extended === undefined) {
+    deprecate('undefined extended: provide extended option')
+  }
+
+  var extended = opts.extended !== false
+  var inflate = opts.inflate !== false
+  var limit = typeof opts.limit !== 'number'
+    ? bytes.parse(opts.limit || '100kb')
+    : opts.limit
+  var type = opts.type || 'application/x-www-form-urlencoded'
+  var verify = opts.verify || false
+
+  if (verify !== false && typeof verify !== 'function') {
+    throw new TypeError('option verify must be function')
+  }
+
+  // create the appropriate query parser
+  var queryparse = extended
+    ? extendedparser(opts)
+    : simpleparser(opts)
+
+  // create the appropriate type checking function
+  var shouldParse = typeof type !== 'function'
+    ? typeChecker(type)
+    : type
+
+  function parse (body) {
+    return body.length
+      ? queryparse(body)
+      : {}
+  }
+
+  return function urlencodedParser (req, res, next) {
+    if (req._body) {
+      debug('body already parsed')
+      next()
+      return
+    }
+
+    req.body = req.body || {}
+
+    // skip requests without bodies
+    if (!typeis.hasBody(req)) {
+      debug('skip empty body')
+      next()
+      return
+    }
+
+    debug('content-type %j', req.headers['content-type'])
+
+    // determine if request should be parsed
+    if (!shouldParse(req)) {
+      debug('skip parsing')
+      next()
+      return
+    }
+
+    // assert charset
+    var charset = getCharset(req) || 'utf-8'
+    if (charset !== 'utf-8') {
+      debug('invalid charset')
+      next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
+        charset: charset,
+        type: 'charset.unsupported'
+      }))
+      return
+    }
+
+    // read
+    read(req, res, next, parse, debug, {
+      debug: debug,
+      encoding: charset,
+      inflate: inflate,
+      limit: limit,
+      verify: verify
+    })
+  }
+}
+
+/**
+ * Get the extended query parser.
+ *
+ * @param {object} options
+ */
+
+function extendedparser (options) {
+  var parameterLimit = options.parameterLimit !== undefined
+    ? options.parameterLimit
+    : 1000
+  var parse = parser('qs')
+
+  if (isNaN(parameterLimit) || parameterLimit < 1) {
+    throw new TypeError('option parameterLimit must be a positive number')
+  }
+
+  if (isFinite(parameterLimit)) {
+    parameterLimit = parameterLimit | 0
+  }
+
+  return function queryparse (body) {
+    var paramCount = parameterCount(body, parameterLimit)
+
+    if (paramCount === undefined) {
+      debug('too many parameters')
+      throw createError(413, 'too many parameters', {
+        type: 'parameters.too.many'
+      })
+    }
+
+    var arrayLimit = Math.max(100, paramCount)
+
+    debug('parse extended urlencoding')
+    return parse(body, {
+      allowPrototypes: true,
+      arrayLimit: arrayLimit,
+      depth: Infinity,
+      parameterLimit: parameterLimit
+    })
+  }
+}
+
+/**
+ * Get the charset of a request.
+ *
+ * @param {object} req
+ * @api private
+ */
+
+function getCharset (req) {
+  try {
+    return (contentType.parse(req).parameters.charset || '').toLowerCase()
+  } catch (e) {
+    return undefined
+  }
+}
+
+/**
+ * Count the number of parameters, stopping once limit reached
+ *
+ * @param {string} body
+ * @param {number} limit
+ * @api private
+ */
+
+function parameterCount (body, limit) {
+  var count = 0
+  var index = 0
+
+  while ((index = body.indexOf('&', index)) !== -1) {
+    count++
+    index++
+
+    if (count === limit) {
+      return undefined
+    }
+  }
+
+  return count
+}
+
+/**
+ * Get parser for module name dynamically.
+ *
+ * @param {string} name
+ * @return {function}
+ * @api private
+ */
+
+function parser (name) {
+  var mod = parsers[name]
+
+  if (mod !== undefined) {
+    return mod.parse
+  }
+
+  // this uses a switch for static require analysis
+  switch (name) {
+    case 'qs':
+      mod = require('qs')
+      break
+    case 'querystring':
+      mod = require('querystring')
+      break
+  }
+
+  // store to prevent invoking require()
+  parsers[name] = mod
+
+  return mod.parse
+}
+
+/**
+ * Get the simple query parser.
+ *
+ * @param {object} options
+ */
+
+function simpleparser (options) {
+  var parameterLimit = options.parameterLimit !== undefined
+    ? options.parameterLimit
+    : 1000
+  var parse = parser('querystring')
+
+  if (isNaN(parameterLimit) || parameterLimit < 1) {
+    throw new TypeError('option parameterLimit must be a positive number')
+  }
+
+  if (isFinite(parameterLimit)) {
+    parameterLimit = parameterLimit | 0
+  }
+
+  return function queryparse (body) {
+    var paramCount = parameterCount(body, parameterLimit)
+
+    if (paramCount === undefined) {
+      debug('too many parameters')
+      throw createError(413, 'too many parameters', {
+        type: 'parameters.too.many'
+      })
+    }
+
+    debug('parse urlencoding')
+    return parse(body, undefined, undefined, { maxKeys: parameterLimit })
+  }
+}
+
+/**
+ * Get the simple type checker.
+ *
+ * @param {string} type
+ * @return {function}
+ */
+
+function typeChecker (type) {
+  return function checkType (req) {
+    return Boolean(typeis(req, type))
+  }
+}

+ 56 - 0
12_Ajax/server/node_modules/body-parser/package.json

@@ -0,0 +1,56 @@
+{
+  "name": "body-parser",
+  "description": "Node.js body parsing middleware",
+  "version": "1.20.0",
+  "contributors": [
+    "Douglas Christopher Wilson <doug@somethingdoug.com>",
+    "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
+  ],
+  "license": "MIT",
+  "repository": "expressjs/body-parser",
+  "dependencies": {
+    "bytes": "3.1.2",
+    "content-type": "~1.0.4",
+    "debug": "2.6.9",
+    "depd": "2.0.0",
+    "destroy": "1.2.0",
+    "http-errors": "2.0.0",
+    "iconv-lite": "0.4.24",
+    "on-finished": "2.4.1",
+    "qs": "6.10.3",
+    "raw-body": "2.5.1",
+    "type-is": "~1.6.18",
+    "unpipe": "1.0.0"
+  },
+  "devDependencies": {
+    "eslint": "7.32.0",
+    "eslint-config-standard": "14.1.1",
+    "eslint-plugin-import": "2.25.4",
+    "eslint-plugin-markdown": "2.2.1",
+    "eslint-plugin-node": "11.1.0",
+    "eslint-plugin-promise": "5.2.0",
+    "eslint-plugin-standard": "4.1.0",
+    "methods": "1.1.2",
+    "mocha": "9.2.2",
+    "nyc": "15.1.0",
+    "safe-buffer": "5.2.1",
+    "supertest": "6.2.2"
+  },
+  "files": [
+    "lib/",
+    "LICENSE",
+    "HISTORY.md",
+    "SECURITY.md",
+    "index.js"
+  ],
+  "engines": {
+    "node": ">= 0.8",
+    "npm": "1.2.8000 || >= 1.4.16"
+  },
+  "scripts": {
+    "lint": "eslint .",
+    "test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/",
+    "test-ci": "nyc --reporter=lcov --reporter=text npm test",
+    "test-cov": "nyc --reporter=html --reporter=text npm test"
+  }
+}

+ 97 - 0
12_Ajax/server/node_modules/bytes/History.md

@@ -0,0 +1,97 @@
+3.1.2 / 2022-01-27
+==================
+
+  * Fix return value for un-parsable strings
+
+3.1.1 / 2021-11-15
+==================
+
+  * Fix "thousandsSeparator" incorrecting formatting fractional part
+
+3.1.0 / 2019-01-22
+==================
+
+  * Add petabyte (`pb`) support
+
+3.0.0 / 2017-08-31
+==================
+
+  * Change "kB" to "KB" in format output
+  * Remove support for Node.js 0.6
+  * Remove support for ComponentJS
+
+2.5.0 / 2017-03-24
+==================
+
+  * Add option "unit"
+
+2.4.0 / 2016-06-01
+==================
+
+  * Add option "unitSeparator"
+
+2.3.0 / 2016-02-15
+==================
+
+  * Drop partial bytes on all parsed units
+  * Fix non-finite numbers to `.format` to return `null`
+  * Fix parsing byte string that looks like hex
+  * perf: hoist regular expressions
+
+2.2.0 / 2015-11-13
+==================
+
+  * add option "decimalPlaces"
+  * add option "fixedDecimals"
+
+2.1.0 / 2015-05-21
+==================
+
+  * add `.format` export
+  * add `.parse` export
+
+2.0.2 / 2015-05-20
+==================
+
+  * remove map recreation
+  * remove unnecessary object construction
+
+2.0.1 / 2015-05-07
+==================
+
+  * fix browserify require
+  * remove node.extend dependency
+
+2.0.0 / 2015-04-12
+==================
+
+  * add option "case"
+  * add option "thousandsSeparator"
+  * return "null" on invalid parse input
+  * support proper round-trip: bytes(bytes(num)) === num
+  * units no longer case sensitive when parsing
+
+1.0.0 / 2014-05-05
+==================
+
+ * add negative support. fixes #6
+
+0.3.0 / 2014-03-19
+==================
+
+ * added terabyte support
+
+0.2.1 / 2013-04-01
+==================
+
+  * add .component
+
+0.2.0 / 2012-10-28
+==================
+
+  * bytes(200).should.eql('200b')
+
+0.1.0 / 2012-07-04
+==================
+
+  * add bytes to string conversion [yields]

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels