tremble 2 سال پیش
والد
کامیت
2cdc716021
100فایلهای تغییر یافته به همراه23630 افزوده شده و 28 حذف شده
  1. 12 2
      miniprogram/app.json
  2. 5 0
      miniprogram/app.less
  3. 79 7
      miniprogram/app.ts
  4. 4 0
      miniprogram/components/authorize/index.json
  5. 24 0
      miniprogram/components/authorize/index.less
  6. 35 0
      miniprogram/components/authorize/index.ts
  7. 9 0
      miniprogram/components/authorize/index.wxml
  8. 4 0
      miniprogram/components/dateselect/index.json
  9. 20 0
      miniprogram/components/dateselect/index.less
  10. 58 0
      miniprogram/components/dateselect/index.ts
  11. 12 0
      miniprogram/components/dateselect/index.wxml
  12. 4 0
      miniprogram/components/downselect/index.json
  13. 47 0
      miniprogram/components/downselect/index.less
  14. 48 0
      miniprogram/components/downselect/index.ts
  15. 6 0
      miniprogram/components/downselect/index.wxml
  16. 4 0
      miniprogram/components/help/index.json
  17. 74 0
      miniprogram/components/help/index.less
  18. 70 0
      miniprogram/components/help/index.ts
  19. 26 0
      miniprogram/components/help/index.wxml
  20. 30 1
      miniprogram/components/paging/index.less
  21. 98 12
      miniprogram/components/paging/index.ts
  22. 21 1
      miniprogram/components/paging/index.wxml
  23. 4 0
      miniprogram/components/roomitem/index.json
  24. 54 0
      miniprogram/components/roomitem/index.less
  25. 36 0
      miniprogram/components/roomitem/index.ts
  26. 10 0
      miniprogram/components/roomitem/index.wxml
  27. 4 0
      miniprogram/components/score/index.json
  28. 14 0
      miniprogram/components/score/index.less
  29. 23 0
      miniprogram/components/score/index.ts
  30. 3 0
      miniprogram/components/score/index.wxml
  31. 6 1
      miniprogram/components/toast/index.json
  32. 15 1
      miniprogram/components/toast/index.less
  33. 1 1
      miniprogram/components/toast/index.ts
  34. 9 2
      miniprogram/components/toast/index.wxml
  35. 4 0
      miniprogram/components/toast/popup/index.json
  36. 6 0
      miniprogram/components/toast/popup/index.less
  37. 21 0
      miniprogram/components/toast/popup/index.ts
  38. 3 0
      miniprogram/components/toast/popup/index.wxml
  39. 7 0
      miniprogram/components/toast/toast_behavior.ts
  40. 8 0
      miniprogram/components/toast/type/index.json
  41. 3 0
      miniprogram/components/toast/type/index.less
  42. 25 0
      miniprogram/components/toast/type/index.ts
  43. 3 0
      miniprogram/components/toast/type/index.wxml
  44. 4 0
      miniprogram/components/toast/type/join/index.json
  45. 42 0
      miniprogram/components/toast/type/join/index.less
  46. 45 0
      miniprogram/components/toast/type/join/index.ts
  47. 9 0
      miniprogram/components/toast/type/join/index.wxml
  48. 6 0
      miniprogram/components/toast/type/new/index.json
  49. 80 0
      miniprogram/components/toast/type/new/index.less
  50. 85 0
      miniprogram/components/toast/type/new/index.ts
  51. 31 0
      miniprogram/components/toast/type/new/index.wxml
  52. 68 0
      miniprogram/miniprogram_npm/fast-deep-equal/index.js
  53. 1 0
      miniprogram/miniprogram_npm/fast-deep-equal/index.js.map
  54. 1 0
      miniprogram/miniprogram_npm/miniprogram-computed/index.js
  55. 204 0
      miniprogram/miniprogram_npm/rfdc/index.js
  56. 1 0
      miniprogram/miniprogram_npm/rfdc/index.js.map
  57. 33 0
      miniprogram/node_modules/.package-lock.json
  58. 21 0
      miniprogram/node_modules/fast-deep-equal/LICENSE
  59. 58 0
      miniprogram/node_modules/fast-deep-equal/README.md
  60. 4 0
      miniprogram/node_modules/fast-deep-equal/index.d.ts
  61. 55 0
      miniprogram/node_modules/fast-deep-equal/index.js
  62. 59 0
      miniprogram/node_modules/fast-deep-equal/package.json
  63. 117 0
      miniprogram/node_modules/miniprogram-api-typings/CHANGELOG.md
  64. 21 0
      miniprogram/node_modules/miniprogram-api-typings/LICENSE
  65. 51 0
      miniprogram/node_modules/miniprogram-api-typings/README-en.md
  66. 50 0
      miniprogram/node_modules/miniprogram-api-typings/README.md
  67. 26 0
      miniprogram/node_modules/miniprogram-api-typings/VERSIONS.md
  68. 1 0
      miniprogram/node_modules/miniprogram-api-typings/index.d.ts
  69. 42 0
      miniprogram/node_modules/miniprogram-api-typings/package.json
  70. 1 0
      miniprogram/node_modules/miniprogram-api-typings/types/index.d.ts
  71. 48 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/index.d.ts
  72. 17968 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.api.d.ts
  73. 272 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.app.d.ts
  74. 66 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.behavior.d.ts
  75. 924 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.cloud.d.ts
  76. 625 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.component.d.ts
  77. 72 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.event.d.ts
  78. 247 0
      miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.page.d.ts
  79. 4 0
      miniprogram/node_modules/miniprogram-api-typings/typings.json
  80. 21 0
      miniprogram/node_modules/miniprogram-computed/LICENSE
  81. 252 0
      miniprogram/node_modules/miniprogram-computed/README.md
  82. 39 0
      miniprogram/node_modules/miniprogram-computed/UPDATE.md
  83. 1 0
      miniprogram/node_modules/miniprogram-computed/dist/index.js
  84. 82 0
      miniprogram/node_modules/miniprogram-computed/package.json
  85. 273 0
      miniprogram/node_modules/miniprogram-computed/src/behavior.ts
  86. 133 0
      miniprogram/node_modules/miniprogram-computed/src/data-path.ts
  87. 60 0
      miniprogram/node_modules/miniprogram-computed/src/data-tracer.ts
  88. 113 0
      miniprogram/node_modules/miniprogram-computed/src/index.ts
  89. 1 0
      miniprogram/node_modules/miniprogram-computed/types/behavior.d.ts
  90. 7 0
      miniprogram/node_modules/miniprogram-computed/types/data-path.d.ts
  91. 10 0
      miniprogram/node_modules/miniprogram-computed/types/data-tracer.d.ts
  92. 31 0
      miniprogram/node_modules/miniprogram-computed/types/index.d.ts
  93. 21 0
      miniprogram/node_modules/rfdc/.github/workflows/ci.yml
  94. 15 0
      miniprogram/node_modules/rfdc/LICENSE
  95. 3 0
      miniprogram/node_modules/rfdc/default.js
  96. 10 0
      miniprogram/node_modules/rfdc/index.d.ts
  97. 191 0
      miniprogram/node_modules/rfdc/index.js
  98. 7 0
      miniprogram/node_modules/rfdc/index.test-d.ts
  99. 69 0
      miniprogram/node_modules/rfdc/package.json
  100. 0 0
      miniprogram/node_modules/rfdc/readme.md

+ 12 - 2
miniprogram/app.json

@@ -1,14 +1,24 @@
 {
   "pages": [
     "pages/index/index",
-    "pages/person/index"
+    "pages/person/index",
+    "pages/activity_mode/index",
+    "pages/activity_detail/index",
+    "pages/game/index"
   ],
   "window": {
     "backgroundTextStyle": "light",
     "navigationBarBackgroundColor": "#fff",
-    "navigationBarTitleText": "Weixin",
+    "navigationBarTitleText": "律道公园大冒险",
     "navigationBarTextStyle": "black"
   },
   "style": "v2",
+  "usingComponents": {
+    "score": "/components/score",
+    "roomitem": "/components/roomitem",
+    "toast": "/components/toast",
+    "dateselect": "/components/dateselect"
+  },
+  "lazyCodeLoading": "requiredComponents",
   "sitemapLocation": "sitemap.json"
 }

+ 5 - 0
miniprogram/app.less

@@ -4,8 +4,13 @@ page{
   width: 100%;
   height: 100%;
   overflow: hidden;
+  color: #765842;
   .container{
     width: 100%;
     height: 100%;
   }
+  .disabled{
+    opacity: 0.7!important;
+    pointer-events: none!important;
+  }
 }

+ 79 - 7
miniprogram/app.ts

@@ -1,20 +1,92 @@
 require('./utils/mixins_core')
+import fetchutil from './utils/http'
+
 
 // app.ts
 App<IAppOption>({
-  globalData: {},
-  onLaunch() {
-    // 展示本地存储能力
-    const logs = wx.getStorageSync('logs') || []
-    logs.unshift(Date.now())
-    wx.setStorageSync('logs', logs)
+  globalData: {
+    // @ts-ignore
+    userInfo:'',
+    hasAvatar: ''
+  },
+
+  // @ts-ignore
+  watch(key, method) {
+    var obj = this.globalData;
 
+    //加个前缀生成隐藏变量,防止死循环发生
+    // @ts-ignore
+    let ori = obj[key]; //obj[key]这个不能放在Object.defineProperty里
+    if (ori) { //处理已经声明的变量,绑定处理
+      method(ori);
+    }
+    Object.defineProperty(obj, key, {
+      configurable: true,
+      enumerable: true,
+      set: function (value) {
+        this['_' + key] = value;
+        method(value);
+      },
+      get: function () {
+        // 在其他界面调用key值的时候,这里就会执行。
+        if (typeof this['_' + key] == 'undefined') {
+          if (ori) {
+            //这里读取数据的时候隐藏变量和 globalData设置不一样,所以要做同步处理
+            this['_' + key] = ori;
+            return ori;
+          } else {
+            return undefined;
+          }
+        } else {
+          return this['_' + key];
+        }
+      }
+    })
+  },
+  // @ts-ignore
+  login() {
     // 登录
     wx.login({
       success: res => {
-        console.log(res.code)
+        fetchutil.get(`wxLogin/${res.code}`, {}, {}).then((response: any) => {
+          wx.setStorageSync('token', response.data.token)
+          this.globalData.userInfo = {
+            ...this.globalData.userInfo,
+            ...response.data.wxUser
+          }
+          // @ts-ignore
+          this.globalData.hasAvatar = response.data.wxUser.avatarUrl
+        })
         // 发送 res.code 到后台换取 openId, sessionKey, unionId
       },
     })
   },
+
+
+
+  onLaunch() {
+    
+    // // @ts-ignore
+    // this.login()
+
+    let token = wx.getStorageSync('token')
+
+    if (token) {
+      fetchutil.get(`wxCheckToken`, {}, {}).then((response:any) => { 
+        this.globalData.userInfo = {
+          ...this.globalData.userInfo,
+          ...response.data
+        }
+        // @ts-ignore
+        this.globalData.hasAvatar = response.data.avatarUrl
+      }).catch(()=>{
+        // @ts-ignore
+        this.login()
+      })
+    } else {
+      // @ts-ignore
+      this.login()
+    }
+
+  },
 })

+ 4 - 0
miniprogram/components/authorize/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 24 - 0
miniprogram/components/authorize/index.less

@@ -0,0 +1,24 @@
+/* components/authorize/index.wxss */
+.authcon{
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%,-50%);
+  .authbody{
+    .avatar-wrapper{
+      width: 200rpx;
+      height: 200rpx;
+      padding: 0;
+      >image{
+        width: 100%;
+        height: 100%;
+      }
+    }
+    >input{
+      background: #ffffff;
+      margin-top: 40rpx;
+      padding: 10rpx 20rpx;
+      border-radius: 8rpx;
+    }
+  }
+}

+ 35 - 0
miniprogram/components/authorize/index.ts

@@ -0,0 +1,35 @@
+// components/authorize/index.ts
+const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
+Component({
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    inputNickName:'',
+    avatarUrl:defaultAvatarUrl
+  },
+  
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    bindKeyInput(e:any) {
+      this.setData({
+        inputNickName: e.detail.value
+      })
+    },
+    onChooseAvatar(e:any) {
+      const { avatarUrl } = e.detail 
+      this.setData({
+        avatarUrl,
+      })
+    }
+  }
+})

+ 9 - 0
miniprogram/components/authorize/index.wxml

@@ -0,0 +1,9 @@
+<!--components/authorize/index.wxml-->
+<view class="authcon">
+  <view class="authbody">
+    <button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
+      <image mode="aspectFit" class="avatar" src="{{avatarUrl}}"></image>
+    </button> 
+    <input type="nickname" bindinput="bindKeyInput" value="{{inputNickName}}" maxlength="20" placeholder="请输入昵称" class="nameinput" />
+  </view>
+</view>

+ 4 - 0
miniprogram/components/dateselect/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 20 - 0
miniprogram/components/dateselect/index.less

@@ -0,0 +1,20 @@
+.re_date {
+  display: flex;
+  align-items: center;
+  >image {
+    width: 20rpx;
+  }
+
+  .sw{
+    width: 200rpx;
+    height: 50rpx;
+    text-align: center;
+    display: inline-block;
+    text {
+      margin: 0 18rpx;
+      transform: translateY(-2rpx);
+      font-size: 32rpx;
+    }
+  }
+  
+}

+ 58 - 0
miniprogram/components/dateselect/index.ts

@@ -0,0 +1,58 @@
+// components/dateselect/index.ts
+Component({
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    g_cdn: String
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    current: 0,
+    date: [{
+      key: 7,
+      name: '最近7天'
+    },
+    {
+      key: 14,
+      name: '最近14天'
+    },
+    {
+      key: 30,
+      name: '最近30天'
+    }]
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    swiperChange(e:any) {
+      this.triggerEvent('dateselect',{current:this.data.date[e.detail.current]}, { bubbles: true, composed: true  })
+    }, 
+    tabSwitch(e: any) {
+      let idx = this.data.current
+      let { oper } = e.currentTarget.dataset
+
+
+      if (oper == 'prev') {
+        idx -= 1
+        if (idx < 0) {
+          idx = this.data.date.length - 1
+        }
+
+      } else {
+        idx += 1
+        if (idx > this.data.date.length - 1) {
+          idx = 0
+        }
+      }
+      this.setData({
+        current: idx
+      })
+    }
+  }
+})

+ 12 - 0
miniprogram/components/dateselect/index.wxml

@@ -0,0 +1,12 @@
+<view class="re_date">
+  <image data-oper="prev" bindtap="tabSwitch" src="{{g_cdn}}/images/left@2x.png" mode="widthFix" />
+  <swiper current="{{current}}" bindchange="swiperChange" class="sw">
+    <block wx:for="{{date}}" wx:key="*this">
+      <swiper-item>
+        <text>{{item.name}}</text>
+      </swiper-item>
+    </block>
+  </swiper>
+
+  <image data-oper="next" bindtap="tabSwitch" src="{{g_cdn}}/images/right@2x.png" mode="widthFix" />
+</view>

+ 4 - 0
miniprogram/components/downselect/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 47 - 0
miniprogram/components/downselect/index.less

@@ -0,0 +1,47 @@
+.downselect{
+  width: 464rpx;
+  height: 76rpx;
+  position: relative;
+  .d_select{
+    width: 100%;
+    height: 100%;
+    clip-path: polygon(0 10%, 100% 0, 96% 100%, 0.5% 96%);
+    background: #422414;
+    position: relative;
+    align-items: center;
+    display: flex;
+    padding-left: 10rpx;
+    box-sizing: border-box;
+    &::before{
+      content: '';
+      display: inline-block;
+      border: 16rpx transparent solid;
+      width: 0;
+      height: 0;
+      border-top: 16rpx solid #fff;
+      position: absolute;
+      right: 40rpx;
+      top: 40%;
+    }
+  }
+  .d_list{
+    position: absolute;
+    z-index: 999999;
+    background: #532E16;
+    width: 96%;
+    margin-top: 10rpx;
+    max-height: 0;
+    overflow: hidden;
+    transition: .3s ease all;
+    >view{
+      font-size: 24rpx;
+      padding: 16rpx 20rpx;
+      &:hover{
+        background-color: rgba(255, 178, 67, 0.5);
+      }
+    }
+  }
+  .active{
+    max-height: 400rpx;
+  }
+}

+ 48 - 0
miniprogram/components/downselect/index.ts

@@ -0,0 +1,48 @@
+import { ComponentWithComputed } from 'miniprogram-computed'
+
+
+// components/downselect/index.ts
+ComponentWithComputed({
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    dateArr:Array,
+    current: Object
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    isShowDown:false
+  },
+
+  
+  watch: {
+    isShowDown: function (isShowDown) {
+      this.triggerEvent('isShowDown',{isShowDown:isShowDown}, { bubbles: true, composed: true  })
+    },
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    onTab(){
+      this.setData({
+        isShowDown: !this.data.isShowDown
+      })
+    },
+    tapItem(e:any){
+      let {key} = e.target.dataset
+      let item = this.data.dateArr.find((ii:any)=>ii.key == key)
+      this.setData({
+        current:item,
+        isShowDown:false
+      })
+
+      this.triggerEvent('currentSelect',{current:this.data.current}, { bubbles: true, composed: true  })
+    },
+  }
+})

+ 6 - 0
miniprogram/components/downselect/index.wxml

@@ -0,0 +1,6 @@
+<view class="downselect">
+  <view class="d_select" bindtap="onTab">{{current.name}}</view>
+  <view class="d_list {{isShowDown?'active':''}}" >
+    <view bindtap="tapItem" wx:for="{{dateArr}}" wx:key="*this" data-key="{{item.key}}">{{item.name}}</view>
+  </view>
+</view>

+ 4 - 0
miniprogram/components/help/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 74 - 0
miniprogram/components/help/index.less

@@ -0,0 +1,74 @@
+.helpcon {
+  padding: 30rpx 20rpx;
+  background: linear-gradient(0deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.6) 100%);
+  box-shadow: 6rpx 10rpx 27rpx 0rpx rgba(75, 126, 160, 0.6);
+  box-sizing: border-box;
+  border: 5rpx solid #fff;
+  border-radius: 10rpx;
+  height: 96%;
+  width: 94%;
+  margin: 4% 3%;
+  position: absolute;
+  color: #fff;
+
+  .h_header {
+    text-align: center;
+    border-bottom: 2rpx solid #fff;
+    padding-bottom: 30rpx;
+    position: relative;
+
+    >image {
+      height: 60rpx;
+    }
+
+    .close {
+      top: 5rpx;
+      right: 10rpx;
+      height: 50rpx;
+      position: absolute;
+    }
+  }
+
+
+  .sw {
+    width: 100%;
+    min-height: 80%;
+    padding: 36rpx 26rpx 0;
+    box-sizing: border-box;
+    .sw_item {
+      width: 100%;
+      height: 100%;
+  
+      >image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+
+  .dots{
+    text-align: center;
+    margin: 4rpx 0 10rpx;
+      >text{
+      vertical-align: middle;
+      display: inline-block;
+      width: 15rpx;
+      margin: 0 24rpx;
+      height: 15rpx;
+      background: rgba(255, 255, 255, 0.5);
+      border-radius: 50%;
+    }
+    .active{
+      background: rgba(255, 255, 255, 1);
+    }
+  }
+
+  .h_detail {
+    margin-top: 20rpx;
+    width: 90%;
+    margin: 0 auto;
+    text-indent: 48rpx;
+    font-size: 24rpx;
+    line-height: 1.5;
+  }
+}

+ 70 - 0
miniprogram/components/help/index.ts

@@ -0,0 +1,70 @@
+// components/toast/type/join/index.ts
+
+var mixinsBehavior = require('../toast/toast_behavior')
+
+Component({
+  behaviors: [mixinsBehavior],
+
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    // g_cdn:String
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    background: [{
+      id: '0',
+      txt: '游戏开始前,将随机指定3个地标为任务目标,在地图中找到这些目标吧!'
+    }, {
+      id: '1',
+      txt: '找到任务目标,在点击弹出窗口中,进行答题任务挑战。'
+    }, {
+      id: '2',
+      txt: '完成全部3个任务挑战,即视为通关完成,耗时越短,积分越高!'
+    }],
+    indicatorDots: false,
+    vertical: false,
+    autoplay: false,
+    interval: 2000,
+    duration: 500,
+    currentIdx: 0,
+    current: {
+      id: '0',
+      txt: '游戏开始前,将随机指定3个地标为任务目标,在地图中找到这些目标吧!'
+    }
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    tapclose() {
+      let item = this.data.background.find(ii => ii.id === '0')
+      this.triggerEvent('close')
+      setTimeout(() => {
+        this.setData({
+          currentIdx: 0,
+          current: item
+        })
+      }, 500);
+    },
+    swiperChange(e: any) {
+      console.log(e.detail.current);
+
+      let item = this.data.background.find(ii => ii.id == e.detail.current)
+
+      if (e.detail.source == 'touch') {
+        this.setData({
+          current: item,
+        })
+      }
+    },
+  }
+})

+ 26 - 0
miniprogram/components/help/index.wxml

@@ -0,0 +1,26 @@
+<view class="helpcon">
+  <view class="h_header">
+      <image src="{{g_cdn}}/images/teach_title.png" mode="heightFix" />
+      <image bindtap="tapclose" class="close" src="{{g_cdn}}/images/cancel@2x.png" mode="heightFix" />
+  </view>
+
+    <swiper current="{{currentIdx}}" bindchange="swiperChange" class="sw" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
+      <block wx:for="{{background}}" wx:key="*this">
+        <swiper-item>
+          <view class="sw_item">
+            <image src="{{g_cdn}}/images/teach_{{item.id}}.jpg" mode="aspectFit" />
+          </view>
+        </swiper-item>
+      </block>
+    </swiper>
+
+    <view class="dots">
+      <block wx:for="{{background}}" wx:key="*this">
+        <text class="{{current.id==item.id?'active':''}}"></text>
+      </block>
+    </view>
+
+    <view class="h_detail">
+      <text>{{current.txt}}</text>
+    </view>
+</view>

+ 30 - 1
miniprogram/components/paging/index.less

@@ -1 +1,30 @@
-/* components/paging/index.wxss */
+.layer {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+  width: 100%;
+  >image{
+    width: 34rpx;
+    height: 34rpx;
+  }
+  text {
+    font-size: 32rpx;
+    color:#4C2508;
+    display: inline-block;
+    vertical-align: middle;
+    margin: 0 20rpx;
+
+    &.active {
+      color: #4C2508;
+      font-weight: bold;
+    }
+  }
+  .number text {
+    margin: 0 10rpx;
+    cursor: pointer;
+    &:first-of-type{
+      margin-left: 0;
+    }
+  }
+}

+ 98 - 12
miniprogram/components/paging/index.ts

@@ -1,23 +1,109 @@
-// components/paging/index.ts
-Component({
-  /**
-   * 组件的属性列表
-   */
-  properties: {
+// component.js
+import { ComponentWithComputed } from 'miniprogram-computed'
+
+ComponentWithComputed({
 
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+
+  properties: {
+    paging: Object,
+    g_cdn: String
   },
 
-  /**
-   * 组件的初始数据
-   */
   data: {
 
   },
 
-  /**
-   * 组件的方法列表
-   */
+  watch:{
+    'paging.current':function (val) {
+      this.triggerEvent('changeCurrent', val)
+    }
+  },
+
+  computed: {
+    min() {
+      return 1
+    },
+    max(data) {
+      return Math.ceil(data.paging.total / data.paging.pageSize)
+    },
+    routineMin(data) {
+      return data.paging.current - Math.ceil(data.paging.showSize / 2)
+    },
+    routineMax(data) {
+      return data.paging.current + Math.floor(data.paging.showSize / 2)
+    },
+    currMin(data: any) {
+      let c = data.max - data.routineMax
+      if (data.routineMin <= data.min) {
+        return data.min
+      } else if (c >= 0) {
+        return data.routineMin
+      } else if (data.routineMin + c <= data.min) {
+        return data.min
+      } else {
+        return data.routineMin + c
+      }
+    },
+    currMax(data: any) {
+      let c = data.min - data.routineMin
+
+      if (data.routineMax >= data.max) {
+        return data.max
+      } else if (c <= 0) {
+        return data.routineMax
+      } else if (data.routineMax + c >= data.max) {
+        return data.max
+      } else {
+        return data.routineMax + c
+      }
+    },
+    numbers(data: any) {
+      let total = data.currMax - data.currMin
+      let numbers = []
+
+      if (total <= 0) {
+        numbers.push(1)
+      } else {
+        for (let i = 0; i <= total; i++) {
+          numbers.push(data.currMin + i)
+        }
+      }
+
+
+      return numbers
+    }
+  },
+
+
+
+
+
   methods: {
+    onTap(e: any) {
+      let { idx } = e.currentTarget.dataset;
+      this.setData({
+        'paging.current': idx
+      })
 
+    },
+    prev() {
+      if (this.properties.paging.current - 1 < this.data.min) {
+        return
+      }
+      this.setData({
+        'paging.current': this.properties.paging.current - 1
+      })
+    },
+    next() {
+      if (this.properties.paging.current + 1 > this.data.max) {
+        return
+      }
+      this.setData({
+        'paging.current': this.properties.paging.current + 1
+      })
+    },
   }
 })

+ 21 - 1
miniprogram/components/paging/index.wxml

@@ -1,2 +1,22 @@
 <!--components/paging/index.wxml-->
-<text>components/paging/index.wxml</text>
+<view class="layer">
+    <image bindtap="prev" src="{{g_cdn}}/images/left@2x.png" mode="aspectFit"/>
+
+    <block wx:if="{{currMin > min}}">
+      <text bindtap="onTap" data-idx="{{min}}">{{min}}</text>
+      <text wx:if="{{currMin - 1 > min}}">…</text>
+    </block>
+
+    <text bindtap="onTap" data-idx="{{item}}"
+    class="{{paging.current == item ? 'active' : ''}}"
+     wx:for="{{numbers}}" wx:key="index">{{item}}</text>
+  
+    <block wx:if="{{currMax < max}}">
+      <text wx:if="{{currMax + 1 < max}}">…</text>
+      <text bindtap="onTap" data-idx="{{max}}">{{max}}</text>
+    </block>
+
+    <image class="next" bindtap="next" src="{{g_cdn}}/images/right@2x.png" mode="aspectFit"/>
+
+</view>
+  

+ 4 - 0
miniprogram/components/roomitem/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 54 - 0
miniprogram/components/roomitem/index.less

@@ -0,0 +1,54 @@
+.roominfo {
+  margin: 0 auto;
+  width: 714rpx;
+  text-align: center;
+  position: relative;
+  height: 220rpx;
+
+  >image {
+    width: 100%;
+    height: 100%;
+  }
+
+  .roomcon {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    font-size: 0;
+    left: 0;
+
+    .icon {
+      width: 168rpx;
+      height: 168rpx;
+      position: absolute;
+      top: 16rpx;
+      left: 34rpx;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      flex-wrap: wrap;
+      >image{
+        width: 33.3%!important;
+        height: 33.3%!important;
+      }
+    }
+
+    .roomname {
+      color: #fff;
+      font-size: 32rpx;
+      position: absolute;
+      top: 14rpx;
+      left: 236rpx;
+    }
+
+    .roomnum{
+      color: #fff;
+      font-size: 32rpx;
+      position: absolute;
+      top: 110rpx;
+      left: 260rpx;
+    }
+
+  }
+}

+ 36 - 0
miniprogram/components/roomitem/index.ts

@@ -0,0 +1,36 @@
+// components/roomitem/index.ts
+Component({
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+  
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    g_cdn:String,
+    type:Number,
+    info:Object
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    tapItem(){
+      // if (this.data.info.statusVo == 1) {
+      //   return
+      // }
+      this.triggerEvent('tapItem',{item:this.data.info})
+      // { bubbles: true, composed: true  }
+      // this.triggerEvent('tapItem',{})
+    }
+  }
+})

+ 10 - 0
miniprogram/components/roomitem/index.wxml

@@ -0,0 +1,10 @@
+<view class="roominfo" bindtap="tapItem">
+		<image src="{{g_cdn}}/images/{{info.statusVo==0?'btn_ing@2x':'btn_end@2x'}}.png" mode="aspectFit" />
+		<view class="roomcon">
+			<view class="icon">
+				<image wx:for="{{info.avatarUrls}}" src="{{item}}" />
+			</view>
+			<text class="roomname">{{info.name}}</text>
+			<text class="roomnum">{{info.count || 1}}</text>
+		</view>
+	</view>

+ 4 - 0
miniprogram/components/score/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 14 - 0
miniprogram/components/score/index.less

@@ -0,0 +1,14 @@
+.score{
+  display: inline-block;
+  max-width: 100rpx;
+  text-align: right;
+  font-weight: bold;
+  font-size: 26rpx;
+  color: #765842;
+  >text{
+    font-size: 50rpx;
+    display: inline-block;
+    margin-right: 4rpx;
+  }
+  
+}

+ 23 - 0
miniprogram/components/score/index.ts

@@ -0,0 +1,23 @@
+// components/score/index.ts
+Component({
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    score: Number
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+
+  }
+})

+ 3 - 0
miniprogram/components/score/index.wxml

@@ -0,0 +1,3 @@
+<view class="score">
+  <text>{{score}}</text>分
+</view>

+ 6 - 1
miniprogram/components/toast/index.json

@@ -1,4 +1,9 @@
 {
   "component": true,
-  "usingComponents": {}
+  "usingComponents": {
+    "popup":"./popup",
+    "type":"./type",
+    "join": "./type/join",
+    "new": "./type/new"
+  }
 }

+ 15 - 1
miniprogram/components/toast/index.less

@@ -1 +1,15 @@
-/* components/toast/index.wxss */
+.toast_con{
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 9999;
+  .toast_body{
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 100%;
+    transform: translate(-50%,-50%);
+  }
+}

+ 1 - 1
miniprogram/components/toast/index.ts

@@ -4,7 +4,7 @@ Component({
    * 组件的属性列表
    */
   properties: {
-
+    type:String
   },
 
   /**

+ 9 - 2
miniprogram/components/toast/index.wxml

@@ -1,2 +1,9 @@
-<!--components/toast/index.wxml-->
-<text>components/toast/index.wxml</text>
+<view class="toast_con">
+  <popup >
+    <view class="toast_body">
+      <type wx:if="{{type=='join'}}" generic:typecom="join"/>
+      <type wx:elif="{{type=='new'}}" generic:typecom="new"/>
+
+    </view>
+  </popup>
+</view>

+ 4 - 0
miniprogram/components/toast/popup/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 6 - 0
miniprogram/components/toast/popup/index.less

@@ -0,0 +1,6 @@
+.popup{
+  width: 100%;
+  height: 100%;
+  position: relative;
+  backdrop-filter: blur(10rpx) brightness(40%);
+}

+ 21 - 0
miniprogram/components/toast/popup/index.ts

@@ -0,0 +1,21 @@
+// components/toast/popup/index.ts
+Component({
+  /**
+   * 组件的属性列表
+   */
+  properties: {},
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+
+  }
+})

+ 3 - 0
miniprogram/components/toast/popup/index.wxml

@@ -0,0 +1,3 @@
+<view class="popup">
+  <slot></slot>
+</view>

+ 7 - 0
miniprogram/components/toast/toast_behavior.ts

@@ -0,0 +1,7 @@
+var mixins = require('../../utils/mixins')
+
+module.exports = Behavior({
+  data: {
+    g_cdn: mixins.data.g_cdn
+  }
+})

+ 8 - 0
miniprogram/components/toast/type/index.json

@@ -0,0 +1,8 @@
+{
+  "component": true,
+  "componentGenerics": {
+    "typecom": {
+      "default": "./join"
+    }
+  }
+}

+ 3 - 0
miniprogram/components/toast/type/index.less

@@ -0,0 +1,3 @@
+.typebody{
+  width: 100%;
+}

+ 25 - 0
miniprogram/components/toast/type/index.ts

@@ -0,0 +1,25 @@
+// components/toast/type/index.ts
+Component({
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+  
+  /**
+   * 组件的属性列表
+   */
+  properties: { },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+
+  }
+})

+ 3 - 0
miniprogram/components/toast/type/index.wxml

@@ -0,0 +1,3 @@
+<view class="typebody">
+  <typecom></typecom>
+</view>

+ 4 - 0
miniprogram/components/toast/type/join/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 42 - 0
miniprogram/components/toast/type/join/index.less

@@ -0,0 +1,42 @@
+.toast_mid{
+  max-width: 90%;
+  text-align: center;
+  position: relative;
+  margin: 0 auto;
+  .t_bg{
+    width: 100%;
+  }
+  .close{
+    position: absolute;
+    width: 60rpx;
+    right: 50rpx;
+    top: 50rpx;
+  }
+
+  .mid_center{
+    position: absolute;
+    top: 52%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    text-align: left;
+    color: #fff;
+    >view{
+      font-size: 28rpx;
+      margin-bottom: 10rpx;
+    }
+    >input{
+      width: 464rpx;
+      height: 76rpx;
+      clip-path: polygon(0 10%, 100% 0, 96% 100%, 0.5% 96%);
+      background: #422414;
+      padding: 0 20rpx;
+      box-sizing: border-box;
+    }
+
+    >image{
+      width: 100%;
+      display: block;
+      margin: 50rpx auto 0;
+    }
+  }
+}

+ 45 - 0
miniprogram/components/toast/type/join/index.ts

@@ -0,0 +1,45 @@
+// components/toast/type/join/index.ts
+
+var mixinsBehavior = require('../../toast_behavior')
+
+Component({
+  behaviors: [mixinsBehavior],
+
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    // g_cdn:String
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    inputValue:''
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    bindKeyInput(e:any) {
+      this.setData({
+        inputValue: e.detail.value
+      })
+    },
+    tapclose(){
+      this.triggerEvent('close',{}, { bubbles: true, composed: true  })
+      this.setData({
+        inputValue: ''
+      })
+    },
+    join(){
+      this.triggerEvent('join',{inputValue:this.data.inputValue}, { bubbles: true, composed: true  })
+      this.tapclose()
+    }
+  }
+})

+ 9 - 0
miniprogram/components/toast/type/join/index.wxml

@@ -0,0 +1,9 @@
+<view class="toast_mid">
+    <image class="t_bg" src="{{g_cdn}}/images/join_bg.png" mode="widthFix" />
+    <image class="close" bindtap="tapclose" src="{{g_cdn}}/images/cancel@2x.png" mode="widthFix" />
+    <view class="mid_center">
+      <view>输入口令</view>
+      <input bindinput="bindKeyInput" value='{{inputValue}}' maxlength="6" />
+      <image bindtap="join" src="{{g_cdn}}/images/btn_join@2x.png" mode="widthFix" />
+    </view>
+</view>

+ 6 - 0
miniprogram/components/toast/type/new/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "downselect": "../../../downselect"
+  }
+}

+ 80 - 0
miniprogram/components/toast/type/new/index.less

@@ -0,0 +1,80 @@
+.toast_mid{
+  max-width: 90%;
+  text-align: center;
+  position: relative;
+  margin: 0 auto;
+  .t_bg{
+    width: 100%;
+  }
+  .close{
+    position: absolute;
+    width: 60rpx;
+    right: 50rpx;
+    top: 50rpx;
+  }
+
+  .mid_center{
+    position: absolute;
+    top: 52%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    text-align: left;
+    color: #fff;
+    >view{
+      font-size: 28rpx;
+      margin-bottom: 10rpx;
+      margin-top: 14rpx;
+    }
+    .btmkouling{
+      width: 464rpx;
+      height: 80rpx;
+      position: relative;
+      >input{
+        width: 100%;
+        height: 90%;
+        clip-path: polygon(0 10%, 100% 0, 94% 100%, 0.5% 96%);
+        background: #422414;
+        padding: 0 20rpx;
+        box-sizing: border-box;
+        z-index: 111;
+        position: relative;
+      }
+      .btmbg{
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        background-color: #FFF6E9;
+        top: 0;
+        left: 0;
+        z-index: 0;
+        clip-path: polygon(0 10%, 100% 0, 96% 100%, 1% 96%);
+      }
+    }
+ 
+
+    >image{
+      width: 100%;
+      display: block;
+      margin: 20rpx auto 0;
+    }
+    .acc_select{
+      display: flex;
+      justify-content: space-between;
+      padding-right: 0;
+      >view{
+        display: inline-block;
+        width: 48%;
+        >image{
+          height: 36rpx;
+          display: inline-block;
+          vertical-align: middle;
+          &:first-of-type{
+            height: 40rpx;
+            margin-right: 20rpx;
+          }
+        }
+      }
+    }
+  
+  }
+}

+ 85 - 0
miniprogram/components/toast/type/new/index.ts

@@ -0,0 +1,85 @@
+// components/toast/type/join/index.ts
+
+var mixinsBehavior = require('../../toast_behavior')
+
+console.log(mixinsBehavior,'mixinsBehavior');
+
+Component({
+  behaviors: [mixinsBehavior],
+
+  options: {
+    styleIsolation: 'apply-shared'
+  },
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    // g_cdn:String
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    inputDisable:false,
+    ispublic: 'public',
+    inputValue:'',
+    current:{},
+    dateArr:[{
+      key:1,
+      name:'1小时后'
+    },{
+      key:3,
+      name:'3小时后'
+    },{
+      key:12,
+      name:'12小时后'
+    },{
+      key:24,
+      name:'24小时后'
+    }]
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    select(e: any) {
+      let { select } = e.currentTarget.dataset
+      
+  
+      this.setData({
+        ispublic: select
+      })
+    },
+    tapclose(){
+      this.setData({
+        inputValue: ''
+      })
+      this.triggerEvent('close',{}, { bubbles: true, composed: true  })
+    },
+    tapComfirm(){
+      this.triggerEvent('submit',{
+        current:this.data.current,
+        inputValue:this.data.inputValue,
+        ispublic:this.data.ispublic
+      }, { bubbles: true, composed: true  })
+      this.tapclose()
+    },
+    oncurrentSelect(e:any){
+      this.setData({
+        current:e.detail.current
+      })
+    },
+    bindKeyInput(e:any) {
+      this.setData({
+        inputValue: e.detail.value.replace(/[^a-zA-Z]/g,'')
+      })
+    },
+    handleShowDown(e:any){
+      this.setData({
+        inputDisable:e.detail.isShowDown
+      })
+    },
+  }
+})

+ 31 - 0
miniprogram/components/toast/type/new/index.wxml

@@ -0,0 +1,31 @@
+<view class="toast_mid">
+    <image class="t_bg" src="{{g_cdn}}/images/new_bg.png" mode="widthFix" />
+    <image class="close" bindtap="tapclose" src="{{g_cdn}}/images/cancel@2x.png" mode="widthFix" />
+    <view class="mid_center">
+      <view>结算时间</view>
+      <downselect bindcurrentSelect="oncurrentSelect" dateArr="{{dateArr}}" current="{{dateArr[0]}}" bindisShowDown="handleShowDown" />
+      
+       <view class="acc_select">
+        <view bindtap="select" data-select="public">
+          <image src="{{g_cdn}}/images/{{ispublic=='public'?'selected':'select'}}@2x.png" mode="heightFix" />
+          <image src="{{g_cdn}}/images/word_pubiic@2x.png" mode="heightFix" />
+        </view>
+
+        <view bindtap="select" data-select="nopublic">
+          <image src="{{g_cdn}}/images/{{ispublic=='nopublic'?'selected':'select'}}@2x.png" mode="heightFix" />
+          <image src="{{g_cdn}}/images/word_set@2x.png" mode="heightFix" />
+        </view>
+      </view>
+
+     <block wx:if="{{ispublic=='nopublic'}}">
+        <view>设置口令</view>
+        <view class="btmkouling">
+          <input bindinput="bindKeyInput" value='{{inputValue}}' maxlength="6" disabled="{{inputDisable}}" />
+          <view class="btmbg"></view>
+        </view>
+     </block>
+       
+
+      <image bindtap="tapComfirm" class="{{!inputValue&&ispublic=='nopublic'?'disabled':''}}" src="{{g_cdn}}/images/new_btn.png" mode="widthFix" />
+    </view>
+</view>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 68 - 0
miniprogram/miniprogram_npm/fast-deep-equal/index.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
miniprogram/miniprogram_npm/fast-deep-equal/index.js.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
miniprogram/miniprogram_npm/miniprogram-computed/index.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 204 - 0
miniprogram/miniprogram_npm/rfdc/index.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
miniprogram/miniprogram_npm/rfdc/index.js.map


+ 33 - 0
miniprogram/node_modules/.package-lock.json

@@ -0,0 +1,33 @@
+{
+  "name": "miniprogram-ts-less-quickstart",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "node_modules/fast-deep-equal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+      "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w=="
+    },
+    "node_modules/miniprogram-api-typings": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmmirror.com/miniprogram-api-typings/-/miniprogram-api-typings-2.12.0.tgz",
+      "integrity": "sha512-ibvbqeslVFur0IAvTxLMvsbtvVcMo6gwvOnj0YZHV7aeDLu091VQRrETT2QuiG9P6aZWRcxeNGJChRKVPCp9VQ==",
+      "dev": true
+    },
+    "node_modules/miniprogram-computed": {
+      "version": "4.3.8",
+      "resolved": "https://registry.npmmirror.com/miniprogram-computed/-/miniprogram-computed-4.3.8.tgz",
+      "integrity": "sha512-37MqgVPpU7Z2Iy9Y9vYlhDUDQw7ae5VWf+3NyURwEn2e7FOJUVop9JXysUWgA2SgPZawNizGHSghfMqYYJjG6g==",
+      "dependencies": {
+        "fast-deep-equal": "^2.0.1",
+        "rfdc": "^1.1.4"
+      }
+    },
+    "node_modules/rfdc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz",
+      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
+    }
+  }
+}

+ 21 - 0
miniprogram/node_modules/fast-deep-equal/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Evgeny Poberezkin
+
+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.

+ 58 - 0
miniprogram/node_modules/fast-deep-equal/README.md

@@ -0,0 +1,58 @@
+# fast-deep-equal
+The fastest deep equal
+
+[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)
+[![npm version](https://badge.fury.io/js/fast-deep-equal.svg)](http://badge.fury.io/js/fast-deep-equal)
+[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)
+
+
+## Install
+
+```bash
+npm install fast-deep-equal
+```
+
+
+## Features
+
+- ES5 compatible
+- works in node.js (0.10+) and browsers (IE9+)
+- checks equality of Date and RegExp objects by value.
+
+
+## Usage
+
+```javascript
+var equal = require('fast-deep-equal');
+console.log(equal({foo: 'bar'}, {foo: 'bar'})); // true
+```
+
+
+## Performance benchmark
+
+Node.js v9.11.1:
+
+```
+fast-deep-equal x 226,960 ops/sec ±1.55% (86 runs sampled)
+nano-equal x 218,210 ops/sec ±0.79% (89 runs sampled)
+shallow-equal-fuzzy x 206,762 ops/sec ±0.84% (88 runs sampled)
+underscore.isEqual x 128,668 ops/sec ±0.75% (91 runs sampled)
+lodash.isEqual x 44,895 ops/sec ±0.67% (85 runs sampled)
+deep-equal x 51,616 ops/sec ±0.96% (90 runs sampled)
+deep-eql x 28,218 ops/sec ±0.42% (85 runs sampled)
+assert.deepStrictEqual x 1,777 ops/sec ±1.05% (86 runs sampled)
+ramda.equals x 13,466 ops/sec ±0.82% (86 runs sampled)
+The fastest is fast-deep-equal
+```
+
+To run benchmark (requires node.js 6+):
+
+```bash
+npm install
+node benchmark
+```
+
+
+## License
+
+[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)

+ 4 - 0
miniprogram/node_modules/fast-deep-equal/index.d.ts

@@ -0,0 +1,4 @@
+declare module 'fast-deep-equal' {
+    const equal: (a: any, b: any) => boolean;
+    export = equal;
+}

+ 55 - 0
miniprogram/node_modules/fast-deep-equal/index.js

@@ -0,0 +1,55 @@
+'use strict';
+
+var isArray = Array.isArray;
+var keyList = Object.keys;
+var hasProp = Object.prototype.hasOwnProperty;
+
+module.exports = function equal(a, b) {
+  if (a === b) return true;
+
+  if (a && b && typeof a == 'object' && typeof b == 'object') {
+    var arrA = isArray(a)
+      , arrB = isArray(b)
+      , i
+      , length
+      , key;
+
+    if (arrA && arrB) {
+      length = a.length;
+      if (length != b.length) return false;
+      for (i = length; i-- !== 0;)
+        if (!equal(a[i], b[i])) return false;
+      return true;
+    }
+
+    if (arrA != arrB) return false;
+
+    var dateA = a instanceof Date
+      , dateB = b instanceof Date;
+    if (dateA != dateB) return false;
+    if (dateA && dateB) return a.getTime() == b.getTime();
+
+    var regexpA = a instanceof RegExp
+      , regexpB = b instanceof RegExp;
+    if (regexpA != regexpB) return false;
+    if (regexpA && regexpB) return a.toString() == b.toString();
+
+    var keys = keyList(a);
+    length = keys.length;
+
+    if (length !== keyList(b).length)
+      return false;
+
+    for (i = length; i-- !== 0;)
+      if (!hasProp.call(b, keys[i])) return false;
+
+    for (i = length; i-- !== 0;) {
+      key = keys[i];
+      if (!equal(a[key], b[key])) return false;
+    }
+
+    return true;
+  }
+
+  return a!==a && b!==b;
+};

+ 59 - 0
miniprogram/node_modules/fast-deep-equal/package.json

@@ -0,0 +1,59 @@
+{
+  "name": "fast-deep-equal",
+  "version": "2.0.1",
+  "description": "Fast deep equal",
+  "main": "index.js",
+  "scripts": {
+    "eslint": "eslint *.js benchmark spec",
+    "test-spec": "mocha spec/*.spec.js -R spec",
+    "test-cov": "nyc npm run test-spec",
+    "test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
+    "test": "npm run eslint && npm run test-ts && npm run test-cov"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
+  },
+  "keywords": [
+    "fast",
+    "equal",
+    "deep-equal"
+  ],
+  "author": "Evgeny Poberezkin",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/epoberezkin/fast-deep-equal/issues"
+  },
+  "homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
+  "devDependencies": {
+    "benchmark": "^2.1.4",
+    "coveralls": "^2.13.1",
+    "deep-eql": "latest",
+    "deep-equal": "latest",
+    "eslint": "^4.0.0",
+    "lodash": "latest",
+    "mocha": "^3.4.2",
+    "nano-equal": "latest",
+    "nyc": "^11.0.2",
+    "pre-commit": "^1.2.2",
+    "ramda": "latest",
+    "shallow-equal-fuzzy": "latest",
+    "typescript": "^2.6.1",
+    "underscore": "latest"
+  },
+  "nyc": {
+    "exclude": [
+      "**/spec/**",
+      "node_modules"
+    ],
+    "reporter": [
+      "lcov",
+      "text-summary"
+    ]
+  },
+  "files": [
+    "index.js",
+    "index.d.ts"
+  ],
+  "types": "index.d.ts"
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 117 - 0
miniprogram/node_modules/miniprogram-api-typings/CHANGELOG.md


+ 21 - 0
miniprogram/node_modules/miniprogram-api-typings/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 
+
+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.

+ 51 - 0
miniprogram/node_modules/miniprogram-api-typings/README-en.md

@@ -0,0 +1,51 @@
+# Wechat Mini Program API Typings
+
+> [中文版本](./README.md)
+
+[![Published on NPM](https://img.shields.io/npm/v/miniprogram-api-typings.svg?style=flat)](https://www.npmjs.com/package/miniprogram-api-typings)
+[![MIT License](https://img.shields.io/github/license/wechat-miniprogram/api-typings.svg)](https://github.com/wechat-miniprogram/api-typings)
+[![Travis CI Test Status](https://travis-ci.org/wechat-miniprogram/api-typings.svg?branch=master)](https://travis-ci.org/wechat-miniprogram/api-typings)
+
+Type definitions for APIs of Wechat Mini Program in TypeScript
+
+## Install
+
+Install by NPM:
+```bash
+# install definitions for latest base library
+npm install miniprogram-api-typings
+```
+
+or specify a base library version:
+
+```bash
+# install definitions for base library version 2.4.1
+npm install miniprogram-api-typings@2.4.1
+```
+
+## Versions
+
+Check out all available versions corresponding to base library version in [VERSIONS.md](https://github.com/wechat-miniprogram/api-typings/blob/master/VERSIONS.md)
+
+## Changelog
+
+See [CHANGELOG.md](https://github.com/wechat-miniprogram/api-typings/blob/master/CHANGELOG.md) (Chinese only)
+
+## Contribution
+
+Definitions of Wechat APIs (`lib.wx.api.d.ts`) are auto-generated together with our [documentations](https://developers.weixin.qq.com/miniprogram/dev/index.html), therefore PRs including that file will __not__ be merged. If you found some APIs defined wrongly, create an issue instead.
+
+Both PR and issue are welcomed for definitions of pages (`Page`), custom components (`Component`) and other else, since they are written manually. Help us improve this definition if you have any bug reports or suggestions! Thanks for contributing!
+
+### Contributors
+
+- [Baran](https://github.com/baranwang)
+- [MinLiang Zeng](https://github.com/zenml/)
+
+### Automated tests
+
+We use [`tsd`](https://github.com/SamVerschueren/tsd) to check if this definition is working properly. All test cases are under folder `test`.
+
+To perform an automated test, clone this repo, `npm install --save-dev` and `npm test`.
+
+If you have test case that fails the test, an issue or PR will be great. Strong test case that passes are also welcomed.

+ 50 - 0
miniprogram/node_modules/miniprogram-api-typings/README.md

@@ -0,0 +1,50 @@
+# 微信小程序定义文件
+
+> [English version](./README-en.md)
+
+[![已在 NPM 发布](https://img.shields.io/npm/v/miniprogram-api-typings.svg?style=flat)](https://www.npmjs.com/package/miniprogram-api-typings)
+[![MIT 协议](https://img.shields.io/github/license/wechat-miniprogram/api-typings.svg)](https://github.com/wechat-miniprogram/api-typings)
+[![Travis CI 测试状况](https://travis-ci.org/wechat-miniprogram/api-typings.svg?branch=master)](https://travis-ci.org/wechat-miniprogram/api-typings)
+
+微信小程序 API 的 TypeScript 类型定义文件
+
+## 安装
+
+通过 npm 安装:
+```bash
+# 安装对应最新基础库的定义文件
+npm install miniprogram-api-typings
+```
+
+或者通过版本号指定一个基础库版本:
+```bash
+# 安装对应基础库版本 2.4.1 的定义文件
+npm install miniprogram-api-typings@2.4.1
+```
+
+## 版本
+
+所有可用的版本和对应的基础库版本,参考 [VERSIONS.md](https://github.com/wechat-miniprogram/api-typings/blob/master/VERSIONS.md)
+
+## 更新日志
+
+参考 [CHANGELOG.md](https://github.com/wechat-miniprogram/api-typings/blob/master/CHANGELOG.md)
+
+## 贡献
+
+API 的定义文件(`lib.wx.api.d.ts`)是随 [文档](https://developers.weixin.qq.com/miniprogram/dev/index.html) 一起自动生成的,如果发现了 API 接口的定义错误,请提一个 issue 给我们,关于 API 的 PR 将 __不会__ 被接受。
+
+如果有针对页面(`Page`)、自定义组件(`Component`)等接口的 bug 和建议,欢迎 PR 或提一个 issue 给我们。非常感谢!
+
+### 贡献者
+
+- [Baran](https://github.com/baranwang)
+- [MinLiang Zeng](https://github.com/zenml/)
+
+### 测试
+
+本定义文件使用 [`tsd`](https://github.com/SamVerschueren/tsd) 进行测试,所有的测试样例放在 `test` 目录下。
+
+想执行测试的话,克隆本项目并完成 `npm install --save-dev` 后执行 `npm test` 即可。
+
+如果您发现了不能通过自动化测试的测试样例,可以提交 PR 或者提一个 issue。当然,能通过自动化测试的强有力的测试样例也是欢迎的。

+ 26 - 0
miniprogram/node_modules/miniprogram-api-typings/VERSIONS.md

@@ -0,0 +1,26 @@
+## 所有可用版本
+
+基础库版本|npm 版本|命令
+-|-|-
+[v2.11.3](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-11-2-2020-06-08) | [2.11.3-beta](https://www.npmjs.com/package/miniprogram-api-typings/v/2.11.3-beta) | `npm install miniprogram-api-typings@2.11.3-beta`
+[v2.11.2](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-11-2-2020-06-08) | [2.11.2-beta](https://www.npmjs.com/package/miniprogram-api-typings/v/2.11.2-beta) | `npm install miniprogram-api-typings@2.11.2-beta`
+[v2.11.0](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-11-0-2020-04-24) | [2.11.0-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.11.0-1) | `npm install miniprogram-api-typings@2.11.0-1`
+[v2.10.4](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-10-4-2020-03-24) | [2.10.4](https://www.npmjs.com/package/miniprogram-api-typings/v/2.10.4) | `npm install miniprogram-api-typings@2.10.4`
+[v2.10.3](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-10-3-2020-03-06) | [2.10.3-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.10.3-1) | `npm install miniprogram-api-typings@2.10.3-1`
+[v2.10.2](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-10-2-2020-02-20) | [2.10.2-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.10.2-1) | `npm install miniprogram-api-typings@2.10.2-1`
+[v2.10.1](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-10-1-2020-01-14) | [2.10.1-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.10.1-1) | `npm install miniprogram-api-typings@2.10.1-1`
+[v2.10.0](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-10-0-2019-12-24) | [2.10.0-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.10.0-1) | `npm install miniprogram-api-typings@2.10.0-1`
+[v2.9.4](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-9-4-2019-11-28) | [2.9.4](https://www.npmjs.com/package/miniprogram-api-typings/v/2.9.4) | `npm install miniprogram-api-typings@2.9.4`
+[v2.9.3](https://developers.weixin.qq.com/miniprogram/dev/framework/release/) | [2.9.3](https://www.npmjs.com/package/miniprogram-api-typings/v/2.9.3) | `npm install miniprogram-api-typings@2.9.3`
+[v2.9.2](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-9-2-2019-11-04) | [2.9.2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.9.2) | `npm install miniprogram-api-typings@2.9.2`
+[v2.9.1](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-9-1-2019-10-29) | [2.9.1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.9.1) | `npm install miniprogram-api-typings@2.9.1`
+[v2.9.0](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-9-0-2019-10-09) | [2.9.0](https://www.npmjs.com/package/miniprogram-api-typings/v/2.9.0) | `npm install miniprogram-api-typings@2.9.0`
+[v2.8.3](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-8-3-2019-09-17) | [2.8.3-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.8.3-1) | `npm install miniprogram-api-typings@2.8.3-1`
+[v2.8.2](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-8-2-2019-08-30) | [2.8.2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.8.2) | `npm install miniprogram-api-typings@2.8.2`
+[v2.8.1](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-8-1-2019-08-22) | [2.8.1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.8.1) | `npm install miniprogram-api-typings@2.8.1`
+[v2.8.0](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-8-0-2019-07-30) | [2.8.0-2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.8.0-2) | `npm install miniprogram-api-typings@2.8.0-2`
+[v2.7.7](https://developers.weixin.qq.com/miniprogram/dev/framework/release/) | [2.7.7-2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.7.7-2) | `npm install miniprogram-api-typings@2.7.7-2`
+[v2.6.5](https://developers.weixin.qq.com/miniprogram/dev/framework/release/#v2-6-5-2019-04-02) | [2.6.5-2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.6.5-2) | `npm install miniprogram-api-typings@2.6.5-2`
+[v2.4.2](https://developers.weixin.qq.com/miniprogram/dev/framework/release/v2.html#v2-4-2-2018-12-04)|[2.4.2-2](https://www.npmjs.com/package/miniprogram-api-typings/v/2.4.2-2)|`npm install miniprogram-api-typings@2.4.2-2`
+[v2.4.1](https://developers.weixin.qq.com/miniprogram/dev/framework/release/v2.html#v2-4-1-2018-11-21)|[2.4.1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.4.1)|`npm install miniprogram-api-typings@2.4.1`
+[v2.4.0](https://developers.weixin.qq.com/miniprogram/dev/framework/release/v2.html#v2-4-0-2018-11-05)|[2.4.0-1](https://www.npmjs.com/package/miniprogram-api-typings/v/2.4.0-1)|`npm install miniprogram-api-typings@2.4.0.1`

+ 1 - 0
miniprogram/node_modules/miniprogram-api-typings/index.d.ts

@@ -0,0 +1 @@
+/// <reference path="./types/index.d.ts" />

+ 42 - 0
miniprogram/node_modules/miniprogram-api-typings/package.json

@@ -0,0 +1,42 @@
+{
+  "name": "miniprogram-api-typings",
+  "version": "2.12.0",
+  "beta": "true",
+  "description": "Type definitions for APIs of Wechat Mini Program in TypeScript",
+  "main": "./index.d.ts",
+  "types": "./index.d.ts",
+  "scripts": {
+    "test": "npm run tsd && npm run tslint",
+    "tsd": "tsd",
+    "tslint": "tslint --project ."
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/wechat-miniprogram/api-typings.git"
+  },
+  "author": "Wechat Miniprogram <wx-miniprogram@qq.com>",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/wechat-miniprogram/api-typings/issues"
+  },
+  "homepage": "https://github.com/wechat-miniprogram/api-typings#readme",
+  "dependencies": {},
+  "devDependencies": {
+    "tsd": "^0.11.0",
+    "tslint": "^5.20.0",
+    "typescript": "^3.5.3"
+  },
+  "tsd": {
+    "directory": "test"
+  },
+  "files": [
+    "LICENSE",
+    "CHANGELOG.md",
+    "VERSIONS.md",
+    "README.md",
+    "README-en.md",
+    "index.d.ts",
+    "typings.json",
+    "types/"
+  ]
+}

+ 1 - 0
miniprogram/node_modules/miniprogram-api-typings/types/index.d.ts

@@ -0,0 +1 @@
+/// <reference path="./wx/index.d.ts" />

+ 48 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/index.d.ts

@@ -0,0 +1,48 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+/// <reference path="./lib.wx.app.d.ts" />
+/// <reference path="./lib.wx.page.d.ts" />
+/// <reference path="./lib.wx.api.d.ts" />
+/// <reference path="./lib.wx.cloud.d.ts" />
+/// <reference path="./lib.wx.component.d.ts" />
+/// <reference path="./lib.wx.behavior.d.ts" />
+/// <reference path="./lib.wx.event.d.ts" />
+
+declare namespace WechatMiniprogram {
+    type IAnyObject = Record<string, any>
+    type Optional<F> = F extends (arg: infer P) => infer R ? (arg?: P) => R : F
+    type OptionalInterface<T> = { [K in keyof T]: Optional<T[K]> }
+    interface AsyncMethodOptionLike {
+        success?: (...args: any[]) => void
+    }
+    type PromisifySuccessResult<
+        P,
+        T extends AsyncMethodOptionLike
+    > = P extends { success: any }
+        ? void
+        : P extends { fail: any }
+        ? void
+        : P extends { complete: any }
+        ? void
+        : Promise<Parameters<Exclude<T['success'], undefined>>[0]>
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 17968 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.api.d.ts


+ 272 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.app.d.ts

@@ -0,0 +1,272 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+declare namespace WechatMiniprogram {
+    namespace App {
+        interface ReferrerInfo {
+            /** 来源小程序或公众号或App的 appId
+             *
+             * 以下场景支持返回 referrerInfo.appId:
+             * - 1020(公众号 profile 页相关小程序列表): appId
+             * - 1035(公众号自定义菜单):来源公众号 appId
+             * - 1036(App 分享消息卡片):来源应用 appId
+             * - 1037(小程序打开小程序):来源小程序 appId
+             * - 1038(从另一个小程序返回):来源小程序 appId
+             * - 1043(公众号模板消息):来源公众号 appId
+             */
+            appId: string
+            /** 来源小程序传过来的数据,scene=1037或1038时支持 */
+            extraData?: any
+        }
+
+        type SceneValues =
+            | 1001
+            | 1005
+            | 1006
+            | 1007
+            | 1008
+            | 1011
+            | 1012
+            | 1013
+            | 1014
+            | 1017
+            | 1019
+            | 1020
+            | 1023
+            | 1024
+            | 1025
+            | 1026
+            | 1027
+            | 1028
+            | 1029
+            | 1030
+            | 1031
+            | 1032
+            | 1034
+            | 1035
+            | 1036
+            | 1037
+            | 1038
+            | 1039
+            | 1042
+            | 1043
+            | 1044
+            | 1045
+            | 1046
+            | 1047
+            | 1048
+            | 1049
+            | 1052
+            | 1053
+            | 1056
+            | 1057
+            | 1058
+            | 1059
+            | 1064
+            | 1067
+            | 1069
+            | 1071
+            | 1072
+            | 1073
+            | 1074
+            | 1077
+            | 1078
+            | 1079
+            | 1081
+            | 1082
+            | 1084
+            | 1089
+            | 1090
+            | 1091
+            | 1092
+            | 1095
+            | 1096
+            | 1097
+            | 1099
+            | 1102
+            | 1124
+            | 1125
+            | 1126
+            | 1129
+
+        interface LaunchShowOption {
+            /** 打开小程序的路径 */
+            path: string
+            /** 打开小程序的query */
+            query: IAnyObject
+            /** 打开小程序的场景值
+             * - 1001:发现栏小程序主入口,「最近使用」列表(基础库2.2.4版本起包含「我的小程序」列表)
+             * - 1005:微信首页顶部搜索框的搜索结果页
+             * - 1006:发现栏小程序主入口搜索框的搜索结果页
+             * - 1007:单人聊天会话中的小程序消息卡片
+             * - 1008:群聊会话中的小程序消息卡片
+             * - 1011:扫描二维码
+             * - 1012:长按图片识别二维码
+             * - 1013:扫描手机相册中选取的二维码
+             * - 1014:小程序模板消息
+             * - 1017:前往小程序体验版的入口页
+             * - 1019:微信钱包(微信客户端7.0.0版本改为支付入口)
+             * - 1020:公众号 profile 页相关小程序列表
+             * - 1023:安卓系统桌面图标
+             * - 1024:小程序 profile 页
+             * - 1025:扫描一维码
+             * - 1026:发现栏小程序主入口,「附近的小程序」列表
+             * - 1027:微信首页顶部搜索框搜索结果页「使用过的小程序」列表
+             * - 1028:我的卡包
+             * - 1029:小程序中的卡券详情页
+             * - 1030:自动化测试下打开小程序
+             * - 1031:长按图片识别一维码
+             * - 1032:扫描手机相册中选取的一维码
+             * - 1034:微信支付完成页
+             * - 1035:公众号自定义菜单
+             * - 1036:App 分享消息卡片
+             * - 1037:小程序打开小程序
+             * - 1038:从另一个小程序返回
+             * - 1039:摇电视
+             * - 1042:添加好友搜索框的搜索结果页
+             * - 1043:公众号模板消息
+             * - 1044:带 shareTicket 的小程序消息卡片 [详情](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html)
+             * - 1045:朋友圈广告
+             * - 1046:朋友圈广告详情页
+             * - 1047:扫描小程序码
+             * - 1048:长按图片识别小程序码
+             * - 1049:扫描手机相册中选取的小程序码
+             * - 1052:卡券的适用门店列表
+             * - 1053:搜一搜的结果页
+             * - 1056:聊天顶部音乐播放器右上角菜单
+             * - 1057:钱包中的银行卡详情页
+             * - 1058:公众号文章
+             * - 1059:体验版小程序绑定邀请页
+             * - 1064:微信首页连Wi-Fi状态栏
+             * - 1067:公众号文章广告
+             * - 1069:移动应用
+             * - 1071:钱包中的银行卡列表页
+             * - 1072:二维码收款页面
+             * - 1073:客服消息列表下发的小程序消息卡片
+             * - 1074:公众号会话下发的小程序消息卡片
+             * - 1077:摇周边
+             * - 1078:微信连Wi-Fi成功提示页
+             * - 1079:微信游戏中心
+             * - 1081:客服消息下发的文字链
+             * - 1082:公众号会话下发的文字链
+             * - 1084:朋友圈广告原生页
+             * - 1089:微信聊天主界面下拉,「最近使用」栏(基础库2.2.4版本起包含「我的小程序」栏)
+             * - 1090:长按小程序右上角菜单唤出最近使用历史
+             * - 1091:公众号文章商品卡片
+             * - 1092:城市服务入口
+             * - 1095:小程序广告组件
+             * - 1096:聊天记录
+             * - 1097:微信支付签约页
+             * - 1099:页面内嵌插件
+             * - 1102:公众号 profile 页服务预览
+             * - 1124:扫“一物一码”打开小程序
+             * - 1125:长按图片识别“一物一码”
+             * - 1126:扫描手机相册中选取的“一物一码”
+             * - 1129:微信爬虫访问 [详情](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/sitemap.html)
+             */
+            scene: SceneValues
+            /** shareTicket,详见 [获取更多转发信息]((转发#获取更多转发信息)) */
+            shareTicket: string
+            /** 当场景为由从另一个小程序或公众号或App打开时,返回此字段 */
+            referrerInfo?: ReferrerInfo
+        }
+
+        interface PageNotFoundOption {
+            /** 不存在页面的路径 */
+            path: string
+            /** 打开不存在页面的 query */
+            query: IAnyObject
+            /** 是否本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面) */
+            isEntryPage: boolean
+        }
+
+        interface Option {
+            /** 生命周期回调—监听小程序初始化
+             *
+             * 小程序初始化完成时触发,全局只触发一次。
+             */
+            onLaunch(options: LaunchShowOption): void
+            /** 生命周期回调—监听小程序显示
+             *
+             * 小程序启动,或从后台进入前台显示时
+             */
+            onShow(options: LaunchShowOption): void
+            /** 生命周期回调—监听小程序隐藏
+             *
+             * 小程序从前台进入后台时
+             */
+            onHide(): void
+            /** 错误监听函数
+             *
+             * 小程序发生脚本错误,或者 api
+             */
+            onError(/** 错误信息,包含堆栈 */ error: string): void
+            /** 页面不存在监听函数
+             *
+             * 小程序要打开的页面不存在时触发,会带上页面信息回调该函数
+             *
+             * **注意:**
+             * 1. 如果开发者没有添加 `onPageNotFound` 监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面。
+             * 2. 如果 `onPageNotFound` 回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不再回调 `onPageNotFound`。
+             *
+             * 最低基础库: 1.9.90
+             */
+            onPageNotFound(options: PageNotFoundOption): void
+            /**
+             * 小程序有未处理的 Promise 拒绝时触发。也可以使用 [wx.onUnhandledRejection](https://developers.weixin.qq.com/miniprogram/dev/api/base/app/app-event/wx.onUnhandledRejection.html) 绑定监听。注意事项请参考 [wx.onUnhandledRejection](https://developers.weixin.qq.com/miniprogram/dev/api/base/app/app-event/wx.onUnhandledRejection.html)。
+             * **参数**:与 [wx.onUnhandledRejection](https://developers.weixin.qq.com/miniprogram/dev/api/base/app/app-event/wx.onUnhandledRejection.html) 一致
+             */
+            onUnhandledRejection: OnUnhandledRejectionCallback
+            /**
+             * 系统切换主题时触发。也可以使用 wx.onThemeChange 绑定监听。
+             *
+             * 最低基础库: 2.11.0
+             */
+            onThemeChange: OnThemeChangeCallback
+        }
+
+        type Instance<T extends IAnyObject> = Option & T
+        type Options<T extends IAnyObject> = Partial<Option> &
+            T &
+            ThisType<Instance<T>>
+        type TrivialInstance = Instance<IAnyObject>
+
+        interface Constructor {
+            <T extends IAnyObject>(options: Options<T>): void
+        }
+
+        interface GetAppOption {
+            /** 在 `App` 未定义时返回默认实现。当App被调用时,默认实现中定义的属性会被覆盖合并到App中。一般用于独立分包
+             *
+             * 最低基础库: 2.2.4
+             */
+            allowDefault?: boolean
+        }
+
+        interface GetApp {
+            <T = IAnyObject>(opts?: GetAppOption): Instance<T>
+        }
+    }
+}
+
+declare let App: WechatMiniprogram.App.Constructor
+declare let getApp: WechatMiniprogram.App.GetApp

+ 66 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.behavior.d.ts

@@ -0,0 +1,66 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+declare namespace WechatMiniprogram {
+    namespace Behavior {
+        type Instance<
+            TData extends DataOption,
+            TProperty extends PropertyOption,
+            TMethod extends MethodOption
+        > = Component.Instance<TData, TProperty, TMethod>
+        type TrivialInstance = Instance<IAnyObject, IAnyObject, IAnyObject>
+        type TrivialOption = Options<IAnyObject, IAnyObject, IAnyObject>
+        type Options<
+            TData extends DataOption,
+            TProperty extends PropertyOption,
+            TMethod extends MethodOption
+        > = Partial<Data<TData>> &
+            Partial<Property<TProperty>> &
+            Partial<Method<TMethod>> &
+            Partial<OtherOption> &
+            Partial<Lifetimes> &
+            ThisType<Instance<TData, TProperty, TMethod>>
+        interface Constructor {
+            <
+                TData extends DataOption,
+                TProperty extends PropertyOption,
+                TMethod extends MethodOption
+            >(
+                options: Options<TData, TProperty, TMethod>
+            ): string
+        }
+
+        type DataOption = Component.DataOption
+        type PropertyOption = Component.PropertyOption
+        type MethodOption = Component.MethodOption
+        type Data<D extends DataOption> = Component.Data<D>
+        type Property<P extends PropertyOption> = Component.Property<P>
+        type Method<M extends MethodOption> = Component.Method<M>
+
+        type DefinitionFilter = Component.DefinitionFilter
+        type Lifetimes = Component.Lifetimes
+
+        type OtherOption = Omit<Component.OtherOption, 'options'>
+    }
+}
+/** 注册一个 `behavior`,接受一个 `Object` 类型的参数。*/
+declare let Behavior: WechatMiniprogram.Behavior.Constructor

+ 924 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.cloud.d.ts

@@ -0,0 +1,924 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+interface IAPIError {
+    errMsg: string
+}
+
+interface IAPIParam<T = any> {
+    config?: ICloudConfig
+    success?: (res: T) => void
+    fail?: (err: IAPIError) => void
+    complete?: (val: T | IAPIError) => void
+}
+
+interface IAPISuccessParam {
+    errMsg: string
+}
+
+type IAPICompleteParam = IAPISuccessParam | IAPIError
+
+type IAPIFunction<T, P extends IAPIParam<T>> = (param?: P) => Promise<T>
+
+interface IInitCloudConfig {
+    env?:
+        | string
+        | {
+              database?: string
+              functions?: string
+              storage?: string
+          }
+    traceUser?: boolean
+}
+
+interface ICloudConfig {
+    env?: string
+    traceUser?: boolean
+}
+
+interface IICloudAPI {
+    init: (config?: IInitCloudConfig) => void
+    [api: string]: AnyFunction | IAPIFunction<any, any>
+}
+
+interface ICloudService {
+    name: string
+
+    getAPIs: () => { [name: string]: IAPIFunction<any, any> }
+}
+
+interface ICloudServices {
+    [serviceName: string]: ICloudService
+}
+
+interface ICloudMetaData {
+    session_id: string
+}
+
+declare class InternalSymbol {}
+
+interface AnyObject {
+    [x: string]: any
+}
+
+type AnyArray = any[]
+
+type AnyFunction = (...args: any[]) => any
+
+/**
+ * extend wx with cloud
+ */
+interface WxCloud {
+    init: (config?: ICloudConfig) => void
+
+    callFunction(param: OQ<ICloud.CallFunctionParam>): void
+    callFunction(
+        param: RQ<ICloud.CallFunctionParam>
+    ): Promise<ICloud.CallFunctionResult>
+
+    uploadFile(param: OQ<ICloud.UploadFileParam>): WechatMiniprogram.UploadTask
+    uploadFile(
+        param: RQ<ICloud.UploadFileParam>
+    ): Promise<ICloud.UploadFileResult>
+
+    downloadFile(
+        param: OQ<ICloud.DownloadFileParam>
+    ): WechatMiniprogram.DownloadTask
+    downloadFile(
+        param: RQ<ICloud.DownloadFileParam>
+    ): Promise<ICloud.DownloadFileResult>
+
+    getTempFileURL(param: OQ<ICloud.GetTempFileURLParam>): void
+    getTempFileURL(
+        param: RQ<ICloud.GetTempFileURLParam>
+    ): Promise<ICloud.GetTempFileURLResult>
+
+    deleteFile(param: OQ<ICloud.DeleteFileParam>): void
+    deleteFile(
+        param: RQ<ICloud.DeleteFileParam>
+    ): Promise<ICloud.DeleteFileResult>
+
+    database: (config?: ICloudConfig) => DB.Database
+
+    CloudID: ICloud.ICloudIDConstructor
+    CDN: ICloud.ICDNConstructor
+}
+
+declare namespace ICloud {
+    interface ICloudAPIParam<T = any> extends IAPIParam<T> {
+        config?: ICloudConfig
+    }
+
+    // === API: callFunction ===
+    type CallFunctionData = AnyObject
+
+    interface CallFunctionResult extends IAPISuccessParam {
+        result: AnyObject | string | undefined
+    }
+
+    interface CallFunctionParam extends ICloudAPIParam<CallFunctionResult> {
+        name: string
+        data?: CallFunctionData
+        slow?: boolean
+    }
+    // === end ===
+
+    // === API: uploadFile ===
+    interface UploadFileResult extends IAPISuccessParam {
+        fileID: string
+        statusCode: number
+    }
+
+    interface UploadFileParam extends ICloudAPIParam<UploadFileResult> {
+        cloudPath: string
+        filePath: string
+        header?: AnyObject
+    }
+    // === end ===
+
+    // === API: downloadFile ===
+    interface DownloadFileResult extends IAPISuccessParam {
+        tempFilePath: string
+        statusCode: number
+    }
+
+    interface DownloadFileParam extends ICloudAPIParam<DownloadFileResult> {
+        fileID: string
+        cloudPath?: string
+    }
+    // === end ===
+
+    // === API: getTempFileURL ===
+    interface GetTempFileURLResult extends IAPISuccessParam {
+        fileList: GetTempFileURLResultItem[]
+    }
+
+    interface GetTempFileURLResultItem {
+        fileID: string
+        tempFileURL: string
+        maxAge: number
+        status: number
+        errMsg: string
+    }
+
+    interface GetTempFileURLParam extends ICloudAPIParam<GetTempFileURLResult> {
+        fileList: string[]
+    }
+    // === end ===
+
+    // === API: deleteFile ===
+    interface DeleteFileResult extends IAPISuccessParam {
+        fileList: DeleteFileResultItem[]
+    }
+
+    interface DeleteFileResultItem {
+        fileID: string
+        status: number
+        errMsg: string
+    }
+
+    interface DeleteFileParam extends ICloudAPIParam<DeleteFileResult> {
+        fileList: string[]
+    }
+    // === end ===
+
+    // === API: CloudID ===
+    abstract class CloudID {
+        constructor(cloudID: string)
+    }
+
+    interface ICloudIDConstructor {
+        new (cloudId: string): CloudID
+        (cloudId: string): CloudID
+    }
+    // === end ===
+
+    // === API: CDN ===
+    abstract class CDN {
+        target: string | ArrayBuffer | ICDNFilePathSpec
+        constructor(target: string | ArrayBuffer | ICDNFilePathSpec)
+    }
+
+    interface ICDNFilePathSpec {
+        type: 'filePath'
+        filePath: string
+    }
+
+    interface ICDNConstructor {
+        new (options: string | ArrayBuffer | ICDNFilePathSpec): CDN
+        (options: string | ArrayBuffer | ICDNFilePathSpec): CDN
+    }
+    // === end ===
+}
+
+// === Database ===
+declare namespace DB {
+    /**
+     * The class of all exposed cloud database instances
+     */
+    class Database {
+        readonly config: ICloudConfig
+        readonly command: DatabaseCommand
+        readonly Geo: IGeo
+        readonly serverDate: () => ServerDate
+        readonly RegExp: IRegExpConstructor
+
+        private constructor()
+
+        collection(collectionName: string): CollectionReference
+    }
+
+    class CollectionReference extends Query {
+        readonly collectionName: string
+
+        private constructor(name: string, database: Database)
+
+        doc(docId: string | number): DocumentReference
+
+        add(options: OQ<IAddDocumentOptions>): void
+        add(options: RQ<IAddDocumentOptions>): Promise<IAddResult>
+    }
+
+    class DocumentReference {
+        private constructor(docId: string | number, database: Database)
+
+        field(object: object): this
+
+        get(options: OQ<IGetDocumentOptions>): void
+        get(options?: RQ<IGetDocumentOptions>): Promise<IQuerySingleResult>
+
+        set(options: OQ<ISetSingleDocumentOptions>): void
+        set(options?: RQ<ISetSingleDocumentOptions>): Promise<ISetResult>
+
+        update(options: OQ<IUpdateSingleDocumentOptions>): void
+        update(
+            options?: RQ<IUpdateSingleDocumentOptions>
+        ): Promise<IUpdateResult>
+
+        remove(options: OQ<IRemoveSingleDocumentOptions>): void
+        remove(
+            options?: RQ<IRemoveSingleDocumentOptions>
+        ): Promise<IRemoveResult>
+
+        watch(options: IWatchOptions): RealtimeListener
+    }
+
+    class RealtimeListener {
+        // "And Now His Watch Is Ended"
+        close: () => Promise<void>
+    }
+
+    class Query {
+        where(condition: IQueryCondition): Query
+
+        orderBy(fieldPath: string, order: string): Query
+
+        limit(max: number): Query
+
+        skip(offset: number): Query
+
+        field(object: object): Query
+
+        get(options: OQ<IGetDocumentOptions>): void
+        get(options?: RQ<IGetDocumentOptions>): Promise<IQueryResult>
+
+        count(options: OQ<ICountDocumentOptions>): void
+        count(options?: RQ<ICountDocumentOptions>): Promise<ICountResult>
+
+        watch(options: IWatchOptions): RealtimeListener
+    }
+
+    interface DatabaseCommand {
+        eq(val: any): DatabaseQueryCommand
+        neq(val: any): DatabaseQueryCommand
+        gt(val: any): DatabaseQueryCommand
+        gte(val: any): DatabaseQueryCommand
+        lt(val: any): DatabaseQueryCommand
+        lte(val: any): DatabaseQueryCommand
+        in(val: any[]): DatabaseQueryCommand
+        nin(val: any[]): DatabaseQueryCommand
+
+        geoNear(options: IGeoNearCommandOptions): DatabaseQueryCommand
+        geoWithin(options: IGeoWithinCommandOptions): DatabaseQueryCommand
+        geoIntersects(
+            options: IGeoIntersectsCommandOptions
+        ): DatabaseQueryCommand
+
+        and(
+            ...expressions: Array<DatabaseLogicCommand | IQueryCondition>
+        ): DatabaseLogicCommand
+        or(
+            ...expressions: Array<DatabaseLogicCommand | IQueryCondition>
+        ): DatabaseLogicCommand
+        nor(
+            ...expressions: Array<DatabaseLogicCommand | IQueryCondition>
+        ): DatabaseLogicCommand
+        not(expression: DatabaseLogicCommand): DatabaseLogicCommand
+
+        exists(val: boolean): DatabaseQueryCommand
+
+        mod(divisor: number, remainder: number): DatabaseQueryCommand
+
+        all(val: any[]): DatabaseQueryCommand
+        elemMatch(val: any): DatabaseQueryCommand
+        size(val: number): DatabaseQueryCommand
+
+        set(val: any): DatabaseUpdateCommand
+        remove(): DatabaseUpdateCommand
+        inc(val: number): DatabaseUpdateCommand
+        mul(val: number): DatabaseUpdateCommand
+        min(val: number): DatabaseUpdateCommand
+        max(val: number): DatabaseUpdateCommand
+        rename(val: string): DatabaseUpdateCommand
+        bit(val: number): DatabaseUpdateCommand
+
+        push(...values: any[]): DatabaseUpdateCommand
+        pop(): DatabaseUpdateCommand
+        shift(): DatabaseUpdateCommand
+        unshift(...values: any[]): DatabaseUpdateCommand
+        addToSet(val: any): DatabaseUpdateCommand
+        pull(val: any): DatabaseUpdateCommand
+        pullAll(val: any): DatabaseUpdateCommand
+
+        project: {
+            slice(val: number | [number, number]): DatabaseProjectionCommand
+        }
+
+        aggregate: {
+            __safe_props__?: Set<string>
+
+            abs(val: any): DatabaseAggregateCommand
+            add(val: any): DatabaseAggregateCommand
+            addToSet(val: any): DatabaseAggregateCommand
+            allElementsTrue(val: any): DatabaseAggregateCommand
+            and(val: any): DatabaseAggregateCommand
+            anyElementTrue(val: any): DatabaseAggregateCommand
+            arrayElemAt(val: any): DatabaseAggregateCommand
+            arrayToObject(val: any): DatabaseAggregateCommand
+            avg(val: any): DatabaseAggregateCommand
+            ceil(val: any): DatabaseAggregateCommand
+            cmp(val: any): DatabaseAggregateCommand
+            concat(val: any): DatabaseAggregateCommand
+            concatArrays(val: any): DatabaseAggregateCommand
+            cond(val: any): DatabaseAggregateCommand
+            convert(val: any): DatabaseAggregateCommand
+            dateFromParts(val: any): DatabaseAggregateCommand
+            dateToParts(val: any): DatabaseAggregateCommand
+            dateFromString(val: any): DatabaseAggregateCommand
+            dateToString(val: any): DatabaseAggregateCommand
+            dayOfMonth(val: any): DatabaseAggregateCommand
+            dayOfWeek(val: any): DatabaseAggregateCommand
+            dayOfYear(val: any): DatabaseAggregateCommand
+            divide(val: any): DatabaseAggregateCommand
+            eq(val: any): DatabaseAggregateCommand
+            exp(val: any): DatabaseAggregateCommand
+            filter(val: any): DatabaseAggregateCommand
+            first(val: any): DatabaseAggregateCommand
+            floor(val: any): DatabaseAggregateCommand
+            gt(val: any): DatabaseAggregateCommand
+            gte(val: any): DatabaseAggregateCommand
+            hour(val: any): DatabaseAggregateCommand
+            ifNull(val: any): DatabaseAggregateCommand
+            in(val: any): DatabaseAggregateCommand
+            indexOfArray(val: any): DatabaseAggregateCommand
+            indexOfBytes(val: any): DatabaseAggregateCommand
+            indexOfCP(val: any): DatabaseAggregateCommand
+            isArray(val: any): DatabaseAggregateCommand
+            isoDayOfWeek(val: any): DatabaseAggregateCommand
+            isoWeek(val: any): DatabaseAggregateCommand
+            isoWeekYear(val: any): DatabaseAggregateCommand
+            last(val: any): DatabaseAggregateCommand
+            let(val: any): DatabaseAggregateCommand
+            literal(val: any): DatabaseAggregateCommand
+            ln(val: any): DatabaseAggregateCommand
+            log(val: any): DatabaseAggregateCommand
+            log10(val: any): DatabaseAggregateCommand
+            lt(val: any): DatabaseAggregateCommand
+            lte(val: any): DatabaseAggregateCommand
+            ltrim(val: any): DatabaseAggregateCommand
+            map(val: any): DatabaseAggregateCommand
+            max(val: any): DatabaseAggregateCommand
+            mergeObjects(val: any): DatabaseAggregateCommand
+            meta(val: any): DatabaseAggregateCommand
+            min(val: any): DatabaseAggregateCommand
+            millisecond(val: any): DatabaseAggregateCommand
+            minute(val: any): DatabaseAggregateCommand
+            mod(val: any): DatabaseAggregateCommand
+            month(val: any): DatabaseAggregateCommand
+            multiply(val: any): DatabaseAggregateCommand
+            neq(val: any): DatabaseAggregateCommand
+            not(val: any): DatabaseAggregateCommand
+            objectToArray(val: any): DatabaseAggregateCommand
+            or(val: any): DatabaseAggregateCommand
+            pow(val: any): DatabaseAggregateCommand
+            push(val: any): DatabaseAggregateCommand
+            range(val: any): DatabaseAggregateCommand
+            reduce(val: any): DatabaseAggregateCommand
+            reverseArray(val: any): DatabaseAggregateCommand
+            rtrim(val: any): DatabaseAggregateCommand
+            second(val: any): DatabaseAggregateCommand
+            setDifference(val: any): DatabaseAggregateCommand
+            setEquals(val: any): DatabaseAggregateCommand
+            setIntersection(val: any): DatabaseAggregateCommand
+            setIsSubset(val: any): DatabaseAggregateCommand
+            setUnion(val: any): DatabaseAggregateCommand
+            size(val: any): DatabaseAggregateCommand
+            slice(val: any): DatabaseAggregateCommand
+            split(val: any): DatabaseAggregateCommand
+            sqrt(val: any): DatabaseAggregateCommand
+            stdDevPop(val: any): DatabaseAggregateCommand
+            stdDevSamp(val: any): DatabaseAggregateCommand
+            strcasecmp(val: any): DatabaseAggregateCommand
+            strLenBytes(val: any): DatabaseAggregateCommand
+            strLenCP(val: any): DatabaseAggregateCommand
+            substr(val: any): DatabaseAggregateCommand
+            substrBytes(val: any): DatabaseAggregateCommand
+            substrCP(val: any): DatabaseAggregateCommand
+            subtract(val: any): DatabaseAggregateCommand
+            sum(val: any): DatabaseAggregateCommand
+            switch(val: any): DatabaseAggregateCommand
+            toBool(val: any): DatabaseAggregateCommand
+            toDate(val: any): DatabaseAggregateCommand
+            toDecimal(val: any): DatabaseAggregateCommand
+            toDouble(val: any): DatabaseAggregateCommand
+            toInt(val: any): DatabaseAggregateCommand
+            toLong(val: any): DatabaseAggregateCommand
+            toObjectId(val: any): DatabaseAggregateCommand
+            toString(val: any): DatabaseAggregateCommand
+            toLower(val: any): DatabaseAggregateCommand
+            toUpper(val: any): DatabaseAggregateCommand
+            trim(val: any): DatabaseAggregateCommand
+            trunc(val: any): DatabaseAggregateCommand
+            type(val: any): DatabaseAggregateCommand
+            week(val: any): DatabaseAggregateCommand
+            year(val: any): DatabaseAggregateCommand
+            zip(val: any): DatabaseAggregateCommand
+        }
+    }
+
+    class DatabaseAggregateCommand {}
+
+    enum LOGIC_COMMANDS_LITERAL {
+        AND = 'and',
+        OR = 'or',
+        NOT = 'not',
+        NOR = 'nor',
+    }
+
+    class DatabaseLogicCommand {
+        and(...expressions: DatabaseLogicCommand[]): DatabaseLogicCommand
+        or(...expressions: DatabaseLogicCommand[]): DatabaseLogicCommand
+        nor(...expressions: DatabaseLogicCommand[]): DatabaseLogicCommand
+        not(expression: DatabaseLogicCommand): DatabaseLogicCommand
+    }
+
+    enum QUERY_COMMANDS_LITERAL {
+        // comparison
+        EQ = 'eq',
+        NEQ = 'neq',
+        GT = 'gt',
+        GTE = 'gte',
+        LT = 'lt',
+        LTE = 'lte',
+        IN = 'in',
+        NIN = 'nin',
+        // geo
+        GEO_NEAR = 'geoNear',
+        GEO_WITHIN = 'geoWithin',
+        GEO_INTERSECTS = 'geoIntersects',
+        // element
+        EXISTS = 'exists',
+        // evaluation
+        MOD = 'mod',
+        // array
+        ALL = 'all',
+        ELEM_MATCH = 'elemMatch',
+        SIZE = 'size',
+    }
+
+    class DatabaseQueryCommand extends DatabaseLogicCommand {
+        eq(val: any): DatabaseLogicCommand
+        neq(val: any): DatabaseLogicCommand
+        gt(val: any): DatabaseLogicCommand
+        gte(val: any): DatabaseLogicCommand
+        lt(val: any): DatabaseLogicCommand
+        lte(val: any): DatabaseLogicCommand
+        in(val: any[]): DatabaseLogicCommand
+        nin(val: any[]): DatabaseLogicCommand
+
+        exists(val: boolean): DatabaseLogicCommand
+
+        mod(divisor: number, remainder: number): DatabaseLogicCommand
+
+        all(val: any[]): DatabaseLogicCommand
+        elemMatch(val: any): DatabaseLogicCommand
+        size(val: number): DatabaseLogicCommand
+
+        geoNear(options: IGeoNearCommandOptions): DatabaseLogicCommand
+        geoWithin(options: IGeoWithinCommandOptions): DatabaseLogicCommand
+        geoIntersects(
+            options: IGeoIntersectsCommandOptions
+        ): DatabaseLogicCommand
+    }
+
+    enum PROJECTION_COMMANDS_LITERAL {
+        SLICE = 'slice',
+    }
+
+    class DatabaseProjectionCommand {}
+
+    enum UPDATE_COMMANDS_LITERAL {
+        // field
+        SET = 'set',
+        REMOVE = 'remove',
+        INC = 'inc',
+        MUL = 'mul',
+        MIN = 'min',
+        MAX = 'max',
+        RENAME = 'rename',
+        // bitwise
+        BIT = 'bit',
+        // array
+        PUSH = 'push',
+        POP = 'pop',
+        SHIFT = 'shift',
+        UNSHIFT = 'unshift',
+        ADD_TO_SET = 'addToSet',
+        PULL = 'pull',
+        PULL_ALL = 'pullAll',
+    }
+
+    class DatabaseUpdateCommand {}
+
+    class Batch {}
+
+    /**
+     * A contract that all API provider must adhere to
+     */
+    class APIBaseContract<
+        PROMISE_RETURN,
+        CALLBACK_RETURN,
+        PARAM extends IAPIParam,
+        CONTEXT = any
+    > {
+        getContext(param: PARAM): CONTEXT
+
+        /**
+         * In case of callback-style invocation, this function will be called
+         */
+        getCallbackReturn(param: PARAM, context: CONTEXT): CALLBACK_RETURN
+
+        getFinalParam<T extends PARAM>(param: PARAM, context: CONTEXT): T
+
+        run<T extends PARAM>(param: T): Promise<PROMISE_RETURN>
+    }
+
+    interface IGeoPointConstructor {
+        new (longitude: number, latitide: number): GeoPoint
+        new (geojson: IGeoJSONPoint): GeoPoint
+        (longitude: number, latitide: number): GeoPoint
+        (geojson: IGeoJSONPoint): GeoPoint
+    }
+
+    interface IGeoMultiPointConstructor {
+        new (points: GeoPoint[] | IGeoJSONMultiPoint): GeoMultiPoint
+        (points: GeoPoint[] | IGeoJSONMultiPoint): GeoMultiPoint
+    }
+
+    interface IGeoLineStringConstructor {
+        new (points: GeoPoint[] | IGeoJSONLineString): GeoLineString
+        (points: GeoPoint[] | IGeoJSONLineString): GeoLineString
+    }
+
+    interface IGeoMultiLineStringConstructor {
+        new (
+            lineStrings: GeoLineString[] | IGeoJSONMultiLineString
+        ): GeoMultiLineString
+        (
+            lineStrings: GeoLineString[] | IGeoJSONMultiLineString
+        ): GeoMultiLineString
+    }
+
+    interface IGeoPolygonConstructor {
+        new (lineStrings: GeoLineString[] | IGeoJSONPolygon): GeoPolygon
+        (lineStrings: GeoLineString[] | IGeoJSONPolygon): GeoPolygon
+    }
+
+    interface IGeoMultiPolygonConstructor {
+        new (polygons: GeoPolygon[] | IGeoJSONMultiPolygon): GeoMultiPolygon
+        (polygons: GeoPolygon[] | IGeoJSONMultiPolygon): GeoMultiPolygon
+    }
+
+    interface IGeo {
+        Point: IGeoPointConstructor
+        MultiPoint: IGeoMultiPointConstructor
+        LineString: IGeoLineStringConstructor
+        MultiLineString: IGeoMultiLineStringConstructor
+        Polygon: IGeoPolygonConstructor
+        MultiPolygon: IGeoMultiPolygonConstructor
+    }
+
+    interface IGeoJSONPoint {
+        type: 'Point'
+        coordinates: [number, number]
+    }
+
+    interface IGeoJSONMultiPoint {
+        type: 'MultiPoint'
+        coordinates: Array<[number, number]>
+    }
+
+    interface IGeoJSONLineString {
+        type: 'LineString'
+        coordinates: Array<[number, number]>
+    }
+
+    interface IGeoJSONMultiLineString {
+        type: 'MultiLineString'
+        coordinates: Array<Array<[number, number]>>
+    }
+
+    interface IGeoJSONPolygon {
+        type: 'Polygon'
+        coordinates: Array<Array<[number, number]>>
+    }
+
+    interface IGeoJSONMultiPolygon {
+        type: 'MultiPolygon'
+        coordinates: Array<Array<Array<[number, number]>>>
+    }
+
+    type IGeoJSONObject =
+        | IGeoJSONPoint
+        | IGeoJSONMultiPoint
+        | IGeoJSONLineString
+        | IGeoJSONMultiLineString
+        | IGeoJSONPolygon
+        | IGeoJSONMultiPolygon
+
+    abstract class GeoPoint {
+        longitude: number
+        latitude: number
+
+        constructor(longitude: number, latitude: number)
+
+        toJSON(): object
+        toString(): string
+    }
+
+    abstract class GeoMultiPoint {
+        points: GeoPoint[]
+
+        constructor(points: GeoPoint[])
+
+        toJSON(): IGeoJSONMultiPoint
+        toString(): string
+    }
+
+    abstract class GeoLineString {
+        points: GeoPoint[]
+
+        constructor(points: GeoPoint[])
+
+        toJSON(): IGeoJSONLineString
+        toString(): string
+    }
+
+    abstract class GeoMultiLineString {
+        lines: GeoLineString[]
+
+        constructor(lines: GeoLineString[])
+
+        toJSON(): IGeoJSONMultiLineString
+        toString(): string
+    }
+
+    abstract class GeoPolygon {
+        lines: GeoLineString[]
+
+        constructor(lines: GeoLineString[])
+
+        toJSON(): IGeoJSONPolygon
+        toString(): string
+    }
+
+    abstract class GeoMultiPolygon {
+        polygons: GeoPolygon[]
+
+        constructor(polygons: GeoPolygon[])
+
+        toJSON(): IGeoJSONMultiPolygon
+        toString(): string
+    }
+
+    type GeoInstance =
+        | GeoPoint
+        | GeoMultiPoint
+        | GeoLineString
+        | GeoMultiLineString
+        | GeoPolygon
+        | GeoMultiPolygon
+
+    interface IGeoNearCommandOptions {
+        geometry: GeoPoint
+        maxDistance?: number
+        minDistance?: number
+    }
+
+    interface IGeoWithinCommandOptions {
+        geometry: GeoPolygon | GeoMultiPolygon
+    }
+
+    interface IGeoIntersectsCommandOptions {
+        geometry:
+            | GeoPoint
+            | GeoMultiPoint
+            | GeoLineString
+            | GeoMultiLineString
+            | GeoPolygon
+            | GeoMultiPolygon
+    }
+
+    interface IServerDateOptions {
+        offset: number
+    }
+
+    abstract class ServerDate {
+        readonly options: IServerDateOptions
+        constructor(options?: IServerDateOptions)
+    }
+
+    interface IRegExpOptions {
+        regexp: string
+        options?: string
+    }
+
+    interface IRegExpConstructor {
+        new (options: IRegExpOptions): RegExp
+        (options: IRegExpOptions): RegExp
+    }
+
+    abstract class RegExp {
+        readonly regexp: string
+        readonly options: string
+        constructor(options: IRegExpOptions)
+    }
+
+    type DocumentId = string | number
+
+    interface IDocumentData {
+        _id?: DocumentId
+        [key: string]: any
+    }
+
+    type IDBAPIParam = IAPIParam
+
+    interface IAddDocumentOptions extends IDBAPIParam {
+        data: IDocumentData
+    }
+
+    type IGetDocumentOptions = IDBAPIParam
+
+    type ICountDocumentOptions = IDBAPIParam
+
+    interface IUpdateDocumentOptions extends IDBAPIParam {
+        data: IUpdateCondition
+    }
+
+    interface IUpdateSingleDocumentOptions extends IDBAPIParam {
+        data: IUpdateCondition
+    }
+
+    interface ISetDocumentOptions extends IDBAPIParam {
+        data: IUpdateCondition
+    }
+
+    interface ISetSingleDocumentOptions extends IDBAPIParam {
+        data: IUpdateCondition
+    }
+
+    interface IRemoveDocumentOptions extends IDBAPIParam {
+        query: IQueryCondition
+    }
+
+    type IRemoveSingleDocumentOptions = IDBAPIParam
+
+    interface IWatchOptions {
+        // server realtime data init & change event
+        onChange: (snapshot: ISnapshot) => void
+        // error while connecting / listening
+        onError: (error: any) => void
+    }
+
+    interface ISnapshot {
+        id: number
+        docChanges: ISingleDBEvent[]
+        docs: Record<string, any>
+        type?: SnapshotType
+    }
+
+    type SnapshotType = 'init'
+
+    interface ISingleDBEvent {
+        id: number
+        dataType: DataType
+        queueType: QueueType
+        docId: string
+        doc: Record<string, any>
+        updatedFields?: Record<string, any>
+        removedFields?: string[]
+    }
+
+    type DataType = 'init' | 'update' | 'replace' | 'add' | 'remove' | 'limit'
+
+    type QueueType = 'init' | 'enqueue' | 'dequeue' | 'update'
+
+    interface IQueryCondition {
+        [key: string]: any
+    }
+
+    type IStringQueryCondition = string
+
+    interface IQueryResult extends IAPISuccessParam {
+        data: IDocumentData[]
+    }
+
+    interface IQuerySingleResult extends IAPISuccessParam {
+        data: IDocumentData
+    }
+
+    interface IUpdateCondition {
+        [key: string]: any
+    }
+
+    type IStringUpdateCondition = string
+
+    interface IAddResult extends IAPISuccessParam {
+        _id: DocumentId
+    }
+
+    interface IUpdateResult extends IAPISuccessParam {
+        stats: {
+            updated: number
+            // created: number,
+        }
+    }
+
+    interface ISetResult extends IAPISuccessParam {
+        _id: DocumentId
+        stats: {
+            updated: number
+            created: number
+        }
+    }
+
+    interface IRemoveResult extends IAPISuccessParam {
+        stats: {
+            removed: number
+        }
+    }
+
+    interface ICountResult extends IAPISuccessParam {
+        total: number
+    }
+}
+
+type Optional<T> = { [K in keyof T]+?: T[K] }
+
+type OQ<
+    T extends Optional<
+        Record<'complete' | 'success' | 'fail', (...args: any[]) => any>
+    >
+> =
+    | (RQ<T> & Required<Pick<T, 'success'>>)
+    | (RQ<T> & Required<Pick<T, 'fail'>>)
+    | (RQ<T> & Required<Pick<T, 'complete'>>)
+    | (RQ<T> & Required<Pick<T, 'success' | 'fail'>>)
+    | (RQ<T> & Required<Pick<T, 'success' | 'complete'>>)
+    | (RQ<T> & Required<Pick<T, 'fail' | 'complete'>>)
+    | (RQ<T> & Required<Pick<T, 'fail' | 'complete' | 'success'>>)
+
+type RQ<
+    T extends Optional<
+        Record<'complete' | 'success' | 'fail', (...args: any[]) => any>
+    >
+> = Pick<T, Exclude<keyof T, 'complete' | 'success' | 'fail'>>

+ 625 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.component.d.ts

@@ -0,0 +1,625 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+declare namespace WechatMiniprogram {
+    namespace Component {
+        type Instance<
+            TData extends DataOption,
+            TProperty extends PropertyOption,
+            TMethod extends Partial<MethodOption>,
+            TCustomInstanceProperty extends IAnyObject = {}
+        > = InstanceProperties &
+            InstanceMethods<TData> &
+            TMethod &
+            TCustomInstanceProperty & {
+                /** 组件数据,**包括内部数据和属性值** */
+                data: TData & PropertyOptionToData<TProperty>
+                /** 组件数据,**包括内部数据和属性值**(与 `data` 一致) */
+                properties: TData & PropertyOptionToData<TProperty>
+            }
+        type TrivialInstance = Instance<
+            IAnyObject,
+            IAnyObject,
+            IAnyObject,
+            IAnyObject
+        >
+        type TrivialOption = Options<
+            IAnyObject,
+            IAnyObject,
+            IAnyObject,
+            IAnyObject
+        >
+        type Options<
+            TData extends DataOption,
+            TProperty extends PropertyOption,
+            TMethod extends MethodOption,
+            TCustomInstanceProperty extends IAnyObject = {}
+        > = Partial<Data<TData>> &
+            Partial<Property<TProperty>> &
+            Partial<Method<TMethod>> &
+            Partial<OtherOption> &
+            Partial<Lifetimes> &
+            ThisType<
+                Instance<TData, TProperty, TMethod, TCustomInstanceProperty>
+            >
+        interface Constructor {
+            <
+                TData extends DataOption,
+                TProperty extends PropertyOption,
+                TMethod extends MethodOption,
+                TCustomInstanceProperty extends IAnyObject = {}
+            >(
+                options: Options<
+                    TData,
+                    TProperty,
+                    TMethod,
+                    TCustomInstanceProperty
+                >
+            ): string
+        }
+        type DataOption = Record<string, any>
+        type PropertyOption = Record<string, AllProperty>
+        type MethodOption = Record<string, (...args: any[]) => any>
+
+        interface Data<D extends DataOption> {
+            /** 组件的内部数据,和 `properties` 一同用于组件的模板渲染 */
+            data?: D
+        }
+        interface Property<P extends PropertyOption> {
+            /** 组件的对外属性,是属性名到属性设置的映射表 */
+            properties: P
+        }
+        interface Method<M extends MethodOption> {
+            /** 组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 [组件间通信与事件](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html) */
+            methods: M
+        }
+        type PropertyType =
+            | StringConstructor
+            | NumberConstructor
+            | BooleanConstructor
+            | ArrayConstructor
+            | ObjectConstructor
+            | null
+        type ValueType<T extends PropertyType> = T extends StringConstructor
+            ? string
+            : T extends NumberConstructor
+            ? number
+            : T extends BooleanConstructor
+            ? boolean
+            : T extends ArrayConstructor
+            ? any[]
+            : T extends ObjectConstructor
+            ? IAnyObject
+            : any
+        type FullProperty<T extends PropertyType> = {
+            /** 属性类型 */
+            type: T
+            /** 属性初始值 */
+            value?: ValueType<T>
+            /** 属性值被更改时的响应函数 */
+            observer?:
+                | string
+                | ((
+                      newVal: ValueType<T>,
+                      oldVal: ValueType<T>,
+                      changedPath: Array<string | number>
+                  ) => void)
+            /** 属性的类型(可以指定多个) */
+            optionalTypes?: ShortProperty[]
+        }
+        type AllFullProperty =
+            | FullProperty<StringConstructor>
+            | FullProperty<NumberConstructor>
+            | FullProperty<BooleanConstructor>
+            | FullProperty<ArrayConstructor>
+            | FullProperty<ObjectConstructor>
+            | FullProperty<null>
+        type ShortProperty =
+            | StringConstructor
+            | NumberConstructor
+            | BooleanConstructor
+            | ArrayConstructor
+            | ObjectConstructor
+            | null
+        type AllProperty = AllFullProperty | ShortProperty
+        type PropertyToData<T extends AllProperty> = T extends ShortProperty
+            ? ValueType<T>
+            : FullPropertyToData<Exclude<T, ShortProperty>>
+        type FullPropertyToData<T extends AllFullProperty> = ValueType<
+            T['type']
+        >
+        type PropertyOptionToData<P extends PropertyOption> = {
+            [name in keyof P]: PropertyToData<P[name]>
+        }
+
+        interface InstanceProperties {
+            /** 组件的文件路径 */
+            is: string
+            /** 节点id */
+            id: string
+            /** 节点dataset */
+            dataset: Record<string, string>
+        }
+
+        interface InstanceMethods<D extends DataOption> {
+            /** `setData` 函数用于将数据从逻辑层发送到视图层
+             *(异步),同时改变对应的 `this.data` 的值(同步)。
+             *
+             * **注意:**
+             *
+             * 1. **直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致**。
+             * 1. 仅支持设置可 JSON 化的数据。
+             * 1. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
+             * 1. 请不要把 data 中任何一项的 value 设为 `undefined` ,否则这一项将不被设置并可能遗留一些潜在问题。
+             */
+            setData(
+                /** 这次要改变的数据
+                 *
+                 * 以 `key: value` 的形式表示,将 `this.data` 中的 `key` 对应的值改变成 `value`。
+                 *
+                 * 其中 `key` 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 `array[2].message`,`a.b.c.d`,并且不需要在 this.data 中预先定义。
+                 */
+                data: Partial<D> & IAnyObject,
+                /** setData引起的界面更新渲染完毕后的回调函数,最低基础库: `1.5.0` */
+                callback?: () => void
+            ): void
+
+            /** 检查组件是否具有 `behavior` (检查时会递归检查被直接或间接引入的所有behavior) */
+            hasBehavior(behavior: object): void
+            /** 触发事件,参见组件事件 */
+            triggerEvent(
+                name: string,
+                detail?: object,
+                options?: TriggerEventOption
+            ): void
+            /** 创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内 */
+            createSelectorQuery(): SelectorQuery
+            /** 创建一个 IntersectionObserver 对象,选择器选取范围为这个组件实例内 */
+            createIntersectionObserver(
+                options: CreateIntersectionObserverOption
+            ): IntersectionObserver
+            /** 使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象(会被 `wx://component-export` 影响) */
+            selectComponent(selector: string): TrivialInstance
+            /** 使用选择器选择组件实例节点,返回匹配到的全部组件实例对象组成的数组 */
+            selectAllComponents(selector: string): TrivialInstance[]
+            /**
+             * 选取当前组件节点所在的组件实例(即组件的引用者),返回它的组件实例对象(会被 `wx://component-export` 影响)
+             *
+             * 最低基础库版本:[`2.8.2`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            selectOwnerComponent(): TrivialInstance
+            /** 获取这个关系所对应的所有关联节点,参见 组件间关系 */
+            getRelationNodes(relationKey: string): TrivialInstance[]
+            /**
+             * 立刻执行 callback ,其中的多个 setData 之间不会触发界面绘制(只有某些特殊场景中需要,如用于在不同组件同时 setData 时进行界面绘制同步)
+             *
+             * 最低基础库版本:[`2.4.0`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            groupSetData(callback?: () => void): void
+            /**
+             * 返回当前页面的 custom-tab-bar 的组件实例
+             *
+             * 最低基础库版本:[`2.6.2`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            getTabBar(): TrivialInstance
+            /**
+             * 返回页面标识符(一个字符串),可以用来判断几个自定义组件实例是不是在同一个页面内
+             *
+             * 最低基础库版本:[`2.7.1`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            getPageId(): string
+            /**
+             * 执行关键帧动画,详见[动画](https://developers.weixin.qq.com/miniprogram/dev/framework/view/animation.html)
+             *
+             * 最低基础库版本:[`2.9.0`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            animate(
+                selector: string,
+                keyFrames: KeyFrame[],
+                duration: number,
+                callback: () => void
+            ): void
+            /**
+             * 执行关键帧动画,详见[动画](https://developers.weixin.qq.com/miniprogram/dev/framework/view/animation.html)
+             *
+             * 最低基础库版本:[`2.9.0`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            animate(
+                selector: string,
+                keyFrames: ScrollTimelineKeyframe[],
+                duration: number,
+                scrollTimeline: ScrollTimelineOption
+            ): void
+            /**
+             * 清除关键帧动画,详见[动画](https://developers.weixin.qq.com/miniprogram/dev/framework/view/animation.html)
+             *
+             * 最低基础库版本:[`2.9.0`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            clearAnimation(selector: string, callback: () => void): void
+            /**
+             * 清除关键帧动画,详见[动画](https://developers.weixin.qq.com/miniprogram/dev/framework/view/animation.html)
+             *
+             * 最低基础库版本:[`2.9.0`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             **/
+            clearAnimation(
+                selector: string,
+                options: ClearAnimationOptions,
+                callback: () => void
+            ): void
+            getOpenerEventChannel(): EventChannel
+        }
+
+        interface ComponentOptions {
+            /**
+             * [启用多slot支持](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#组件wxml的slot)
+             */
+            multipleSlots?: boolean
+            /**
+             * [组件样式隔离](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#组件样式隔离)
+             */
+            addGlobalClass?: boolean
+            /**
+             * [组件样式隔离](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#组件样式隔离)
+             */
+            styleIsolation?:
+                | 'isolated'
+                | 'apply-shared'
+                | 'shared'
+                | 'page-isolated'
+                | 'page-apply-shared'
+                | 'page-shared'
+            /**
+             * [纯数据字段](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/pure-data.html) 是一些不用于界面渲染的 data 字段,可以用于提升页面更新性能。从小程序基础库版本 2.8.2 开始支持。
+             */
+            pureDataPattern?: RegExp
+        }
+
+        interface TriggerEventOption {
+            /** 事件是否冒泡
+             *
+             * 默认值: `false`
+             */
+            bubbles?: boolean
+            /** 事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部
+             *
+             * 默认值: `false`
+             */
+            composed?: boolean
+            /** 事件是否拥有捕获阶段
+             *
+             * 默认值: `false`
+             */
+            capturePhase?: boolean
+        }
+
+        interface RelationOption {
+            /** 目标组件的相对关系 */
+            type: 'parent' | 'child' | 'ancestor' | 'descendant'
+            /** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
+            linked?(target: TrivialInstance): void
+            /** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */
+            linkChanged?(target: TrivialInstance): void
+            /** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */
+            unlinked?(target: TrivialInstance): void
+            /** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */
+            target?: string
+        }
+
+        interface PageLifetimes {
+            /** 页面生命周期回调—监听页面显示
+             *
+             * 页面显示/切入前台时触发。
+             */
+            show(): void
+            /** 页面生命周期回调—监听页面隐藏
+             *
+             * 页面隐藏/切入后台时触发。 如 `navigateTo` 或底部 `tab` 切换到其他页面,小程序切入后台等。
+             */
+            hide(): void
+            /** 页面生命周期回调—监听页面尺寸变化
+             *
+             * 所在页面尺寸变化时执行
+             */
+            resize(size: Page.IResizeOption): void
+        }
+
+        type DefinitionFilter = <T extends TrivialOption>(
+            /** 使用该 behavior 的 component/behavior 的定义对象 */
+            defFields: T,
+            /** 该 behavior 所使用的 behavior 的 definitionFilter 函数列表 */
+            definitionFilterArr?: DefinitionFilter[]
+        ) => void
+
+        interface Lifetimes {
+            /** 组件生命周期声明对象,组件的生命周期:`created`、`attached`、`ready`、`moved`、`detached` 将收归到 `lifetimes` 字段内进行声明,原有声明方式仍旧有效,如同时存在两种声明方式,则 `lifetimes` 字段内声明方式优先级最高
+             *
+             * 最低基础库: `2.2.3` */
+            lifetimes: Partial<{
+                /**
+                 * 在组件实例刚刚被创建时执行,注意此时不能调用 `setData`
+                 *
+                 * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                created(): void
+                /**
+                 * 在组件实例进入页面节点树时执行
+                 *
+                 * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                attached(): void
+                /**
+                 * 在组件在视图层布局完成后执行
+                 *
+                 * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                ready(): void
+                /**
+                 * 在组件实例被移动到节点树另一个位置时执行
+                 *
+                 * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                moved(): void
+                /**
+                 * 在组件实例被从页面节点树移除时执行
+                 *
+                 * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                detached(): void
+                /**
+                 * 每当组件方法抛出错误时执行
+                 *
+                 * 最低基础库版本:[`2.4.1`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+                 */
+                error(err: Error): void
+            }>
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 在组件实例刚刚被创建时执行
+             *
+             * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            created(): void
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 在组件实例进入页面节点树时执行
+             *
+             * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            attached(): void
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 在组件在视图层布局完成后执行
+             *
+             * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            ready(): void
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 在组件实例被移动到节点树另一个位置时执行
+             *
+             * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            moved(): void
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 在组件实例被从页面节点树移除时执行
+             *
+             * 最低基础库版本:[`1.6.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            detached(): void
+            /**
+             * @deprecated 旧式的定义方式,基础库 `2.2.3` 起请在 lifetimes 中定义
+             *
+             * 每当组件方法抛出错误时执行
+             *
+             * 最低基础库版本:[`2.4.1`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            error(err: Error): void
+        }
+
+        interface OtherOption {
+            /** 类似于mixins和traits的组件间代码复用机制,参见 [behaviors](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html) */
+            behaviors: string[]
+            /**
+             * 组件数据字段监听器,用于监听 properties 和 data 的变化,参见 [数据监听器](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/observer.html)
+             *
+             * 最低基础库版本:[`2.6.1`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
+             */
+            observers: Record<string, (...args: any[]) => any>
+            /** 组件间关系定义,参见 [组件间关系](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html) */
+            relations: {
+                [componentName: string]: RelationOption
+            }
+            /** 组件接受的外部样式类,参见 [外部样式类](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html) */
+            externalClasses?: string[]
+            /** 组件所在页面的生命周期声明对象,参见 [组件生命周期](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html)
+             *
+             * 最低基础库版本: [`2.2.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) */
+            pageLifetimes?: Partial<PageLifetimes>
+            /** 一些选项(文档中介绍相关特性时会涉及具体的选项设置,这里暂不列举) */
+            options: ComponentOptions
+
+            /** 定义段过滤器,用于自定义组件扩展,参见 [自定义组件扩展](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/extend.html)
+             *
+             * 最低基础库版本: [`2.2.3`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) */
+            definitionFilter?: DefinitionFilter
+        }
+
+        interface KeyFrame {
+            /** 关键帧的偏移,范围[0-1] */
+            offset?: number
+            /** 动画缓动函数 */
+            ease?: string
+            /** 基点位置,即 CSS transform-origin */
+            transformOrigin?: string
+            /** 背景颜色,即 CSS background-color */
+            backgroundColor?: string
+            /** 底边位置,即 CSS bottom */
+            bottom?: number | string
+            /** 高度,即 CSS height */
+            height?: number | string
+            /** 左边位置,即 CSS left */
+            left?: number | string
+            /** 宽度,即 CSS width */
+            width?: number | string
+            /** 不透明度,即 CSS opacity */
+            opacity?: number | string
+            /** 右边位置,即 CSS right */
+            right?: number | string
+            /** 顶边位置,即 CSS top */
+            top?: number | string
+            /** 变换矩阵,即 CSS transform matrix */
+            matrix?: number[]
+            /** 三维变换矩阵,即 CSS transform matrix3d */
+            matrix3d?: number[]
+            /** 旋转,即 CSS transform rotate */
+            rotate?: number
+            /** 三维旋转,即 CSS transform rotate3d */
+            rotate3d?: number[]
+            /** X 方向旋转,即 CSS transform rotateX */
+            rotateX?: number
+            /** Y 方向旋转,即 CSS transform rotateY */
+            rotateY?: number
+            /** Z 方向旋转,即 CSS transform rotateZ */
+            rotateZ?: number
+            /** 缩放,即 CSS transform scale */
+            scale?: number[]
+            /** 三维缩放,即 CSS transform scale3d */
+            scale3d?: number[]
+            /** X 方向缩放,即 CSS transform scaleX */
+            scaleX?: number
+            /** Y 方向缩放,即 CSS transform scaleY */
+            scaleY?: number
+            /** Z 方向缩放,即 CSS transform scaleZ */
+            scaleZ?: number
+            /** 倾斜,即 CSS transform skew */
+            skew?: number[]
+            /** X 方向倾斜,即 CSS transform skewX */
+            skewX?: number
+            /** Y 方向倾斜,即 CSS transform skewY */
+            skewY?: number
+            /** 位移,即 CSS transform translate */
+            translate?: Array<number | string>
+            /** 三维位移,即 CSS transform translate3d */
+            translate3d?: Array<number | string>
+            /** X 方向位移,即 CSS transform translateX */
+            translateX?: number | string
+            /** Y 方向位移,即 CSS transform translateY */
+            translateY?: number | string
+            /** Z 方向位移,即 CSS transform translateZ */
+            translateZ?: number | string
+        }
+        interface ClearAnimationOptions {
+            /** 基点位置,即 CSS transform-origin */
+            transformOrigin?: boolean
+            /** 背景颜色,即 CSS background-color */
+            backgroundColor?: boolean
+            /** 底边位置,即 CSS bottom */
+            bottom?: boolean
+            /** 高度,即 CSS height */
+            height?: boolean
+            /** 左边位置,即 CSS left */
+            left?: boolean
+            /** 宽度,即 CSS width */
+            width?: boolean
+            /** 不透明度,即 CSS opacity */
+            opacity?: boolean
+            /** 右边位置,即 CSS right */
+            right?: boolean
+            /** 顶边位置,即 CSS top */
+            top?: boolean
+            /** 变换矩阵,即 CSS transform matrix */
+            matrix?: boolean
+            /** 三维变换矩阵,即 CSS transform matrix3d */
+            matrix3d?: boolean
+            /** 旋转,即 CSS transform rotate */
+            rotate?: boolean
+            /** 三维旋转,即 CSS transform rotate3d */
+            rotate3d?: boolean
+            /** X 方向旋转,即 CSS transform rotateX */
+            rotateX?: boolean
+            /** Y 方向旋转,即 CSS transform rotateY */
+            rotateY?: boolean
+            /** Z 方向旋转,即 CSS transform rotateZ */
+            rotateZ?: boolean
+            /** 缩放,即 CSS transform scale */
+            scale?: boolean
+            /** 三维缩放,即 CSS transform scale3d */
+            scale3d?: boolean
+            /** X 方向缩放,即 CSS transform scaleX */
+            scaleX?: boolean
+            /** Y 方向缩放,即 CSS transform scaleY */
+            scaleY?: boolean
+            /** Z 方向缩放,即 CSS transform scaleZ */
+            scaleZ?: boolean
+            /** 倾斜,即 CSS transform skew */
+            skew?: boolean
+            /** X 方向倾斜,即 CSS transform skewX */
+            skewX?: boolean
+            /** Y 方向倾斜,即 CSS transform skewY */
+            skewY?: boolean
+            /** 位移,即 CSS transform translate */
+            translate?: boolean
+            /** 三维位移,即 CSS transform translate3d */
+            translate3d?: boolean
+            /** X 方向位移,即 CSS transform translateX */
+            translateX?: boolean
+            /** Y 方向位移,即 CSS transform translateY */
+            translateY?: boolean
+            /** Z 方向位移,即 CSS transform translateZ */
+            translateZ?: boolean
+        }
+        interface ScrollTimelineKeyframe {
+            composite?: 'replace' | 'add' | 'accumulate' | 'auto'
+            easing?: string
+            offset?: number | null
+            [property: string]: string | number | null | undefined
+        }
+        interface ScrollTimelineOption {
+            /** 指定滚动元素的选择器(只支持 scroll-view),该元素滚动时会驱动动画的进度 */
+            scrollSource: string
+            /** 指定滚动的方向。有效值为 horizontal 或 vertical */
+            orientation?: string
+            /** 指定开始驱动动画进度的滚动偏移量,单位 px */
+            startScrollOffset: number
+            /** 指定停止驱动动画进度的滚动偏移量,单位 px */
+            endScrollOffset: number
+            /** 起始和结束的滚动范围映射的时间长度,该时间可用于与关键帧动画里的时间 (duration) 相匹配,单位 ms */
+            timeRange: number
+        }
+    }
+}
+/** Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。
+ *
+ * * 使用 `this.data` 可以获取内部数据和属性值,但不要直接修改它们,应使用 `setData` 修改。
+ * * 生命周期函数无法在组件方法中通过 `this` 访问到。
+ * * 属性名应避免以 data 开头,即不要命名成 `dataXyz` 这样的形式,因为在 WXML 中, `data-xyz=""` 会被作为节点 dataset 来处理,而不是组件属性。
+ * * 在一个组件的定义和使用时,组件的属性名和 data 字段相互间都不能冲突(尽管它们位于不同的定义段中)。
+ * * 从基础库 `2.0.9` 开始,对象类型的属性和 data 字段中可以包含函数类型的子字段,即可以通过对象类型的属性字段来传递函数。低于这一版本的基础库不支持这一特性。
+ * * `bug` : 对于 type 为 Object 或 Array 的属性,如果通过该组件自身的 `this.setData` 来改变属性值的一个子字段,则依旧会触发属性 observer ,且 observer 接收到的 `newVal` 是变化的那个子字段的值, `oldVal` 为空, `changedPath` 包含子字段的字段名相关信息。
+ */
+declare let Component: WechatMiniprogram.Component.Constructor

+ 72 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.event.d.ts

@@ -0,0 +1,72 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+declare namespace WechatMiniprogram {
+    interface Touch {
+        clientX: number
+        clientY: number
+        force: number
+        identifier: number
+        pageX: number
+        pageY: number
+    }
+    interface Event {
+        currentTarget: {
+            id: string
+            dataset: {
+                [key: string]: string
+            }
+            offsetTop: number
+            offsetLeft: number
+        }
+        target: {
+            id: string
+            dataset: {
+                [key: string]: string
+            }
+            offsetTop: number
+            offsetLeft: number
+        }
+        timeStamp: number
+        touches: Touch[]
+        mut: boolean
+        type: string
+    }
+    interface TapEvent extends Event {
+        changedTouches: []
+        detail: {
+            x: number
+            y: number
+        }
+        type: 'tap'
+    }
+
+    interface InputEvent extends Event {
+        changedTouches: []
+        detail: {
+            cursor: number
+            keyCode: number
+            value: string
+        }
+        type: 'input'
+    }
+}

+ 247 - 0
miniprogram/node_modules/miniprogram-api-typings/types/wx/lib.wx.page.d.ts

@@ -0,0 +1,247 @@
+/*! *****************************************************************************
+Copyright (c) 2020 Tencent, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+***************************************************************************** */
+
+declare namespace WechatMiniprogram {
+    namespace Page {
+        type Instance<
+            TData extends DataOption,
+            TCustom extends CustomOption
+        > = OptionalInterface<ILifetime> &
+            InstanceProperties &
+            InstanceMethods<TData> &
+            Data<TData> &
+            TCustom
+        type Options<
+            TData extends DataOption,
+            TCustom extends CustomOption
+        > = (TCustom & Partial<Data<TData>> & Partial<ILifetime>) &
+            ThisType<Instance<TData, TCustom>>
+        type TrivialInstance = Instance<IAnyObject, IAnyObject>
+        interface Constructor {
+            <TData extends DataOption, TCustom extends CustomOption>(
+                options: Options<TData, TCustom>
+            ): void
+        }
+        interface ILifetime {
+            /** 生命周期回调—监听页面加载
+             *
+             * 页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
+             */
+            onLoad(
+                /** 打开当前页面路径中的参数 */
+                query: Record<string, string | undefined>
+            ): void
+            /** 生命周期回调—监听页面显示
+             *
+             * 页面显示/切入前台时触发。
+             */
+            onShow(): void
+            /** 生命周期回调—监听页面初次渲染完成
+       *
+       * 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
+       *
+
+      * 注意:对界面内容进行设置的 API 如`wx.setNavigationBarTitle`,请在`onReady`之后进行。
+      */
+            onReady(): void
+            /** 生命周期回调—监听页面隐藏
+             *
+             * 页面隐藏/切入后台时触发。 如 `navigateTo` 或底部 `tab` 切换到其他页面,小程序切入后台等。
+             */
+            onHide(): void
+            /** 生命周期回调—监听页面卸载
+             *
+             * 页面卸载时触发。如`redirectTo`或`navigateBack`到其他页面时。
+             */
+            onUnload(): void
+            /** 监听用户下拉动作
+             *
+             * 监听用户下拉刷新事件。
+             * - 需要在`app.json`的`window`选项中或页面配置中开启`enablePullDownRefresh`。
+             * - 可以通过`wx.startPullDownRefresh`触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
+             * - 当处理完数据刷新后,`wx.stopPullDownRefresh`可以停止当前页面的下拉刷新。
+             */
+            onPullDownRefresh(): void
+            /** 页面上拉触底事件的处理函数
+             *
+             * 监听用户上拉触底事件。
+             * - 可以在`app.json`的`window`选项中或页面配置中设置触发距离`onReachBottomDistance`。
+             * - 在触发距离内滑动期间,本事件只会被触发一次。
+             */
+            onReachBottom(): void
+            /** 用户点击右上角转发
+             *
+             * 监听用户点击页面内转发按钮(`<button>` 组件 `open-type="share"`)或右上角菜单“转发”按钮的行为,并自定义转发内容。
+             *
+             * **注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮**
+             *
+             * 此事件需要 return 一个 Object,用于自定义转发内容
+             */
+            onShareAppMessage(
+                /** 分享发起来源参数 */
+                options: IShareAppMessageOption
+            ): ICustomShareContent | void
+            /** 页面滚动触发事件的处理函数
+             *
+             * 监听用户滑动页面事件。
+             */
+            onPageScroll(
+                /** 页面滚动参数 */
+                options: IPageScrollOption
+            ): void
+
+            /** 当前是 tab 页时,点击 tab 时触发,最低基础库: `1.9.0` */
+            onTabItemTap(
+                /** tab 点击参数 */
+                options: ITabItemTapOption
+            ): void
+
+            /** 窗口尺寸改变时触发,最低基础库:`2.4.0` */
+            onResize(
+                /** 窗口尺寸参数 */
+                options: IResizeOption
+            ): void
+
+            /**
+             * 监听用户点击右上角菜单“收藏”按钮的行为,并自定义收藏内容。
+             * 基础库 2.10.3,安卓 7.0.15 版本起支持,iOS 暂不支持
+             */
+            onAddToFavorites(
+                options: IAddToFavoritesOption
+            ): IAddToFavoritesContent
+        }
+        interface InstanceProperties {
+            /** 页面的文件路径 */
+            is: string
+
+            /** 到当前页面的路径 */
+            route: string
+
+            /** 打开当前页面路径中的参数 */
+            options: Record<string, string | undefined>
+        }
+
+        type DataOption = Record<string, any>
+        type CustomOption = Record<string, any>
+
+        type InstanceMethods<D extends DataOption> = Component.InstanceMethods<
+            D
+        >
+
+        interface Data<D extends DataOption> {
+            /** 页面的初始数据
+             *
+             * `data` 是页面第一次渲染使用的**初始数据**。
+             *
+             * 页面加载时,`data` 将会以`JSON`字符串的形式由逻辑层传至渲染层,因此`data`中的数据必须是可以转成`JSON`的类型:字符串,数字,布尔值,对象,数组。
+             *
+             * 渲染层可以通过 `WXML` 对数据进行绑定。
+             */
+            data: D
+        }
+
+        interface ICustomShareContent {
+            /** 转发标题。默认值:当前小程序名称 */
+            title?: string
+            /** 转发路径,必须是以 / 开头的完整路径。默认值:当前页面 path */
+            path?: string
+            /** 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4,最低基础库: `1.5.0`。默认值:使用默认截图 */
+            imageUrl?: string
+        }
+
+        interface IPageScrollOption {
+            /** 页面在垂直方向已滚动的距离(单位px) */
+            scrollTop: number
+        }
+
+        interface IShareAppMessageOption {
+            /** 转发事件来源。
+             *
+             * 可选值:
+             * - `button`:页面内转发按钮;
+             * - `menu`:右上角转发菜单。
+             *
+             * 最低基础库: `1.2.4`
+             */
+            from: 'button' | 'menu' | string
+            /** 如果 `from` 值是 `button`,则 `target` 是触发这次转发事件的 `button`,否则为 `undefined`
+             *
+             * 最低基础库: `1.2.4` */
+            target: any
+            /** 页面中包含`<web-view>`组件时,返回当前`<web-view>`的url
+             *
+             * 最低基础库: `1.6.4`
+             */
+            webViewUrl?: string
+        }
+
+        interface ITabItemTapOption {
+            /** 被点击tabItem的序号,从0开始,最低基础库: `1.9.0` */
+            index: string
+            /** 被点击tabItem的页面路径,最低基础库: `1.9.0` */
+            pagePath: string
+            /** 被点击tabItem的按钮文字,最低基础库: `1.9.0` */
+            text: string
+        }
+
+        interface IResizeOption {
+            size: {
+                /** 变化后的窗口宽度,单位 px */
+                windowWidth: number
+                /** 变化后的窗口高度,单位 px */
+                windowHeight: number
+            }
+        }
+
+        interface IAddToFavoritesOption {
+            /** 页面中包含web-view组件时,返回当前web-view的url */
+            webviewUrl?: string
+        }
+
+        interface IAddToFavoritesContent {
+            /** 自定义标题,默认值:页面标题或账号名称 */
+            title?: string
+            /** 自定义图片,显示图片长宽比为 1:1,默认值:页面截图 */
+            imageUrl?: string
+            /** 自定义query字段,默认值:当前页面的query */
+            query?: string
+        }
+
+        interface getCurrentPages {
+            (): Array<Instance<IAnyObject, IAnyObject>>
+        }
+    }
+}
+
+/**
+ * 注册小程序中的一个页面。接受一个 `Object` 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。
+ */
+declare let Page: WechatMiniprogram.Page.Constructor
+/**
+ * 获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。
+
+ *  __注意:__
+
+ *  - __不要尝试修改页面栈,会导致路由以及页面状态错误。__
+ *  - 不要在 `App.onLaunch` 的时候调用 `getCurrentPages()`,此时 `page` 还没有生成。
+ */
+declare let getCurrentPages: WechatMiniprogram.Page.getCurrentPages

+ 4 - 0
miniprogram/node_modules/miniprogram-api-typings/typings.json

@@ -0,0 +1,4 @@
+{
+	"name": "miniprogram-api-typings",
+	"main": "index.d.ts"
+}

+ 21 - 0
miniprogram/node_modules/miniprogram-computed/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 wechat-miniprogram
+
+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.

+ 252 - 0
miniprogram/node_modules/miniprogram-computed/README.md

@@ -0,0 +1,252 @@
+# computed
+
+小程序自定义组件扩展 behavior,计算属性 `computed` 和监听器 `watch` 的实现。在 data 或者 properties 改变时,会重新计算 `computed` 字段并触发 `watch` 监听器。
+
+> 此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅[官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)。
+
+注意: 4.0.0 大版本变更了最基本的接口名,升级到 4.0.0 以上时请注意 [#60](https://github.com/wechat-miniprogram/computed/issues/60) 的问题。旧版文档可以参考对应版本的 git tag 中的 README ,如 [v3.1.1](https://github.com/wechat-miniprogram/computed/tree/v3.1.1) tag 。
+
+## 使用方法
+
+### 方式一 代码片段
+
+需要小程序基础库版本 >= 2.6.1 的环境。
+
+可以直接体验一下这个代码片段,它包含了基本用法示例:[https://developers.weixin.qq.com/s/4KYn6TmJ7osP](https://developers.weixin.qq.com/s/4KYn6TmJ7osP)
+
+体验该代码片段前,需要先安装并构建相对应的 npm 包。
+
+```shell
+npm install --save miniprogram-computed
+```
+
+### 方式二 本地构建
+
+将本仓库 clone 到本地,进入根目录安装 npm 依赖。
+
+```shell
+npm install
+```
+
+安装完成后执行
+
+```shell
+npm run dev // 构建 dev 版本
+```
+
+构建完毕后,根目录下的 `demo` 即为小程序代码根目录,可以将此 demo 导入开发者工具中进行体验。
+
+### computed 基本用法
+
+```js
+// component.js
+const computedBehavior = require('miniprogram-computed').behavior
+const behaviorTest = require('./behavior-test') // 引入自定义 behavior
+
+Component({
+  behaviors: [behaviorTest, computedBehavior],
+  data: {
+    a: 1,
+    b: 1,
+  },
+  computed: {
+    sum(data) {
+      // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问
+      // 这个函数的返回值会被设置到 this.data.sum 字段中
+      return data.a + data.b + data.c // data.c 为自定义 behavior 数据段
+    },
+  },
+  methods: {
+    onTap() {
+      this.setData({
+        a: this.data.b,
+        b: this.data.a + this.data.b,
+      })
+    },
+  },
+})
+```
+
+```js
+//behavior-test.js
+module.exports = Behavior({
+  data: {
+    c: 2,
+  },
+})
+```
+
+```xml
+<view>A = {{a}}</view>
+<view>B = {{b}}</view>
+<view>SUM = {{sum}}</view>
+<button bindtap="onTap">click</button>
+```
+
+### watch 基本用法
+
+```js
+const computedBehavior = require('miniprogram-computed').behavior
+
+Component({
+  behaviors: [computedBehavior],
+  data: {
+    a: 1,
+    b: 1,
+    sum: 2,
+  },
+  watch: {
+    'a, b': function (a, b) {
+      this.setData({
+        sum: a + b,
+      })
+    },
+  },
+  methods: {
+    onTap() {
+      this.setData({
+        a: this.data.b,
+        b: this.data.a + this.data.b,
+      })
+    },
+  },
+})
+```
+
+```xml
+<view>A = {{a}}</view>
+<view>B = {{b}}</view>
+<view>SUM = {{sum}}</view>
+<button bindtap="onTap">click</button>
+```
+
+### TypeScript 支持
+
+由于通过 behavior 的方式引入不能获得类型支持, 因此为了获得类型的支持, 可以使用一个辅助组件构造器:
+
+```ts
+import { ComponentWithComputed } from 'miniprogram-computed'
+
+ComponentWithComputed({
+  data: {
+    a: 1,
+    b: 1,
+    sum: 2,
+  },
+  watch: {
+    'a, b': function (a, b) {
+      this.setData({
+        sum: a + b,
+      })
+    },
+  },
+  computed: {
+    sum(data) {
+      // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问
+      // 这个函数的返回值会被设置到 this.data.sum 字段中
+      return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段
+    },
+  },
+})
+```
+
+当使用该构造器的时候, 编译器可以给 `computed` 和 `watch` 提供自动提示和类型支持。
+
+**注意: 当使用该构造器的时候, 无需手动加入 `computedBehavior` , 该构造器会自动引入该 behavior 。**
+
+(类似地,也有 `BehaviorWithComputed` 构造器对应于 `Bahavior` 。)
+
+**关于 TS 兼容问题**
+
+若在小程序中用 `TypeScript` 进行开发并使用到了 `Component` 构造器。这时定义 `computed` 或 `watch` 字段会出现类型报错。
+
+针对此问题,推荐使用 `ComponentWithComputed` 构造器代替 `Component` 构造器。
+
+**关于类型声明**
+
+在 `4.0.5` 版本之前,并未提供相关的 `.d.ts` 类型声明。
+
+强烈建议将 `miniprogram-computed` npm 包依赖升级至 `^4.0.5` 已获取完整的类型能力。
+
+## ^4.0.0 与 ^1.0.0、 ^2.0.0、 ^3.0.0 版本的差异
+
+### ^4.0.0 版本
+
+- 变更了最基本的接口。
+
+- 新增简单的 TypeScript 支持。
+
+### ^3.0.0 版本
+
+- 支持 mobx-miniprogram 扩展库引入的数据段。
+
+- 对自定义 behavior 数据段使用 computed 时,支持在初始化视图中进行数据渲染。
+
+- 基于 proxy 更新了 computed 数据追踪的实现方式,computed 依赖的数据路径追踪初始化操作,延后到组件的 created 阶段 。
+
+### ^2.0.0 版本
+
+基于小程序基础库 2.6.1 开始支持的 observers 定义段实现,具有较好的性能。
+
+以下是版本之间主要区别的比较。
+
+| 项目                                            | ^1.0.0          | ^2.0.0        | ^3.0.0 和 ^4.0.0 |
+| ----------------------------------------------- | --------------- | ------------- | ---------------- |
+| 支持的基础库最低版本                            | 2.2.3           | 2.6.1         | 2.6.1            |
+| 支持 `watch` 定义段                             | 否              | 是            | 是               |
+| 性能                                            | 相对较差        | 相对较好      | 相对较好         |
+| 支持 `mobx-miniprogram` 扩展库                  | 不支持          | 不支持        | 支持             |
+| 支持自定义 `behavior` 数据字段 / 初始化视图渲染 | 不支持 / 不支持 | 支持 / 不支持 | 支持 / 支持      |
+
+## 常见问题说明
+
+### 我应该使用 computed 还是 watch ?
+
+从原理上说, `watch` 的性能比 `computed` 更好;但 `computed` 的用法更简洁干净。
+
+此外, `computed` 字段状态只能依赖于 `data` 和其他 `computed` 字段,不能访问 `this` 。如果不可避免要访问 `this` ,则必须使用 `watch` 代替。
+
+### watch 和小程序基础库本身的 observers 有什么区别?
+
+- 无论字段是否真的改变, `observers` 都会被触发,而 `watch` 只在字段值改变了的时候触发,并且触发时带有参数。
+
+### 关于 \*\* 通配符
+
+在 `watch` 字段上可以使用 `**` 通配符,是它能够监听这个字段下的子字段的变化(类似于小程序基础库本身的 observers )。
+
+```js
+const computedBehavior = require('miniprogram-computed').behavior
+
+Component({
+  behaviors: [computedBehavior],
+  data: {
+    obj: {
+      a: 1,
+      b: 2,
+    },
+  },
+  watch: {
+    'obj.**': function (obj) {
+      this.setData({
+        sum: obj.a + obj.b,
+      })
+    },
+  },
+  methods: {
+    onTap() {
+      this.setData({
+        'obj.a': 10,
+      })
+    },
+  },
+})
+```
+
+除此以外:
+
+- 对于没有使用 `**` 通配符的字段,在 `watch` 检查值是否发生变化时,只会进行粗略的浅比较(使用 `===` );
+- 对于使用了 `**` 通配符的字段,则会进行深比较,来尝试精确检测对象是否真的发生了变化,这要求对象字段不能包含循环(类似于 `JSON.stringify` )。
+
+### 关于低版本兼容
+
+对于 IOS `9.3` 以下的版本,由于无法原生支持 `Proxy`,这里会使用 `proxy-polyfill` 去代替。

+ 39 - 0
miniprogram/node_modules/miniprogram-computed/UPDATE.md

@@ -0,0 +1,39 @@
+## 0.0.6
+
+- 支持 properties。
+
+## 0.0.7
+
+- 修复 setData 设置 properties 会报 can't call setData in computed getter function! 问题
+
+## 2.0.0
+
+- 基于 observers 重构,开始支持 watch
+
+## 2.1.0
+
+- 支持 watch 的 `.**` 语法
+
+## 3.0.0
+
+- 修复 computed 中使用自定义 behavior 数据段时,初始化视图的 computed data 不渲染的问题。
+- 支持 mobx-miniprogram 扩展库。
+- 更新 computed 数据追踪方式。
+
+## 4.0.0
+
+- 使用 TypeScript 重构。
+- 优化部分生命周期逻辑。
+
+# 4.1.1
+
+- 优化打包方式
+- 优化 dev 开发流程
+
+# 4.2.x
+
+- 增加 polyfill
+
+# 4.3.x
+
+- 修复引用类型的部分问题

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
miniprogram/node_modules/miniprogram-computed/dist/index.js


+ 82 - 0
miniprogram/node_modules/miniprogram-computed/package.json

@@ -0,0 +1,82 @@
+{
+  "name": "miniprogram-computed",
+  "version": "4.3.8",
+  "description": "Computed & watch - wechat miniprogram custom component extend behavior",
+  "main": "dist/index.js",
+  "types": "types/index.d.ts",
+  "scripts": {
+    "dev": "gulp dev",
+    "watch": "gulp dev-watch",
+    "build": "gulp",
+    "gen_dts": "gulp dts",
+    "test": "jest ./test/* --bail",
+    "coverage": "jest ./test/* --coverage --bail",
+    "lint": "eslint . --fix"
+  },
+  "miniprogram": "dist",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/wechat-miniprogram/computed.git"
+  },
+  "files": [
+    "src",
+    "dist",
+    "types",
+    "LICENSE",
+    "package.json",
+    "README.md",
+    "UPDATE.md"
+  ],
+  "author": "wechat-miniprogram",
+  "license": "MIT",
+  "devDependencies": {
+    "@swc/cli": "^0.1.49",
+    "@swc/core": "^1.2.80",
+    "@types/jest": "^27.0.1",
+    "@types/rfdc": "^1.1.0",
+    "@types/wechat-miniprogram": "^3.0.0",
+    "@typescript-eslint/eslint-plugin": "^2.23.0",
+    "@typescript-eslint/parser": "^2.23.0",
+    "codecov": "^3.7.0",
+    "colors": "^1.4.0",
+    "eslint": "^5.14.1",
+    "eslint-config-airbnb-base": "13.1.0",
+    "eslint-config-prettier": "^6.10.1",
+    "eslint-loader": "^2.1.2",
+    "eslint-plugin-import": "^2.16.0",
+    "eslint-plugin-node": "^7.0.1",
+    "eslint-plugin-prettier": "^3.1.2",
+    "eslint-plugin-promise": "^3.8.0",
+    "gulp": "^4.0.0",
+    "gulp-clean": "^0.4.0",
+    "gulp-esbuild": "^0.8.6",
+    "gulp-swc": "^1.1.1",
+    "gulp-typescript": "^6.0.0-alpha.1",
+    "gulp-watch": "^5.0.1",
+    "husky": "^7.0.2",
+    "jest": "^27.0.6",
+    "miniprogram-exparser": "^2.11.2",
+    "miniprogram-simulate": "^1.2.9",
+    "prettier": "^2.0.1",
+    "proxy-polyfill": "^0.3.2",
+    "ts-jest": "^27.0.5",
+    "ts-node": "^10.2.1",
+    "typescript": "^4.5.4"
+  },
+  "dependencies": {
+    "fast-deep-equal": "^2.0.1",
+    "rfdc": "^1.1.4"
+  },
+  "husky": {
+    "hooks": {
+      "pre-commit": "npm run lint"
+    }
+  },
+  "pnpm": {
+    "overrides": {
+      "ansi-regex@>2.1.1 <5.0.1": ">=5.0.1",
+      "braces@<2.3.1": ">=2.3.1",
+      "glob-parent@<5.1.2": ">=5.1.2"
+    }
+  }
+}

+ 273 - 0
miniprogram/node_modules/miniprogram-computed/src/behavior.ts

@@ -0,0 +1,273 @@
+import rfdc from 'rfdc'
+import deepEqual from 'fast-deep-equal'
+import * as dataPath from './data-path'
+import * as dataTracer from './data-tracer'
+import type { IRelatedPathValue } from './data-tracer'
+
+const deepClone = rfdc({ proto: true })
+
+interface BehaviorData {
+  '_computedWatchInit': ComputedWatchInitStatus;
+  [k: string]: any;
+}
+
+interface BehaviorExtend {
+  // original
+  data: BehaviorData;
+  setData(d: Record<string, any>): void;
+  _computedWatchInfo: Record<string, ComputedWatchInfo>;
+}
+
+interface ObserversItem {
+  fields: string;
+  observer(): void;
+}
+
+interface ComputedWatchInfo {
+  computedUpdaters: Array<(...args: unknown[]) => boolean>;
+  computedRelatedPathValues: Record<string, Array<IRelatedPathValue>>;
+  watchCurVal: Record<string, any>;
+  _triggerFromComputedAttached: Record<string, boolean>;
+}
+
+enum ComputedWatchInitStatus {
+  CREATED,
+  ATTACHED
+}
+
+let computedWatchDefIdInc = 0
+
+function equal(a: unknown, b: unknown) {
+  if (a === b) {
+    return true
+  } else {
+    // When a = b = NaN
+    // NaN === NaN is false
+    return a !== a && b !== b
+  }
+}
+
+export const behavior = Behavior({
+  lifetimes: {
+    attached(this: BehaviorExtend) {
+      this.setData({
+        _computedWatchInit: ComputedWatchInitStatus.ATTACHED,
+      })
+    },
+    created(this: BehaviorExtend) {
+      this.setData({
+        _computedWatchInit: ComputedWatchInitStatus.CREATED,
+      })
+    },
+  },
+
+  definitionFilter(defFields: any & BehaviorExtend) {
+    const computedDef = defFields.computed
+    const watchDef = defFields.watch
+    const observersItems: ObserversItem[] = []
+    const computedWatchDefId = computedWatchDefIdInc++
+    observersItems.push({
+      fields: '_computedWatchInit',
+      observer(this: BehaviorExtend) {
+        const status = this.data._computedWatchInit
+        if (status === ComputedWatchInitStatus.CREATED) {
+          // init data fields
+          const computedWatchInfo = {
+            computedUpdaters: [],
+            computedRelatedPathValues: {},
+            watchCurVal: {},
+            _triggerFromComputedAttached: {},
+          }
+          if (!this._computedWatchInfo) this._computedWatchInfo = {}
+          this._computedWatchInfo[computedWatchDefId] = computedWatchInfo
+          // handling watch
+          // 1. push to initFuncs
+          if (watchDef) {
+            Object.keys(watchDef).forEach((watchPath) => {
+              const paths = dataPath.parseMultiDataPaths(watchPath)
+              // record the original value of watch targets
+              const curVal = paths.map(({ path, options }) => {
+                const val = dataPath.getDataOnPath(this.data, path)
+                return options.deepCmp ? deepClone(val) : val
+              })
+              computedWatchInfo.watchCurVal[watchPath] = curVal
+            })
+          }
+        } else if (status === ComputedWatchInitStatus.ATTACHED) {
+          // handling computed
+          // 1. push to initFuncs
+          // 2. push to computedUpdaters
+          const computedWatchInfo = this._computedWatchInfo[computedWatchDefId]
+          if (computedDef) {
+            Object.keys(computedDef).forEach((targetField) => {
+              const updateMethod = computedDef[targetField]
+              const relatedPathValuesOnDef = []
+              const val = updateMethod(
+                dataTracer.create(this.data, relatedPathValuesOnDef),
+              )
+              const pathValues = relatedPathValuesOnDef.map(({ path }) => ({
+                path,
+                value: dataPath.getDataOnPath(this.data, path),
+              }))
+              // here we can do small setDatas
+              // because observer handlers will force grouping small setDatas together
+              this.setData({
+                [targetField]: dataTracer.unwrap(val),
+              })
+              computedWatchInfo._triggerFromComputedAttached[targetField] = true
+              computedWatchInfo.computedRelatedPathValues[targetField] =
+                pathValues
+
+              // will be invoked when setData is called
+              const updateValueAndRelatedPaths = () => {
+                const oldPathValues =
+                  computedWatchInfo.computedRelatedPathValues[targetField]
+                let needUpdate = false
+                // check whether its dependency updated
+                for (let i = 0; i < oldPathValues.length; i++) {
+                  const { path, value: oldVal } = oldPathValues[i]
+                  const curVal = dataPath.getDataOnPath(this.data, path)
+                  if (!equal(oldVal, curVal)) {
+                    needUpdate = true
+                    break
+                  }
+                }
+                if (!needUpdate) return false
+
+                const relatedPathValues = []
+                const val = updateMethod(
+                  dataTracer.create(this.data, relatedPathValues),
+                )
+                this.setData({
+                  [targetField]: dataTracer.unwrap(val),
+                })
+                const pathValues = relatedPathValues.map(({ path }) => ({
+                  path,
+                  value: dataPath.getDataOnPath(this.data, path),
+                }))
+                computedWatchInfo.computedRelatedPathValues[targetField] =
+                  pathValues
+                return true
+              }
+              computedWatchInfo.computedUpdaters.push(
+                updateValueAndRelatedPaths,
+              )
+            })
+          }
+        }
+      },
+    })
+
+    if (computedDef) {
+      observersItems.push({
+        fields: '**',
+        observer(this: BehaviorExtend) {
+          if (!this._computedWatchInfo) return
+          const computedWatchInfo = this._computedWatchInfo[computedWatchDefId]
+          if (!computedWatchInfo) return
+
+          let changed: boolean
+          do {
+            changed = computedWatchInfo.computedUpdaters.some((func) =>
+              func.call(this),
+            )
+          } while (changed)
+        },
+      })
+    }
+
+    if (watchDef) {
+      Object.keys(watchDef).forEach((watchPath) => {
+        const paths = dataPath.parseMultiDataPaths(watchPath)
+        observersItems.push({
+          fields: watchPath,
+          observer(this: BehaviorExtend) {
+            if (!this._computedWatchInfo) return
+            const computedWatchInfo =
+              this._computedWatchInfo[computedWatchDefId]
+            if (!computedWatchInfo) return
+            // (issue #58) ignore watch func when trigger by computed attached
+            if (
+              Object.keys(computedWatchInfo._triggerFromComputedAttached).length
+            ) {
+              const pathsMap: Record<string, boolean> = {}
+              paths.forEach((path) => (pathsMap[path.path[0]] = true))
+              for (const computedVal in computedWatchInfo._triggerFromComputedAttached) {
+                if (
+                  computedWatchInfo._triggerFromComputedAttached.hasOwnProperty(
+                    computedVal,
+                  )
+                ) {
+                  if (
+                    pathsMap[computedVal] &&
+                    computedWatchInfo._triggerFromComputedAttached[computedVal]
+                  ) {
+                    computedWatchInfo._triggerFromComputedAttached[
+                      computedVal
+                    ] = false
+                    return
+                  }
+                }
+              }
+            }
+            const oldVal = computedWatchInfo.watchCurVal[watchPath]
+
+            // get new watching field value
+            const originalCurValWithOptions = paths.map(({ path, options }) => {
+              const val = dataPath.getDataOnPath(this.data, path)
+              return { val, options }
+            })
+            const curVal = originalCurValWithOptions.map(({ val, options }) =>
+              options.deepCmp ? deepClone(val) : val,
+            )
+            computedWatchInfo.watchCurVal[watchPath] = curVal
+
+            // compare
+            let changed = false
+            for (let i = 0; i < curVal.length; i++) {
+              const options = paths[i].options
+              const deepCmp = options.deepCmp
+              if (
+                deepCmp
+                  ? !deepEqual(oldVal[i], curVal[i])
+                  : !equal(oldVal[i], curVal[i])
+              ) {
+                changed = true
+                break
+              }
+            }
+
+            // if changed, update
+            if (changed) {
+              watchDef[watchPath].apply(
+                this,
+                originalCurValWithOptions.map(({ val }) => val),
+              )
+            }
+          },
+        })
+      })
+    }
+
+    if (typeof defFields.observers !== 'object') {
+      defFields.observers = {}
+    }
+
+    if (Array.isArray(defFields.observers)) {
+      defFields.observers.push(...observersItems)
+    } else {
+      observersItems.forEach((item) => {
+        // defFields.observers[item.fields] = item.observer
+        const f = defFields.observers[item.fields]
+        if (!f) {
+          defFields.observers[item.fields] = item.observer
+        } else {
+          defFields.observers[item.fields] = function () {
+            item.observer.call(this)
+            f.call(this)
+          }
+        }
+      })
+    }
+  },
+})

+ 133 - 0
miniprogram/node_modules/miniprogram-computed/src/data-path.ts

@@ -0,0 +1,133 @@
+const WHITE_SPACE_CHAR_REGEXP = /^\s/
+
+interface IParserState { 
+  index: number;
+  length: number;
+}
+
+const throwParsingError = (path: string, index: number) => {
+  throw new Error(
+    'Parsing data path "' +
+      path +
+      '" failed at char "' +
+      path[index] +
+      '" (index ' +
+      index +
+      ')',
+  )
+}
+
+const parseArrIndex = (path: string, state: IParserState) => {
+  const startIndex = state.index
+  while (state.index < state.length) {
+    const ch = path[state.index]
+    if (/^[0-9]/.test(ch)) {
+      state.index++
+      continue
+    }
+    break
+  }
+  if (startIndex === state.index) {
+    throwParsingError(path, state.index)
+  }
+  return parseInt(path.slice(startIndex, state.index), 10)
+}
+
+const parseIdent = (path: string, state: IParserState) => {
+  const startIndex = state.index
+  const ch = path[startIndex]
+  if (/^[_a-zA-Z$]/.test(ch)) {
+    state.index++
+    while (state.index < state.length) {
+      const ch = path[state.index]
+      if (/^[_a-zA-Z0-9$]/.test(ch)) {
+        state.index++
+        continue
+      }
+      break
+    }
+  } else {
+    throwParsingError(path, state.index)
+  }
+  return path.slice(startIndex, state.index)
+}
+
+const parseSinglePath = (path: string, state: IParserState) => {
+  const paths = [parseIdent(path, state)]
+  const options = {
+    deepCmp: false,
+  }
+  while (state.index < state.length) {
+    const ch = path[state.index]
+    if (ch === '[') {
+      state.index++
+      paths.push(`${parseArrIndex(path, state)}`)
+      const nextCh = path[state.index]
+      if (nextCh !== ']') throwParsingError(path, state.index)
+      state.index++
+    } else if (ch === '.') {
+      state.index++
+      const ch = path[state.index]
+      if (ch === '*') {
+        state.index++
+        const ch = path[state.index]
+        if (ch === '*') {
+          state.index++
+          options.deepCmp = true
+          break
+        }
+        throwParsingError(path, state.index)
+      }
+      paths.push(parseIdent(path, state))
+    } else {
+      break
+    }
+  }
+  return { path: paths, options }
+}
+
+const parseMultiPaths = (path: string, state: IParserState) => {
+  while (WHITE_SPACE_CHAR_REGEXP.test(path[state.index])) {
+    state.index++
+  }
+  const ret = [parseSinglePath(path, state)]
+  let splitted = false
+  while (state.index < state.length) {
+    const ch = path[state.index]
+    if (WHITE_SPACE_CHAR_REGEXP.test(ch)) {
+      state.index++
+    } else if (ch === ',') {
+      splitted = true
+      state.index++
+    } else if (splitted) {
+      splitted = false
+      ret.push(parseSinglePath(path, state))
+    } else {
+      throwParsingError(path, state.index)
+    }
+  }
+  return ret
+}
+
+const parseEOF = (path: string, state: IParserState) => {
+  if (state.index < state.length) throwParsingError(path, state.index)
+}
+
+export const parseMultiDataPaths = (path: string) => {
+  const state = {
+    length: path.length,
+    index: 0,
+  }
+  const ret = parseMultiPaths(path, state)
+  parseEOF(path, state)
+  return ret
+}
+
+export const getDataOnPath = (data: unknown, path: Array<string>) => {
+  let ret = data
+  path.forEach((s) => {
+    if (typeof ret !== 'object' || ret === null) ret = undefined
+    else ret = ret[s]
+  })
+  return ret
+}

+ 60 - 0
miniprogram/node_modules/miniprogram-computed/src/data-tracer.ts

@@ -0,0 +1,60 @@
+import ProxyPolyfillBuilder from 'proxy-polyfill/src/proxy'
+const ProxyPolyfill = ProxyPolyfillBuilder()
+
+interface IWrappedData { 
+  __rawObject__: unknown;
+}
+
+export interface IRelatedPathValue {
+  path: Array<string>;
+  value: unknown;
+}
+
+const wrapData = (data: unknown, relatedPathValues: Array<IRelatedPathValue>, basePath: Array<string>) => {
+  if (typeof data !== 'object' || data === null) return data
+  const handler = {
+    get(obj: unknown, key: string) {
+      if (key === '__rawObject__') return obj
+      let keyWrapper = null
+      const keyPath = basePath.concat(key)
+      const value = obj[key]
+      relatedPathValues.push({
+        path: keyPath,
+        value,
+      })
+      keyWrapper = wrapData(value, relatedPathValues, keyPath)
+      return keyWrapper
+    },
+  }
+  try {
+    return new Proxy(data, handler)
+  } catch (e) {
+    return new ProxyPolyfill(data, handler)
+  }
+}
+
+export function create(data: unknown, relatedPathValues: Array<IRelatedPathValue>) {
+  return wrapData(data, relatedPathValues, [])
+}
+
+export function unwrap(wrapped: IWrappedData) {
+  // #70
+  if (wrapped !== null && typeof wrapped === 'object' && typeof wrapped.__rawObject__ !== 'object' ) {
+    if (Array.isArray(wrapped)) {
+      return wrapped.map((i) => unwrap(i))
+    }
+    const ret = {}
+    Object.keys(wrapped).forEach(k => {
+      ret[k] = unwrap(wrapped[k])
+    })
+    return ret
+  }
+  if (
+    typeof wrapped !== 'object' ||
+    wrapped === null ||
+    typeof wrapped.__rawObject__ !== 'object'
+  ) {
+    return wrapped
+  }
+  return wrapped.__rawObject__
+}

+ 113 - 0
miniprogram/node_modules/miniprogram-computed/src/index.ts

@@ -0,0 +1,113 @@
+import { behavior } from './behavior'
+
+export { behavior } from './behavior'
+
+type ComputedInstance<
+  D extends WechatMiniprogram.Component.DataOption,
+  P extends WechatMiniprogram.Component.PropertyOption,
+  M extends WechatMiniprogram.Component.MethodOption,
+  C extends Record<string, (data: D & { [K in keyof P]: any }) => any>,
+  TCustomProperty extends WechatMiniprogram.IAnyObject = Record<string, never>,
+> = WechatMiniprogram.Component.Instance<D, P, M, TCustomProperty> & {
+  data: { [K in keyof C]: ReturnType<C[K]> } & { [K in keyof P]: any };
+}
+
+type ComputedOptions<
+  TData extends WechatMiniprogram.Component.DataOption,
+  TProperty extends WechatMiniprogram.Component.PropertyOption,
+  TMethod extends WechatMiniprogram.Component.MethodOption,
+  TWatch extends Record<string, (...args: any[]) => void>,
+  TComputed extends Record<
+    string,
+    (data: TData & { [K in keyof TProperty]: any }) => any
+  >,
+  TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {},
+> = (Partial<WechatMiniprogram.Component.Data<TData>> &
+  Partial<WechatMiniprogram.Component.Property<TProperty>> &
+  Partial<WechatMiniprogram.Component.Method<TMethod>> &
+  Partial<WechatMiniprogram.Component.OtherOption> &
+  Partial<WechatMiniprogram.Component.Lifetimes> & {
+    watch?: TWatch;
+    computed?: TComputed;
+    template?: string;
+  }) &
+  ThisType<
+    ComputedInstance<
+      TData,
+      TProperty,
+      TMethod,
+      TComputed,
+      TCustomInstanceProperty
+    >
+  >
+
+export function ComponentWithComputed<
+  TData extends WechatMiniprogram.Component.DataOption,
+  TProperty extends WechatMiniprogram.Component.PropertyOption,
+  TMethod extends WechatMiniprogram.Component.MethodOption,
+  TWatch extends Record<string, (...args: any[]) => void>,
+  TComputed extends Record<
+    string,
+    (data: TData & { [K in keyof TProperty]: any }) => any
+  >,
+  TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {},
+>(
+  options: ComputedOptions<
+    TData,
+    TProperty,
+    TMethod,
+    TWatch,
+    TComputed,
+    TCustomInstanceProperty
+  >,
+): string {
+  if (!Array.isArray(options.behaviors)) {
+    options.behaviors = []
+  }
+  options.behaviors.unshift(behavior)
+  return Component(options)
+}
+
+export function BehaviorWithComputed<
+  TData extends WechatMiniprogram.Behavior.DataOption,
+  TProperty extends WechatMiniprogram.Behavior.PropertyOption,
+  TMethod extends WechatMiniprogram.Behavior.MethodOption,
+  TWatch extends Record<string, (...args: any[]) => void>,
+  TComputed extends Record<
+    string,
+    (data: TData & { [K in keyof TProperty]: any }) => any
+  >,
+  TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {},
+>(
+  options: ComputedOptions<
+    TData,
+    TProperty,
+    TMethod,
+    TWatch,
+    TComputed,
+    TCustomInstanceProperty
+  >,
+): string {
+  if (!Array.isArray(options.behaviors)) {
+    options.behaviors = []
+  }
+  options.behaviors.unshift(behavior)
+  return Behavior(options)
+}
+
+// data tracer mode
+export enum DataTracerMode {
+  Auto,
+  Proxy,
+  DefineProperty,
+}
+
+let currentDataTracerMode = DataTracerMode.Auto
+
+export const getCurrentDataTracerMode = () => {
+  return currentDataTracerMode
+}
+
+export const setCurrentDataTracerMode = (mode: DataTracerMode) => {
+  currentDataTracerMode = mode
+}

+ 1 - 0
miniprogram/node_modules/miniprogram-computed/types/behavior.d.ts

@@ -0,0 +1 @@
+export declare const behavior: string;

+ 7 - 0
miniprogram/node_modules/miniprogram-computed/types/data-path.d.ts

@@ -0,0 +1,7 @@
+export declare const parseMultiDataPaths: (path: string) => {
+    path: string[];
+    options: {
+        deepCmp: boolean;
+    };
+}[];
+export declare const getDataOnPath: (data: unknown, path: Array<string>) => unknown;

+ 10 - 0
miniprogram/node_modules/miniprogram-computed/types/data-tracer.d.ts

@@ -0,0 +1,10 @@
+interface IWrappedData {
+    __rawObject__: unknown;
+}
+export interface IRelatedPathValue {
+    path: Array<string>;
+    value: unknown;
+}
+export declare function create(data: unknown, relatedPathValues: Array<IRelatedPathValue>): any;
+export declare function unwrap(wrapped: IWrappedData): any;
+export {};

+ 31 - 0
miniprogram/node_modules/miniprogram-computed/types/index.d.ts

@@ -0,0 +1,31 @@
+/// <reference types="wechat-miniprogram" />
+export { behavior } from './behavior';
+declare type ComputedInstance<D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, C extends Record<string, (data: D & {
+    [K in keyof P]: any;
+}) => any>, TCustomProperty extends WechatMiniprogram.IAnyObject = Record<string, never>> = WechatMiniprogram.Component.Instance<D, P, M, TCustomProperty> & {
+    data: {
+        [K in keyof C]: ReturnType<C[K]>;
+    } & {
+        [K in keyof P]: any;
+    };
+};
+declare type ComputedOptions<TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption, TWatch extends Record<string, (...args: any[]) => void>, TComputed extends Record<string, (data: TData & {
+    [K in keyof TProperty]: any;
+}) => any>, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}> = (Partial<WechatMiniprogram.Component.Data<TData>> & Partial<WechatMiniprogram.Component.Property<TProperty>> & Partial<WechatMiniprogram.Component.Method<TMethod>> & Partial<WechatMiniprogram.Component.OtherOption> & Partial<WechatMiniprogram.Component.Lifetimes> & {
+    watch?: TWatch;
+    computed?: TComputed;
+    template?: string;
+}) & ThisType<ComputedInstance<TData, TProperty, TMethod, TComputed, TCustomInstanceProperty>>;
+export declare function ComponentWithComputed<TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption, TWatch extends Record<string, (...args: any[]) => void>, TComputed extends Record<string, (data: TData & {
+    [K in keyof TProperty]: any;
+}) => any>, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}>(options: ComputedOptions<TData, TProperty, TMethod, TWatch, TComputed, TCustomInstanceProperty>): string;
+export declare function BehaviorWithComputed<TData extends WechatMiniprogram.Behavior.DataOption, TProperty extends WechatMiniprogram.Behavior.PropertyOption, TMethod extends WechatMiniprogram.Behavior.MethodOption, TWatch extends Record<string, (...args: any[]) => void>, TComputed extends Record<string, (data: TData & {
+    [K in keyof TProperty]: any;
+}) => any>, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}>(options: ComputedOptions<TData, TProperty, TMethod, TWatch, TComputed, TCustomInstanceProperty>): string;
+export declare enum DataTracerMode {
+    Auto = 0,
+    Proxy = 1,
+    DefineProperty = 2
+}
+export declare const getCurrentDataTracerMode: () => DataTracerMode;
+export declare const setCurrentDataTracerMode: (mode: DataTracerMode) => void;

+ 21 - 0
miniprogram/node_modules/rfdc/.github/workflows/ci.yml

@@ -0,0 +1,21 @@
+name: CI
+
+on: [push, pull_request]
+
+jobs:
+  test:
+    runs-on: ${{ matrix.os }}
+
+    strategy:
+      matrix:
+        os: [ubuntu-latest, windows-latest, macos-latest]
+        node-version: [8.x, 10.x, 12.x, 14.x]
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - run: npm install
+    - run: npm run ci

+ 15 - 0
miniprogram/node_modules/rfdc/LICENSE

@@ -0,0 +1,15 @@
+Copyright 2019 "David Mark Clements <david.mark.clements@gmail.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.

+ 3 - 0
miniprogram/node_modules/rfdc/default.js

@@ -0,0 +1,3 @@
+'use strict'
+
+module.exports = require('./index.js')()

+ 10 - 0
miniprogram/node_modules/rfdc/index.d.ts

@@ -0,0 +1,10 @@
+declare namespace rfdc {
+  interface Options {
+    proto?: boolean;
+    circles?: boolean;
+  }
+}
+
+declare function rfdc(options?: rfdc.Options): <T>(input: T) => T;
+
+export = rfdc;

+ 191 - 0
miniprogram/node_modules/rfdc/index.js

@@ -0,0 +1,191 @@
+'use strict'
+module.exports = rfdc
+
+function copyBuffer (cur) {
+  if (cur instanceof Buffer) {
+    return Buffer.from(cur)
+  }
+
+  return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)
+}
+
+function rfdc (opts) {
+  opts = opts || {}
+
+  if (opts.circles) return rfdcCircles(opts)
+  return opts.proto ? cloneProto : clone
+
+  function cloneArray (a, fn) {
+    var keys = Object.keys(a)
+    var a2 = new Array(keys.length)
+    for (var i = 0; i < keys.length; i++) {
+      var k = keys[i]
+      var cur = a[k]
+      if (typeof cur !== 'object' || cur === null) {
+        a2[k] = cur
+      } else if (cur instanceof Date) {
+        a2[k] = new Date(cur)
+      } else if (ArrayBuffer.isView(cur)) {
+        a2[k] = copyBuffer(cur)
+      } else {
+        a2[k] = fn(cur)
+      }
+    }
+    return a2
+  }
+
+  function clone (o) {
+    if (typeof o !== 'object' || o === null) return o
+    if (o instanceof Date) return new Date(o)
+    if (Array.isArray(o)) return cloneArray(o, clone)
+    if (o instanceof Map) return new Map(cloneArray(Array.from(o), clone))
+    if (o instanceof Set) return new Set(cloneArray(Array.from(o), clone))
+    var o2 = {}
+    for (var k in o) {
+      if (Object.hasOwnProperty.call(o, k) === false) continue
+      var cur = o[k]
+      if (typeof cur !== 'object' || cur === null) {
+        o2[k] = cur
+      } else if (cur instanceof Date) {
+        o2[k] = new Date(cur)
+      } else if (cur instanceof Map) {
+        o2[k] = new Map(cloneArray(Array.from(cur), clone))
+      } else if (cur instanceof Set) {
+        o2[k] = new Set(cloneArray(Array.from(cur), clone))
+      } else if (ArrayBuffer.isView(cur)) {
+        o2[k] = copyBuffer(cur)
+      } else {
+        o2[k] = clone(cur)
+      }
+    }
+    return o2
+  }
+
+  function cloneProto (o) {
+    if (typeof o !== 'object' || o === null) return o
+    if (o instanceof Date) return new Date(o)
+    if (Array.isArray(o)) return cloneArray(o, cloneProto)
+    if (o instanceof Map) return new Map(cloneArray(Array.from(o), cloneProto))
+    if (o instanceof Set) return new Set(cloneArray(Array.from(o), cloneProto))
+    var o2 = {}
+    for (var k in o) {
+      var cur = o[k]
+      if (typeof cur !== 'object' || cur === null) {
+        o2[k] = cur
+      } else if (cur instanceof Date) {
+        o2[k] = new Date(cur)
+      } else if (cur instanceof Map) {
+        o2[k] = new Map(cloneArray(Array.from(cur), cloneProto))
+      } else if (cur instanceof Set) {
+        o2[k] = new Set(cloneArray(Array.from(cur), cloneProto))
+      } else if (ArrayBuffer.isView(cur)) {
+        o2[k] = copyBuffer(cur)
+      } else {
+        o2[k] = cloneProto(cur)
+      }
+    }
+    return o2
+  }
+}
+
+function rfdcCircles (opts) {
+  var refs = []
+  var refsNew = []
+
+  return opts.proto ? cloneProto : clone
+
+  function cloneArray (a, fn) {
+    var keys = Object.keys(a)
+    var a2 = new Array(keys.length)
+    for (var i = 0; i < keys.length; i++) {
+      var k = keys[i]
+      var cur = a[k]
+      if (typeof cur !== 'object' || cur === null) {
+        a2[k] = cur
+      } else if (cur instanceof Date) {
+        a2[k] = new Date(cur)
+      } else if (ArrayBuffer.isView(cur)) {
+        a2[k] = copyBuffer(cur)
+      } else {
+        var index = refs.indexOf(cur)
+        if (index !== -1) {
+          a2[k] = refsNew[index]
+        } else {
+          a2[k] = fn(cur)
+        }
+      }
+    }
+    return a2
+  }
+
+  function clone (o) {
+    if (typeof o !== 'object' || o === null) return o
+    if (o instanceof Date) return new Date(o)
+    if (Array.isArray(o)) return cloneArray(o, clone)
+    if (o instanceof Map) return new Map(cloneArray(Array.from(o), clone))
+    if (o instanceof Set) return new Set(cloneArray(Array.from(o), clone))
+    var o2 = {}
+    refs.push(o)
+    refsNew.push(o2)
+    for (var k in o) {
+      if (Object.hasOwnProperty.call(o, k) === false) continue
+      var cur = o[k]
+      if (typeof cur !== 'object' || cur === null) {
+        o2[k] = cur
+      } else if (cur instanceof Date) {
+        o2[k] = new Date(cur)
+      } else if (cur instanceof Map) {
+        o2[k] = new Map(cloneArray(Array.from(cur), clone))
+      } else if (cur instanceof Set) {
+        o2[k] = new Set(cloneArray(Array.from(cur), clone))
+      } else if (ArrayBuffer.isView(cur)) {
+        o2[k] = copyBuffer(cur)
+      } else {
+        var i = refs.indexOf(cur)
+        if (i !== -1) {
+          o2[k] = refsNew[i]
+        } else {
+          o2[k] = clone(cur)
+        }
+      }
+    }
+    refs.pop()
+    refsNew.pop()
+    return o2
+  }
+
+  function cloneProto (o) {
+    if (typeof o !== 'object' || o === null) return o
+    if (o instanceof Date) return new Date(o)
+    if (Array.isArray(o)) return cloneArray(o, cloneProto)
+    if (o instanceof Map) return new Map(cloneArray(Array.from(o), cloneProto))
+    if (o instanceof Set) return new Set(cloneArray(Array.from(o), cloneProto))
+    var o2 = {}
+    refs.push(o)
+    refsNew.push(o2)
+    for (var k in o) {
+      var cur = o[k]
+      if (typeof cur !== 'object' || cur === null) {
+        o2[k] = cur
+      } else if (cur instanceof Date) {
+        o2[k] = new Date(cur)
+      } else if (cur instanceof Map) {
+        o2[k] = new Map(cloneArray(Array.from(cur), cloneProto))
+      } else if (cur instanceof Set) {
+        o2[k] = new Set(cloneArray(Array.from(cur), cloneProto))
+      } else if (ArrayBuffer.isView(cur)) {
+        o2[k] = copyBuffer(cur)
+      } else {
+        var i = refs.indexOf(cur)
+        if (i !== -1) {
+          o2[k] = refsNew[i]
+        } else {
+          o2[k] = cloneProto(cur)
+        }
+      }
+    }
+    refs.pop()
+    refsNew.pop()
+    return o2
+  }
+}

+ 7 - 0
miniprogram/node_modules/rfdc/index.test-d.ts

@@ -0,0 +1,7 @@
+import { expectType } from 'tsd';
+import rfdc = require('.');
+
+const clone = rfdc();
+
+expectType<number>(clone(5));
+expectType<{ lorem: string }>(clone({ lorem: "ipsum" }));

+ 69 - 0
miniprogram/node_modules/rfdc/package.json

@@ -0,0 +1,69 @@
+{
+  "name": "rfdc",
+  "version": "1.3.0",
+  "description": "Really Fast Deep Clone",
+  "main": "index.js",
+  "exports": {
+    ".": "./index.js",
+    "./default": "./default.js"
+  },
+  "scripts": {
+    "test": "tap -R min test && npm run lint && tsd",
+    "bench": "node benchmark",
+    "lint": "standard --fix",
+    "cov": "tap --100 test",
+    "cov-ui": "tap --coverage-report=html test",
+    "ci": "standard && tap --100 --coverage-report=text-lcov test | codecov --pipe"
+  },
+  "keywords": [
+    "object",
+    "obj",
+    "properties",
+    "clone",
+    "copy",
+    "deep",
+    "recursive",
+    "key",
+    "keys",
+    "values",
+    "prop",
+    "deep-clone",
+    "deepclone",
+    "deep-copy",
+    "deepcopy",
+    "fast",
+    "performance",
+    "performant",
+    "fastclone",
+    "fastcopy",
+    "fast-clone",
+    "fast-deep-clone",
+    "fast-copy",
+    "fast-deep-copy"
+  ],
+  "author": "David Mark Clements <david.clements@nearform.com>",
+  "license": "MIT",
+  "devDependencies": {
+    "clone-deep": "^4.0.1",
+    "codecov": "^3.4.0",
+    "deep-copy": "^1.4.2",
+    "fast-copy": "^1.2.1",
+    "fastbench": "^1.0.1",
+    "lodash.clonedeep": "^4.5.0",
+    "standard": "^11.0.1",
+    "tap": "^12.0.1",
+    "tsd": "^0.7.4"
+  },
+  "directories": {
+    "test": "test"
+  },
+  "dependencies": {},
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/davidmarkclements/rfdc.git"
+  },
+  "bugs": {
+    "url": "https://github.com/davidmarkclements/rfdc/issues"
+  },
+  "homepage": "https://github.com/davidmarkclements/rfdc#readme"
+}

+ 0 - 0
miniprogram/node_modules/rfdc/readme.md


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است