瀏覽代碼

2023.12.01
- 初始化项目

zweiqin 1 年之前
當前提交
2fab2ecc35
共有 100 個文件被更改,包括 12213 次插入0 次删除
  1. 33 0
      App.vue
  2. 201 0
      LICENSE
  3. 13 0
      README.md
  4. 4 0
      changelog.md
  5. 49 0
      common/js/request.js
  6. 57 0
      common/js/util.js
  7. 103 0
      common/util.js
  8. 172 0
      components/Sansnn-uQRCode/README.md
  9. 198 0
      components/Sansnn-uQRCode/Sansnn-uQRCode.vue
  10. 1438 0
      components/Sansnn-uQRCode/uqrcode.js
  11. 62 0
      components/uni-agreements/uni-agreements.vue
  12. 368 0
      components/uni-quick-login/uni-quick-login.vue
  13. 137 0
      components/uni-send-sms-code/uni-send-sms-code.vue
  14. 15 0
      main.js
  15. 115 0
      manifest.json
  16. 5 0
      package-lock.json
  17. 85 0
      package.json
  18. 39 0
      pages.json
  19. 103 0
      pages/agree.vue
  20. 207 0
      pages/edit.vue
  21. 603 0
      pages/index.vue
  22. 135 0
      pages/login.vue
  23. 二進制
      static/images/mpbg1.jpg
  24. 二進制
      static/images/userimg.png
  25. 二進制
      static/images/wxa.png
  26. 52 0
      store/index.js
  27. 69 0
      uni-starter.config.js
  28. 77 0
      uni.scss
  29. 198 0
      uniCloud-aliyun/cloudfunctions/common/wx-auth/index.js
  30. 12 0
      uniCloud-aliyun/cloudfunctions/common/wx-auth/package.json
  31. 49 0
      uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js
  32. 14 0
      uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json
  33. 358 0
      uniCloud-aliyun/cloudfunctions/uni-card/index.js
  34. 970 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/CHANGELOG.md
  35. 22 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/LICENSE
  36. 55 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/README.md
  37. 71 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/af.js
  38. 156 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-dz.js
  39. 54 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-kw.js
  40. 171 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-ly.js
  41. 55 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-ma.js
  42. 104 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-sa.js
  43. 54 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-tn.js
  44. 189 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar.js
  45. 101 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/az.js
  46. 141 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/be.js
  47. 87 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bg.js
  48. 52 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bm.js
  49. 128 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bn-bd.js
  50. 118 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bn.js
  51. 122 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bo.js
  52. 165 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/br.js
  53. 149 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bs.js
  54. 97 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ca.js
  55. 171 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cs.js
  56. 62 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cv.js
  57. 97 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cy.js
  58. 53 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/da.js
  59. 79 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de-at.js
  60. 78 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de-ch.js
  61. 78 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de.js
  62. 90 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/dv.js
  63. 104 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/el.js
  64. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-au.js
  65. 64 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-ca.js
  66. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-gb.js
  67. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-ie.js
  68. 64 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-il.js
  69. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-in.js
  70. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-nz.js
  71. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-sg.js
  72. 68 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/eo.js
  73. 104 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-do.js
  74. 106 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-mx.js
  75. 106 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-us.js
  76. 106 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es.js
  77. 78 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/et.js
  78. 63 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/eu.js
  79. 110 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fa.js
  80. 121 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fi.js
  81. 58 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fil.js
  82. 56 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fo.js
  83. 69 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr-ca.js
  84. 73 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr-ch.js
  85. 104 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr.js
  86. 77 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fy.js
  87. 95 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ga.js
  88. 95 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gd.js
  89. 74 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gl.js
  90. 124 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gom-deva.js
  91. 124 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gom-latn.js
  92. 121 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gu.js
  93. 94 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/he.js
  94. 164 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hi.js
  95. 154 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hr.js
  96. 118 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hu.js
  97. 92 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hy-am.js
  98. 76 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/id.js
  99. 139 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/is.js
  100. 64 0
      uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/it-ch.js

+ 33 - 0
App.vue

@@ -0,0 +1,33 @@
+<style lang="scss">
+	@import "uview-ui/index.scss";
+</style>
+<script>
+	import {
+		request
+	} from '@/common/js/request'
+	export default {
+		onLaunch: function(options) {
+			console.log('App Launch')
+			console.log('options Launch', options)
+			uni.setStorageSync('options', options);
+			if (options.query.id)
+				uni.setStorageSync('id', options.query.id);
+			const logged = uni.getStorageSync('logged');
+			if (!logged) {
+				uni.navigateTo({
+					url: "/pages/login"
+				})
+			}
+		},
+		onShow: function(options) {
+			if (options.query.id)
+				uni.setStorageSync('id', options.query.id);
+		},
+		onHide: function() {
+			console.log('App Hide')
+		},
+		methods: {
+
+		}
+	}
+</script>

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 13 - 0
README.md

@@ -0,0 +1,13 @@
+## 说明
+##### 欢迎加入CxCloud开发交流QQ群:640145
+##### 不定期共享新项目源码
+##### 对项目使用有问题或有定制需求可以联系作者
+##### WX/QQ:365015
+
+## 其他作品
+##### [1.基于云开发的小程序礼券提货系统-CxCloud](https://ext.dcloud.net.cn/plugin?id=4813 "1.基于云开发的小程序礼券提货系统-CxCloud")
+##### [2.基于云开发的礼券提货系统管理后台-CxCloud](https://ext.dcloud.net.cn/plugin?id=4817 "2.基于云开发的礼券提货系统管理后台-CxCloud")
+##### [3.基于云开发的小程序答题发红包系统-CxCloud](https://ext.dcloud.net.cn/plugin?id=5452 "3.基于云开发的小程序答题发红包系统-CxCloud")
+##### [4.基于云开发的积分榜微信小程序系统-CxCloud](https://ext.dcloud.net.cn/plugin?id=5565 "4.基于云开发的积分榜微信小程序系统-CxCloud")
+##### [5.MBTI职业性格测试-CxCloud](https://ext.dcloud.net.cn/plugin?id=6888 "5.MBTI职业性格测试-CxCloud")
+##### [6.基于云开发的通用问卷投票考试答题系统-CxCloud](https://ext.dcloud.net.cn/plugin?id=5583 "6.基于云开发的通用问卷投票考试答题系统-CxCloud")

+ 4 - 0
changelog.md

@@ -0,0 +1,4 @@
+## 1.0.1(2021-12-12)
+增加用户协议
+## 1.0.0(2021-12-10)
+第一版

+ 49 - 0
common/js/request.js

@@ -0,0 +1,49 @@
+import {
+	msg
+} from './util'
+
+/**
+ * @param {String} cloudFnName
+ * @param {String} operation  操作类型(增删改查)
+ * @param {Object} data 请求参数
+ * @param {Object} ext 附加参数
+ */
+export const request = (cloudFnName, operation, data = {}, ext = {}) => {
+	return new Promise((resolve, reject) => {
+		if (ext.showLoading !== false) {
+			uni.showLoading()
+		}
+		uniCloud.callFunction({
+			name: cloudFnName,
+			data: {
+				operation,
+				data
+			}
+		}).then(res => {
+			if (ext.showLoading !== false) {
+				uni.hideLoading()
+			}
+			if(res.result.code!=200){
+				uni.showToast({
+					icon:"none",
+				    title: res.result.msg,
+				    duration: 2000
+				});
+				reject(res.result.msg);
+			}else{
+				console.log("requestResult",res)
+				resolve(res.result.data);
+			}
+		}).catch((err) => {
+			if (ext.showLoading !== false) {
+				uni.hideLoading()
+			}
+			uni.showToast({
+				icon:"none",
+			    title: err.toString().replace("Error:",""),
+			    duration: 2000
+			});
+			reject(err);
+		})
+	})
+}

+ 57 - 0
common/js/util.js

@@ -0,0 +1,57 @@
+let _debounceTimeout = null,
+	_throttleRunning = false
+
+/**
+ * 防抖
+ * @param {Function} 执行函数
+ * @param {Number} delay 延时ms
+ */
+export const debounce = (fn, delay=500) => {
+	clearTimeout(_debounceTimeout);
+	_debounceTimeout = setTimeout(() => {
+		fn();
+	}, delay);
+}
+/**
+ * 节流
+ * @param {Function} 执行函数
+ * @param {Number} delay 延时ms
+ */
+export const throttle = (fn, delay=500) => {
+	if(_throttleRunning){
+		return;
+	}
+	_throttleRunning = true;
+	fn();
+	setTimeout(() => {
+	    _throttleRunning = false;
+	}, delay);
+}
+/**
+ * toast
+ */
+export const msg = (title = '', param={}) => {
+	if(!title) return;
+	uni.showToast({
+		title,
+		duration: param.duration || 1500,
+		mask: param.mask || false,
+		icon: param.icon || 'none'
+	});
+}
+/**
+ * 检查登录
+ * @return {Boolean}
+ */
+export const isLogin = (options={}) => {
+	const userInfo = uni.getStorageSync('userInfo');
+	if(userInfo){
+		return true;
+	}
+	if(options.nav !== false){
+		uni.navigateTo({
+			url: '/pages/login'
+		})
+	}
+	return false;
+}

+ 103 - 0
common/util.js

@@ -0,0 +1,103 @@
+function formatTime(time) {
+	if (typeof time !== 'number' || time < 0) {
+		return time
+	}
+
+	var hour = parseInt(time / 3600)
+	time = time % 3600
+	var minute = parseInt(time / 60)
+	time = time % 60
+	var second = time
+
+	return ([hour, minute, second]).map(function(n) {
+		n = n.toString()
+		return n[1] ? n : '0' + n
+	}).join(':')
+}
+
+function formatDateTime(date, fmt = 'yyyy-MM-dd hh:mm:ss') {
+	if(!date) {
+		return ''
+	}
+    if (typeof (date) === 'number') {
+        date = new Date(date * 1000)
+    }
+    var o = {
+        "M+": date.getMonth() + 1, //月份
+        "d+": date.getDate(), //日
+        "h+": date.getHours(), //小时
+        "m+": date.getMinutes(), //分
+        "s+": date.getSeconds(), //秒
+        "q+": Math.floor((date.getMonth() + 3) / 3), //季度
+        "S": date.getMilliseconds() //毫秒
+    }
+    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length))
+    for (var k in o)
+        if (new RegExp("(" + k + ")").test(fmt))
+            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
+    return fmt
+}
+
+function formatLocation(longitude, latitude) {
+	if (typeof longitude === 'string' && typeof latitude === 'string') {
+		longitude = parseFloat(longitude)
+		latitude = parseFloat(latitude)
+	}
+
+	longitude = longitude.toFixed(2)
+	latitude = latitude.toFixed(2)
+
+	return {
+		longitude: longitude.toString().split('.'),
+		latitude: latitude.toString().split('.')
+	}
+}
+
+var dateUtils = {
+	UNITS: {
+		'年': 31557600000,
+		'月': 2629800000,
+		'天': 86400000,
+		'小时': 3600000,
+		'分钟': 60000,
+		'秒': 1000
+	},
+	humanize: function(milliseconds) {
+		var humanize = '';
+		for (var key in this.UNITS) {
+			if (milliseconds >= this.UNITS[key]) {
+				humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
+				break;
+			}
+		}
+		return humanize || '刚刚';
+	},
+	format: function(dateStr) {
+		var date = this.parse(dateStr)
+		var diff = Date.now() - date.getTime();
+		if (diff < this.UNITS['天']) {
+			return this.humanize(diff);
+		}
+		var _format = function(number) {
+			return (number < 10 ? ('0' + number) : number);
+		};
+		return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
+			_format(date.getHours()) + ':' + _format(date.getMinutes());
+	},
+	parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
+		var a = str.split(/[^0-9]/);
+		return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
+	}
+};
+
+const hexToRgba = (hex, opacity) => {	//16进制颜色转rgba
+	return "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + opacity + ")"
+}
+
+module.exports = {
+	formatTime,
+	formatDateTime,
+	formatLocation,
+	dateUtils,
+	hexToRgba
+}

+ 172 - 0
components/Sansnn-uQRCode/README.md

@@ -0,0 +1,172 @@
+> 插件来源:[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)
+##### 以下是作者写的插件介绍:
+
+# uQRCode
+
+### 云函数版二维码生成插件explain-qrcode现已发布,URL化后一句代码即可生成,有网就有二维码,100%生成成功,不会因为平台差异,设备差异导致生成失败,无需在前端做适配和兼容,极力推荐。插件地址:[explain-qrcode云函数二维码生成](https://ext.dcloud.net.cn/plugin?id=3359)
+
+uQRCode 生成方式简单,可扩展性高,如有复杂需求可通过自定义组件或修改源码完成需求。已测试H5、微信小程序、iPhoneXsMax真机。
+
+本示例项目中的自定义组件旨在抛砖引玉,有其他需求的朋友可自行扩展,自定义组件参考 ``/components/uni-qrcode/uni-qrcode.vue`` ,自定义组件使用案例参考 ``/pages/component/qrcode/qrcode.vue`` 。
+
+联系方式:QQ540000228。
+
+最近一次用于更新代码的 HBuilder X 版本为 2.8.11。
+
+### 二维码
+**什么是QR码**
+
+QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。
+
+**QR码的特点**
+
+一是高速读取(QR就是取自“Quick Response”的首字母),通过摄像头从拍摄到解码到显示内容也就三秒左右,对摄像的角度也没有什么要求;
+
+二是高容量、高密度,理论上内容经过压缩处理后可以存7089个数字,4296个字母和数字混合字符,2953个8位字节数据,1817个汉字;
+
+三是支持纠错处理,按照QR码的标准文档说明,QR码的纠错分为4个级别,分别是:
+- level L : 最大 7% 的错误能够被纠正;
+- level M : 最大 15% 的错误能够被纠正;
+- level Q : 最大 25% 的错误能够被纠正;
+- level H : 最大 30% 的错误能够被纠正;
+
+四是结构化,看似无规则的图形,其实对区域有严格的定义。
+
+更多二维码介绍及原理:[https://blog.csdn.net/jason_ldh/article/details/11801355](https://blog.csdn.net/jason_ldh/article/details/11801355)
+
+### 使用方式
+
+在 ``script`` 中引用组件
+
+```javascript
+import uQRCode from '@/common/uqrcode.js'
+```
+
+在 ``template`` 中创建 ``<canvas></canvas>``
+
+```html
+<canvas canvas-id="qrcode" style="width: 354px;height: 354px;" ></canvas>
+```
+
+在 ``script`` 中调用 ``make()`` 方法
+
+```javascript
+export default {
+  methods: {
+    async make() {
+      // 回调方式
+      uQRCode.make({
+        canvasId: 'qrcode',
+        componentInstance: this,
+        text: 'uQRCode',
+        size: 354,
+        margin: 10,
+        backgroundColor: '#ffffff',
+        foregroundColor: '#000000',
+        fileType: 'jpg',
+        errorCorrectLevel: uQRCode.errorCorrectLevel.H,
+        success: res => {
+          console.log(res)
+        }
+      })
+
+      // Promise
+      uQRCode.make({
+        canvasId: 'qrcode',
+        componentInstance: this,
+        text: 'uQRCode',
+        size: 354,
+        margin: 10,
+        backgroundColor: '#ffffff',
+        foregroundColor: '#000000',
+        fileType: 'jpg',
+        errorCorrectLevel: uQRCode.errorCorrectLevel.H
+      }).then(res => {
+          console.log(res)
+      })
+
+      // 同步等待
+      var res = await uQRCode.make({
+        canvasId: 'qrcode',
+        componentInstance: this,
+        text: 'uQRCode',
+        size: 354,
+        margin: 10,
+        backgroundColor: '#ffffff',
+        foregroundColor: '#000000',
+        fileType: 'jpg',
+        errorCorrectLevel: uQRCode.errorCorrectLevel.H
+      })
+      console.log(res)
+    }
+  }
+}
+```
+
+### 属性说明
+
+|属性名|说明|
+|---|:---|
+|errorCorrectLevel|纠错等级,包含 `errorCorrectLevel.L`、`errorCorrectLevel.M`、`errorCorrectLevel.Q`、`errorCorrectLevel.H` 四个级别,`L`: 最大 7% 的错误能够被纠正;`M`: 最大 15% 的错误能够被纠正;`Q`: 最大 25% 的错误能够被纠正;`H`: 最大 30% 的错误能够被纠正。|
+|defaults|二维码生成参数的默认值。|
+
+### 方法说明
+
+|方法名|说明|
+|---|:---|
+|[make](#makeoptions)|生成二维码。|
+
+### make(options)
+
+生成二维码
+
+**options参数说明:**
+
+|参数|类型|必填|说明|
+|---|---|---|:---|
+|canvasId|String|是|画布标识,传入 `<canvas></canvas>` 的 `canvas-id`|
+|componentInstance|Object|否|自定义组件实例 `this` ,表示在这个自定义组件下查找拥有 `canvas-id` 的 `<canvas></canvas>` ,如果省略,则不在任何自定义组件内查找|
+|text|String|是|二维码内容|
+|size|Number|否|画布尺寸大小,请与 `<canvas></canvas>` 所设 `width` , `height` 保持一致(默认:`354`)|
+|margin|Number|否|边距,二维码实际尺寸会根据所设边距值进行缩放调整(默认:`0`)|
+|backgroundColor|String|否|背景色,若设置为透明背景, `fileType` 需设置为 `'png'` , 然后设置背景色为 `'rgba(255,255,255,0)'` 即可(默认:`'#ffffff'`)|
+|foregroundColor|String|否|前景色(默认:`'#000000'`)|
+|fileType|String|否|输出图片的类型,只支持 `'jpg'` 和 `'png'`(默认:`'png'`)|
+|errorCorrectLevel|Number|否|纠错等级,参考属性说明 `errorCorrectLevel`(默认:`errorCorrectLevel.H`)|
+
+### 使用建议
+canvas在二维码生成中请当做一个生成工具来看待,它的作用仅是绘制出二维码。应把生成回调得到的资源保存并使用,显示用image图片组件,原因是方便操作,例如调整大小,或是H5端长按保存或识别,所以canvas应将它放在看不见的地方。不能用`display:none;overflow:hidden;`隐藏,否则生成空白。这里推荐canvas的隐藏样式代码
+```html
+<style>
+	.canvas-hide {
+		/* 1 */
+		position: fixed;
+		right: 100vw;
+		bottom: 100vh;
+		/* 2 */
+		z-index: -9999;
+		/* 3 */
+		opacity: 0;
+	}
+</style>
+```
+
+### 常见问题
+**二维码生成不完整**
+
+canvas宽高必须和size一致,并且size的单位是px,如果canvas的单位是rpx,那么不同设备屏幕分辨率不一样,rpx转换成px后的画布尺寸不足以放下全部内容,实际绘制图案超出,就会出现不完整的情况。
+
+**如何扫码跳转指定网页**
+
+text参数直接放入完整的网页地址即可,例如:`https://ext.dcloud.net.cn/plugin?id=1287`。微信客户端不能是ip地址。
+
+**小程序、APP报错**
+
+canvas不支持放在 `slot` 插槽,请尽量放在模板根节点,也就是第一个 `<view></view>` 标签里面
+
+**H5长按识别**
+
+canvas无法长按识别,长按识别需要是图片才行,所以只需将回调过来的资源用image组件显示即可。
+
+### Tips
+- 示例项目中的图片采集于互联网,仅作为案例展示,不作为广告/商业,如有侵权,请告知删除。下载使用的用户,请勿把示例项目中的图片应用到你的项目。

+ 198 - 0
components/Sansnn-uQRCode/Sansnn-uQRCode.vue

@@ -0,0 +1,198 @@
+<template>
+	<view>
+		<canvas :id="cid" :canvas-id="cid" :style="{width: `${size}px`, height: `${size}px`}" />
+	</view>
+</template>
+
+<script>
+	import uQRCode from './uqrcode.js'
+
+	export default {
+		props: {
+			cid: {
+				type: String,
+				default(){
+					return Date.now()+Math.random()+'';
+				}
+			},
+			text: {
+				type: String,
+				required: true
+			},
+			size: {
+				type: Number,
+				default: uni.upx2px(200)
+			},
+			margin: {
+				type: Number,
+				default: 0
+			},
+			backgroundColor: {
+				type: String,
+				default: '#ffffff'
+			},
+			foregroundColor: {
+				type: String,
+				default: '#000000'
+			},
+			backgroundImage: {
+				type: String
+			},
+			logo: {
+				type: String
+			},
+			makeOnLoad: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+
+			}
+		},
+		mounted() {
+			if (this.makeOnLoad) {
+				this.make()
+			}
+		},
+		methods: {
+			async make() {
+				var options = {
+					canvasId: this.cid,
+					componentInstance: this,
+					text: this.text,
+					size: this.size,
+					margin: this.margin,
+					backgroundColor: this.backgroundImage ? 'rgba(255,255,255,0)' : this.backgroundColor,
+					foregroundColor: this.foregroundColor
+				}
+				var filePath = await this.makeSync(options)
+
+				if (this.backgroundImage) {
+					filePath = await this.drawBackgroundImageSync(filePath)
+				}
+
+				if (this.logo) {
+					filePath = await this.drawLogoSync(filePath)
+				}
+
+				this.makeComplete(filePath)
+			},
+			makeComplete(filePath) {
+				this.$emit('makeComplete', filePath)
+			},
+			drawBackgroundImage(options) {
+				var ctx = uni.createCanvasContext(this.cid, this)
+
+				ctx.drawImage(this.backgroundImage, 0, 0, this.size, this.size)
+
+				ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
+
+				ctx.draw(false, () => {
+					uni.canvasToTempFilePath({
+						canvasId: this.cid,
+						success: res => {
+							options.success && options.success(res.tempFilePath)
+						},
+						fail: error => {
+							options.fail && options.fail(error)
+						}
+					}, this)
+				})
+			},
+			async drawBackgroundImageSync(filePath) {
+				return new Promise((resolve, reject) => {
+					this.drawBackgroundImage({
+						filePath: filePath,
+						success: res => {
+							resolve(res)
+						},
+						fail: error => {
+							reject(error)
+						}
+					})
+				})
+			},
+			fillRoundRect(ctx, r, x, y, w, h) {
+				ctx.save()
+				ctx.translate(x, y)
+				ctx.beginPath()
+				ctx.arc(w - r, h - r, r, 0, Math.PI / 2)
+				ctx.lineTo(r, h)
+				ctx.arc(r, h - r, r, Math.PI / 2, Math.PI)
+				ctx.lineTo(0, r)
+				ctx.arc(r, r, r, Math.PI, Math.PI * 3 / 2)
+				ctx.lineTo(w - r, 0)
+				ctx.arc(w - r, r, r, Math.PI * 3 / 2, Math.PI * 2)
+				ctx.lineTo(w, h - r)
+				ctx.closePath()
+				ctx.setFillStyle('#ffffff')
+				ctx.fill()
+				ctx.restore()
+			},
+			drawLogo(options) {
+				var ctx = uni.createCanvasContext(this.cid, this)
+
+				ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
+
+				var logoSize = this.size / 4
+				var logoX = this.size / 2 - logoSize / 2
+				var logoY = logoX
+
+				var borderSize = logoSize + 10
+				var borderX = this.size / 2 - borderSize / 2
+				var borderY = borderX
+				var borderRadius = 5
+
+				this.fillRoundRect(ctx, borderRadius, borderX, borderY, borderSize, borderSize)
+
+				ctx.drawImage(this.logo, logoX, logoY, logoSize, logoSize)
+				
+				ctx.draw(false, () => {
+					uni.canvasToTempFilePath({
+						canvasId: this.cid,
+						success: res => {
+							options.success && options.success(res.tempFilePath)
+						},
+						fail: error => {
+							options.fail && options.fail(error)
+						}
+					}, this)
+				})
+			},
+			async drawLogoSync(filePath) {
+				return new Promise((resolve, reject) => {
+					this.drawLogo({
+						filePath: filePath,
+						success: res => {
+							resolve(res)
+						},
+						fail: error => {
+							reject(error)
+						}
+					})
+				})
+			},
+			async makeSync(options) {
+				return new Promise((resolve, reject) => {
+					uQRCode.make({
+						canvasId: options.canvasId,
+						componentInstance: options.componentInstance,
+						text: options.text,
+						size: options.size,
+						margin: options.margin,
+						backgroundColor: options.backgroundColor,
+						foregroundColor: options.foregroundColor,
+						success: res => {
+							resolve(res)
+						},
+						fail: error => {
+							reject(error)
+						}
+					})
+				})
+			}
+		}
+	}
+</script>

+ 1438 - 0
components/Sansnn-uQRCode/uqrcode.js

@@ -0,0 +1,1438 @@
+//---------------------------------------------------------------------
+// github https://github.com/Sansnn/uQRCode
+//---------------------------------------------------------------------
+
+let uQRCode = {};
+
+(function() {
+	//---------------------------------------------------------------------
+	// QRCode for JavaScript
+	//
+	// Copyright (c) 2009 Kazuhiko Arase
+	//
+	// URL: http://www.d-project.com/
+	//
+	// Licensed under the MIT license:
+	//   http://www.opensource.org/licenses/mit-license.php
+	//
+	// The word "QR Code" is registered trademark of 
+	// DENSO WAVE INCORPORATED
+	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
+	//
+	//---------------------------------------------------------------------
+
+	//---------------------------------------------------------------------
+	// QR8bitByte
+	//---------------------------------------------------------------------
+
+	function QR8bitByte(data) {
+		this.mode = QRMode.MODE_8BIT_BYTE;
+		this.data = data;
+	}
+
+	QR8bitByte.prototype = {
+
+		getLength: function(buffer) {
+			return this.data.length;
+		},
+
+		write: function(buffer) {
+			for (var i = 0; i < this.data.length; i++) {
+				// not JIS ...
+				buffer.put(this.data.charCodeAt(i), 8);
+			}
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// QRCode
+	//---------------------------------------------------------------------
+
+	function QRCode(typeNumber, errorCorrectLevel) {
+		this.typeNumber = typeNumber;
+		this.errorCorrectLevel = errorCorrectLevel;
+		this.modules = null;
+		this.moduleCount = 0;
+		this.dataCache = null;
+		this.dataList = new Array();
+	}
+
+	QRCode.prototype = {
+
+		addData: function(data) {
+			var newData = new QR8bitByte(data);
+			this.dataList.push(newData);
+			this.dataCache = null;
+		},
+
+		isDark: function(row, col) {
+			if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
+				throw new Error(row + "," + col);
+			}
+			return this.modules[row][col];
+		},
+
+		getModuleCount: function() {
+			return this.moduleCount;
+		},
+
+		make: function() {
+			// Calculate automatically typeNumber if provided is < 1
+			if (this.typeNumber < 1) {
+				var typeNumber = 1;
+				for (typeNumber = 1; typeNumber < 40; typeNumber++) {
+					var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
+
+					var buffer = new QRBitBuffer();
+					var totalDataCount = 0;
+					for (var i = 0; i < rsBlocks.length; i++) {
+						totalDataCount += rsBlocks[i].dataCount;
+					}
+
+					for (var i = 0; i < this.dataList.length; i++) {
+						var data = this.dataList[i];
+						buffer.put(data.mode, 4);
+						buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+						data.write(buffer);
+					}
+					if (buffer.getLengthInBits() <= totalDataCount * 8)
+						break;
+				}
+				this.typeNumber = typeNumber;
+			}
+			this.makeImpl(false, this.getBestMaskPattern());
+		},
+
+		makeImpl: function(test, maskPattern) {
+
+			this.moduleCount = this.typeNumber * 4 + 17;
+			this.modules = new Array(this.moduleCount);
+
+			for (var row = 0; row < this.moduleCount; row++) {
+
+				this.modules[row] = new Array(this.moduleCount);
+
+				for (var col = 0; col < this.moduleCount; col++) {
+					this.modules[row][col] = null; //(col + row) % 3;
+				}
+			}
+
+			this.setupPositionProbePattern(0, 0);
+			this.setupPositionProbePattern(this.moduleCount - 7, 0);
+			this.setupPositionProbePattern(0, this.moduleCount - 7);
+			this.setupPositionAdjustPattern();
+			this.setupTimingPattern();
+			this.setupTypeInfo(test, maskPattern);
+
+			if (this.typeNumber >= 7) {
+				this.setupTypeNumber(test);
+			}
+
+			if (this.dataCache == null) {
+				this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
+			}
+
+			this.mapData(this.dataCache, maskPattern);
+		},
+
+		setupPositionProbePattern: function(row, col) {
+
+			for (var r = -1; r <= 7; r++) {
+
+				if (row + r <= -1 || this.moduleCount <= row + r) continue;
+
+				for (var c = -1; c <= 7; c++) {
+
+					if (col + c <= -1 || this.moduleCount <= col + c) continue;
+
+					if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
+						(0 <= c && c <= 6 && (r == 0 || r == 6)) ||
+						(2 <= r && r <= 4 && 2 <= c && c <= 4)) {
+						this.modules[row + r][col + c] = true;
+					} else {
+						this.modules[row + r][col + c] = false;
+					}
+				}
+			}
+		},
+
+		getBestMaskPattern: function() {
+
+			var minLostPoint = 0;
+			var pattern = 0;
+
+			for (var i = 0; i < 8; i++) {
+
+				this.makeImpl(true, i);
+
+				var lostPoint = QRUtil.getLostPoint(this);
+
+				if (i == 0 || minLostPoint > lostPoint) {
+					minLostPoint = lostPoint;
+					pattern = i;
+				}
+			}
+
+			return pattern;
+		},
+
+		createMovieClip: function(target_mc, instance_name, depth) {
+
+			var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
+			var cs = 1;
+
+			this.make();
+
+			for (var row = 0; row < this.modules.length; row++) {
+
+				var y = row * cs;
+
+				for (var col = 0; col < this.modules[row].length; col++) {
+
+					var x = col * cs;
+					var dark = this.modules[row][col];
+
+					if (dark) {
+						qr_mc.beginFill(0, 100);
+						qr_mc.moveTo(x, y);
+						qr_mc.lineTo(x + cs, y);
+						qr_mc.lineTo(x + cs, y + cs);
+						qr_mc.lineTo(x, y + cs);
+						qr_mc.endFill();
+					}
+				}
+			}
+
+			return qr_mc;
+		},
+
+		setupTimingPattern: function() {
+
+			for (var r = 8; r < this.moduleCount - 8; r++) {
+				if (this.modules[r][6] != null) {
+					continue;
+				}
+				this.modules[r][6] = (r % 2 == 0);
+			}
+
+			for (var c = 8; c < this.moduleCount - 8; c++) {
+				if (this.modules[6][c] != null) {
+					continue;
+				}
+				this.modules[6][c] = (c % 2 == 0);
+			}
+		},
+
+		setupPositionAdjustPattern: function() {
+
+			var pos = QRUtil.getPatternPosition(this.typeNumber);
+
+			for (var i = 0; i < pos.length; i++) {
+
+				for (var j = 0; j < pos.length; j++) {
+
+					var row = pos[i];
+					var col = pos[j];
+
+					if (this.modules[row][col] != null) {
+						continue;
+					}
+
+					for (var r = -2; r <= 2; r++) {
+
+						for (var c = -2; c <= 2; c++) {
+
+							if (r == -2 || r == 2 || c == -2 || c == 2 ||
+								(r == 0 && c == 0)) {
+								this.modules[row + r][col + c] = true;
+							} else {
+								this.modules[row + r][col + c] = false;
+							}
+						}
+					}
+				}
+			}
+		},
+
+		setupTypeNumber: function(test) {
+
+			var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+
+			for (var i = 0; i < 18; i++) {
+				var mod = (!test && ((bits >> i) & 1) == 1);
+				this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
+			}
+
+			for (var i = 0; i < 18; i++) {
+				var mod = (!test && ((bits >> i) & 1) == 1);
+				this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+			}
+		},
+
+		setupTypeInfo: function(test, maskPattern) {
+
+			var data = (this.errorCorrectLevel << 3) | maskPattern;
+			var bits = QRUtil.getBCHTypeInfo(data);
+
+			// vertical		
+			for (var i = 0; i < 15; i++) {
+
+				var mod = (!test && ((bits >> i) & 1) == 1);
+
+				if (i < 6) {
+					this.modules[i][8] = mod;
+				} else if (i < 8) {
+					this.modules[i + 1][8] = mod;
+				} else {
+					this.modules[this.moduleCount - 15 + i][8] = mod;
+				}
+			}
+
+			// horizontal
+			for (var i = 0; i < 15; i++) {
+
+				var mod = (!test && ((bits >> i) & 1) == 1);
+
+				if (i < 8) {
+					this.modules[8][this.moduleCount - i - 1] = mod;
+				} else if (i < 9) {
+					this.modules[8][15 - i - 1 + 1] = mod;
+				} else {
+					this.modules[8][15 - i - 1] = mod;
+				}
+			}
+
+			// fixed module
+			this.modules[this.moduleCount - 8][8] = (!test);
+
+		},
+
+		mapData: function(data, maskPattern) {
+
+			var inc = -1;
+			var row = this.moduleCount - 1;
+			var bitIndex = 7;
+			var byteIndex = 0;
+
+			for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+
+				if (col == 6) col--;
+
+				while (true) {
+
+					for (var c = 0; c < 2; c++) {
+
+						if (this.modules[row][col - c] == null) {
+
+							var dark = false;
+
+							if (byteIndex < data.length) {
+								dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
+							}
+
+							var mask = QRUtil.getMask(maskPattern, row, col - c);
+
+							if (mask) {
+								dark = !dark;
+							}
+
+							this.modules[row][col - c] = dark;
+							bitIndex--;
+
+							if (bitIndex == -1) {
+								byteIndex++;
+								bitIndex = 7;
+							}
+						}
+					}
+
+					row += inc;
+
+					if (row < 0 || this.moduleCount <= row) {
+						row -= inc;
+						inc = -inc;
+						break;
+					}
+				}
+			}
+
+		}
+
+	};
+
+	QRCode.PAD0 = 0xEC;
+	QRCode.PAD1 = 0x11;
+
+	QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
+
+		var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
+
+		var buffer = new QRBitBuffer();
+
+		for (var i = 0; i < dataList.length; i++) {
+			var data = dataList[i];
+			buffer.put(data.mode, 4);
+			buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+			data.write(buffer);
+		}
+
+		// calc num max data.
+		var totalDataCount = 0;
+		for (var i = 0; i < rsBlocks.length; i++) {
+			totalDataCount += rsBlocks[i].dataCount;
+		}
+
+		if (buffer.getLengthInBits() > totalDataCount * 8) {
+			throw new Error("code length overflow. (" +
+				buffer.getLengthInBits() +
+				">" +
+				totalDataCount * 8 +
+				")");
+		}
+
+		// end code
+		if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
+			buffer.put(0, 4);
+		}
+
+		// padding
+		while (buffer.getLengthInBits() % 8 != 0) {
+			buffer.putBit(false);
+		}
+
+		// padding
+		while (true) {
+
+			if (buffer.getLengthInBits() >= totalDataCount * 8) {
+				break;
+			}
+			buffer.put(QRCode.PAD0, 8);
+
+			if (buffer.getLengthInBits() >= totalDataCount * 8) {
+				break;
+			}
+			buffer.put(QRCode.PAD1, 8);
+		}
+
+		return QRCode.createBytes(buffer, rsBlocks);
+	}
+
+	QRCode.createBytes = function(buffer, rsBlocks) {
+
+		var offset = 0;
+
+		var maxDcCount = 0;
+		var maxEcCount = 0;
+
+		var dcdata = new Array(rsBlocks.length);
+		var ecdata = new Array(rsBlocks.length);
+
+		for (var r = 0; r < rsBlocks.length; r++) {
+
+			var dcCount = rsBlocks[r].dataCount;
+			var ecCount = rsBlocks[r].totalCount - dcCount;
+
+			maxDcCount = Math.max(maxDcCount, dcCount);
+			maxEcCount = Math.max(maxEcCount, ecCount);
+
+			dcdata[r] = new Array(dcCount);
+
+			for (var i = 0; i < dcdata[r].length; i++) {
+				dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+			}
+			offset += dcCount;
+
+			var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+			var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+
+			var modPoly = rawPoly.mod(rsPoly);
+			ecdata[r] = new Array(rsPoly.getLength() - 1);
+			for (var i = 0; i < ecdata[r].length; i++) {
+				var modIndex = i + modPoly.getLength() - ecdata[r].length;
+				ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
+			}
+
+		}
+
+		var totalCodeCount = 0;
+		for (var i = 0; i < rsBlocks.length; i++) {
+			totalCodeCount += rsBlocks[i].totalCount;
+		}
+
+		var data = new Array(totalCodeCount);
+		var index = 0;
+
+		for (var i = 0; i < maxDcCount; i++) {
+			for (var r = 0; r < rsBlocks.length; r++) {
+				if (i < dcdata[r].length) {
+					data[index++] = dcdata[r][i];
+				}
+			}
+		}
+
+		for (var i = 0; i < maxEcCount; i++) {
+			for (var r = 0; r < rsBlocks.length; r++) {
+				if (i < ecdata[r].length) {
+					data[index++] = ecdata[r][i];
+				}
+			}
+		}
+
+		return data;
+
+	}
+
+	//---------------------------------------------------------------------
+	// QRMode
+	//---------------------------------------------------------------------
+
+	var QRMode = {
+		MODE_NUMBER: 1 << 0,
+		MODE_ALPHA_NUM: 1 << 1,
+		MODE_8BIT_BYTE: 1 << 2,
+		MODE_KANJI: 1 << 3
+	};
+
+	//---------------------------------------------------------------------
+	// QRErrorCorrectLevel
+	//---------------------------------------------------------------------
+
+	var QRErrorCorrectLevel = {
+		L: 1,
+		M: 0,
+		Q: 3,
+		H: 2
+	};
+
+	//---------------------------------------------------------------------
+	// QRMaskPattern
+	//---------------------------------------------------------------------
+
+	var QRMaskPattern = {
+		PATTERN000: 0,
+		PATTERN001: 1,
+		PATTERN010: 2,
+		PATTERN011: 3,
+		PATTERN100: 4,
+		PATTERN101: 5,
+		PATTERN110: 6,
+		PATTERN111: 7
+	};
+
+	//---------------------------------------------------------------------
+	// QRUtil
+	//---------------------------------------------------------------------
+
+	var QRUtil = {
+
+		PATTERN_POSITION_TABLE: [
+			[],
+			[6, 18],
+			[6, 22],
+			[6, 26],
+			[6, 30],
+			[6, 34],
+			[6, 22, 38],
+			[6, 24, 42],
+			[6, 26, 46],
+			[6, 28, 50],
+			[6, 30, 54],
+			[6, 32, 58],
+			[6, 34, 62],
+			[6, 26, 46, 66],
+			[6, 26, 48, 70],
+			[6, 26, 50, 74],
+			[6, 30, 54, 78],
+			[6, 30, 56, 82],
+			[6, 30, 58, 86],
+			[6, 34, 62, 90],
+			[6, 28, 50, 72, 94],
+			[6, 26, 50, 74, 98],
+			[6, 30, 54, 78, 102],
+			[6, 28, 54, 80, 106],
+			[6, 32, 58, 84, 110],
+			[6, 30, 58, 86, 114],
+			[6, 34, 62, 90, 118],
+			[6, 26, 50, 74, 98, 122],
+			[6, 30, 54, 78, 102, 126],
+			[6, 26, 52, 78, 104, 130],
+			[6, 30, 56, 82, 108, 134],
+			[6, 34, 60, 86, 112, 138],
+			[6, 30, 58, 86, 114, 142],
+			[6, 34, 62, 90, 118, 146],
+			[6, 30, 54, 78, 102, 126, 150],
+			[6, 24, 50, 76, 102, 128, 154],
+			[6, 28, 54, 80, 106, 132, 158],
+			[6, 32, 58, 84, 110, 136, 162],
+			[6, 26, 54, 82, 110, 138, 166],
+			[6, 30, 58, 86, 114, 142, 170]
+		],
+
+		G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+		G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+		G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+
+		getBCHTypeInfo: function(data) {
+			var d = data << 10;
+			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+				d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
+			}
+			return ((data << 10) | d) ^ QRUtil.G15_MASK;
+		},
+
+		getBCHTypeNumber: function(data) {
+			var d = data << 12;
+			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+				d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
+			}
+			return (data << 12) | d;
+		},
+
+		getBCHDigit: function(data) {
+
+			var digit = 0;
+
+			while (data != 0) {
+				digit++;
+				data >>>= 1;
+			}
+
+			return digit;
+		},
+
+		getPatternPosition: function(typeNumber) {
+			return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
+		},
+
+		getMask: function(maskPattern, i, j) {
+
+			switch (maskPattern) {
+
+				case QRMaskPattern.PATTERN000:
+					return (i + j) % 2 == 0;
+				case QRMaskPattern.PATTERN001:
+					return i % 2 == 0;
+				case QRMaskPattern.PATTERN010:
+					return j % 3 == 0;
+				case QRMaskPattern.PATTERN011:
+					return (i + j) % 3 == 0;
+				case QRMaskPattern.PATTERN100:
+					return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
+				case QRMaskPattern.PATTERN101:
+					return (i * j) % 2 + (i * j) % 3 == 0;
+				case QRMaskPattern.PATTERN110:
+					return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
+				case QRMaskPattern.PATTERN111:
+					return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
+
+				default:
+					throw new Error("bad maskPattern:" + maskPattern);
+			}
+		},
+
+		getErrorCorrectPolynomial: function(errorCorrectLength) {
+
+			var a = new QRPolynomial([1], 0);
+
+			for (var i = 0; i < errorCorrectLength; i++) {
+				a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+			}
+
+			return a;
+		},
+
+		getLengthInBits: function(mode, type) {
+
+			if (1 <= type && type < 10) {
+
+				// 1 - 9
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 10;
+					case QRMode.MODE_ALPHA_NUM:
+						return 9;
+					case QRMode.MODE_8BIT_BYTE:
+						return 8;
+					case QRMode.MODE_KANJI:
+						return 8;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else if (type < 27) {
+
+				// 10 - 26
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 12;
+					case QRMode.MODE_ALPHA_NUM:
+						return 11;
+					case QRMode.MODE_8BIT_BYTE:
+						return 16;
+					case QRMode.MODE_KANJI:
+						return 10;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else if (type < 41) {
+
+				// 27 - 40
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 14;
+					case QRMode.MODE_ALPHA_NUM:
+						return 13;
+					case QRMode.MODE_8BIT_BYTE:
+						return 16;
+					case QRMode.MODE_KANJI:
+						return 12;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else {
+				throw new Error("type:" + type);
+			}
+		},
+
+		getLostPoint: function(qrCode) {
+
+			var moduleCount = qrCode.getModuleCount();
+
+			var lostPoint = 0;
+
+			// LEVEL1
+
+			for (var row = 0; row < moduleCount; row++) {
+
+				for (var col = 0; col < moduleCount; col++) {
+
+					var sameCount = 0;
+					var dark = qrCode.isDark(row, col);
+
+					for (var r = -1; r <= 1; r++) {
+
+						if (row + r < 0 || moduleCount <= row + r) {
+							continue;
+						}
+
+						for (var c = -1; c <= 1; c++) {
+
+							if (col + c < 0 || moduleCount <= col + c) {
+								continue;
+							}
+
+							if (r == 0 && c == 0) {
+								continue;
+							}
+
+							if (dark == qrCode.isDark(row + r, col + c)) {
+								sameCount++;
+							}
+						}
+					}
+
+					if (sameCount > 5) {
+						lostPoint += (3 + sameCount - 5);
+					}
+				}
+			}
+
+			// LEVEL2
+
+			for (var row = 0; row < moduleCount - 1; row++) {
+				for (var col = 0; col < moduleCount - 1; col++) {
+					var count = 0;
+					if (qrCode.isDark(row, col)) count++;
+					if (qrCode.isDark(row + 1, col)) count++;
+					if (qrCode.isDark(row, col + 1)) count++;
+					if (qrCode.isDark(row + 1, col + 1)) count++;
+					if (count == 0 || count == 4) {
+						lostPoint += 3;
+					}
+				}
+			}
+
+			// LEVEL3
+
+			for (var row = 0; row < moduleCount; row++) {
+				for (var col = 0; col < moduleCount - 6; col++) {
+					if (qrCode.isDark(row, col) &&
+						!qrCode.isDark(row, col + 1) &&
+						qrCode.isDark(row, col + 2) &&
+						qrCode.isDark(row, col + 3) &&
+						qrCode.isDark(row, col + 4) &&
+						!qrCode.isDark(row, col + 5) &&
+						qrCode.isDark(row, col + 6)) {
+						lostPoint += 40;
+					}
+				}
+			}
+
+			for (var col = 0; col < moduleCount; col++) {
+				for (var row = 0; row < moduleCount - 6; row++) {
+					if (qrCode.isDark(row, col) &&
+						!qrCode.isDark(row + 1, col) &&
+						qrCode.isDark(row + 2, col) &&
+						qrCode.isDark(row + 3, col) &&
+						qrCode.isDark(row + 4, col) &&
+						!qrCode.isDark(row + 5, col) &&
+						qrCode.isDark(row + 6, col)) {
+						lostPoint += 40;
+					}
+				}
+			}
+
+			// LEVEL4
+
+			var darkCount = 0;
+
+			for (var col = 0; col < moduleCount; col++) {
+				for (var row = 0; row < moduleCount; row++) {
+					if (qrCode.isDark(row, col)) {
+						darkCount++;
+					}
+				}
+			}
+
+			var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
+			lostPoint += ratio * 10;
+
+			return lostPoint;
+		}
+
+	};
+
+
+	//---------------------------------------------------------------------
+	// QRMath
+	//---------------------------------------------------------------------
+
+	var QRMath = {
+
+		glog: function(n) {
+
+			if (n < 1) {
+				throw new Error("glog(" + n + ")");
+			}
+
+			return QRMath.LOG_TABLE[n];
+		},
+
+		gexp: function(n) {
+
+			while (n < 0) {
+				n += 255;
+			}
+
+			while (n >= 256) {
+				n -= 255;
+			}
+
+			return QRMath.EXP_TABLE[n];
+		},
+
+		EXP_TABLE: new Array(256),
+
+		LOG_TABLE: new Array(256)
+
+	};
+
+	for (var i = 0; i < 8; i++) {
+		QRMath.EXP_TABLE[i] = 1 << i;
+	}
+	for (var i = 8; i < 256; i++) {
+		QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
+			QRMath.EXP_TABLE[i - 5] ^
+			QRMath.EXP_TABLE[i - 6] ^
+			QRMath.EXP_TABLE[i - 8];
+	}
+	for (var i = 0; i < 255; i++) {
+		QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+	}
+
+	//---------------------------------------------------------------------
+	// QRPolynomial
+	//---------------------------------------------------------------------
+
+	function QRPolynomial(num, shift) {
+
+		if (num.length == undefined) {
+			throw new Error(num.length + "/" + shift);
+		}
+
+		var offset = 0;
+
+		while (offset < num.length && num[offset] == 0) {
+			offset++;
+		}
+
+		this.num = new Array(num.length - offset + shift);
+		for (var i = 0; i < num.length - offset; i++) {
+			this.num[i] = num[i + offset];
+		}
+	}
+
+	QRPolynomial.prototype = {
+
+		get: function(index) {
+			return this.num[index];
+		},
+
+		getLength: function() {
+			return this.num.length;
+		},
+
+		multiply: function(e) {
+
+			var num = new Array(this.getLength() + e.getLength() - 1);
+
+			for (var i = 0; i < this.getLength(); i++) {
+				for (var j = 0; j < e.getLength(); j++) {
+					num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+				}
+			}
+
+			return new QRPolynomial(num, 0);
+		},
+
+		mod: function(e) {
+
+			if (this.getLength() - e.getLength() < 0) {
+				return this;
+			}
+
+			var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
+
+			var num = new Array(this.getLength());
+
+			for (var i = 0; i < this.getLength(); i++) {
+				num[i] = this.get(i);
+			}
+
+			for (var i = 0; i < e.getLength(); i++) {
+				num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+			}
+
+			// recursive call
+			return new QRPolynomial(num, 0).mod(e);
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// QRRSBlock
+	//---------------------------------------------------------------------
+
+	function QRRSBlock(totalCount, dataCount) {
+		this.totalCount = totalCount;
+		this.dataCount = dataCount;
+	}
+
+	QRRSBlock.RS_BLOCK_TABLE = [
+
+		// L
+		// M
+		// Q
+		// H
+
+		// 1
+		[1, 26, 19],
+		[1, 26, 16],
+		[1, 26, 13],
+		[1, 26, 9],
+
+		// 2
+		[1, 44, 34],
+		[1, 44, 28],
+		[1, 44, 22],
+		[1, 44, 16],
+
+		// 3
+		[1, 70, 55],
+		[1, 70, 44],
+		[2, 35, 17],
+		[2, 35, 13],
+
+		// 4		
+		[1, 100, 80],
+		[2, 50, 32],
+		[2, 50, 24],
+		[4, 25, 9],
+
+		// 5
+		[1, 134, 108],
+		[2, 67, 43],
+		[2, 33, 15, 2, 34, 16],
+		[2, 33, 11, 2, 34, 12],
+
+		// 6
+		[2, 86, 68],
+		[4, 43, 27],
+		[4, 43, 19],
+		[4, 43, 15],
+
+		// 7		
+		[2, 98, 78],
+		[4, 49, 31],
+		[2, 32, 14, 4, 33, 15],
+		[4, 39, 13, 1, 40, 14],
+
+		// 8
+		[2, 121, 97],
+		[2, 60, 38, 2, 61, 39],
+		[4, 40, 18, 2, 41, 19],
+		[4, 40, 14, 2, 41, 15],
+
+		// 9
+		[2, 146, 116],
+		[3, 58, 36, 2, 59, 37],
+		[4, 36, 16, 4, 37, 17],
+		[4, 36, 12, 4, 37, 13],
+
+		// 10		
+		[2, 86, 68, 2, 87, 69],
+		[4, 69, 43, 1, 70, 44],
+		[6, 43, 19, 2, 44, 20],
+		[6, 43, 15, 2, 44, 16],
+
+		// 11
+		[4, 101, 81],
+		[1, 80, 50, 4, 81, 51],
+		[4, 50, 22, 4, 51, 23],
+		[3, 36, 12, 8, 37, 13],
+
+		// 12
+		[2, 116, 92, 2, 117, 93],
+		[6, 58, 36, 2, 59, 37],
+		[4, 46, 20, 6, 47, 21],
+		[7, 42, 14, 4, 43, 15],
+
+		// 13
+		[4, 133, 107],
+		[8, 59, 37, 1, 60, 38],
+		[8, 44, 20, 4, 45, 21],
+		[12, 33, 11, 4, 34, 12],
+
+		// 14
+		[3, 145, 115, 1, 146, 116],
+		[4, 64, 40, 5, 65, 41],
+		[11, 36, 16, 5, 37, 17],
+		[11, 36, 12, 5, 37, 13],
+
+		// 15
+		[5, 109, 87, 1, 110, 88],
+		[5, 65, 41, 5, 66, 42],
+		[5, 54, 24, 7, 55, 25],
+		[11, 36, 12],
+
+		// 16
+		[5, 122, 98, 1, 123, 99],
+		[7, 73, 45, 3, 74, 46],
+		[15, 43, 19, 2, 44, 20],
+		[3, 45, 15, 13, 46, 16],
+
+		// 17
+		[1, 135, 107, 5, 136, 108],
+		[10, 74, 46, 1, 75, 47],
+		[1, 50, 22, 15, 51, 23],
+		[2, 42, 14, 17, 43, 15],
+
+		// 18
+		[5, 150, 120, 1, 151, 121],
+		[9, 69, 43, 4, 70, 44],
+		[17, 50, 22, 1, 51, 23],
+		[2, 42, 14, 19, 43, 15],
+
+		// 19
+		[3, 141, 113, 4, 142, 114],
+		[3, 70, 44, 11, 71, 45],
+		[17, 47, 21, 4, 48, 22],
+		[9, 39, 13, 16, 40, 14],
+
+		// 20
+		[3, 135, 107, 5, 136, 108],
+		[3, 67, 41, 13, 68, 42],
+		[15, 54, 24, 5, 55, 25],
+		[15, 43, 15, 10, 44, 16],
+
+		// 21
+		[4, 144, 116, 4, 145, 117],
+		[17, 68, 42],
+		[17, 50, 22, 6, 51, 23],
+		[19, 46, 16, 6, 47, 17],
+
+		// 22
+		[2, 139, 111, 7, 140, 112],
+		[17, 74, 46],
+		[7, 54, 24, 16, 55, 25],
+		[34, 37, 13],
+
+		// 23
+		[4, 151, 121, 5, 152, 122],
+		[4, 75, 47, 14, 76, 48],
+		[11, 54, 24, 14, 55, 25],
+		[16, 45, 15, 14, 46, 16],
+
+		// 24
+		[6, 147, 117, 4, 148, 118],
+		[6, 73, 45, 14, 74, 46],
+		[11, 54, 24, 16, 55, 25],
+		[30, 46, 16, 2, 47, 17],
+
+		// 25
+		[8, 132, 106, 4, 133, 107],
+		[8, 75, 47, 13, 76, 48],
+		[7, 54, 24, 22, 55, 25],
+		[22, 45, 15, 13, 46, 16],
+
+		// 26
+		[10, 142, 114, 2, 143, 115],
+		[19, 74, 46, 4, 75, 47],
+		[28, 50, 22, 6, 51, 23],
+		[33, 46, 16, 4, 47, 17],
+
+		// 27
+		[8, 152, 122, 4, 153, 123],
+		[22, 73, 45, 3, 74, 46],
+		[8, 53, 23, 26, 54, 24],
+		[12, 45, 15, 28, 46, 16],
+
+		// 28
+		[3, 147, 117, 10, 148, 118],
+		[3, 73, 45, 23, 74, 46],
+		[4, 54, 24, 31, 55, 25],
+		[11, 45, 15, 31, 46, 16],
+
+		// 29
+		[7, 146, 116, 7, 147, 117],
+		[21, 73, 45, 7, 74, 46],
+		[1, 53, 23, 37, 54, 24],
+		[19, 45, 15, 26, 46, 16],
+
+		// 30
+		[5, 145, 115, 10, 146, 116],
+		[19, 75, 47, 10, 76, 48],
+		[15, 54, 24, 25, 55, 25],
+		[23, 45, 15, 25, 46, 16],
+
+		// 31
+		[13, 145, 115, 3, 146, 116],
+		[2, 74, 46, 29, 75, 47],
+		[42, 54, 24, 1, 55, 25],
+		[23, 45, 15, 28, 46, 16],
+
+		// 32
+		[17, 145, 115],
+		[10, 74, 46, 23, 75, 47],
+		[10, 54, 24, 35, 55, 25],
+		[19, 45, 15, 35, 46, 16],
+
+		// 33
+		[17, 145, 115, 1, 146, 116],
+		[14, 74, 46, 21, 75, 47],
+		[29, 54, 24, 19, 55, 25],
+		[11, 45, 15, 46, 46, 16],
+
+		// 34
+		[13, 145, 115, 6, 146, 116],
+		[14, 74, 46, 23, 75, 47],
+		[44, 54, 24, 7, 55, 25],
+		[59, 46, 16, 1, 47, 17],
+
+		// 35
+		[12, 151, 121, 7, 152, 122],
+		[12, 75, 47, 26, 76, 48],
+		[39, 54, 24, 14, 55, 25],
+		[22, 45, 15, 41, 46, 16],
+
+		// 36
+		[6, 151, 121, 14, 152, 122],
+		[6, 75, 47, 34, 76, 48],
+		[46, 54, 24, 10, 55, 25],
+		[2, 45, 15, 64, 46, 16],
+
+		// 37
+		[17, 152, 122, 4, 153, 123],
+		[29, 74, 46, 14, 75, 47],
+		[49, 54, 24, 10, 55, 25],
+		[24, 45, 15, 46, 46, 16],
+
+		// 38
+		[4, 152, 122, 18, 153, 123],
+		[13, 74, 46, 32, 75, 47],
+		[48, 54, 24, 14, 55, 25],
+		[42, 45, 15, 32, 46, 16],
+
+		// 39
+		[20, 147, 117, 4, 148, 118],
+		[40, 75, 47, 7, 76, 48],
+		[43, 54, 24, 22, 55, 25],
+		[10, 45, 15, 67, 46, 16],
+
+		// 40
+		[19, 148, 118, 6, 149, 119],
+		[18, 75, 47, 31, 76, 48],
+		[34, 54, 24, 34, 55, 25],
+		[20, 45, 15, 61, 46, 16]
+	];
+
+	QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
+
+		var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
+
+		if (rsBlock == undefined) {
+			throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
+		}
+
+		var length = rsBlock.length / 3;
+
+		var list = new Array();
+
+		for (var i = 0; i < length; i++) {
+
+			var count = rsBlock[i * 3 + 0];
+			var totalCount = rsBlock[i * 3 + 1];
+			var dataCount = rsBlock[i * 3 + 2];
+
+			for (var j = 0; j < count; j++) {
+				list.push(new QRRSBlock(totalCount, dataCount));
+			}
+		}
+
+		return list;
+	}
+
+	QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
+
+		switch (errorCorrectLevel) {
+			case QRErrorCorrectLevel.L:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
+			case QRErrorCorrectLevel.M:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
+			case QRErrorCorrectLevel.Q:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
+			case QRErrorCorrectLevel.H:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
+			default:
+				return undefined;
+		}
+	}
+
+	//---------------------------------------------------------------------
+	// QRBitBuffer
+	//---------------------------------------------------------------------
+
+	function QRBitBuffer() {
+		this.buffer = new Array();
+		this.length = 0;
+	}
+
+	QRBitBuffer.prototype = {
+
+		get: function(index) {
+			var bufIndex = Math.floor(index / 8);
+			return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
+		},
+
+		put: function(num, length) {
+			for (var i = 0; i < length; i++) {
+				this.putBit(((num >>> (length - i - 1)) & 1) == 1);
+			}
+		},
+
+		getLengthInBits: function() {
+			return this.length;
+		},
+
+		putBit: function(bit) {
+
+			var bufIndex = Math.floor(this.length / 8);
+			if (this.buffer.length <= bufIndex) {
+				this.buffer.push(0);
+			}
+
+			if (bit) {
+				this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
+			}
+
+			this.length++;
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// Support Chinese
+	//---------------------------------------------------------------------
+	function utf16To8(text) {
+		var result = '';
+		var c;
+		for (var i = 0; i < text.length; i++) {
+			c = text.charCodeAt(i);
+			if (c >= 0x0001 && c <= 0x007F) {
+				result += text.charAt(i);
+			} else if (c > 0x07FF) {
+				result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
+				result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
+				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+			} else {
+				result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
+				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+			}
+		}
+		return result;
+	}
+
+	uQRCode = {
+
+		errorCorrectLevel: QRErrorCorrectLevel,
+
+		defaults: {
+			size: 354,
+			margin: 0,
+			backgroundColor: '#ffffff',
+			foregroundColor: '#000000',
+			fileType: 'png', // 'jpg', 'png'
+			errorCorrectLevel: QRErrorCorrectLevel.H,
+			typeNumber: -1
+		},
+
+		make: function(options) {
+			return new Promise((reslove, reject) => {
+				var defaultOptions = {
+					canvasId: options.canvasId,
+					componentInstance: options.componentInstance,
+					text: options.text,
+					size: this.defaults.size,
+					margin: this.defaults.margin,
+					backgroundColor: this.defaults.backgroundColor,
+					foregroundColor: this.defaults.foregroundColor,
+					fileType: this.defaults.fileType,
+					errorCorrectLevel: this.defaults.errorCorrectLevel,
+					typeNumber: this.defaults.typeNumber
+				};
+				if (options) {
+					for (var i in options) {
+						defaultOptions[i] = options[i];
+					}
+				}
+				options = defaultOptions;
+				if (!options.canvasId) {
+					console.error('uQRCode: Please set canvasId!');
+					return;
+				}
+
+				function createCanvas() {
+					var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
+					qrcode.addData(utf16To8(options.text));
+					qrcode.make();
+
+					var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
+					ctx.setFillStyle(options.backgroundColor);
+					ctx.fillRect(0, 0, options.size, options.size);
+
+					var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
+					var tileH = tileW;
+
+					for (var row = 0; row < qrcode.getModuleCount(); row++) {
+						for (var col = 0; col < qrcode.getModuleCount(); col++) {
+							var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
+							ctx.setFillStyle(style);
+							var x = Math.round(col * tileW) + options.margin;
+							var y = Math.round(row * tileH) + options.margin;
+							var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
+							var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
+							ctx.fillRect(x, y, w, h);
+						}
+					}
+
+					setTimeout(function() {
+						ctx.draw(false, (function() {
+							setTimeout(function() {
+								uni.canvasToTempFilePath({
+									canvasId: options.canvasId,
+									fileType: options.fileType,
+									width: options.size,
+									height: options.size,
+									destWidth: options.size,
+									destHeight: options.size,
+									success: function(res) {
+										let resData; // 将统一为base64格式
+										let tempFilePath = res.tempFilePath; // H5为base64,其他为相对路径
+
+										// #ifdef H5
+										resData = tempFilePath;
+										options.success && options.success(resData);
+										reslove(resData);
+										// #endif
+
+										// #ifdef APP-PLUS
+										const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
+										let fileReader = new plus.io.FileReader();
+										fileReader.readAsDataURL(path);
+										fileReader.onloadend = res => {
+											resData = res.target.result;
+											options.success && options.success(resData);
+											reslove(resData);
+										};
+										// #endif
+
+										// #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+										uni.getFileSystemManager().readFile({
+											filePath: tempFilePath,
+											encoding: 'base64',
+											success: res => {
+												resData = 'data:image/png;base64,' + res.data;
+												options.success && options.success(resData);
+												reslove(resData);
+											}
+										})
+										// #endif
+
+										// #ifndef H5 || APP-PLUS || MP-WEIXIN || MP-QQ || MP-TOUTIAO
+										if (plus) {
+											const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
+											let fileReader = new plus.io.FileReader();
+											fileReader.readAsDataURL(path);
+											fileReader.onloadend = res => {
+												resData = res.target.result;
+												options.success && options.success(resData);
+												reslove(resData);
+											};
+										} else {
+											uni.request({
+												url: tempFilePath,
+												method: 'GET',
+												responseType: 'arraybuffer',
+												success: res => {
+													resData = `data:image/png;base64,${uni.arrayBufferToBase64(res.data)}`; // 把arraybuffer转成base64
+													options.success && options.success(resData);
+													reslove(resData);
+												}
+											})
+										}
+										// #endif
+									},
+									fail: function(error) {
+										options.fail && options.fail(error);
+										reject(error);
+									},
+									complete: function(res) {
+										options.complete && options.complete(res);
+									}
+								}, options.componentInstance);
+							}, options.text.length + 100);
+						})());
+					}, 150);
+				}
+
+				createCanvas();
+			});
+		}
+	}
+
+})()
+
+export default uQRCode

+ 62 - 0
components/uni-agreements/uni-agreements.vue

@@ -0,0 +1,62 @@
+<template>
+	<view class="root">
+		<checkbox-group @change="setAgree" class="checkbox-group">
+			<checkbox  style="transform: scale(0.7);" />
+			<text>同意</text>
+		</checkbox-group>
+		<template v-for="(agreement,index) in agreements">
+			<text class="agreement" @click="navigateTo(agreement)">{{agreement.title}}</text>
+			<text class="hint" v-if="hasAnd(agreements,index)">和</text>
+		</template>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"uni-agreements",
+		computed:{
+			agreements(){
+				return getApp().globalData.config.about.agreements||[]
+			}
+		},
+		methods:{
+			navigateTo({url,title}){
+				uni.navigateTo({
+					url: '/pages/common/webview/webview?url='+url+'&title='+title,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			hasAnd(agreements,index){
+				return agreements.length-1>index
+			},
+			setAgree(e){
+				this.isAgree = !this.isAgree
+				this.$emit('setAgree',this.isAgree)
+			}
+		},
+		data() {
+			return {
+				isAgree:false
+			};
+		}
+	}
+</script>
+
+<style>
+.root{
+	flex-direction: row;
+	align-items: center;
+	font-size: 28rpx;
+	color: #8a8f8b;
+}
+.checkbox-group{
+	align-items: center;
+	display: flex;
+	flex-direction: row;
+}
+.agreement{
+	color:#04498c;
+}
+</style>

+ 368 - 0
components/uni-quick-login/uni-quick-login.vue

@@ -0,0 +1,368 @@
+<template>
+	<view class="quick-login-box">
+		<view class="item" v-for="(item,index) in servicesList" :key="index"
+			@click="item.path?to(item.path):login_before(item.id,false)">
+			<image class="logo" :src="item.logo" mode="widthFix"></image>
+			<text class="login-title">{{item.text}}</text>
+		</view>
+	</view>
+</template>
+<script>
+	import {
+		mapGetters,
+		mapMutations
+	} from 'vuex';
+	//前一个窗口的页面地址。控制点击切换快捷登录方式是创建还是返回
+	import loginSuccess from '@/pages/ucenter/login-page/common/loginSuccess.js';
+	export default {
+		computed: {
+			loginConfig() {
+				return getApp().globalData.config.router.login
+			},
+			agreements() {
+				return getApp().globalData.config.about.agreements || []
+			}
+		},
+		data() {
+			return {
+				servicesList: [{
+						"id": "username",
+						"text": "账号登录",
+						"logo": "/static/uni-quick-login/user.png",
+						"path": "/pages/ucenter/login-page/pwd-login/pwd-login"
+					},
+					{
+						"id": "smsCode",
+						"text": "短信验证码",
+						"logo": "/static/uni-quick-login/sms.png",
+						"path": "/pages/ucenter/login-page/index/index"
+					}
+				],
+				oauthServices: [],
+				config: {
+					"weixin": {
+						"text": "微信登录",
+						"logo": "/static/uni-quick-login/wechat.png",
+					},
+					"apple": {
+						"text": "苹果登录",
+						"logo": "/static/uni-quick-login/apple.png",
+					},
+					"univerify": {
+						"text": "一键登录",
+						"logo": "/static/uni-quick-login/univerify.png",
+					},
+					"qq": {
+						"text": "QQ登录",//暂未提供该登录方式的接口示例
+						"logo": "/static/uni-quick-login/univerify.png",
+					},
+					"xiaomi": {
+						"text": "小米登录",//暂未提供该登录方式的接口示例
+						"logo": "/static/uni-quick-login/univerify.png",
+					},
+					"sinaweibo": {
+						"text": "微博登录",//暂未提供该登录方式的接口示例
+						"logo": "/static/uni-quick-login/univerify.png",
+					}
+				},
+				univerifyStyle:{ //一键登录弹出窗的样式配置参数
+					"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
+					"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
+					"buttons": { // 自定义登陆按钮
+						"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
+						"list": []
+					},
+					"privacyTerms": {
+						"defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true   
+						"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB  
+						"termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3  
+						"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”  
+						"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”  
+						"privacyItems": []
+					}
+				}
+			}
+		},
+		watch: {
+			agree(agree) {
+				this.univerifyStyle.privacyTerms.defaultCheckBoxState = agree
+			}
+		},
+		props: {
+			agree: {
+				type: Boolean,
+				default () {
+					return false
+				}
+			}
+		},
+		async created() {
+			this.univerifyStyle.privacyTerms.privacyItems = this.agreements
+			
+			let servicesList = this.servicesList
+			//获取当前环境能用的快捷登录方式
+			// #ifdef MP-WEIXIN
+			let id = 'weixin'
+			if (this.loginConfig.includes(id)) {
+				servicesList.push({
+					...this.config[id],
+					id
+				})
+			}
+			// #endif
+			// #ifdef APP-PLUS
+			this.oauthServices = await new Promise((callBack)=>{
+				plus.oauth.getServices(oauthServices => {
+					callBack(oauthServices.filter(({nativeClient,id})=>nativeClient&&this.loginConfig.includes(id))) 
+					//只返回1.应用支持 && 2.手机已安装对应客户端 && 3.uni-card.config.js配置项中存在的快捷登录方式
+				}, err => {
+					callBack([])
+					uni.hideLoading()
+					uni.showModal({
+						title: '获取服务供应商失败:' + JSON.stringify(err),
+						showCancel: false,
+						confirmText: '知道了'
+					});
+					console.error('获取服务供应商失败:' + JSON.stringify(err));
+				})
+			})
+			// #endif
+			//添加已配置且可用的第三方快捷登陆项
+			servicesList = servicesList.concat(this.oauthServices.map( ({id})=>{
+				return {...this.config[id],id}
+			}))
+			//设置一键登录功能底下的快捷登陆按钮
+			servicesList.forEach(({id,logo})=>{
+				if(id != 'univerify'){
+					this.univerifyStyle.buttons.list.push({"iconPath":logo,"provider":id})
+				}
+			})
+			//去掉当前页面对应的登录选项
+			this.servicesList = servicesList.filter(item=>{
+				return item.path != this.getRoute(1)
+			})
+			// console.log('servicesList',servicesList,this.servicesList);
+		},
+		methods: {
+			...mapMutations({
+				setUserInfo: 'user/login'
+			}),
+			getRoute(n = 0) {
+				let pages = getCurrentPages();
+				// console.log('route-pages-length', pages.length);
+				if (n > pages.length) {
+					return ''
+				}
+				return '/' + pages[pages.length - n].route
+			},
+			to(path) {
+				// console.log('比较', this.getRoute(2), path)
+				if (this.getRoute(2) == path) { // 控制路由是重新打开还是返回,避免重复打开页面
+					uni.navigateBack();
+				} else {
+					uni.navigateTo({
+						url: path
+					})
+				}
+			},
+			login_before(type, navigateBack = true) {
+				if (!this.agree&&type!='univerify') {
+					return uni.showToast({
+						title: '你未同意隐私政策协议',
+						icon: 'none'
+					});
+				}
+				uni.showLoading({
+					mask: true
+				})
+				// console.log(arguments);
+				let oauthService = this.oauthServices.find((service) => service.id == type)
+				// console.log(type);
+
+				// #ifdef APP-PLUS
+				//请勿直接使用前端获取的unionid或openid直接用于登录,前端的数据都是不可靠的
+				if (type == 'weixin') {
+					return oauthService.authorize(({
+							code
+						}) => {
+							// console.log(code);
+							this.login({
+								code
+							}, type)
+						},
+						err => {
+							uni.hideLoading()
+							console.log(err);
+							uni.showModal({
+								content: JSON.stringify(err),
+								showCancel: false
+							});
+						})
+				}
+				// #endif
+
+				uni.login({
+					"provider": type,
+					"univerifyStyle": this.univerifyStyle,
+					complete: (e) => {
+						console.log(e);
+					},
+					success: async e => {
+						console.log(e);
+						if (type == 'apple') {
+							let res = await this.getUserInfo({
+								provider: "apple"
+							})
+							uni.hideLoading()
+							Object.assign(e.authResult, res.userInfo)
+						}
+						// #ifdef MP-WEIXIN
+						if (type == 'weixin') {
+							return this.login({
+								code: e.code
+							}, type)
+						}
+						// #endif
+						this.login(e.authResult, type)
+					},
+					fail: (err) => {
+						uni.hideLoading()
+						console.log(err);
+
+						if (type == 'univerify') {
+							if (err.metadata && err.metadata.error_data) {
+								uni.showToast({
+									title: "一键登录:" + err.metadata.error_data,
+									icon: 'none'
+								});
+							}
+							if (err.errMsg) {
+								uni.showToast({
+									title: "一键登录:" + err.errMsg,
+									icon: 'none'
+								});
+							}
+							switch (err.errCode) {
+								case 30002:
+									console.log('在一键登录界面,点击其他登录方式');
+									break;
+								case 30003:
+									console.log('关闭了登录');
+									if (navigateBack) {
+										uni.navigateBack()
+									}
+									break;
+								case 30006:
+									uni.showModal({
+										title: "登录服务初始化错误",
+										content: err.metadata.error_data,
+										showCancel: false,
+										confirmText: '知道了',
+									});
+									break;
+								case "30008":
+									uni.showToast({
+										title: '点击了第三方登陆',
+										icon: 'none'
+									});
+									console.log('点击了第三方登陆,provider:',err.provider);
+									let {path} = this.servicesList.find(item=>item.id==err.provider)||{}
+									console.log('path',path);
+									if(path&&path!=this.getRoute(1)){ //存在路径,且并不是当前已经打开的路径
+										this.to(path)
+									}else{
+										this.login_before(err.provider)
+									}
+									break;
+								default:
+									console.log(9527, err);
+									break;
+							}
+						}
+					}
+				})
+			},
+			login(params, type) { //联网验证登录
+				console.log({
+					params,
+					type
+				});
+				let action = 'loginBy' + type.trim().toLowerCase().replace(type[0], type[0].toUpperCase())
+				uniCloud.callFunction({
+					name: 'uni-id-cf',
+					data: {
+						action,
+						params
+					},
+					success: ({
+						result
+					}) => {
+						console.log(result);
+						if (result.code === 0) {
+							if (type == 'univerify') {
+								uni.closeAuthView()
+							}
+							uni.hideLoading()
+							loginSuccess(result)
+							delete result.userInfo.token
+							this.setUserInfo(result.userInfo)
+						} else {
+							uni.showModal({
+								content: result.msg,
+								showCancel: false
+							});
+						}
+					},
+					complete: () => {
+						uni.hideLoading()
+					}
+				})
+			},
+			async getUserInfo(e) {
+				return new Promise((resolve, reject) => {
+					uni.getUserInfo({
+						...e,
+						success: (res) => {
+							resolve(res);
+						},
+						fail: (err) => {
+							uni.showModal({
+								content: JSON.stringify(err),
+								showCancel: false
+							});
+							reject(err);
+						}
+					})
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.quick-login-box {
+		flex-direction: row;
+		width: 750rpx;
+		justify-content: space-around;
+		position: fixed;
+		bottom: 10rpx;
+		left: 0;
+	}
+
+	.item {
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 200rpx;
+	}
+
+	.logo {
+		width: 60rpx;
+		height: 60rpx;
+	}
+
+	.login-title {
+		margin-top: 4px;
+		font-size: 26rpx;
+	}
+</style>

+ 137 - 0
components/uni-send-sms-code/uni-send-sms-code.vue

@@ -0,0 +1,137 @@
+<template>
+	<view class="short-code-btn" hover-class="hover" @click="start">
+		<text class="inner-text" :class="reverseNumber==0?'inner-text-active':''">{{innerText}}</text>
+	</view>
+</template>
+
+<script>
+	function debounce(func, wait) {
+		let timer;
+		wait = wait || 500;
+		return function() {
+			let context = this;
+			let args = arguments;
+			if (timer) clearTimeout(timer);
+			let callNow = !timer;
+			timer = setTimeout(() => {
+				timer = null;
+			}, wait)
+			if (callNow) func.apply(context, args);
+		}
+	}
+	export default {
+		name: "uni-send-sms-code",
+		props: {
+			/**
+			 * 倒计时时长 s
+			 */
+			count: {
+				type: [String, Number],
+				default: 60
+			},
+			/**
+			 * 手机号码
+			 */
+			phone: {
+				type: [String, Number],
+				default: ''
+			},
+			/*
+				验证码类型,用于防止不同功能的验证码混用,目前支持的类型login登录、register注册、bind绑定手机、unbind解绑手机
+			*/
+			codeType:{
+				type: String,
+				default(){
+					return 'login'
+				}
+			}
+		},
+		data() {
+			return {
+				reverseNumber: 0,
+				reverseTimer: null
+			};
+		},
+		computed: {
+			innerText() {
+				if (this.reverseNumber == 0) return '获取验证码';
+				return '重新发送('+this.reverseNumber+'s)';
+			}
+		},
+		created() {
+			this.initClick();
+		},
+		methods: {
+			initClick() {
+				this.start = debounce(() => {
+					if (this.reverseNumber != 0) return;
+					this.sendMsg();
+				})
+			},
+			sendMsg() {
+				let reg_phone = /^1\d{10}$/;
+				if(!reg_phone.test(this.phone))return uni.showToast({
+					title: '手机号格式错误',
+					icon: 'none'
+				});
+				uniCloud.callFunction({
+					name:'uni-id-cf',
+					data:{
+						action:'sendSmsCode',
+						params:{
+							"mobile": this.phone,
+							"type": this.codeType
+						},
+					},
+					success: ({result}) => {
+						console.log(result);
+						if(result.code===0){
+							uni.showToast({
+								title: "短信验证码发送成功",
+								icon: 'none'
+							});
+							this.reverseNumber = Number(this.count);
+							this.getCode();
+							this.$emit('getCode');
+						}else{
+							uni.showModal({
+								content: result.msg,
+								showCancel: false
+							});
+						}
+					}
+				})
+			},
+			getCode() {
+				if (this.reverseNumber == 0) {
+					clearTimeout(this.reverseTimer);
+					this.reverseTimer = null;
+					return;
+				}
+				this.reverseNumber--;
+				this.reverseTimer = setTimeout(() => {
+					this.getCode();
+				}, 1000)
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.short-code-btn {
+		width: 200rpx;
+		height: 85rpx;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+	.inner-text {
+		font-size: 28rpx;
+		color: #AAAAAA;
+	}
+	.inner-text-active {
+		color: #007aff;
+	}
+</style>

+ 15 - 0
main.js

@@ -0,0 +1,15 @@
+import Vue from 'vue'
+import App from './App'
+import store from './store/index.js';
+import * as util from '@/common/js/util.js'
+Vue.prototype.$util = util
+import uView from "uview-ui";
+Vue.use(uView);
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+const app = new Vue({
+    ...App,
+	store
+})
+app.$mount()

+ 115 - 0
manifest.json

@@ -0,0 +1,115 @@
+{
+    "name" : "基于云开发的微信小程序电子名片-CxCloud",
+    "appid" : "__UNI__2AD76E7",
+    "description" : "电子名片",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    "app-plus" : {
+        "privacy" : {
+            "prompt" : "template",
+            "template" : {
+                "title" : "服务协议和隐私政策",
+                "message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://ask.dcloud.net.cn/protocol.html\">《服务协议》</a>和<a href=\"https://ask.dcloud.net.cn/protocol.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
+                "buttonAccept" : "同意",
+                "buttonRefuse" : "暂不同意"
+            }
+        },
+        "compatible" : {
+            "ignoreVersion" : true
+        },
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {
+            "Fingerprint" : {},
+            "Share" : {},
+            "OAuth" : {},
+            "FaceID" : {},
+            "Push" : {}
+        },
+        "distribute" : {
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ],
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
+            },
+            "ios" : {},
+            "sdkConfigs" : {
+                "oauth" : {
+                    "apple" : {},
+                    "weixin" : {
+                        "appid" : "wxffdd8fa6ec4ef2a0",
+                        "appsecret" : "",
+                        "UniversalLinks" : ""
+                    },
+                    "univerify" : {}
+                },
+                "ad" : {},
+                "share" : {
+                    "weixin" : {
+                        "appid" : "wxffdd8fa6ec4ef2a0",
+                        "UniversalLinks" : ""
+                    }
+                },
+                "geolocation" : {},
+                "push" : {
+                    "unipush" : {}
+                },
+                "payment" : {}
+            }
+        },
+        "nvueLaunchMode" : ""
+    },
+    "quickapp" : {},
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : false,
+            "minified" : true
+        },
+        "usingComponents" : true,
+        "betterScopedSlots" : true,
+        "permission" : {}
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "h5" : {
+        "template" : ""
+    },
+    "vueVersion" : "2"
+}

+ 5 - 0
package-lock.json

@@ -0,0 +1,5 @@
+{
+    "name": "基于云开发的电子名片-CxCloud",
+    "version": "1.0.1",
+    "lockfileVersion": 1
+}

+ 85 - 0
package.json

@@ -0,0 +1,85 @@
+{
+    "id": "cxcloud-card",
+    "displayName": "基于云开发的电子名片-CxCloud",
+    "version": "1.0.1",
+    "description": "基于云开发的电子名片-CxCloud",
+    "keywords": [
+        "名片",
+        "电子名片"
+    ],
+    "repository": "",
+    "engines": {
+        "HBuilderX": "^3.1.20"
+    },
+    "dcloudext": {
+        "category": [
+            "uniCloud",
+            "云端一体项目模板"
+        ],
+        "sale": {
+            "regular": {
+                "price": "0.00"
+            },
+            "sourcecode": {
+                "price": "0.00"
+            }
+        },
+        "contact": {
+            "qq": "365015"
+        },
+        "declaration": {
+            "ads": "无",
+            "data": "无",
+            "permissions": "无"
+        },
+        "npmurl": ""
+    },
+    "uni_modules": {
+        "dependencies": [],
+        "encrypt": [],
+        "platforms": {
+            "cloud": {
+                "tcb": "y",
+                "aliyun": "y"
+            },
+            "client": {
+                "App": {
+                    "app-vue": "y",
+                    "app-nvue": "y"
+                },
+                "H5-mobile": {
+                    "Safari": "y",
+                    "Android Browser": "y",
+                    "微信浏览器(Android)": "y",
+                    "QQ浏览器(Android)": "y"
+                },
+                "H5-pc": {
+                    "Chrome": "y",
+                    "IE": "y",
+                    "Edge": "y",
+                    "Firefox": "y",
+                    "Safari": "y"
+                },
+                "小程序": {
+                    "微信": "y",
+                    "阿里": "y",
+                    "百度": "y",
+                    "字节跳动": "y",
+                    "QQ": "y"
+                },
+                "快应用": {
+                    "华为": "y",
+                    "联盟": "y"
+                },
+                "Vue": {
+                    "vue2": "y",
+                    "vue3": "u"
+                }
+            }
+        }
+    },
+    "name": "基于云开发的电子名片-CxCloud",
+    "dependencies": {
+        "uview-ui": "^2.0.10"
+    }
+}

+ 39 - 0
pages.json

@@ -0,0 +1,39 @@
+{
+	"easycom": {
+		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
+	},
+	"pages": [{
+			"path": "pages/index",
+			"style": {
+				"navigationBarTitleText": "畅享云名片",
+				"navigationStyle": "default"
+			}
+		},{
+			"path": "pages/edit",
+			"style": {
+				"navigationBarTitleText": "编辑名片",
+				"navigationStyle": "default"
+			}
+		}, {
+			"path": "pages/login",
+			"style": {
+				"navigationBarTitleText": "登录",
+				"navigationStyle": "default"
+			}
+		},
+		{
+			"path": "pages/agree",
+			"style": {
+				"navigationBarTitleText": "用户协议",
+				"navigationStyle": "default"
+			}
+		}
+	],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-card",
+		"navigationBarBackgroundColor": "#FFFFFF",
+		"backgroundColor": "#F8F8F8",
+		"enablePullDownRefresh": false
+	}
+}

+ 103 - 0
pages/agree.vue

@@ -0,0 +1,103 @@
+<template>
+	<view>
+		<view class="weui-desktop-panel_inner">
+			<h3 class="panel__title-center">畅享云名片小程序隐私保护指引</h3>
+			<view class="group-infos">
+				<text>本指引是畅享云名片小程序开发者 "常熟市畅享计算机信息技术有限公司"(以下简称“开发者”)为处理你的个人信息而制定。</text>
+			</view>
+			<view class="group-infos">
+				<view class="group-infos__hd">
+					<text class="group-infos__title">开发者处理的信息</text>
+					<text class="group-infos__hd-privacyText">根据法律规定,开发者仅处理实现小程序功能所必要的信息。</text>
+				</view>
+				<text>
+					开发者 收集你选中的照片或视频信息,用于业务介绍。
+				</text>
+				<text>
+					开发者 收集你选中的文件,用于信息展示。
+				</text>
+			</view>
+			<view class="group-infos">
+				<view class="group-infos__hd">
+					<text class="group-infos__title">你的权益</text>
+				</view>
+				<text class="group-infos_order">
+					关于收集你选中的照片或视频信息、收集你选中的照片或视频信息、收集你选中的文件、收集你选中的文件,你可以通过以下路径:小程序主页右上角“...” — “设置” —
+					“小程序已获取的信息” — 点击特定信息 — 点击“通知开发者删除”,开发者承诺收到通知后将删除信息。</text>
+				<text class="group-infos_order">关于你的个人信息,你可以通过以下方式与开发者联系,行使查阅、复制、更正、删除等法定权利。</text>
+			</view>
+			<view class="group-infos">
+				<view class="group-infos__hd">
+					<text class="group-infos__title">开发者对信息的存储</text>
+				</view>
+				<text>开发者承诺,除法律法规另有规定外,开发者对你的信息的保存期限应当为实现处理目的所必要的最短时间。</text>
+			</view>
+			<view class="group-infos">
+				<view class="group-infos__hd">
+					<text class="group-infos__title">信息的使用规则</text>
+				</view>
+				<text class="group-infos_order">开发者将会在本指引所明示的用途内使用收集的信息</text>
+				<text>如开发者使用你的信息超出本指引目的或合理范围,开发者必须在变更使用目的或范围前,再次以电话方式告知并征得你的明示同意。</text>
+			</view>
+			<view class="group-infos">
+				<view class="group-infos__hd">
+					<text class="group-infos__title">信息对外提供</text>
+				</view>
+				<text class="group-infos_order">开发者承诺,不会主动共享或转让你的信息至任何第三方,如存在确需共享或转让时,开发者应当直接征得或确认第三方征得你的单独同意。
+				</text>
+				<text class="group-infos_order">
+					开发者承诺,不会对外公开披露你的信息,如必须公开披露时,开发者应当向你告知公开披露的目的、披露信息的类型及可能涉及的信息,并征得你的单独同意。</text>
+			</view>
+			<view class="group-infos">
+					<text class="group-infos_order">
+						你认为开发者未遵守上述约定,或有其他的投诉建议、或未成年人个人信息保护相关问题,可通过以下方式与开发者联系;或者向微信进行投诉。</text>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "",
+		data() {
+			return {
+
+			}
+		},
+		onLoad() {
+
+		},
+		methods: {
+
+		}
+	}
+</script>
+<style scoped>
+	page {
+		background: #fff;
+	}
+
+	.panel__title-center {
+		font-size: 18px;
+		text-align: center;
+		height: 60px;
+		line-height: 60px;
+	}
+
+	.group-infos_order {
+		height: 24px;
+		line-height: 24px;
+		text-indent: 24px;
+	}
+
+	.signature {
+		text-align: right;
+	}
+
+	.group-infos__title {
+		display: block;
+		height: 60px;
+		line-height: 60px;
+	}
+</style>

+ 207 - 0
pages/edit.vue

@@ -0,0 +1,207 @@
+<template>
+	<view>
+		<view class="wrap">
+			<u--form labelPosition="left" :model="cardObj" :rules="rules" ref="form1" labelWidth="80">
+				<u-form-item label="姓名" prop="cardObj.name" borderBottom>
+					<u--input v-model="cardObj.name" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="电话" prop="cardObj.phone" borderBottom>
+					<u--input v-model="cardObj.phone" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="公司" prop="company" borderBottom>
+					<u--input v-model="cardObj.company" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="地址" prop="address" borderBottom>
+					<u--input v-model="cardObj.address" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="职位" prop="job" borderBottom>
+					<u--input v-model="cardObj.job" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="微信" prop="wechat" borderBottom>
+					<u--input v-model="cardObj.wechat" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="QQ" prop="wechat" borderBottom>
+					<u--input v-model="cardObj.qq" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="邮箱" prop="email" borderBottom>
+					<u--input v-model="cardObj.email" border="none"></u--input>
+				</u-form-item>
+				<u-form-item label="业务介绍" prop="intro" borderBottom>
+					<u--textarea v-model="cardObj.intro" border="none"></u--textarea>
+				</u-form-item>
+				<u-form-item label="头像" prop="intro" borderBottom>
+					<u-upload :fileList="fileList1" @afterRead="afterRead" name="5" :maxCount="1" @delete="deletePic"
+						:previewFullImage="true">
+					</u-upload>
+				</u-form-item>
+			</u--form>
+			<view class="wrap">
+				<view style="float:left;width: 40px;">
+					<u-checkbox-group  v-model="checked" change="changeClick()">
+					<u-checkbox shape="circle" ></u-checkbox>
+					</u-checkbox-group>
+				</view>
+				<text style="float:left;color:#04498c" @click="goAgree()">同意用户服务协议&隐私政策</text>
+			</view>
+		</view>
+		<view class="bottom-block"></view>
+		<view class="bottombtn" type="primary" @click="onSave">立即保存</view>
+	</view>
+</template>
+
+<script>
+	import {
+		request
+	} from '@/common/js/request'
+	export default {
+		name: "Edit",
+		components: {},
+		data() {
+			return {
+				checked: false,
+				cardObj: {},
+				fileList1: [],
+				isAdd: true,
+				rules: {
+					'cardObj.name': {
+						type: 'string',
+						required: true,
+						message: '必填',
+						trigger: ['blur', 'change']
+					},
+					'cardObj.phone': {
+						type: 'string',
+						required: true,
+						message: '必填',
+						trigger: ['blur', 'change']
+					},
+				},
+			};
+		},
+		mounted() {},
+		async onLoad(options) {
+			const logged = uni.getStorageSync('logged');
+			if (logged) {
+				var user = uni.getStorageSync('userInfo');
+				const res = await request('uni-card', 'getMyCard', {
+					uid: user.id
+				}, {
+					showloading: true
+				});
+				if (res.uid == null)
+					this.isAdd = true;
+				else {
+					if (res.uid != user.id) {
+						uni.navigateTo({
+							url: "/pages/index"
+						})
+					}
+					this.cardObj = res;
+					this.isAdd = false;
+					this.fileList1.push({
+						url: res.head_img
+					})
+				}
+			}
+		},
+		methods: {
+			goAgree() {
+				uni.navigateTo({
+					url: "/pages/agree"
+				})
+			},
+			changeClick(){
+				console.log("this.checked",this.checked)
+			},
+			async onSave() {
+				if (!this.checked) {
+					this.$util.msg('请点击同意用户服务协议&隐私政策');
+					return;
+				}
+				if (!this.cardObj.name) {
+					this.$util.msg('请填写姓名');
+					return;
+				}
+				if (!this.cardObj.phone) {
+					this.$util.msg('请填写电话');
+					return;
+				}
+				var user = uni.getStorageSync('userInfo');
+				this.cardObj.uid = user.id;
+				const res = await request('uni-card', 'saveCard', this.cardObj, {
+					showloading: true
+				});
+				console.log("res", res)
+				this.$util.msg('保存成功');
+				uni.setStorageSync('id', res.id);
+				uni.navigateTo({
+					url: "/pages/index"
+				})
+			},
+			deletePic(event) {
+				this.fileList1 = [];
+				this.cardObj.head_img = "";
+			},
+			async afterRead(event) {
+				console.log("event", event)
+				const result = await this.uploadFilePromise(event.file.url)
+			},
+			uploadFilePromise(url) {
+				return new Promise((resolve, reject) => {
+					var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
+					var maxLen = $chars.length;
+					var noncestr = '';
+					for (var i = 0; i < 32; i++) {
+						noncestr += $chars.charAt(Math.floor(Math.random() * maxLen));
+					}
+					var that = this;
+					uniCloud.uploadFile({
+						filePath: url,
+						cloudPath: noncestr + ".jpg",
+						onUploadProgress: function(progressEvent) {
+							console.log("上传进度", progressEvent);
+							var percentCompleted = Math.round(
+								(progressEvent.loaded * 100) / progressEvent.total
+							);
+						},
+						success(e) {
+							console.log("uploadFile", e)
+							that.fileList1.push({
+								url: e.fileID
+							})
+							that.cardObj.head_img = e.fileID
+						},
+						fail() {},
+						complete() {}
+					});
+				})
+			},
+		}
+	};
+</script>
+
+<style>
+	/deep/.u-scroll-bar {
+		background: red !important;
+	}
+
+	.wrap {
+		padding: 20px;
+	}
+
+	.bottombtn {
+		position: fixed;
+		bottom: 0;
+		width: 100%;
+		height: 60px;
+		background: #007AFF;
+		color: #fff;
+		line-height: 60px;
+		text-align: center;
+	}
+	.bottom-block {
+		display: block;
+		width: 100%;
+		height: 80px;
+	}
+</style>

+ 603 - 0
pages/index.vue

@@ -0,0 +1,603 @@
+<template>
+	<view class="content">
+		<view class="content-box">
+			<view class="top-main-box">
+				<view class="zzbg">
+					<image class="mpimg" src="/static/images/mpbg1.jpg" mode="widthFix"></image>
+				</view>
+				<view class="topmain">
+					<view class="leftimg">
+						<u-avatar size="60" :src="cardObj.head_img" shape="square"></u-avatar>
+					</view>
+					<view class="rightcont">
+						<view class="name">{{cardObj.name}}</view>
+						<view class="tip">{{cardObj.job}}</view>
+						<view class="tipa">{{cardObj.company}}</view>
+					</view>
+				</view>
+				<view class="btnmain">
+					<u-icon name="map-fill"></u-icon><text>{{cardObj.address}}</text>
+				</view>
+			</view>
+
+
+
+			<view class="top-mainb">
+				<view class="conta">
+					<view class="cont" v-if="cardObj.phone" @click="onPhone()">
+						<view class="box">
+							<u-icon name="phone-fill" color="#007AFF" size="40"> </u-icon>
+							<view class="right">
+								<text class="tit">拨打电话</text>
+								<text>{{cardObj.phone}}</text>
+							</view>
+						</view>
+					</view>
+					<view class="cont" v-if="cardObj.wechat" @click="onCopy(cardObj.wechat)">
+						<view class="box">
+							<u-icon name="weixin-fill" color="#007AFF" size="40"> </u-icon>
+							<view class="right">
+								<text class="tit">加微信</text>
+								<text>{{cardObj.wechat}}</text>
+							</view>
+						</view>
+					</view>
+					<view class="cont" v-if="cardObj.qq" @click="onCopy(cardObj.qq)">
+						<view class="box">
+							<u-icon name="qq-fill" color="#007AFF" size="40"> </u-icon>
+							<view class="right">
+								<text class="tit">QQ</text>
+								<text>{{cardObj.qq}}</text>
+							</view>
+						</view>
+					</view>
+					<view class="cont" v-if="cardObj.email" @click="onCopy(cardObj.email)">
+						<view class="box">
+							<u-icon name="email-fill" color="#007AFF" size="40"> </u-icon>
+							<view class="right">
+								<text class="tit">邮箱</text>
+								<text>{{cardObj.email}}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="top-maina">
+				<button class="left" @click="onAdd()">
+					同步到通讯录
+				</button>
+				<button class="right" open-type="share">
+					分享名片
+				</button>
+			</view>
+			<view class="top-mainc">
+				<view class="left">
+					<u-avatar-group :urls="headerList" size="35" gap="0.4" :default-url="headerImg" randomBgColor>
+					</u-avatar-group>
+					<text>{{visitorCount}}人浏览</text>
+				</view>
+			</view>
+			<view class="top-main-tit">
+				<u-icon name="file-text-fill" color="#007AFF" size="40"> </u-icon>
+				<text>业务介绍</text>
+			</view>
+			<view class="top-maind">
+				<view class="topmain">
+					<view class="leftimg">
+						<u-avatar size="60" :src="cardObj.head_img" shape="square"></u-avatar>
+					</view>
+					<view class="rightcont">
+						<view class="name" v-if="!cardObj.intro">Hi~欢迎访问我的名片,了解更多内容请直接咨询我。</view>
+						<view class="name" v-if="cardObj.intro">{{cardObj.intro}}</view>
+					</view>
+				</view>
+			</view>
+
+		</view>
+		<view class="bottom-block"></view>
+		<view class="bottombtn" type="primary" @click="gotoEdit">编辑我的名片</view>
+	</view>
+</template>
+
+<script>
+	import {
+		request
+	} from '@/common/js/request'
+	export default {
+		data() {
+			return {
+				id: "",
+				headerImg: "/static/images/userimg.png",
+				cardObj: {},
+				visitorList: [],
+				visitorCount: 0,
+				headerList: []
+			}
+		},
+		async onShow(options) {
+			console.log("onLoad options", options);
+			const logged = uni.getStorageSync('logged');
+			if (logged) {
+				var id = uni.getStorageSync('id');
+				var user = uni.getStorageSync('userInfo');
+				if (id != null && id != "") {
+					this.id = id;
+					const card = await request('uni-card', 'getCard', {
+						id: id,
+						uid: user.id
+					}, {
+						showloading: true
+					});
+					if (card._id == "") {
+						this.getDefault();
+					} else {
+						const visitorList = await request('uni-card', 'getVisitorList', {
+							card_id: id,
+							skip: 0,
+							limit: 8
+						}, {
+							showloading: true
+						});
+						this.cardObj = card;
+						this.visitorCount = visitorList.total;
+						visitorList.items.forEach((arr, index) => {
+							if (arr.head_img)
+								this.headerList.push(arr.head_img)
+							else
+								this.headerList.push("/static/images/userimg.png")
+						})
+					}
+				} else {
+					const mycard = await request('uni-card', 'getMyCard', {
+						uid: user.id
+					}, {
+						showloading: true
+					});
+					if (mycard._id == "") {
+						this.getDefault();
+					} else {
+						const myVisitorList = await request('uni-card', 'getMyVisitorList', {
+							uid: user.id,
+							skip: 0,
+							limit: 8
+						}, {
+							showloading: true
+						});
+						this.cardObj = mycard;
+						this.visitorCount = myVisitorList.total;
+						myVisitorList.items.forEach((arr, index) => {
+							if (arr.head_img)
+								this.headerList.push(arr.head_img)
+							else
+								this.headerList.push("/static/images/userimg.png")
+						})
+					}
+				}
+			}
+		},
+		onShareAppMessage(res) {
+			if (this.id == "" || this.id == null) {
+				this.id = "61b30b8091a7500001dea375"
+			}
+			return {
+				title: '您好,这是我的名片,望惠存',
+				path: '/pages/index?id=' + this.id
+			}
+		},
+		methods: {
+			async getDefault() {
+				const card = await request('uni-card', 'getCard', {
+					id: "61b30b8091a7500001dea375",
+					uid: "61b30b4e7964120001e32f41"
+				}, {
+					showloading: true
+				});
+				if (card._id == "") {
+					this.gotoEdit();
+				}
+				const visitorList = await request('uni-card', 'getVisitorList', {
+					card_id: "61b30b8091a7500001dea375",
+					skip: 0,
+					limit: 8
+				}, {
+					showloading: true
+				});
+				this.cardObj = card;
+				this.visitorCount = visitorList.total;
+				visitorList.items.forEach((arr, index) => {
+					if (arr.head_img)
+						this.headerList.push(arr.head_img)
+					else
+						this.headerList.push("/static/images/userimg.png")
+				})
+			},
+			onAdd() {
+				uni.addPhoneContact({
+					organization: this.cardObj.company,
+					firstName: this.cardObj.name,
+					title: this.cardObj.job,
+					email: this.cardObj.email,
+					mobilePhoneNumber: this.cardObj.phone,
+					weChatNumber: this.cardObj.wechat,
+					remark: this.cardObj.address,
+					success: function() {
+						console.log('success');
+					},
+					fail: function() {
+						console.log('fail');
+					}
+				});
+			},
+			onPhone() {
+				uni.makePhoneCall({
+					phoneNumber: this.cardObj.phone,
+					success: (res) => {
+						console.log('调用成功!')
+					},
+					fail: (res) => {
+						console.log('调用失败!')
+					}
+				})
+			},
+			onCopy(data) {
+				uni.setClipboardData({
+					data: data, //要被复制的内容
+					success: function() {
+						//重点~做笔记
+						//在success中加入uni.hideToast()可以解决
+						uni.showToast({
+							title: '复制成功',
+							duration: 2000,
+							icon: 'none'
+						});
+						//以下就可自定义操作了~
+					},
+					fail: function(err) {
+						uni.showToast({
+							title: '复制失败',
+							duration: 2000,
+							icon: 'none'
+						});
+					}
+				});
+			},
+			gotoEdit() {
+				uni.navigateTo({
+					url: "/pages/edit"
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #f7f7f7;
+	}
+
+	.content {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.content-box {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 0 5%;
+	}
+
+	.content-box .top-main-box {
+		width: 100%;
+		box-sizing: border-box;
+		border-radius: 15rpx;
+		height: 52vw;
+		overflow: hidden;
+		position: relative;
+		box-shadow: 0px 0px 10px #cccccc;
+	}
+
+	.content-box .top-main-box .zzbg {
+		width: 100%;
+		position: absolute;
+		top: 0;
+		left: 0;
+		background: rgba(139, 139, 139, 0.5);
+		z-index: 1;
+	}
+
+	.content-box .top-main-box .mpimg {
+		width: 100%;
+	}
+
+	.content-box .top-main-box .topmain {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 40rpx 5%;
+		display: flex;
+		align-items: flex-start;
+		position: relative;
+		z-index: 4;
+	}
+
+	.content-box .top-main-box .topmain .leftimg {
+		width: 150rpx;
+		height: 150rpx;
+		border-radius: 15rpx;
+		overflow: hidden;
+	}
+
+	.content-box .top-main-box .topmain .leftimg .tximg {
+		width: 100%;
+	}
+
+	.content-box .top-main-box .topmain .rightcont {
+		color: #fff;
+		flex: 1;
+		box-sizing: border-box;
+		padding-left: 25rpx;
+	}
+
+	.content-box .top-main-box .topmain .rightcont .name {
+		font-size: 42rpx;
+		padding-bottom: 10rpx;
+	}
+
+	.content-box .top-main-box .topmain .rightcont .tip,
+	.content-box .top-main-box .topmain .rightcont .tipa {
+		font-size: 34rpx;
+		text-shadow: 1px 1px 1px #000;
+	}
+
+	.content-box .top-main-box .btnmain {
+		width: 100%;
+		position: absolute;
+		left: 0;
+		bottom: 0px;
+		z-index: 5;
+		box-sizing: border-box;
+		padding: 25rpx 5%;
+		background: #fff;
+		display: inline;
+		align-items: center;
+		justify-content: space-between;
+		text-align: left;
+	}
+
+	.content-box .top-main-box .btnmain view {
+		float: left;
+	}
+
+	.content-box .top-main-box .btnmain text {
+		font-size: 24rpx;
+		color: #333333;
+		padding-left: 10rpx;
+		float: left;
+	}
+
+	.content-box .top-maina {
+		width: 100%;
+		box-sizing: border-box;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		margin: 20rpx auto;
+	}
+
+	.content-box .top-maina view {
+		width: 48%;
+		border-radius: 15rpx;
+		text-align: center;
+		padding: 25rpx 0;
+		font-size: 18px;
+	}
+
+	.content-box .top-maina .left {
+		border: 1px solid #007AFF;
+		color: #007AFF;
+		width: 48%;
+	}
+
+	.content-box .top-maina .right {
+		background: #007AFF;
+		border: 1px solid #007AFF;
+		color: #fff;
+		width: 48%;
+	}
+
+	.content-box .top-mainb {
+		width: 100%;
+		overflow: scroll;
+		padding: 15rpx 0;
+		overflow-x: hidden;
+	}
+
+	.content-box .top-mainb .conta {
+		width: 100%;
+		overflow-x: auto;
+		word-break: keep-all;
+		/* 不换行 */
+		white-space: nowrap;
+		/* 不换行 */
+		padding-bottom: 20rpx;
+	}
+
+	.content-box .top-mainb .conta .cont {
+		display: inline-block;
+		margin-right: 20rpx;
+		background: #fff;
+		box-shadow: 0px 0px 8px #cccccc;
+		border-radius: 10rpx;
+		overflow: hidden;
+	}
+
+	.content-box .top-mainb .conta .cont .box {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		box-sizing: border-box;
+		padding: 15rpx 20rpx;
+	}
+
+	.content-box .top-mainb .conta .cont .box image {
+		width: 80rpx;
+		height: 80rpx;
+	}
+
+	.content-box .top-mainb .conta .cont .box .right {
+		flex: 1;
+		box-sizing: border-box;
+		padding-left: 10rpx;
+	}
+
+	.content-box .top-mainb .conta .cont .box .right text {
+		display: block;
+		font-size: 30rpx;
+	}
+
+	.content-box .top-mainb .conta .cont .box .right .tit {
+		font-size: 34rpx;
+	}
+
+	.content-box .top-mainc {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 20rpx 10rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		margin: 10rpx auto;
+		background: #fff;
+	}
+
+	.content-box .top-mainc .left {
+		flex: 1;
+		display: flex;
+		align-items: center;
+	}
+
+	.content-box .top-mainc .left text {
+		font-size: 28rpx;
+		color: #555555;
+	}
+
+	.content-box .top-mainc .left image {
+		width: 60rpx;
+		height: 60rpx;
+		margin-right: 5rpx;
+		border-radius: 10rpx;
+	}
+
+	.content-box .top-mainc .right {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.content-box .top-mainc .right text {
+		font-size: 28rpx;
+		color: #555555;
+		padding-right: 10rpx;
+	}
+
+	.content-box .top-mainc .right image {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.content-box .top-main-tit {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 20rpx 10rpx;
+		display: flex;
+		align-items: center;
+	}
+
+	.content-box .top-main-tit image {
+		width: 60rpx;
+		height: 60rpx;
+	}
+
+	.content-box .top-main-tit text {
+		color: #333;
+		font-size: 18px;
+		padding-left: 10rpx;
+	}
+
+	.content-box .top-maind {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 40rpx 5%;
+		background: #fff;
+		box-shadow: 0px 0px 8px #cccccc;
+	}
+
+	.content-box .top-maind .topmain {
+		width: 100%;
+		box-sizing: border-box;
+		display: flex;
+		align-items: flex-start;
+	}
+
+	.content-box .top-maind .topmain .leftimg {
+		width: 120rpx;
+		height: 120rpx;
+		border-radius: 15rpx;
+		overflow: hidden;
+	}
+
+	.content-box .top-maind .topmain .leftimg .tximg {
+		width: 100%;
+	}
+
+	.content-box .top-maind .topmain .rightcont {
+		color: #555;
+		flex: 1;
+		box-sizing: border-box;
+		padding-left: 25rpx;
+		line-height: 42rpx;
+		font-size: 28rpx;
+	}
+
+	.content-box .top-maind .toptip {
+		width: 100%;
+	}
+
+	.content-box .top-maind .toptip .box {
+		display: inline-block;
+		margin-top: 25rpx;
+		padding: 10rpx 15rpx;
+		background: #e6e6e6;
+		border-radius: 10rpx;
+		overflow: hidden;
+		margin-right: 20rpx;
+	}
+
+	.content-box .top-maind .toptip .box image {
+		width: 30rpx;
+		height: 30rpx;
+	}
+
+	.content-box .top-maind .toptip .box text {
+		font-size: 28rpx;
+		padding-left: 10rpx;
+	}
+
+	.bottombtn {
+		position: fixed;
+		bottom: 0;
+		width: 100%;
+		height: 60px;
+		background: #007AFF;
+		color: #fff;
+		line-height: 60px;
+		text-align: center;
+	}
+
+	.bottom-block {
+		display: block;
+		width: 100%;
+		height: 80px;
+	}
+</style>

+ 135 - 0
pages/login.vue

@@ -0,0 +1,135 @@
+<template>
+	<view>
+		<view class="login-main">
+			<image class="user" src="/static/images/userimg.png"></image>
+			<view class="name">你好 </view>
+			<view class="tip">为了您的最佳体验,请登录</view>
+		</view>
+
+		<button class="lgin-btn" open-type="getUserInfo" lang="zh_CN" withCredentials="true" @getuserinfo="mpWxLogin">
+			<image src="/static/images/wxa.png"></image>
+			<view class="text">微信一键登录</view>
+		</button>
+	</view>
+</template>
+
+<script>
+	import {
+		request
+	} from '@/common/js/request'
+	export default {
+		name: "",
+		data() {
+			return {
+				logged: uni.getStorageSync("logged"),
+			}
+		},
+		onLoad() {
+
+		},
+		methods: {
+			async mpWxLogin(userInfoData) {
+				console.log("登陆")
+				await this.mpWxGetUserInfo(userInfoData)
+				this.$util.msg('登陆成功');
+				this.logged = true;
+				await uni.setStorageSync("logged", true)
+				uni.navigateTo({
+					url: "/pages/index"
+				})
+			},
+			// 获取用户信息
+			async mpWxGetUserInfo(userInfoData) {
+				return new Promise((resolve, reject) => {
+					if (!userInfoData.detail.userInfo) {
+						reject(new Error('未拿到用户信息'))
+					}
+					this.$util.throttle(async () => {
+						const [loginErr, loginData] = await uni.login({
+							provider: 'weixin'
+						})
+						const [err, userData] = await uni.getUserInfo();
+						const res = await request('uni-card', 'loginByWx', {
+							code: loginData.code,
+							encryptedData: userData.encryptedData,
+							iv: userData.iv
+						}, {
+							showLoading: true
+						});
+						console.log("res", res)
+						resolve(res)
+					})
+				}).then(async userInfo => {
+					console.log("mpWxGetUserInfo", userInfo)
+					this.$store.dispatch('setUserData', userInfo);
+					await uni.setStorageSync("userInfo", userInfo);
+					return userInfo
+				})
+			},
+		}
+	}
+</script>
+<style>
+	page {
+		background: #fff;
+	}
+</style>
+<style scoped>
+	.login-main {
+		width: 100%;
+		padding-top: 200rpx;
+	}
+
+	.login-main .user {
+		width: 180rpx;
+		height: 180rpx;
+		margin: 0 auto;
+		display: block;
+	}
+
+	.login-main .name {
+		text-align: center;
+		font-size: 40rpx;
+	}
+
+	.login-main .name text {
+		padding: 0 0 0 20rpx;
+	}
+
+	.login-main .tip {
+		color: #999;
+		padding: .9em 0;
+		text-align: center;
+		padding-bottom: 50rpx;
+	}
+
+	.lgin-btn {
+		width: 80%;
+		margin: 0 auto;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		background: #DBA871;
+		border-radius: 10rpx;
+		padding: 15rpx 0;
+	}
+
+	.lgin-btn image {
+		width: 50rpx;
+		height: 50rpx;
+		display: block;
+	}
+
+	.lgin-btn .text {
+		color: #fff;
+		font-size: 32rpx;
+		padding-left: 10rpx;
+	}
+
+	.lgin-tip {
+		color: #DBA871;
+		text-align: center;
+		padding: 20rpx 0;
+		font-size: 28rpx;
+	}
+</style>

二進制
static/images/mpbg1.jpg


二進制
static/images/userimg.png


二進制
static/images/wxa.png


+ 52 - 0
store/index.js

@@ -0,0 +1,52 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+	state: {
+		userInfo: {}
+	},
+	getters: {
+		userId(state) {
+			return state.userInfo.id || null;
+		}
+	},
+	mutations: {
+		//更新state数据
+		setStateAttr(state, param) {
+			if (param instanceof Array) {
+				for (let item of param) {
+					state[item.key] = item.val;
+				}
+			} else {
+				state[param.key] = param.val;
+			}
+		}
+	},
+	actions: {
+		async setUserData({
+			state,
+			commit
+		}, data) {
+			commit('setStateAttr', {
+				key: 'userInfo',
+				val: data
+			})
+			uni.setStorageSync('userInfo', data);
+		},
+		logout({
+			state,
+			commit
+		}) {
+			commit('setStateAttr', {
+				key: 'userInfo',
+				val: {}
+			})
+			uni.removeStorageSync('userInfo');
+		}
+	}
+})
+
+
+export default store

+ 69 - 0
uni-starter.config.js

@@ -0,0 +1,69 @@
+//这是应用的配置页面,App.vue挂载到getApp().globalData.config
+module.exports = {
+	"h5": {
+		"url": "https://uni-card.dcloud.net.cn/", //	前端网页托管的域名
+		 // 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改
+		"openApp": {
+			//点击悬浮下载栏后打开的网页链接
+			"openUrl": '/#/pages/ucenter/invite/invite',
+			//左侧显示的应用名称
+			"appname": 'uni-card',
+			//应用的图标
+			"logo": './static/logo.png',
+		}
+	},
+	"mp": {
+		"weixin": {
+			//微信小程序原始id,微信小程序分享时
+			"id": "gh_33446d7f7a26"
+		}
+	},
+	"router": {
+		//needLogin:配置强制需要登陆的页面,在打开这些页面之前会自动检查(前端校验)uni_id_token的值是否有效,如果无效会自动跳转到登陆页面
+		"needLogin": [
+			"/pages/ucenter/userinfo/userinfo",
+			"/uni_modules/uni-news-favorite/pages/uni-news-favorite/list",
+			"/uni_modules/uni-feedback/pages/uni-feedback/add"
+		],
+		/*
+		login:配置登陆类型与优先级
+			未列举到的,或设备环境不支持的选项,将被隐藏。如果你需要在不同平台有不同的配置,直接用条件编译即可
+			根据数组的第0项,决定登录方式的第一优先级。
+		*/
+		"login": ["username","smsCode","univerify", "weixin", "apple"],
+	},
+	//关于应用
+	"about": {
+		//应用名称
+		"appName": "uni-card",
+		//应用logo
+		"logo": "/static/logo.png",
+		//公司名称
+		"company": "常熟市畅享计算机信息技术有限公司",
+		//口号
+		"slogan": "云端一体应用快速开发模版",
+		//政策协议
+		"agreements": [{
+				"title": "用户服务协议", //协议名称
+				"url": "https://ask.dcloud.net.cn/protocol.html" //对应的网络链接
+			},
+			{
+				"title": "隐私政策",
+				"url": "https://ask.dcloud.net.cn/protocol.html"
+			}
+		],
+		//应用的链接,用于分享到第三方平台和生成关于我们页的二维码
+		"download": "https://m3w.cn/uniapp",
+		//version
+		"version":"1.0.0" //用于非app端显示,app端自动获取
+	},
+	"download":{ //用于生成二合一下载页面
+		"ios":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253?mt=8",
+		"android":"https://vkceyugu.cdn.bspapp.com/VKCEYUGU-97fca9f2-41f6-449f-a35e-3f135d4c3875/6d754387-a6c3-48ed-8ad2-e8f39b40fc01.apk"
+	},
+	//用于打开应用市场评分界面
+	"marketId":{
+		"ios":"id1417078253",
+		"android":"123456"
+	}
+}

+ 77 - 0
uni.scss

@@ -0,0 +1,77 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:24rpx;
+$uni-font-size-base:28rpx;
+$uni-font-size-lg:32rpx;
+
+/* 图片尺寸 */
+$uni-img-size-sm:40rpx;
+$uni-img-size-base:52rpx;
+$uni-img-size-lg:80rpx;
+
+/* Border Radius */
+$uni-border-radius-sm: 4rpx;
+$uni-border-radius-base: 6rpx;
+$uni-border-radius-lg: 12rpx;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 10px;
+$uni-spacing-row-base: 20rpx;
+$uni-spacing-row-lg: 30rpx;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 8rpx;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 24rpx;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:40rpx;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:36rpx;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:30rpx;
+@import 'uview-ui/theme.scss';

+ 198 - 0
uniCloud-aliyun/cloudfunctions/common/wx-auth/index.js

@@ -0,0 +1,198 @@
+'use strict';
+/**
+ * 微信相关业务
+ */
+const wxConfigMp = {
+	appId: 'wxe920d4492b51c1ef',
+	secret: '1b01ea7c449392739c693ed8f460beda'
+}
+
+const crypto = require('crypto')
+
+/**
+ * 微信小程序授权登录获取session_key
+ * @param {Object} options
+ * @param {String} options.code 小程序code
+ *
+ * @param {String} options.encryptedData 可选,存在encryptedData和iv时返回用户信息(包含unionid)
+ * @param {String} options.iv 可选
+ */
+const mpWxGetSessionKey = async options => {
+	const {
+		code,
+		encryptedData,
+		iv
+	} = options;
+	const {
+		appId,
+		secret
+	} = wxConfigMp;
+
+	let url = 'https://api.weixin.qq.com/sns/jscode2session';
+	url += '?appid=' + appId;
+	url += '&secret=' + secret;
+	url += '&js_code=' + code + '&grant_type=authorization_code';
+	const res = await uniCloud.httpclient.request(url, {
+		method: 'GET',
+		dataType: 'json'
+	})
+
+	const data = res.res.data;
+	if (data.errcode) {
+		return {
+			status: 0,
+			msg: 'appid错误',
+			data,
+			appId
+		}
+	}
+	if (!data.session_key) {
+		return {
+			status: 0,
+			msg: '获取微信授权失败',
+			data
+		}
+	}
+	if (!encryptedData || !iv) {
+		return {
+			status: 1,
+			openid: data.openid,
+			session_key: data.session_key
+		}
+	}
+	const userInfo = WXBizDataCrypt({
+		sessionKey: data.session_key,
+		encryptedData,
+		iv
+	})
+	return {
+		status: 1,
+		session_key: data.session_key,
+		userInfo
+	}
+}
+
+/**
+ * 微信小程序授权登录获取session_key
+ * @param {Object} options
+ * @param {String} options.code 小程序code
+ *
+ * @param {String} options.encryptedData 可选,存在encryptedData和iv时返回用户信息(包含unionid)
+ * @param {String} options.iv 可选
+ */
+const mpWxGetPhoneNo = async options => {
+	const {
+		sessionKey,
+		encryptedData,
+		iv
+	} = options;
+	const userInfo = WXBizDataCrypt({
+		sessionKey: sessionKey,
+		encryptedData: encryptedData,
+		iv: iv
+	})
+	return {
+		userInfo
+	}
+}
+
+/**
+ * 解密encryptedData 获取unionid
+ * @param {Object} options
+ * @param {String} options.sessionKey
+ * @param {String} options.encryptedData
+ * @param {String} options.iv
+ */
+const WXBizDataCrypt = options => {
+	const appId = wxConfigMp.appId;
+	let {
+		sessionKey,
+		encryptedData,
+		iv
+	} = options;
+	console.log("sessionKey", sessionKey)
+	console.log("encryptedData", encryptedData)
+	console.log("iv", iv)
+	sessionKey = new Buffer(sessionKey, 'base64')
+	encryptedData = new Buffer(encryptedData, 'base64')
+	iv = new Buffer(iv, 'base64')
+
+	let decoded;
+	try {
+		// 解密
+		let decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
+		// 设置自动 padding 为 true,删除填充补位
+		decipher.setAutoPadding(true)
+		decoded = decipher.update(encryptedData, 'binary', 'utf8')
+		decoded += decipher.final('utf8')
+		decoded = JSON.parse(decoded)
+	} catch (err) {
+		throw new Error('Illegal Buffer')
+	}
+	if (decoded.watermark.appid !== appId) {
+		throw new Error('Illegal Buffer')
+	}
+	return decoded
+}
+const getWxConfigPart = async options => {
+	const {
+		data
+	} = options;
+	const {
+		appId,
+		secret
+	} = wxConfigMp;
+
+	const res0 = await uniCloud.httpclient.request(
+		"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" +
+		appSecret, {
+			method: 'GET',
+			data: {},
+			contentType: 'json', // 指定以application/json发送data内的数据
+			dataType: 'json' // 指定返回值为json格式,自动进行parse
+		})
+	var access_token = res0.data.access_token;
+	const res = await uniCloud.httpclient.request(
+		"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi", {
+			method: 'GET',
+			data: {},
+			contentType: 'json', // 指定以application/json发送data内的数据
+			dataType: 'json' // 指定返回值为json格式,自动进行parse
+		})
+	var jsapiticket = res.data.ticket;
+	var timestamp = new Date().getTime();
+	var url = data.url;
+	/****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
+	var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
+	var maxLen = $chars.length;
+	var noncestr = '';
+	for (var i = 0; i < 32; i++) {
+		noncestr += $chars.charAt(Math.floor(Math.random() * maxLen));
+	}
+	var str = "jsapi_ticket=" + jsapiticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" +
+		url;
+	var signature = sha1(str);
+	
+	console.log("签名=========", {
+		appId: appId,
+		timestamp: timestamp,
+		noncestr: noncestr,
+		signature: signature,
+		jsapiticket: jsapiticket
+	});
+	return {
+		code: 200,
+		data: {
+			appId: appId,
+			timestamp: timestamp,
+			noncestr: noncestr,
+			signature: signature,
+			jsapiticket: jsapiticket
+		}
+	}
+}
+module.exports = {
+	mpWxGetSessionKey,
+	mpWxGetPhoneNo,
+	getWxConfigPart
+}

+ 12 - 0
uniCloud-aliyun/cloudfunctions/common/wx-auth/package.json

@@ -0,0 +1,12 @@
+{
+  "name": "wx-auth",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC"
+}

+ 49 - 0
uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js

@@ -0,0 +1,49 @@
+'use strict';
+exports.main = async (event, context) => {
+	/**
+	 * 根据搜索记录,设定时间间隔来归纳出热搜数据并存储在热搜表中
+	 */
+	const SEARCHHOT = 'opendb-search-hot'; // 热搜数据库名称
+	const SEARCHLOG = 'opendb-search-log'; // 搜索记录数据库名称
+	const SEARCHLOG_timeZone = 604800000; // 归纳搜索记录时间间隔,毫秒数,默认为最近7天
+	const SEARCHHOT_size = 10; //	热搜条数
+
+	const DB = uniCloud.database();
+	const DBCmd = DB.command;
+	const $ = DB.command.aggregate;
+	const SEARCHHOT_db = DB.collection(SEARCHHOT);
+	const SEARCHLOG_db = DB.collection(SEARCHLOG);
+	const timeEnd = Date.now() - SEARCHLOG_timeZone;
+
+	let {
+		data: searchHotData
+	} = await SEARCHLOG_db
+		.aggregate()
+		.match({
+			create_date: DBCmd.gt(timeEnd)
+		})
+		.group({
+			_id: {
+				'content': '$content',
+			},
+			count: $.sum(1)
+		})
+		.replaceRoot({
+			newRoot: $.mergeObjects(['$_id', '$$ROOT'])
+		})
+		.project({
+			_id: false
+		})
+		.sort({
+			count: -1
+		})
+		.end();
+
+	let now = Date.now();
+	searchHotData.map(item => {
+		item.create_date = now;
+		return item;
+	}).slice(0, SEARCHHOT_size);
+	// searchHotData = searchHotData.sort((a, b) => b.count - a.count).slice(0, SEARCHHOT_size);
+	return searchHotData.length ? await SEARCHHOT_db.add(searchHotData) : ''
+};

+ 14 - 0
uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json

@@ -0,0 +1,14 @@
+{
+	"name": "uni-analyse-searchhot",
+	"version": "1.0.0",
+	"description": "定时归纳热搜",
+	"main": "index.js",
+	"dependencies": {},
+	"cloudfunction-config": {
+		"triggers": [{
+			"name": "analyse-searchHot",
+			"type": "timer",
+			"config": "0 0 */2 * * * *"
+		}]
+	}
+}

+ 358 - 0
uniCloud-aliyun/cloudfunctions/uni-card/index.js

@@ -0,0 +1,358 @@
+'use strict';
+const {
+	mpWxGetSessionKey,
+	mpWxGetPhoneNo
+} = require('wx-auth')
+const moment = require('moment');
+const db = uniCloud.database();
+const dbCmd = db.command
+const $ = dbCmd.aggregate
+const cardCollection = db.collection('card')
+const visitorCollection = db.collection('visitor')
+const userCollection = db.collection('user');
+let uniID = require('uni-id')
+const createConfig = require('uni-config-center')
+const uniIdConfig = createConfig({
+	pluginId: 'uni-id'
+}).config()
+exports.main = async (event, context) => {
+	uniID = uniID.createInstance({
+		context
+	})
+	console.log('event : ' + JSON.stringify(event))
+	const {
+		operation,
+		data
+	} = event;
+	try {
+		console.log('operation : ' + operation)
+		switch (operation) {
+			case "getInfo": {
+				return true;
+			}
+			case "loginByWx": {
+				return await loginByWx(data);
+			}
+			case "getWxConfigPart": {
+				return await getWxConfigPart(data);
+			}
+			case "getPhoneByWeixin": {
+				return await getPhoneByWeixin(data);
+			}
+			case "bindPhone": {
+				return await bindPhone(data);
+			}
+			case "getCard": {
+				return await getCard(data);
+			}
+			case "getMyCard": {
+				return await getMyCard(data);
+			}
+			case "saveCard": {
+				return await saveCard(data);
+			}
+			case "getVisitorList": {
+				return await getVisitorList(data);
+			}
+			case "getMyVisitorList": {
+				return await getMyVisitorList(data);
+			}
+			default: {
+				throw new Error("未找到接口")
+			}
+		}
+	} catch (e) {
+		var msg = e.toString().replace("Error: ", "")
+		console.log("出错了", msg)
+		return {
+			code: 50101,
+			msg: msg
+		};
+	}
+
+};
+/**
+ * 绑定手机
+ */
+async function bindPhone() {
+	var user = await userCollection.where({
+		_id: data.user_id
+	}).get();
+	if (user.data.length == 0)
+		throw new Error("用户不存在")
+	await userCollection.doc(data.user_id).update({
+		phone: data.phone
+	});
+}
+/**
+ * 获取名片
+ */
+async function getCard(data) {
+	var user = await userCollection.where({
+		_id: data.uid
+	}).get();
+	if (user.data.length == 0)
+		throw new Error("用户不存在")
+	var card = await cardCollection.where({
+			_id: data.id
+		})
+		.get();
+	if (card.data.length == 0) {
+		return {
+			code: 200,
+			data: {
+				name: "",
+				phone: "",
+				job: "",
+				company: "",
+				head_img: "",
+				address: "",
+				phone: "",
+				wechat: "",
+				qq: "",
+				email: "",
+				intro: "",
+				_id: ""
+			}
+		}
+	}
+	
+	var visitors = await visitorCollection.where({
+		uid: user.data[0]._id,
+		card_id: data.id
+	}).get();
+	if (visitors.data.length == 0) {
+		var visitor = {
+			card_id: data.id,
+			uid: user.data[0]._id,
+			name: user.data[0].nickName,
+			head_img: user.data[0].avatar,
+			phone: user.data[0].phone
+		};
+		var res = await visitorCollection.add(visitor);
+	}
+
+	return {
+		code: 200,
+		data: card.data[0]
+	};
+}
+/**
+ * 获取名片
+ */
+async function getMyCard(data) {
+	var user = await userCollection.where({
+		_id: data.uid
+	}).get();
+	if (user.data.length == 0) {
+		throw new Error("用户不存在")
+	}
+	var card = await cardCollection.where({
+			uid: data.uid
+		})
+		.get();
+	if (card.data.length == 0) {
+		return {
+			code: 200,
+			data: {
+				name: "",
+				phone: "",
+				job: "",
+				company: "",
+				head_img: "",
+				address: "",
+				phone: "",
+				wechat: "",
+				qq: "",
+				email: "",
+				intro: "",
+				_id: ""
+			}
+		}
+	}
+	return {
+		code: 200,
+		data: card.data[0]
+	};
+}
+/**
+ * 提交名片
+ */
+async function saveCard(data) {
+	const now = Date.now()
+	if (data.length == 0) {
+		throw new Error("请勿提交空内容");
+	}
+	var id = "";
+	var user = await userCollection.where({
+		_id: data.uid
+	}).get();
+	if (user.data.length == 0)
+		throw new Error("用户不存在")
+	var card = await cardCollection.where({
+			uid: user.data[0]._id
+		})
+		.get();
+	if (data.name == "") {
+		throw new Error("请填写姓名");
+	}
+	if (data.phone == "") {
+		throw new Error("请填写手机号");
+	}
+	if (card.data.length == 0) {
+		data.uid = user.data[0]._id;
+		data.create_time = now;
+		var res = await cardCollection.add(data);
+		console.log("cardCollection.add",res)
+		id = res.id;
+	} else {
+		await cardCollection.doc(card.data[0]._id).update({
+			name: data.name,
+			phone: data.phone,
+			job: data.job,
+			company: data.company,
+			head_img: data.head_img,
+			address: data.address,
+			phone: data.phone,
+			wechat: data.wechat,
+			qq: data.qq,
+			email: data.email,
+			intro: data.intro,
+			create_time: now
+		});
+		id = card.data[0]._id;
+	}
+	return {
+		code: 200,
+		data: {
+			id: id
+		}
+	};
+}
+/**
+ * 获取浏览列表
+ */
+async function getVisitorList(data, token, deviceId) {
+	const now = Date.now()
+	var total = await visitorCollection.where({
+		card_id: dbCmd.eq(data.card_id)
+	}).count();
+	var res = await visitorCollection.where({
+			card_id: dbCmd.eq(data.card_id)
+		})
+		.orderBy('create_time', 'desc')
+		.skip(data.skip)
+		.limit(data.limit)
+		.get();
+	return {
+		code: 200,
+		data: {
+			total: total.total,
+			items: res.data
+		}
+	};
+}
+/**
+ * 获取浏览列表
+ */
+async function getMyVisitorList(data, token, deviceId) {
+	const now = Date.now()
+	var total = await visitorCollection.where({
+		card_id: dbCmd.eq(data.uid)
+	}).count();
+	var res = await visitorCollection.where({
+			card_id: dbCmd.eq(data.uid)
+		})
+		.orderBy('create_time', 'desc')
+		.skip(data.skip)
+		.limit(data.limit)
+		.get();
+	return {
+		code: 200,
+		data: {
+			total: total.total,
+			items: res.data
+		}
+	};
+}
+// 通过微信登录
+async function loginByWx(data) {
+	// 获取openid
+	const wxUser = await mpWxGetSessionKey(data)
+	console.log("wxUser", wxUser)
+	if (wxUser.status == 0) {
+		throw new Error(wxUser.msg)
+	}
+	// 通过openid查库里的数据
+	const result = await userCollection.where({
+		openId: wxUser.userInfo.openId
+	}).get()
+	let id = null;
+	console.log("result", result.data[0])
+	const now = moment().format('YYYY-MM-DD HH:mm:ss');
+	// 如果已经有了,则更新库里的信息
+	if (result.data.length > 0) {
+		let user = result.data[0]
+		const r = await userCollection.doc(user._id).update({
+			nickName: wxUser.userInfo.nickName,
+			gender: wxUser.userInfo.gender,
+			avatar: wxUser.userInfo.avatar,
+			city: wxUser.userInfo.city,
+			language: wxUser.userInfo.language,
+			updateTime: now
+		})
+		return {
+			code: 200,
+			data: {
+				id: user._id,
+				nickName: wxUser.userInfo.nickName,
+				gender: wxUser.userInfo.gender,
+				avatar: wxUser.userInfo.avatar,
+				city: wxUser.userInfo.city,
+				language: wxUser.userInfo.language,
+				sessionKey: wxUser.session_key
+			}
+		};
+	} else {
+		// 若没有,则插入该用户数据
+		const r = await userCollection.add({
+			nickName: wxUser.userInfo.nickName,
+			gender: wxUser.userInfo.gender,
+			avatar: wxUser.userInfo.avatar,
+			openId: wxUser.userInfo.openId,
+			avatar: wxUser.userInfo.avatar,
+			city: wxUser.userInfo.city,
+			language: wxUser.userInfo.language,
+			createTime: now,
+			updateTime: now
+		})
+		return {
+			code: 200,
+			data: {
+				id: r.id,
+				nickName: wxUser.userInfo.nickName,
+				openId: wxUser.userInfo.openId,
+				gender: wxUser.userInfo.gender,
+				avatar: wxUser.userInfo.avatar,
+				city: wxUser.userInfo.city,
+				language: wxUser.userInfo.language,
+				sessionKey: wxUser.session_key
+			}
+		}
+	}
+}
+//获取微信授权手机号码
+async function getPhoneByWeixin(data) {
+	var res = await mpWxGetPhoneNo(data);
+	return {
+		code: 200,
+		data: res
+	}
+}
+async function getWxConfigPart(data) {
+	var res = await getWxConfigPart(data);
+	return {
+		code: 200,
+		data: res
+	}
+}

+ 970 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/CHANGELOG.md

@@ -0,0 +1,970 @@
+Changelog
+=========
+
+### 2.29.1 [See full changelog](https://gist.github.com/marwahaha/cc478ba01a1292ab4bd4e861d164d99b)
+
+* Release Oct 6, 2020
+
+Updated deprecation message, bugfix in hi locale
+
+### 2.29.0 [See full changelog](https://gist.github.com/marwahaha/b0111718641a6461800066549957ec14)
+
+* Release Sept 22, 2020
+
+New locales (es-mx, bn-bd).
+Minor bugfixes and locale improvements.
+More tests.
+Moment is in maintenance mode. Read more at this link:
+https://momentjs.com/docs/#/-project-status/
+
+### 2.28.0 [See full changelog](https://gist.github.com/marwahaha/028fd6c2b2470b2804857cfd63c0e94f)
+
+* Release Sept 13, 2020
+
+Fix bug where .format() modifies original instance, and locale updates
+
+### 2.27.0 [See full changelog](https://gist.github.com/marwahaha/5100c9c2f42019067b1f6cefc333daa7)
+
+* Release June 18, 2020
+
+Added Turkmen locale, other locale improvements, slight TypeScript fixes
+
+### 2.26.0 [See full changelog](https://gist.github.com/marwahaha/0725c40740560854a849b096ea7b7590)
+
+* Release May 19, 2020
+
+TypeScript fixes and many locale improvements
+
+### 2.25.3
+
+* Release May 4, 2020
+
+Remove package.json module property. It looks like webpack behaves differently
+for modules loaded via module vs jsnext:main.
+
+### 2.25.2
+
+* Release May 4, 2020
+
+This release includes ES Module bundled moment, separate from it's source code
+under dist/ folder. This might alleviate issues with finding the `./locale
+subfolder for loading locales. This might also mean now webpack will bundle all
+locales automatically, unless told otherwise.
+
+### 2.25.1
+
+* Release May 1, 2020
+
+This is a quick patch release to address some of the issues raised after
+releasing 2.25.0.
+
+* [2e268635](https://github.com/moment/moment/commit/2e268635) [misc] Revert #5269 due to webpack warning
+* [226799e1](https://github.com/moment/moment/commit/226799e1) [locale] fil: Fix metadata comment
+* [a83a521](https://github.com/moment/moment/commit/a83a521) [bugfix] Fix typeoff usages
+* [e324334](https://github.com/moment/moment/commit/e324334) [pkg] Add ts3.1-typings in npm package
+* [28cc23e](https://github.com/moment/moment/commit/28cc23e) [misc] Remove deleted generated locale en-SG
+
+### 2.25.0 [See full changelog](https://gist.github.com/ichernev/6148e64df2427e455b10ce6a18de1a65)
+
+* Release May 1, 2020
+
+* [#4611](https://github.com/moment/moment/issues/4611) [022dc038](https://github.com/moment/moment/commit/022dc038) [feature] Support for strict string parsing, fixes [#2469](https://github.com/moment/moment/issues/2469)
+* [#4599](https://github.com/moment/moment/issues/4599) [4b615b9d](https://github.com/moment/moment/commit/4b615b9d) [feature] Add support for eras in en and jp
+* [#4296](https://github.com/moment/moment/issues/4296) [757d4ff8](https://github.com/moment/moment/commit/757d4ff8) [feature] Accept custom relative thresholds in duration.humanize
+
+* 18 bigfixes
+* 36 locale fixes
+* 5 new locales (oc-lnc, zh-mo, en-in, gom-deva, fil)
+
+### 2.24.0 [See full changelog](https://gist.github.com/marwahaha/12366fe45bee328f33acf125d4cd540e)
+
+* Release Jan 21, 2019
+
+* [#4338](https://github.com/moment/moment/pull/4338) [bugfix] Fix startOf/endOf DST issues while boosting performance
+* [#4553](https://github.com/moment/moment/pull/4553) [feature] Add localeSort param to Locale weekday methods
+* [#4887](https://github.com/moment/moment/pull/4887) [bugfix] Make Duration#as work with quarters
+* 3 new locales (it-ch, ga, en-SG)
+* Lots of locale improvements
+
+### 2.23.0 [See full changelog](https://gist.github.com/marwahaha/eadb7ac11b761290399a576f8b2419a5)
+
+* Release Dec 12, 2018
+
+* [#4863](https://github.com/moment/moment/pull/4863) [new locale] added Kurdish language (ku)
+* [#4417](https://github.com/moment/moment/pull/4417) [bugfix] isBetween should return false for invalid dates
+* [#4700](https://github.com/moment/moment/pull/4700) [bugfix] Fix [#4698](https://github.com/moment/moment/pull/4698): Use ISO WeekYear for HTML5_FMT.WEEK
+* [#4563](https://github.com/moment/moment/pull/4563) [feature] Fix [#4518](https://github.com/moment/moment/pull/4518): Add support to add/subtract ISO weeks
+* other locale changes, build process changes, typos
+
+### 2.22.2 [See full changelog](https://gist.github.com/marwahaha/4d992c13c2dbc0f59d4d8acae1dc6d3a)
+
+* Release May 31, 2018
+
+* [#4564](https://github.com/moment/moment/pull/4564) [bugfix] Avoid using trim()
+* [#4453](https://github.com/moment/moment/pull/4453) [bugfix] Treat periods as periods, not regex-anything period, for weekday parsing in strict mode.
+* Minor locale improvements (pa-in, be, az)
+
+### 2.22.1 [See full changelog](https://gist.github.com/marwahaha/ff2cd13d0eda08afb7a237b10aae558c)
+
+* Release Apr 14, 2018
+
+* [#4495](https://github.com/moment/moment/pull/4495) [bugfix] Added HTML5_FMT to moment.d.ts
+* Minor locale improvements
+* QUnit upgrade and coveralls reporting
+
+### 2.22.0 [See full changelog](https://gist.github.com/marwahaha/ae895025dac3f0641fa9ec2e36d282bb)
+
+* Release Mar 30, 2018
+
+* [#4423](https://github.com/moment/moment/pull/4423) [new locale] Added Mongolian locale mn
+* Various locale improvements
+* Minor misc changes
+
+### 2.21.0 [See full changelog](https://gist.github.com/marwahaha/80d19ef882b71df1948df7865efdd40e)
+
+* Release Mar 2, 2018
+
+* [#4391](https://github.com/moment/moment/pull/4391) [bugfix] Fix [#4390](https://github.com/moment/moment/pull/4390): use offset properly in toISOString
+* [#4310](https://github.com/moment/moment/pull/4310) [bugfix] Fix [#3883](https://github.com/moment/moment/pull/3883) lazy load parentLocale in defineLocale, fallback to global if missing
+* [#4085](https://github.com/moment/moment/pull/4085) [misc] Print console warning when setting non-existent locales
+* [#4371](https://github.com/moment/moment/pull/4371) [misc] fix deprecated rollup options
+* New locales: ug-cn, en-il, tg
+* Various locale improvements
+
+### 2.20.1 [See changelog](https://gist.github.com/marwahaha/d72c1cb22076373be889b16272cbd187)
+
+* Release Dec 18, 2017
+
+* [#4359](https://github.com/moment/moment/pull/4359) [locale] Fix Arabic locale for months (again)
+* [#4357](https://github.com/moment/moment/pull/4357) [misc] Add optional parameter keepOffset to toISOString
+
+### 2.20.0 [See full changelog](https://gist.github.com/marwahaha/e0d4135fbf8bb75fa85c4aa2bddc5031)
+
+* Release Dec 16, 2017
+
+* [#4312](https://github.com/moment/moment/pull/4312) [bugfix] Fix [#4251](https://github.com/moment/moment/pull/4251): Avoid RFC2822 in utc() test
+* [#4240](https://github.com/moment/moment/pull/4240) [bugfix] Fix incorrect strict parsing with full-width parentheses
+* [#4341](https://github.com/moment/moment/pull/4341) [feature] Prevent toISOString converting to UTC (issue [#1751](https://github.com/moment/moment/pull/1751))
+* [#4154](https://github.com/moment/moment/pull/4154) [feature] add format constants to support output to HTML5 input type formats (see [#3928](https://github.com/moment/moment/pull/3928))
+* [#4143](https://github.com/moment/moment/pull/4143) [new locale] mt: Maltese language
+* [#4183](https://github.com/moment/moment/pull/4183) [locale] Relative seconds i18n
+* Various other locale improvements
+
+### 2.19.4 [See changelog](https://gist.github.com/marwahaha/d3b7b0ddf4bdae512244f16e8cc59efb)
+
+* Release Dec 10, 2017
+
+* [#4332](https://github.com/moment/moment/pull/4332) [bugfix] Fix weekday verification for UTC and offset days (fixes [#4227](https://github.com/moment/moment/pull/4227))
+* [#4336](https://github.com/moment/moment/pull/4336) [bugfix] Fix [#4334](https://github.com/moment/moment/pull/4334): Remove unused function call argument
+* [#4246](https://github.com/moment/moment/pull/4246) [misc] Add 'ss' relative time key to typescript definition
+
+### 2.19.3 [See changelog](https://gist.github.com/marwahaha/3654006bc0c2e522451c08d12c0bfabf)
+
+* Release Nov 29, 2017
+
+* [#4326](https://github.com/moment/moment/pull/4326) [bugfix] Fix for ReDOS vulnerability (see [#4163](https://github.com/moment/moment/issues/4163))
+* [#4289](https://github.com/moment/moment/pull/4289) [misc] Fix spelling and formatting for U.S. for es-us
+
+### 2.19.2 [See changelog (it's the same >:D)](https://gist.github.com/ichernev/76b1a3f33d3a8ff9665ce434a45221d0)
+
+* Release Nov 11, 2017
+
+* [#4255](https://github.com/moment/moment/pull/4255) [bugfix] Fix year setter for random days in a leap year, fixes [#4238](https://github.com/moment/moment/issues/4238)
+* [#4242](https://github.com/moment/moment/pull/4242) [bugfix] updateLocale now tries to load parent, fixes [#3626](https://github.com/moment/moment/issues/3626)
+
+### 2.19.1
+
+* Release Oct 11, 2017
+
+Make react native and webpack both work
+* #4225 #4226 #4232
+
+### 2.19.0 [See full changelog](https://gist.github.com/ichernev/5f3f4eb02761b4f765a0cccf02cec603)
+
+* Release Oct 10, 2017
+
+## Fix React Native 0.49+ crash
+* [#4213](https://github.com/moment/moment/pull/4213) [critical] Rename dynamic
+  require to avoid React Native crash
+* [#4214](https://github.com/moment/moment/pull/4214) [fixup] Move require
+  rename inside try/catch, fixes
+  [#4213](https://github.com/moment/moment/issues/4213)
+
+## Features
+
+* [#3735](https://github.com/moment/moment/pull/3735) [feature] Ignore NaN values in setters
+* [#4106](https://github.com/moment/moment/pull/4106) [fixup] Drop isNumeric utility fn, fixes [#3735](https://github.com/moment/moment/issues/3735)
+* [#4080](https://github.com/moment/moment/pull/4080) [feature] Implement a clone method for durations, fixes [#4078](https://github.com/moment/moment/issues/4078)
+* [#4215](https://github.com/moment/moment/pull/4215) [misc] TS: Add duration.clone(), for [#4080](https://github.com/moment/moment/issues/4080)
+
+## Packaging
+
+* [#4003](https://github.com/moment/moment/pull/4003) [pkg] bower: Remove tests from package
+* [#3904](https://github.com/moment/moment/pull/3904) [pkg] jsnext:main -> module in package.json
+* [#4060](https://github.com/moment/moment/pull/4060) [pkg] Account for new rollup interface
+
+Bugfixes, new locales, locale fixes etc...
+
+### 2.18.1
+
+* Release Mar 22, 2017
+
+* [#3853](https://github.com/moment/moment/pull/3853) [misc] Fix invalid whitespace character causing inability to parse
+  moment.js
+
+### 2.18.0 [See full changelog](https://gist.github.com/ichernev/78920c5a1e419fb28c6e4546d1b7235c)
+
+* Release Mar 18, 2017
+
+## Features
+
+* [#3708](https://github.com/moment/moment/pull/3708) [feature] RFC2822 parsing
+* [#3611](https://github.com/moment/moment/pull/3611) [feature] Durations gain validity
+* [#3738](https://github.com/moment/moment/pull/3738) [feature] Enable relative time for multiple seconds, request [#2558](https://github.com/moment/moment/issues/2558)
+* [#3766](https://github.com/moment/moment/pull/3766) [feature] Add support for k and kk format parsing
+
+## Bugfixes
+
+* [#3643](https://github.com/moment/moment/pull/3643) [bugfix] Fixes [#3520](https://github.com/moment/moment/issues/3520), parseZone incorrectly handled minutes under 16
+* [#3710](https://github.com/moment/moment/pull/3710) [bugfix] Fixes [#3632](https://github.com/moment/moment/issues/3632), toISOString returns null for invalid date
+* [#3787](https://github.com/moment/moment/pull/3787) [bugfix] Fixes [#3717](https://github.com/moment/moment/issues/3717), ensure day-of-year is non-zero
+* [#3780](https://github.com/moment/moment/pull/3780) [bugfix] Fixes [#3765](https://github.com/moment/moment/issues/3765): Ensure year 0 is formatted with YYYY
+* [#3806](https://github.com/moment/moment/pull/3806) [bugfix] Fixes [#3805](https://github.com/moment/moment/issues/3805), fix locale month getters for standalone/format cases
+
+7 new locales, many locale improvements and some misc changes
+
+### 2.17.1 [Also available here](https://gist.github.com/ichernev/f38280b2b29c4932914a6d3a4e50bfb2)
+* Release Dec 03, 2016
+
+* [#3638](https://github.com/moment/moment/pull/3638) [misc] TS: Make typescript definitions work with 1.x
+* [#3628](https://github.com/moment/moment/pull/3628) [misc] Adds "sign CLA" link to `CONTRIBUTING.md`
+* [#3640](https://github.com/moment/moment/pull/3640) [misc] Fix locale issues
+
+### 2.17.0 [Also available here](https://gist.github.com/ichernev/ed58f76fb95205eeac653d719972b90c)
+* Release Nov 22, 2016
+
+* [#3435](https://github.com/moment/moment/pull/3435) [new locale] yo: Yoruba (Nigeria) locale
+* [#3595](https://github.com/moment/moment/pull/3595) [bugfix] Fix accidental reference to global "value" variable
+* [#3506](https://github.com/moment/moment/pull/3506) [bugfix] Fix invalid moments returning valid dates to method calls
+* [#3563](https://github.com/moment/moment/pull/3563) [locale] ca: Change future relative time
+* [#3504](https://github.com/moment/moment/pull/3504) [tests] Fixes [#3463](https://github.com/moment/moment/issues/3463), parseZone not handling Z correctly (tests only)
+* [#3591](https://github.com/moment/moment/pull/3591) [misc] typescript: update typescript to 2.0.8, add strictNullChecks=true
+* [#3597](https://github.com/moment/moment/pull/3597) [misc] Fixed capitalization in nuget spec
+
+### 2.16.0 [See full changelog](https://gist.github.com/ichernev/17bffc1005a032cb1a8ac4c1558b4994)
+* Release Nov 9, 2016
+
+## Features
+* [#3530](https://github.com/moment/moment/pull/3530) [feature] Check whether input is date before checking if format is array
+* [#3515](https://github.com/moment/moment/pull/3515) [feature] Fix [#2300](https://github.com/moment/moment/issues/2300): Default to current week.
+
+## Bugfixes
+* [#3546](https://github.com/moment/moment/pull/3546) [bugfix] Implement lazy-loading of child locales with missing prents
+* [#3523](https://github.com/moment/moment/pull/3523) [bugfix] parseZone should handle UTC
+* [#3502](https://github.com/moment/moment/pull/3502) [bugfix] Fix [#3500](https://github.com/moment/moment/issues/3500): ISO 8601 parsing should match the full string, not the beginning of the string.
+* [#3581](https://github.com/moment/moment/pull/3581) [bugfix] Fix parseZone, redo [#3504](https://github.com/moment/moment/issues/3504), fix [#3463](https://github.com/moment/moment/issues/3463)
+
+## New Locales
+* [#3416](https://github.com/moment/moment/pull/3416) [new locale] nl-be: Dutch (Belgium) locale
+* [#3393](https://github.com/moment/moment/pull/3393) [new locale] ar-dz: Arabic (Algeria) locale
+* [#3342](https://github.com/moment/moment/pull/3342) [new locale] tet: Tetun Dili (East Timor) locale
+
+And more locale, build and typescript improvements
+
+### 2.15.2
+* Release Oct 23, 2016
+* [#3525](https://github.com/moment/moment/pull/3525) Speedup month standalone/format regexes **(IMPORTANT)**
+* [#3466](https://github.com/moment/moment/pull/3466) Fix typo of Javanese
+
+### 2.15.1
+* Release Sept 20, 2016
+* [#3438](https://github.com/moment/moment/pull/3438) Fix locale autoload, revert [#3344](https://github.com/moment/moment/pull/3344)
+
+### 2.15.0 [See full changelog](https://gist.github.com/ichernev/10e1c5bf647545c72ca30e9628a09ed3)
+- Release Sept 12, 2016
+
+## New Locales
+* [#3255](https://github.com/moment/moment/pull/3255) [new locale] mi: Maori language
+* [#3267](https://github.com/moment/moment/pull/3267) [new locale] ar-ly: Arabic (Libya) locale
+* [#3333](https://github.com/moment/moment/pull/3333) [new locale] zh-hk: Chinese (Hong Kong) locale
+
+## Bugfixes
+* [#3276](https://github.com/moment/moment/pull/3276) [bugfix] duration: parser: Support ms durations in .NET syntax
+* [#3312](https://github.com/moment/moment/pull/3312) [bugfix] locales: Enable locale-data getters without moment (fixes [#3284](https://github.com/moment/moment/issues/3284))
+* [#3381](https://github.com/moment/moment/pull/3381) [bugfix] parsing: Fix parseZone without timezone in string, fixes [#3083](https://github.com/moment/moment/issues/3083)
+* [#3383](https://github.com/moment/moment/pull/3383) [bugfix] toJSON: Fix isValid so that toJSON works after a moment is frozen
+* [#3427](https://github.com/moment/moment/pull/3427) [bugfix] ie8: Fix IE8 (regression in 2.14.x)
+
+## Packaging
+* [#3299](https://github.com/moment/moment/pull/3299) [pkg] npm: Do not include .npmignore in npm package
+* [#3273](https://github.com/moment/moment/pull/3273) [pkg] jspm: Include moment.d.ts file in package
+* [#3344](https://github.com/moment/moment/pull/3344) [pkg] exports: use module.require for nodejs
+
+Also some locale and typescript improvements
+
+### 2.14.1
+- Release July 20, 2016
+* [#3280](https://github.com/moment/moment/pull/3280) Fix typescript definitions
+
+
+### 2.14.0 [See full changelog](https://gist.github.com/ichernev/812e79ac36a7829a22598fe964bfc18a)
+
+- Release July 20, 2016
+
+## New Features
+* [#3233](https://github.com/moment/moment/pull/3233) Introduce month.isFormat for format/standalone discovery
+* [#2848](https://github.com/moment/moment/pull/2848) Allow user to get/set the rounding method used when calculating relative time
+* [#3112](https://github.com/moment/moment/pull/3112) optimize configFromStringAndFormat
+* [#3147](https://github.com/moment/moment/pull/3147) Call calendar format function with moment context
+* [#3160](https://github.com/moment/moment/pull/3160) deprecate isDSTShifted
+* [#3175](https://github.com/moment/moment/pull/3175) make moment calendar extensible with ad-hoc options
+* [#3191](https://github.com/moment/moment/pull/3191) toDate returns a copy of the internal date object
+* [#3192](https://github.com/moment/moment/pull/3192) Adding support for rollup import.
+* [#3238](https://github.com/moment/moment/pull/3238) Handle empty object and empty array for creation as now
+* [#3082](https://github.com/moment/moment/pull/3082) Use relative AMD moment dependency
+
+## Bugfixes
+* [#3241](https://github.com/moment/moment/pull/3241) Escape all 24 mixed pieces, not only first 12 in computeMonthsParse
+* [#3008](https://github.com/moment/moment/pull/3008) Object setter orders sets based on size of unit
+* [#3177](https://github.com/moment/moment/pull/3177) Bug Fix [#2704](https://github.com/moment/moment/pull/2704) - isoWeekday(String) inconsistent with isoWeekday(Number)
+* [#3230](https://github.com/moment/moment/pull/3230) fix passing date with format string to ignore format string
+* [#3232](https://github.com/moment/moment/pull/3232) Fix negative 0 in certain diff cases
+* [#3235](https://github.com/moment/moment/pull/3235) Use proper locale inheritance for the base locale, fixes [#3137](https://github.com/moment/moment/pull/3137)
+
+Plus es-do locale and locale bugfixes
+
+### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)
+- Release April 18, 2016
+
+## Enhancements:
+* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().
+* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601
+* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals
+* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers
+* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens
+
+## Bugfixes
+* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.
+* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters
+* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))
+* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations
+* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs
+* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token
+* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion
+* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes
+
+Plus 3 new locales and locale fixes.
+
+### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)
+
+- Release March 7, 2016
+
+## Enhancements:
+* [#2932](https://github.com/moment/moment/pull/2932) List loaded locales
+* [#2818](https://github.com/moment/moment/pull/2818) Parse ISO-8061 duration containing both day and week values
+* [#2774](https://github.com/moment/moment/pull/2774) Implement locale inheritance and locale updating
+
+## Bugfixes:
+* [#2970](https://github.com/moment/moment/pull/2970) change add subtract to handle decimal values by rounding
+* [#2887](https://github.com/moment/moment/pull/2887) Fix toJSON casting of invalid moment
+* [#2897](https://github.com/moment/moment/pull/2897) parse string arguments for month() correctly, closes #2884
+* [#2946](https://github.com/moment/moment/pull/2946) Fix usage suggestions for min and max
+
+## New locales:
+* [#2917](https://github.com/moment/moment/pull/2917) Locale Punjabi(Gurmukhi) India format conversion
+
+And more
+
+### 2.11.2 (Fix ReDoS attack vector)
+
+- Release February 7, 2016
+
+* [#2939](https://github.com/moment/moment/pull/2939) use full-string match to speed up aspnet regex match
+
+### 2.11.1 [See full changelog](https://gist.github.com/ichernev/8ec3ee25b749b4cff3c2)
+
+- Release January 9, 2016
+
+## Bugfixes:
+* [#2881](https://github.com/moment/moment/pull/2881) Revert "Merge pull request #2746 from mbad0la:develop" Sep->Sept
+* [#2868](https://github.com/moment/moment/pull/2868) Add format and parse token Y, so it actually works
+* [#2865](https://github.com/moment/moment/pull/2865) Use typeof checks for undefined for global variables
+* [#2858](https://github.com/moment/moment/pull/2858) Fix Date mocking regression introduced in 2.11.0
+* [#2864](https://github.com/moment/moment/pull/2864) Include changelog in npm release
+* [#2830](https://github.com/moment/moment/pull/2830) dep: add grunt-cli
+* [#2869](https://github.com/moment/moment/pull/2869) Fix months parsing for some locales
+
+### 2.11.0 [See full changelog](https://gist.github.com/ichernev/6594bc29719dde6b2f66)
+
+- Release January 4, 2016
+
+* [#2624](https://github.com/moment/moment/pull/2624) Proper handling of invalid moments
+* [#2634](https://github.com/moment/moment/pull/2634) Fix strict month parsing issue in cs,ru,sk
+* [#2735](https://github.com/moment/moment/pull/2735) Reset the locale back to 'en' after defining all locales in min/locales.js
+* [#2702](https://github.com/moment/moment/pull/2702) Week rework
+* [#2746](https://github.com/moment/moment/pull/2746) Changed September Abbreviation to "Sept" in locale-specific english
+  files and default locale file
+* [#2646](https://github.com/moment/moment/pull/2646) Fix [#2645](https://github.com/moment/moment/pull/2645) - invalid dates pre-1970
+
+* [#2641](https://github.com/moment/moment/pull/2641) Implement basic format and comma as ms separator in ISO 8601
+* [#2665](https://github.com/moment/moment/pull/2665) Implement stricter weekday parsing
+* [#2700](https://github.com/moment/moment/pull/2700) Add [Hh]mm and [Hh]mmss formatting tokens, so you can parse 123 with
+  hmm for example
+* [#2565](https://github.com/moment/moment/pull/2565) [#2835](https://github.com/moment/moment/pull/2835) Expose arguments used for moment creation with creationData
+  (fix [#2443](https://github.com/moment/moment/pull/2443))
+* [#2648](https://github.com/moment/moment/pull/2648) fix issue [#2640](https://github.com/moment/moment/pull/2640): support instanceof operator
+* [#2709](https://github.com/moment/moment/pull/2709) Add isSameOrAfter and isSameOrBefore comparison methods
+* [#2721](https://github.com/moment/moment/pull/2721) Fix moment creation from object with strings values
+* [#2740](https://github.com/moment/moment/pull/2740) Enable 'd hh:mm:ss.sss' format for durations
+* [#2766](https://github.com/moment/moment/pull/2766) [#2833](https://github.com/moment/moment/pull/2833) Alternate Clock Source Support
+
+### 2.10.6
+
+- Release July 28, 2015
+
+[#2515](https://github.com/moment/moment/pull/2515) Fix regression introduced
+in `2.10.5` related to `moment.ISO_8601` parsing.
+
+### 2.10.5 [See full changelog](https://gist.github.com/ichernev/6ec13ac7efc396da44b2)
+
+- Release July 26, 2015
+
+Important changes:
+* [#2357](https://github.com/moment/moment/pull/2357) Improve unit bubbling for ISO dates
+  this fixes day to year conversions to work around end-of-year (~365 days). As
+  a side effect 365 days is 11 months and 30 days, and 366 days is one year.
+* [#2438](https://github.com/moment/moment/pull/2438) Fix inconsistent moment.min and moment.max results
+  Return invalid result if any of the inputs is invalid
+* [#2494](https://github.com/moment/moment/pull/2494) Fix two digit year parsing with YYYY format
+  This brings the benefits of YY to YYYY
+* [#2368](https://github.com/moment/moment/pull/2368) perf: use faster form of copying dates, across the board improvement
+
+
+### 2.10.3 [See full changelog](https://gist.github.com/ichernev/f264b9bed5b00f8b1b7f)
+
+- Release May 13, 2015
+
+* add `moment.fn.to` and `moment.fn.toNow` (similar to `from` and `fromNow`)
+* new locales (Sinhalese (si), Montenegrin (me), Javanese (ja))
+* performance improvements
+
+### 2.10.2
+
+- Release April 9, 2015
+
+* fixed moment-with-locales in browser env caused by esperanto change
+
+### 2.10.1
+
+* regression: Add moment.duration.fn back
+
+### 2.10.0
+
+Ported code to es6 modules.
+
+### 2.9.0 [See full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)
+
+- Release January 8, 2015
+
+languages:
+* [2104](https://github.com/moment/moment/issues/2104) Frisian (fy) language file with unit test
+* [2097](https://github.com/moment/moment/issues/2097) add ar-tn locale
+
+deprecations:
+* [2074](https://github.com/moment/moment/issues/2074) Implement `moment.fn.utcOffset`, deprecate `moment.fn.zone`
+
+features:
+* [2088](https://github.com/moment/moment/issues/2088) add moment.fn.isBetween
+* [2054](https://github.com/moment/moment/issues/2054) Call updateOffset when creating moment (needed for default timezone in
+  moment-timezone)
+* [1893](https://github.com/moment/moment/issues/1893) Add moment.isDate method
+* [1825](https://github.com/moment/moment/issues/1825) Implement toJSON function on Duration
+* [1809](https://github.com/moment/moment/issues/1809) Allowing moment.set() to accept a hash of units
+* [2128](https://github.com/moment/moment/issues/2128) Add firstDayOfWeek, firstDayOfYear locale getters
+* [2131](https://github.com/moment/moment/issues/2131) Add quarter diff support
+
+Some bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)
+
+### 2.8.4 [See full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)
+
+- Release November 19, 2014
+
+Features:
+
+* [#2000](https://github.com/moment/moment/issues/2000) Add LTS localised format that includes seconds
+* [#1960](https://github.com/moment/moment/issues/1960) added formatToken 'x' for unix offset in milliseconds #1938
+* [#1965](https://github.com/moment/moment/issues/1965) Support 24:00:00.000 to mean next day, at midnight.
+* [#2002](https://github.com/moment/moment/issues/2002) Accept 'date' key when creating moment with object
+* [#2009](https://github.com/moment/moment/issues/2009) Use native toISOString when we can
+
+Some bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)
+
+### 2.8.3
+
+- Release September 5, 2014
+
+Bugfixes:
+
+* [#1801](https://github.com/moment/moment/issues/1801) proper pluralization for Arabic
+* [#1833](https://github.com/moment/moment/issues/1833) improve spm integration
+* [#1871](https://github.com/moment/moment/issues/1871) fix zone bug caused by Firefox 24
+* [#1882](https://github.com/moment/moment/issues/1882) Use hh:mm in Czech
+* [#1883](https://github.com/moment/moment/issues/1883) Fix 2.8.0 regression in duration as conversions
+* [#1890](https://github.com/moment/moment/issues/1890) Faster travis builds
+* [#1892](https://github.com/moment/moment/issues/1892) Faster isBefore/After/Same
+* [#1848](https://github.com/moment/moment/issues/1848) Fix flaky month diffs
+* [#1895](https://github.com/moment/moment/issues/1895) Fix 2.8.0 regression in moment.utc with format array
+* [#1896](https://github.com/moment/moment/issues/1896) Support setting invalid instance locale (noop)
+* [#1897](https://github.com/moment/moment/issues/1897) Support moment([str]) in addition to moment([int])
+
+### 2.8.2
+
+- Release August 22, 2014
+
+Minor bugfixes:
+
+* [#1874](https://github.com/moment/moment/issues/1874) use `Object.prototype.hasOwnProperty`
+  instead of `obj.hasOwnProperty` (ie8 bug)
+* [#1873](https://github.com/moment/moment/issues/1873) add `duration#toString()`
+* [#1859](https://github.com/moment/moment/issues/1859) better month/weekday names in norwegian
+* [#1812](https://github.com/moment/moment/issues/1812) meridiem parsing for greek
+* [#1804](https://github.com/moment/moment/issues/1804) spanish del -> de
+* [#1800](https://github.com/moment/moment/issues/1800) korean LT improvement
+
+### 2.8.1
+
+- Release August 1, 2014
+
+* bugfix [#1813](https://github.com/moment/moment/issues/1813): fix moment().lang([key]) incompatibility
+
+### 2.8.0 [See changelog](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4)
+
+- Release July 31, 2014
+
+* incompatible changes
+    * [#1761](https://github.com/moment/moment/issues/1761): moments created without a language are no longer following the global language, in case it changes. Only newly created moments take the global language by default. In case you're affected by this, wait, comment on [#1797](https://github.com/moment/moment/issues/1797) and wait for a proper reimplementation
+    * [#1642](https://github.com/moment/moment/issues/1642): 45 days is no longer "a month" according to humanize, cutoffs for month, and year have changed. Hopefully your code does not depend on a particular answer from humanize (which it shouldn't anyway)
+    * [#1784](https://github.com/moment/moment/issues/1784): if you use the human readable English datetime format in a weird way (like storing them in a database) that would break when the format changes you're at risk.
+
+* deprecations (old behavior will be dropped in 3.0)
+    * [#1761](https://github.com/moment/moment/issues/1761) `lang` is renamed to `locale`, `langData` -> `localeData`. Also there is now `defineLocale` that should be used when creating new locales
+    * [#1763](https://github.com/moment/moment/issues/1763) `add(unit, value)` and `subtract(unit, value)` are now deprecated. Use `add(value, unit)` and `subtract(value, unit)` instead.
+    * [#1759](https://github.com/moment/moment/issues/1759) rename `duration.toIsoString` to `duration.toISOString`. The js standard library and moment's `toISOString` follow that convention.
+
+* new locales
+    * [#1789](https://github.com/moment/moment/issues/1789) Tibetan (bo)
+    * [#1786](https://github.com/moment/moment/issues/1786) Africaans (af)
+    * [#1778](https://github.com/moment/moment/issues/1778) Burmese (my)
+    * [#1727](https://github.com/moment/moment/issues/1727) Belarusian (be)
+
+* bugfixes, locale bugfixes, performance improvements, features
+
+### 2.7.0 [See changelog](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7)
+
+- Release June 12, 2014
+
+* new languages
+
+  * [#1678](https://github.com/moment/moment/issues/1678) Bengali (bn)
+  * [#1628](https://github.com/moment/moment/issues/1628) Azerbaijani (az)
+  * [#1633](https://github.com/moment/moment/issues/1633) Arabic, Saudi Arabia (ar-sa)
+  * [#1648](https://github.com/moment/moment/issues/1648) Austrian German (de-at)
+
+* features
+
+  * [#1663](https://github.com/moment/moment/issues/1663) configurable relative time thresholds
+  * [#1554](https://github.com/moment/moment/issues/1554) support anchor time in moment.calendar
+  * [#1693](https://github.com/moment/moment/issues/1693) support moment.ISO_8601 as parsing format
+  * [#1637](https://github.com/moment/moment/issues/1637) add moment.min and moment.max and deprecate min/max instance methods
+  * [#1704](https://github.com/moment/moment/issues/1704) support string value in add/subtract
+  * [#1647](https://github.com/moment/moment/issues/1647) add spm support (package manager)
+
+* bugfixes
+
+### 2.6.0 [See changelog](https://gist.github.com/ichernev/10544682)
+
+- Release April 12 , 2014
+
+* languages
+  * [#1529](https://github.com/moment/moment/issues/1529) Serbian-Cyrillic (sr-cyr)
+  * [#1544](https://github.com/moment/moment/issues/1544), [#1546](https://github.com/moment/moment/issues/1546) Khmer Cambodia (km)
+
+* features
+    * [#1419](https://github.com/moment/moment/issues/1419), [#1468](https://github.com/moment/moment/issues/1468), [#1467](https://github.com/moment/moment/issues/1467), [#1546](https://github.com/moment/moment/issues/1546) better handling of timezone-d moments around DST
+    * [#1462](https://github.com/moment/moment/issues/1462) add weeksInYear and isoWeeksInYear
+    * [#1475](https://github.com/moment/moment/issues/1475) support ordinal parsing
+    * [#1499](https://github.com/moment/moment/issues/1499) composer support
+    * [#1577](https://github.com/moment/moment/issues/1577), [#1604](https://github.com/moment/moment/issues/1604) put Date parsing in moment.createFromInputFallback so it can be properly deprecated and controlled in the future
+    * [#1545](https://github.com/moment/moment/issues/1545) extract two-digit year parsing in moment.parseTwoDigitYear, so it can be overwritten
+    * [#1590](https://github.com/moment/moment/issues/1590) (see [#1574](https://github.com/moment/moment/issues/1574)) set AMD global before module definition to better support non AMD module dependencies used in AMD environment
+    * [#1589](https://github.com/moment/moment/issues/1589) remove global in Node.JS environment (was not working before, nobody complained, was scheduled for removal anyway)
+    * [#1586](https://github.com/moment/moment/issues/1586) support quarter setting and parsing
+
+* 18 bugs fixed
+
+### 2.5.1
+
+- Release January 22, 2014
+
+* languages
+  * [#1392](https://github.com/moment/moment/issues/1392) Armenian (hy-am)
+
+* bugfixes
+  * [#1429](https://github.com/moment/moment/issues/1429) fixes [#1423](https://github.com/moment/moment/issues/1423) weird chrome-32 bug with js object creation
+  * [#1421](https://github.com/moment/moment/issues/1421) remove html entities from Welsh
+  * [#1418](https://github.com/moment/moment/issues/1418) fixes [#1401](https://github.com/moment/moment/issues/1401) improved non-padded tokens in strict matching
+  * [#1417](https://github.com/moment/moment/issues/1417) fixes [#1404](https://github.com/moment/moment/issues/1404) handle buggy moment object created by property cloning
+  * [#1398](https://github.com/moment/moment/issues/1398) fixes [#1397](https://github.com/moment/moment/issues/1397) fix Arabic-like week number parsing
+  * [#1396](https://github.com/moment/moment/issues/1396) add leftZeroFill(4) to GGGG and gggg formats
+  * [#1373](https://github.com/moment/moment/issues/1373) use lowercase for months and days in Catalan
+
+* testing
+  * [#1374](https://github.com/moment/moment/issues/1374) run tests on multiple browser/os combos via SauceLabs and Travis
+
+### 2.5.0 [See changelog](https://gist.github.com/ichernev/8104451)
+
+- Release Dec 24, 2013
+
+* New languages
+  * Luxemburish (lb) [1247](https://github.com/moment/moment/issues/1247)
+  * Serbian (rs) [1319](https://github.com/moment/moment/issues/1319)
+  * Tamil (ta) [1324](https://github.com/moment/moment/issues/1324)
+  * Macedonian (mk) [1337](https://github.com/moment/moment/issues/1337)
+
+* Features
+  * [1311](https://github.com/moment/moment/issues/1311) Add quarter getter and format token `Q`
+  * [1303](https://github.com/moment/moment/issues/1303) strict parsing now respects number of digits per token (fix [1196](https://github.com/moment/moment/issues/1196))
+  * 0d30bb7 add jspm support
+  * [1347](https://github.com/moment/moment/issues/1347) improve zone parsing
+  * [1362](https://github.com/moment/moment/issues/1362) support merideam parsing in Korean
+
+* 22 bugfixes
+
+### 2.4.0
+
+- Release Oct 27, 2013
+
+* **Deprecate** globally exported moment, will be removed in next major
+* New languages
+  * Farose (fo) [#1206](https://github.com/moment/moment/issues/1206)
+  * Tagalog/Filipino (tl-ph) [#1197](https://github.com/moment/moment/issues/1197)
+  * Welsh (cy) [#1215](https://github.com/moment/moment/issues/1215)
+* Bugfixes
+  * properly handle Z at the end of iso RegExp [#1187](https://github.com/moment/moment/issues/1187)
+  * chinese meridian time improvements [#1076](https://github.com/moment/moment/issues/1076)
+  * fix language tests [#1177](https://github.com/moment/moment/issues/1177)
+  * remove some failing tests (that should have never existed :))
+    [#1185](https://github.com/moment/moment/issues/1185)
+    [#1183](https://github.com/moment/moment/issues/1183)
+  * handle russian noun cases in weird cases [#1195](https://github.com/moment/moment/issues/1195)
+
+### 2.3.1
+
+- Release Oct 9, 2013
+
+Removed a trailing comma [1169] and fixed a bug with `months`, `weekdays` getters [#1171](https://github.com/moment/moment/issues/1171).
+
+### 2.3.0 [See changelog](https://gist.github.com/ichernev/6864354)
+
+- Release Oct 7, 2013
+
+Changed isValid, added strict parsing.
+Week tokens parsing.
+
+### 2.2.1
+
+- Release Sep 12, 2013
+
+Fixed bug in string prototype test.
+Updated authors and contributors.
+
+### 2.2.0 [See changelog](https://gist.github.com/ichernev/00f837a9baf46a3565e4)
+
+- Release  Sep 11, 2013
+
+Added bower support.
+
+Language files now use UMD.
+
+Creating moment defaults to current date/month/year.
+
+Added a bundle of moment and all language files.
+
+### 2.1.0 [See changelog](https://gist.github.com/timrwood/b8c2d90d528eddb53ab5)
+
+- Release Jul 8, 2013
+
+Added better week support.
+
+Added ability to set offset with `moment#zone`.
+
+Added ability to set month or weekday from a string.
+
+Added `moment#min` and `moment#max`
+
+### 2.0.0 [See changelog](https://gist.github.com/timrwood/e72f2eef320ed9e37c51)
+
+- Release Feb 9, 2013
+
+Added short form localized tokens.
+
+Added ability to define language a string should be parsed in.
+
+Added support for reversed add/subtract arguments.
+
+Added support for `endOf('week')` and `startOf('week')`.
+
+Fixed the logic for `moment#diff(Moment, 'months')` and `moment#diff(Moment, 'years')`
+
+`moment#diff` now floors instead of rounds.
+
+Normalized `moment#toString`.
+
+Added `isSame`, `isAfter`, and `isBefore` methods.
+
+Added better week support.
+
+Added `moment#toJSON`
+
+Bugfix: Fixed parsing of first century dates
+
+Bugfix: Parsing 10Sep2001 should work as expected
+
+Bugfix: Fixed weirdness with `moment.utc()` parsing.
+
+Changed language ordinal method to return the number + ordinal instead of just the ordinal.
+
+Changed two digit year parsing cutoff to match strptime.
+
+Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.
+
+Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.
+
+Removed the lang data objects from the top level namespace.
+
+Duplicate `Date` passed to `moment()` instead of referencing it.
+
+### 1.7.2 [See discussion](https://github.com/timrwood/moment/issues/456)
+
+- Release Oct 2, 2012
+
+Bugfixes
+
+### 1.7.1 [See discussion](https://github.com/timrwood/moment/issues/384)
+
+- Release Oct 1, 2012
+
+Bugfixes
+
+### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)
+
+- Release Jul 26, 2012
+
+Added `moment.fn.endOf()` and `moment.fn.startOf()`.
+
+Added validation via `moment.fn.isValid()`.
+
+Made formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions
+
+Add support for month/weekday callbacks in `moment.fn.format()`
+
+Added instance specific languages.
+
+Added two letter weekday abbreviations with the formatting token `dd`.
+
+Various language updates.
+
+Various bugfixes.
+
+### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)
+
+- Release Apr 26, 2012
+
+Added Durations.
+
+Revamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).
+
+Added support for millisecond parsing and formatting tokens (S SS SSS)
+
+Added a getter for `moment.lang()`
+
+Various bugfixes.
+
+There are a few things deprecated in the 1.6.0 release.
+
+1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.
+
+2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.
+
+3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).
+
+### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)
+
+- Release Mar 20, 2012
+
+Added UTC mode.
+
+Added automatic ISO8601 parsing.
+
+Various bugfixes.
+
+### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)
+
+- Release Feb 4, 2012
+
+Added `moment.fn.toDate` as a replacement for `moment.fn.native`.
+
+Added `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.
+
+Various bugfixes.
+
+### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)
+
+- Release Jan 5, 2012
+
+Added support for parsing month names in the current language.
+
+Added escape blocks for parsing tokens.
+
+Added `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.
+
+Added `moment.fn.day` as a setter.
+
+Various bugfixes
+
+### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)
+
+- Release Dec 7, 2011
+
+Added timezones to parser and formatter.
+
+Added `moment.fn.isDST`.
+
+Added `moment.fn.zone` to get the timezone offset in minutes.
+
+### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)
+
+- Release Nov 18, 2011
+
+Various bugfixes
+
+### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)
+
+- Release Nov 12, 2011
+
+Added time specific diffs (months, days, hours, etc)
+
+### 1.1.0
+
+- Release Oct 28, 2011
+
+Added `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)
+
+Fixed [issue 31](https://github.com/timrwood/moment/pull/31).
+
+### 1.0.1
+
+- Release Oct 18, 2011
+
+Added `moment.version` to get the current version.
+
+Removed `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)
+
+### 1.0.0
+
+- Release
+
+Added convenience methods for getting and setting date parts.
+
+Added better support for `moment.add()`.
+
+Added better lang support in NodeJS.
+
+Renamed library from underscore.date to Moment.js
+
+### 0.6.1
+
+- Release Oct 12, 2011
+
+Added Portuguese, Italian, and French language support
+
+### 0.6.0
+
+- Release Sep 21, 2011
+
+Added _date.lang() support.
+Added support for passing multiple formats to try to parse a date. _date("07-10-1986", ["MM-DD-YYYY", "YYYY-MM-DD"]);
+Made parse from string and single format 25% faster.
+
+### 0.5.2
+
+- Release Jul 11, 2011
+
+Bugfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).
+
+### 0.5.1
+
+- Release Jun 17, 2011
+
+Bugfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).
+
+### 0.5.0
+
+- Release Jun 13, 2011
+
+Dropped the redundant `_date.date()` in favor of `_date()`.
+Removed `_date.now()`, as it is a duplicate of `_date()` with no parameters.
+Removed `_date.isLeapYear(yearNumber)`. Use `_date([yearNumber]).isLeapYear()` instead.
+Exposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.
+
+### 0.4.1
+
+- Release May 9, 2011
+
+Added date input formats for input strings.
+
+### 0.4.0
+
+- Release May 9, 2011
+
+Added underscore.date to npm. Removed dependencies on underscore.
+
+### 0.3.2
+
+- Release Apr 9, 2011
+
+Added `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.
+
+### 0.3.1
+
+- Release Mar 25, 2011
+
+Cleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.
+
+### 0.3.0
+
+- Release Mar 25, 2011
+
+Switched to the Underscore methodology of not mucking with the native objects' prototypes.
+Made chaining possible.
+
+### 0.2.1
+
+- Release
+
+Changed date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.
+Added `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.
+
+### 0.2.0
+
+- Release
+
+Changed function names to be more concise.
+Changed date format from php date format to custom format.
+
+### 0.1.0
+
+- Release
+
+Initial release
+

+ 22 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/LICENSE

@@ -0,0 +1,22 @@
+Copyright (c) JS Foundation and other contributors
+
+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.

+ 55 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/README.md

@@ -0,0 +1,55 @@
+# [Moment.js](http://momentjs.com/)
+
+[![NPM version][npm-version-image]][npm-url]
+[![NPM downloads][npm-downloads-image]][npm-downloads-url]
+[![MIT License][license-image]][license-url]
+[![Build Status][travis-image]][travis-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+[![FOSSA Status][fossa-badge-image]][fossa-badge-url]
+[![SemVer compatibility][semver-image]][semver-url]
+
+A JavaScript date library for parsing, validating, manipulating, and formatting dates.
+
+## Project Status
+
+Moment.js is a legacy project, now in maintenance mode.  In most cases, you should choose a different library.
+
+For more details and recommendations, please see [Project Status](https://momentjs.com/docs/#/-project-status/) in the docs.
+
+*Thank you.*
+
+## Resources
+
+- [Documentation](https://momentjs.com/docs/)
+- [Changelog](CHANGELOG.md)
+- [Stack Overflow](https://stackoverflow.com/questions/tagged/momentjs)
+
+## License
+
+Moment.js is freely distributable under the terms of the [MIT license][license-url].
+
+[![FOSSA Status][fossa-large-image]][fossa-large-url]
+
+[license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat
+[license-url]: LICENSE
+
+[npm-url]: https://npmjs.org/package/moment
+[npm-version-image]: https://img.shields.io/npm/v/moment.svg?style=flat
+
+[npm-downloads-image]: https://img.shields.io/npm/dm/moment.svg?style=flat
+[npm-downloads-url]: https://npmcharts.com/compare/moment?minimal=true
+
+[travis-url]: https://travis-ci.org/moment/moment
+[travis-image]: https://img.shields.io/travis/moment/moment/develop.svg?style=flat
+
+[coveralls-image]: https://coveralls.io/repos/moment/moment/badge.svg?branch=develop
+[coveralls-url]: https://coveralls.io/r/moment/moment?branch=develop
+
+[fossa-badge-image]: https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment.svg?type=shield
+[fossa-badge-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment?ref=badge_shield
+
+[fossa-large-image]: https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment.svg?type=large
+[fossa-large-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment?ref=badge_large
+
+[semver-image]: https://api.dependabot.com/badges/compatibility_score?dependency-name=moment&package-manager=npm_and_yarn&version-scheme=semver
+[semver-url]: https://dependabot.com/compatibility-score.html?dependency-name=moment&package-manager=npm_and_yarn&version-scheme=semver

+ 71 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/af.js

@@ -0,0 +1,71 @@
+//! moment.js locale configuration
+//! locale : Afrikaans [af]
+//! author : Werner Mollentze : https://github.com/wernerm
+
+import moment from '../moment';
+
+export default moment.defineLocale('af', {
+    months: 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
+    weekdays: 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split(
+        '_'
+    ),
+    weekdaysShort: 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
+    weekdaysMin: 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
+    meridiemParse: /vm|nm/i,
+    isPM: function (input) {
+        return /^nm$/i.test(input);
+    },
+    meridiem: function (hours, minutes, isLower) {
+        if (hours < 12) {
+            return isLower ? 'vm' : 'VM';
+        } else {
+            return isLower ? 'nm' : 'NM';
+        }
+    },
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Vandag om] LT',
+        nextDay: '[Môre om] LT',
+        nextWeek: 'dddd [om] LT',
+        lastDay: '[Gister om] LT',
+        lastWeek: '[Laas] dddd [om] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'oor %s',
+        past: '%s gelede',
+        s: "'n paar sekondes",
+        ss: '%d sekondes',
+        m: "'n minuut",
+        mm: '%d minute',
+        h: "'n uur",
+        hh: '%d ure',
+        d: "'n dag",
+        dd: '%d dae',
+        M: "'n maand",
+        MM: '%d maande',
+        y: "'n jaar",
+        yy: '%d jaar',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
+    ordinal: function (number) {
+        return (
+            number +
+            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
+        ); // Thanks to Joris Röling : https://github.com/jjupiter
+    },
+    week: {
+        dow: 1, // Maandag is die eerste dag van die week.
+        doy: 4, // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
+    },
+});

+ 156 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-dz.js

@@ -0,0 +1,156 @@
+//! moment.js locale configuration
+//! locale : Arabic (Algeria) [ar-dz]
+//! author : Amine Roukh: https://github.com/Amine27
+//! author : Abdel Said: https://github.com/abdelsaid
+//! author : Ahmed Elkhatib
+//! author : forabi https://github.com/forabi
+//! author : Noureddine LOUAHEDJ : https://github.com/noureddinem
+
+import moment from '../moment';
+
+var pluralForm = function (n) {
+        return n === 0
+            ? 0
+            : n === 1
+            ? 1
+            : n === 2
+            ? 2
+            : n % 100 >= 3 && n % 100 <= 10
+            ? 3
+            : n % 100 >= 11
+            ? 4
+            : 5;
+    },
+    plurals = {
+        s: [
+            'أقل من ثانية',
+            'ثانية واحدة',
+            ['ثانيتان', 'ثانيتين'],
+            '%d ثوان',
+            '%d ثانية',
+            '%d ثانية',
+        ],
+        m: [
+            'أقل من دقيقة',
+            'دقيقة واحدة',
+            ['دقيقتان', 'دقيقتين'],
+            '%d دقائق',
+            '%d دقيقة',
+            '%d دقيقة',
+        ],
+        h: [
+            'أقل من ساعة',
+            'ساعة واحدة',
+            ['ساعتان', 'ساعتين'],
+            '%d ساعات',
+            '%d ساعة',
+            '%d ساعة',
+        ],
+        d: [
+            'أقل من يوم',
+            'يوم واحد',
+            ['يومان', 'يومين'],
+            '%d أيام',
+            '%d يومًا',
+            '%d يوم',
+        ],
+        M: [
+            'أقل من شهر',
+            'شهر واحد',
+            ['شهران', 'شهرين'],
+            '%d أشهر',
+            '%d شهرا',
+            '%d شهر',
+        ],
+        y: [
+            'أقل من عام',
+            'عام واحد',
+            ['عامان', 'عامين'],
+            '%d أعوام',
+            '%d عامًا',
+            '%d عام',
+        ],
+    },
+    pluralize = function (u) {
+        return function (number, withoutSuffix, string, isFuture) {
+            var f = pluralForm(number),
+                str = plurals[u][pluralForm(number)];
+            if (f === 2) {
+                str = str[withoutSuffix ? 0 : 1];
+            }
+            return str.replace(/%d/i, number);
+        };
+    },
+    months = [
+        'جانفي',
+        'فيفري',
+        'مارس',
+        'أفريل',
+        'ماي',
+        'جوان',
+        'جويلية',
+        'أوت',
+        'سبتمبر',
+        'أكتوبر',
+        'نوفمبر',
+        'ديسمبر',
+    ];
+
+export default moment.defineLocale('ar-dz', {
+    months: months,
+    monthsShort: months,
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'D/\u200FM/\u200FYYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /ص|م/,
+    isPM: function (input) {
+        return 'م' === input;
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'ص';
+        } else {
+            return 'م';
+        }
+    },
+    calendar: {
+        sameDay: '[اليوم عند الساعة] LT',
+        nextDay: '[غدًا عند الساعة] LT',
+        nextWeek: 'dddd [عند الساعة] LT',
+        lastDay: '[أمس عند الساعة] LT',
+        lastWeek: 'dddd [عند الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'بعد %s',
+        past: 'منذ %s',
+        s: pluralize('s'),
+        ss: pluralize('s'),
+        m: pluralize('m'),
+        mm: pluralize('m'),
+        h: pluralize('h'),
+        hh: pluralize('h'),
+        d: pluralize('d'),
+        dd: pluralize('d'),
+        M: pluralize('M'),
+        MM: pluralize('M'),
+        y: pluralize('y'),
+        yy: pluralize('y'),
+    },
+    postformat: function (string) {
+        return string.replace(/,/g, '،');
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 54 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-kw.js

@@ -0,0 +1,54 @@
+//! moment.js locale configuration
+//! locale : Arabic (Kuwait) [ar-kw]
+//! author : Nusret Parlak: https://github.com/nusretparlak
+
+import moment from '../moment';
+
+export default moment.defineLocale('ar-kw', {
+    months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
+        '_'
+    ),
+    monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
+        '_'
+    ),
+    weekdays: 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[اليوم على الساعة] LT',
+        nextDay: '[غدا على الساعة] LT',
+        nextWeek: 'dddd [على الساعة] LT',
+        lastDay: '[أمس على الساعة] LT',
+        lastWeek: 'dddd [على الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'في %s',
+        past: 'منذ %s',
+        s: 'ثوان',
+        ss: '%d ثانية',
+        m: 'دقيقة',
+        mm: '%d دقائق',
+        h: 'ساعة',
+        hh: '%d ساعات',
+        d: 'يوم',
+        dd: '%d أيام',
+        M: 'شهر',
+        MM: '%d أشهر',
+        y: 'سنة',
+        yy: '%d سنوات',
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 12, // The week that contains Jan 12th is the first week of the year.
+    },
+});

+ 171 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-ly.js

@@ -0,0 +1,171 @@
+//! moment.js locale configuration
+//! locale : Arabic (Lybia) [ar-ly]
+//! author : Ali Hmer: https://github.com/kikoanis
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '1',
+        2: '2',
+        3: '3',
+        4: '4',
+        5: '5',
+        6: '6',
+        7: '7',
+        8: '8',
+        9: '9',
+        0: '0',
+    },
+    pluralForm = function (n) {
+        return n === 0
+            ? 0
+            : n === 1
+            ? 1
+            : n === 2
+            ? 2
+            : n % 100 >= 3 && n % 100 <= 10
+            ? 3
+            : n % 100 >= 11
+            ? 4
+            : 5;
+    },
+    plurals = {
+        s: [
+            'أقل من ثانية',
+            'ثانية واحدة',
+            ['ثانيتان', 'ثانيتين'],
+            '%d ثوان',
+            '%d ثانية',
+            '%d ثانية',
+        ],
+        m: [
+            'أقل من دقيقة',
+            'دقيقة واحدة',
+            ['دقيقتان', 'دقيقتين'],
+            '%d دقائق',
+            '%d دقيقة',
+            '%d دقيقة',
+        ],
+        h: [
+            'أقل من ساعة',
+            'ساعة واحدة',
+            ['ساعتان', 'ساعتين'],
+            '%d ساعات',
+            '%d ساعة',
+            '%d ساعة',
+        ],
+        d: [
+            'أقل من يوم',
+            'يوم واحد',
+            ['يومان', 'يومين'],
+            '%d أيام',
+            '%d يومًا',
+            '%d يوم',
+        ],
+        M: [
+            'أقل من شهر',
+            'شهر واحد',
+            ['شهران', 'شهرين'],
+            '%d أشهر',
+            '%d شهرا',
+            '%d شهر',
+        ],
+        y: [
+            'أقل من عام',
+            'عام واحد',
+            ['عامان', 'عامين'],
+            '%d أعوام',
+            '%d عامًا',
+            '%d عام',
+        ],
+    },
+    pluralize = function (u) {
+        return function (number, withoutSuffix, string, isFuture) {
+            var f = pluralForm(number),
+                str = plurals[u][pluralForm(number)];
+            if (f === 2) {
+                str = str[withoutSuffix ? 0 : 1];
+            }
+            return str.replace(/%d/i, number);
+        };
+    },
+    months = [
+        'يناير',
+        'فبراير',
+        'مارس',
+        'أبريل',
+        'مايو',
+        'يونيو',
+        'يوليو',
+        'أغسطس',
+        'سبتمبر',
+        'أكتوبر',
+        'نوفمبر',
+        'ديسمبر',
+    ];
+
+export default moment.defineLocale('ar-ly', {
+    months: months,
+    monthsShort: months,
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'D/\u200FM/\u200FYYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /ص|م/,
+    isPM: function (input) {
+        return 'م' === input;
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'ص';
+        } else {
+            return 'م';
+        }
+    },
+    calendar: {
+        sameDay: '[اليوم عند الساعة] LT',
+        nextDay: '[غدًا عند الساعة] LT',
+        nextWeek: 'dddd [عند الساعة] LT',
+        lastDay: '[أمس عند الساعة] LT',
+        lastWeek: 'dddd [عند الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'بعد %s',
+        past: 'منذ %s',
+        s: pluralize('s'),
+        ss: pluralize('s'),
+        m: pluralize('m'),
+        mm: pluralize('m'),
+        h: pluralize('h'),
+        hh: pluralize('h'),
+        d: pluralize('d'),
+        dd: pluralize('d'),
+        M: pluralize('M'),
+        MM: pluralize('M'),
+        y: pluralize('y'),
+        yy: pluralize('y'),
+    },
+    preparse: function (string) {
+        return string.replace(/،/g, ',');
+    },
+    postformat: function (string) {
+        return string
+            .replace(/\d/g, function (match) {
+                return symbolMap[match];
+            })
+            .replace(/,/g, '،');
+    },
+    week: {
+        dow: 6, // Saturday is the first day of the week.
+        doy: 12, // The week that contains Jan 12th is the first week of the year.
+    },
+});

+ 55 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-ma.js

@@ -0,0 +1,55 @@
+//! moment.js locale configuration
+//! locale : Arabic (Morocco) [ar-ma]
+//! author : ElFadili Yassine : https://github.com/ElFadiliY
+//! author : Abdel Said : https://github.com/abdelsaid
+
+import moment from '../moment';
+
+export default moment.defineLocale('ar-ma', {
+    months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
+        '_'
+    ),
+    monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
+        '_'
+    ),
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[اليوم على الساعة] LT',
+        nextDay: '[غدا على الساعة] LT',
+        nextWeek: 'dddd [على الساعة] LT',
+        lastDay: '[أمس على الساعة] LT',
+        lastWeek: 'dddd [على الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'في %s',
+        past: 'منذ %s',
+        s: 'ثوان',
+        ss: '%d ثانية',
+        m: 'دقيقة',
+        mm: '%d دقائق',
+        h: 'ساعة',
+        hh: '%d ساعات',
+        d: 'يوم',
+        dd: '%d أيام',
+        M: 'شهر',
+        MM: '%d أشهر',
+        y: 'سنة',
+        yy: '%d سنوات',
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 104 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-sa.js

@@ -0,0 +1,104 @@
+//! moment.js locale configuration
+//! locale : Arabic (Saudi Arabia) [ar-sa]
+//! author : Suhail Alkowaileet : https://github.com/xsoh
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '١',
+        2: '٢',
+        3: '٣',
+        4: '٤',
+        5: '٥',
+        6: '٦',
+        7: '٧',
+        8: '٨',
+        9: '٩',
+        0: '٠',
+    },
+    numberMap = {
+        '١': '1',
+        '٢': '2',
+        '٣': '3',
+        '٤': '4',
+        '٥': '5',
+        '٦': '6',
+        '٧': '7',
+        '٨': '8',
+        '٩': '9',
+        '٠': '0',
+    };
+
+export default moment.defineLocale('ar-sa', {
+    months: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
+        '_'
+    ),
+    monthsShort: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
+        '_'
+    ),
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /ص|م/,
+    isPM: function (input) {
+        return 'م' === input;
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'ص';
+        } else {
+            return 'م';
+        }
+    },
+    calendar: {
+        sameDay: '[اليوم على الساعة] LT',
+        nextDay: '[غدا على الساعة] LT',
+        nextWeek: 'dddd [على الساعة] LT',
+        lastDay: '[أمس على الساعة] LT',
+        lastWeek: 'dddd [على الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'في %s',
+        past: 'منذ %s',
+        s: 'ثوان',
+        ss: '%d ثانية',
+        m: 'دقيقة',
+        mm: '%d دقائق',
+        h: 'ساعة',
+        hh: '%d ساعات',
+        d: 'يوم',
+        dd: '%d أيام',
+        M: 'شهر',
+        MM: '%d أشهر',
+        y: 'سنة',
+        yy: '%d سنوات',
+    },
+    preparse: function (string) {
+        return string
+            .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
+                return numberMap[match];
+            })
+            .replace(/،/g, ',');
+    },
+    postformat: function (string) {
+        return string
+            .replace(/\d/g, function (match) {
+                return symbolMap[match];
+            })
+            .replace(/,/g, '،');
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 54 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar-tn.js

@@ -0,0 +1,54 @@
+//! moment.js locale configuration
+//! locale  :  Arabic (Tunisia) [ar-tn]
+//! author : Nader Toukabri : https://github.com/naderio
+
+import moment from '../moment';
+
+export default moment.defineLocale('ar-tn', {
+    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
+        '_'
+    ),
+    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
+        '_'
+    ),
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[اليوم على الساعة] LT',
+        nextDay: '[غدا على الساعة] LT',
+        nextWeek: 'dddd [على الساعة] LT',
+        lastDay: '[أمس على الساعة] LT',
+        lastWeek: 'dddd [على الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'في %s',
+        past: 'منذ %s',
+        s: 'ثوان',
+        ss: '%d ثانية',
+        m: 'دقيقة',
+        mm: '%d دقائق',
+        h: 'ساعة',
+        hh: '%d ساعات',
+        d: 'يوم',
+        dd: '%d أيام',
+        M: 'شهر',
+        MM: '%d أشهر',
+        y: 'سنة',
+        yy: '%d سنوات',
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 189 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ar.js

@@ -0,0 +1,189 @@
+//! moment.js locale configuration
+//! locale : Arabic [ar]
+//! author : Abdel Said: https://github.com/abdelsaid
+//! author : Ahmed Elkhatib
+//! author : forabi https://github.com/forabi
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '١',
+        2: '٢',
+        3: '٣',
+        4: '٤',
+        5: '٥',
+        6: '٦',
+        7: '٧',
+        8: '٨',
+        9: '٩',
+        0: '٠',
+    },
+    numberMap = {
+        '١': '1',
+        '٢': '2',
+        '٣': '3',
+        '٤': '4',
+        '٥': '5',
+        '٦': '6',
+        '٧': '7',
+        '٨': '8',
+        '٩': '9',
+        '٠': '0',
+    },
+    pluralForm = function (n) {
+        return n === 0
+            ? 0
+            : n === 1
+            ? 1
+            : n === 2
+            ? 2
+            : n % 100 >= 3 && n % 100 <= 10
+            ? 3
+            : n % 100 >= 11
+            ? 4
+            : 5;
+    },
+    plurals = {
+        s: [
+            'أقل من ثانية',
+            'ثانية واحدة',
+            ['ثانيتان', 'ثانيتين'],
+            '%d ثوان',
+            '%d ثانية',
+            '%d ثانية',
+        ],
+        m: [
+            'أقل من دقيقة',
+            'دقيقة واحدة',
+            ['دقيقتان', 'دقيقتين'],
+            '%d دقائق',
+            '%d دقيقة',
+            '%d دقيقة',
+        ],
+        h: [
+            'أقل من ساعة',
+            'ساعة واحدة',
+            ['ساعتان', 'ساعتين'],
+            '%d ساعات',
+            '%d ساعة',
+            '%d ساعة',
+        ],
+        d: [
+            'أقل من يوم',
+            'يوم واحد',
+            ['يومان', 'يومين'],
+            '%d أيام',
+            '%d يومًا',
+            '%d يوم',
+        ],
+        M: [
+            'أقل من شهر',
+            'شهر واحد',
+            ['شهران', 'شهرين'],
+            '%d أشهر',
+            '%d شهرا',
+            '%d شهر',
+        ],
+        y: [
+            'أقل من عام',
+            'عام واحد',
+            ['عامان', 'عامين'],
+            '%d أعوام',
+            '%d عامًا',
+            '%d عام',
+        ],
+    },
+    pluralize = function (u) {
+        return function (number, withoutSuffix, string, isFuture) {
+            var f = pluralForm(number),
+                str = plurals[u][pluralForm(number)];
+            if (f === 2) {
+                str = str[withoutSuffix ? 0 : 1];
+            }
+            return str.replace(/%d/i, number);
+        };
+    },
+    months = [
+        'يناير',
+        'فبراير',
+        'مارس',
+        'أبريل',
+        'مايو',
+        'يونيو',
+        'يوليو',
+        'أغسطس',
+        'سبتمبر',
+        'أكتوبر',
+        'نوفمبر',
+        'ديسمبر',
+    ];
+
+export default moment.defineLocale('ar', {
+    months: months,
+    monthsShort: months,
+    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
+    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
+    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'D/\u200FM/\u200FYYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /ص|م/,
+    isPM: function (input) {
+        return 'م' === input;
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'ص';
+        } else {
+            return 'م';
+        }
+    },
+    calendar: {
+        sameDay: '[اليوم عند الساعة] LT',
+        nextDay: '[غدًا عند الساعة] LT',
+        nextWeek: 'dddd [عند الساعة] LT',
+        lastDay: '[أمس عند الساعة] LT',
+        lastWeek: 'dddd [عند الساعة] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'بعد %s',
+        past: 'منذ %s',
+        s: pluralize('s'),
+        ss: pluralize('s'),
+        m: pluralize('m'),
+        mm: pluralize('m'),
+        h: pluralize('h'),
+        hh: pluralize('h'),
+        d: pluralize('d'),
+        dd: pluralize('d'),
+        M: pluralize('M'),
+        MM: pluralize('M'),
+        y: pluralize('y'),
+        yy: pluralize('y'),
+    },
+    preparse: function (string) {
+        return string
+            .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
+                return numberMap[match];
+            })
+            .replace(/،/g, ',');
+    },
+    postformat: function (string) {
+        return string
+            .replace(/\d/g, function (match) {
+                return symbolMap[match];
+            })
+            .replace(/,/g, '،');
+    },
+    week: {
+        dow: 6, // Saturday is the first day of the week.
+        doy: 12, // The week that contains Jan 12th is the first week of the year.
+    },
+});

+ 101 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/az.js

@@ -0,0 +1,101 @@
+//! moment.js locale configuration
+//! locale : Azerbaijani [az]
+//! author : topchiyev : https://github.com/topchiyev
+
+import moment from '../moment';
+
+var suffixes = {
+    1: '-inci',
+    5: '-inci',
+    8: '-inci',
+    70: '-inci',
+    80: '-inci',
+    2: '-nci',
+    7: '-nci',
+    20: '-nci',
+    50: '-nci',
+    3: '-üncü',
+    4: '-üncü',
+    100: '-üncü',
+    6: '-ncı',
+    9: '-uncu',
+    10: '-uncu',
+    30: '-uncu',
+    60: '-ıncı',
+    90: '-ıncı',
+};
+
+export default moment.defineLocale('az', {
+    months: 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split(
+        '_'
+    ),
+    monthsShort: 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
+    weekdays: 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split(
+        '_'
+    ),
+    weekdaysShort: 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
+    weekdaysMin: 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[bugün saat] LT',
+        nextDay: '[sabah saat] LT',
+        nextWeek: '[gələn həftə] dddd [saat] LT',
+        lastDay: '[dünən] LT',
+        lastWeek: '[keçən həftə] dddd [saat] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s sonra',
+        past: '%s əvvəl',
+        s: 'bir neçə saniyə',
+        ss: '%d saniyə',
+        m: 'bir dəqiqə',
+        mm: '%d dəqiqə',
+        h: 'bir saat',
+        hh: '%d saat',
+        d: 'bir gün',
+        dd: '%d gün',
+        M: 'bir ay',
+        MM: '%d ay',
+        y: 'bir il',
+        yy: '%d il',
+    },
+    meridiemParse: /gecə|səhər|gündüz|axşam/,
+    isPM: function (input) {
+        return /^(gündüz|axşam)$/.test(input);
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'gecə';
+        } else if (hour < 12) {
+            return 'səhər';
+        } else if (hour < 17) {
+            return 'gündüz';
+        } else {
+            return 'axşam';
+        }
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
+    ordinal: function (number) {
+        if (number === 0) {
+            // special case for zero
+            return number + '-ıncı';
+        }
+        var a = number % 10,
+            b = (number % 100) - a,
+            c = number >= 100 ? 100 : null;
+        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 141 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/be.js

@@ -0,0 +1,141 @@
+//! moment.js locale configuration
+//! locale : Belarusian [be]
+//! author : Dmitry Demidov : https://github.com/demidov91
+//! author: Praleska: http://praleska.pro/
+//! Author : Menelion Elensúle : https://github.com/Oire
+
+import moment from '../moment';
+
+function plural(word, num) {
+    var forms = word.split('_');
+    return num % 10 === 1 && num % 100 !== 11
+        ? forms[0]
+        : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
+        ? forms[1]
+        : forms[2];
+}
+function relativeTimeWithPlural(number, withoutSuffix, key) {
+    var format = {
+        ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд',
+        mm: withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
+        hh: withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
+        dd: 'дзень_дні_дзён',
+        MM: 'месяц_месяцы_месяцаў',
+        yy: 'год_гады_гадоў',
+    };
+    if (key === 'm') {
+        return withoutSuffix ? 'хвіліна' : 'хвіліну';
+    } else if (key === 'h') {
+        return withoutSuffix ? 'гадзіна' : 'гадзіну';
+    } else {
+        return number + ' ' + plural(format[key], +number);
+    }
+}
+
+export default moment.defineLocale('be', {
+    months: {
+        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split(
+            '_'
+        ),
+        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split(
+            '_'
+        ),
+    },
+    monthsShort: 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split(
+        '_'
+    ),
+    weekdays: {
+        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split(
+            '_'
+        ),
+        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split(
+            '_'
+        ),
+        isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/,
+    },
+    weekdaysShort: 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
+    weekdaysMin: 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D MMMM YYYY г.',
+        LLL: 'D MMMM YYYY г., HH:mm',
+        LLLL: 'dddd, D MMMM YYYY г., HH:mm',
+    },
+    calendar: {
+        sameDay: '[Сёння ў] LT',
+        nextDay: '[Заўтра ў] LT',
+        lastDay: '[Учора ў] LT',
+        nextWeek: function () {
+            return '[У] dddd [ў] LT';
+        },
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                case 3:
+                case 5:
+                case 6:
+                    return '[У мінулую] dddd [ў] LT';
+                case 1:
+                case 2:
+                case 4:
+                    return '[У мінулы] dddd [ў] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'праз %s',
+        past: '%s таму',
+        s: 'некалькі секунд',
+        m: relativeTimeWithPlural,
+        mm: relativeTimeWithPlural,
+        h: relativeTimeWithPlural,
+        hh: relativeTimeWithPlural,
+        d: 'дзень',
+        dd: relativeTimeWithPlural,
+        M: 'месяц',
+        MM: relativeTimeWithPlural,
+        y: 'год',
+        yy: relativeTimeWithPlural,
+    },
+    meridiemParse: /ночы|раніцы|дня|вечара/,
+    isPM: function (input) {
+        return /^(дня|вечара)$/.test(input);
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'ночы';
+        } else if (hour < 12) {
+            return 'раніцы';
+        } else if (hour < 17) {
+            return 'дня';
+        } else {
+            return 'вечара';
+        }
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            case 'M':
+            case 'd':
+            case 'DDD':
+            case 'w':
+            case 'W':
+                return (number % 10 === 2 || number % 10 === 3) &&
+                    number % 100 !== 12 &&
+                    number % 100 !== 13
+                    ? number + '-і'
+                    : number + '-ы';
+            case 'D':
+                return number + '-га';
+            default:
+                return number;
+        }
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 87 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bg.js

@@ -0,0 +1,87 @@
+//! moment.js locale configuration
+//! locale : Bulgarian [bg]
+//! author : Krasen Borisov : https://github.com/kraz
+
+import moment from '../moment';
+
+export default moment.defineLocale('bg', {
+    months: 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split(
+        '_'
+    ),
+    monthsShort: 'яну_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
+    weekdays: 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split(
+        '_'
+    ),
+    weekdaysShort: 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
+    weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'D.MM.YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY H:mm',
+        LLLL: 'dddd, D MMMM YYYY H:mm',
+    },
+    calendar: {
+        sameDay: '[Днес в] LT',
+        nextDay: '[Утре в] LT',
+        nextWeek: 'dddd [в] LT',
+        lastDay: '[Вчера в] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                case 3:
+                case 6:
+                    return '[Миналата] dddd [в] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[Миналия] dddd [в] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'след %s',
+        past: 'преди %s',
+        s: 'няколко секунди',
+        ss: '%d секунди',
+        m: 'минута',
+        mm: '%d минути',
+        h: 'час',
+        hh: '%d часа',
+        d: 'ден',
+        dd: '%d дена',
+        w: 'седмица',
+        ww: '%d седмици',
+        M: 'месец',
+        MM: '%d месеца',
+        y: 'година',
+        yy: '%d години',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
+    ordinal: function (number) {
+        var lastDigit = number % 10,
+            last2Digits = number % 100;
+        if (number === 0) {
+            return number + '-ев';
+        } else if (last2Digits === 0) {
+            return number + '-ен';
+        } else if (last2Digits > 10 && last2Digits < 20) {
+            return number + '-ти';
+        } else if (lastDigit === 1) {
+            return number + '-ви';
+        } else if (lastDigit === 2) {
+            return number + '-ри';
+        } else if (lastDigit === 7 || lastDigit === 8) {
+            return number + '-ми';
+        } else {
+            return number + '-ти';
+        }
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 52 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bm.js

@@ -0,0 +1,52 @@
+//! moment.js locale configuration
+//! locale : Bambara [bm]
+//! author : Estelle Comment : https://github.com/estellecomment
+// Language contact person : Abdoufata Kane : https://github.com/abdoufata
+
+import moment from '../moment';
+
+export default moment.defineLocale('bm', {
+    months: 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split(
+        '_'
+    ),
+    monthsShort: 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'),
+    weekdays: 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'),
+    weekdaysShort: 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'),
+    weekdaysMin: 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'MMMM [tile] D [san] YYYY',
+        LLL: 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm',
+        LLLL: 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm',
+    },
+    calendar: {
+        sameDay: '[Bi lɛrɛ] LT',
+        nextDay: '[Sini lɛrɛ] LT',
+        nextWeek: 'dddd [don lɛrɛ] LT',
+        lastDay: '[Kunu lɛrɛ] LT',
+        lastWeek: 'dddd [tɛmɛnen lɛrɛ] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s kɔnɔ',
+        past: 'a bɛ %s bɔ',
+        s: 'sanga dama dama',
+        ss: 'sekondi %d',
+        m: 'miniti kelen',
+        mm: 'miniti %d',
+        h: 'lɛrɛ kelen',
+        hh: 'lɛrɛ %d',
+        d: 'tile kelen',
+        dd: 'tile %d',
+        M: 'kalo kelen',
+        MM: 'kalo %d',
+        y: 'san kelen',
+        yy: 'san %d',
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 128 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bn-bd.js

@@ -0,0 +1,128 @@
+//! moment.js locale configuration
+//! locale : Bengali (Bangladesh) [bn-bd]
+//! author : Asraf Hossain Patoary : https://github.com/ashwoolford
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '১',
+        2: '২',
+        3: '৩',
+        4: '৪',
+        5: '৫',
+        6: '৬',
+        7: '৭',
+        8: '৮',
+        9: '৯',
+        0: '০',
+    },
+    numberMap = {
+        '১': '1',
+        '২': '2',
+        '৩': '3',
+        '৪': '4',
+        '৫': '5',
+        '৬': '6',
+        '৭': '7',
+        '৮': '8',
+        '৯': '9',
+        '০': '0',
+    };
+
+export default moment.defineLocale('bn-bd', {
+    months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split(
+        '_'
+    ),
+    monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split(
+        '_'
+    ),
+    weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split(
+        '_'
+    ),
+    weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
+    weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'),
+    longDateFormat: {
+        LT: 'A h:mm সময়',
+        LTS: 'A h:mm:ss সময়',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY, A h:mm সময়',
+        LLLL: 'dddd, D MMMM YYYY, A h:mm সময়',
+    },
+    calendar: {
+        sameDay: '[আজ] LT',
+        nextDay: '[আগামীকাল] LT',
+        nextWeek: 'dddd, LT',
+        lastDay: '[গতকাল] LT',
+        lastWeek: '[গত] dddd, LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s পরে',
+        past: '%s আগে',
+        s: 'কয়েক সেকেন্ড',
+        ss: '%d সেকেন্ড',
+        m: 'এক মিনিট',
+        mm: '%d মিনিট',
+        h: 'এক ঘন্টা',
+        hh: '%d ঘন্টা',
+        d: 'এক দিন',
+        dd: '%d দিন',
+        M: 'এক মাস',
+        MM: '%d মাস',
+        y: 'এক বছর',
+        yy: '%d বছর',
+    },
+    preparse: function (string) {
+        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
+            return numberMap[match];
+        });
+    },
+    postformat: function (string) {
+        return string.replace(/\d/g, function (match) {
+            return symbolMap[match];
+        });
+    },
+
+    meridiemParse: /রাত|ভোর|সকাল|দুপুর|বিকাল|সন্ধ্যা|রাত/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'রাত') {
+            return hour < 4 ? hour : hour + 12;
+        } else if (meridiem === 'ভোর') {
+            return hour;
+        } else if (meridiem === 'সকাল') {
+            return hour;
+        } else if (meridiem === 'দুপুর') {
+            return hour >= 3 ? hour : hour + 12;
+        } else if (meridiem === 'বিকাল') {
+            return hour + 12;
+        } else if (meridiem === 'সন্ধ্যা') {
+            return hour + 12;
+        }
+    },
+
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'রাত';
+        } else if (hour < 6) {
+            return 'ভোর';
+        } else if (hour < 12) {
+            return 'সকাল';
+        } else if (hour < 15) {
+            return 'দুপুর';
+        } else if (hour < 18) {
+            return 'বিকাল';
+        } else if (hour < 20) {
+            return 'সন্ধ্যা';
+        } else {
+            return 'রাত';
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 118 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bn.js

@@ -0,0 +1,118 @@
+//! moment.js locale configuration
+//! locale : Bengali [bn]
+//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '১',
+        2: '২',
+        3: '৩',
+        4: '৪',
+        5: '৫',
+        6: '৬',
+        7: '৭',
+        8: '৮',
+        9: '৯',
+        0: '০',
+    },
+    numberMap = {
+        '১': '1',
+        '২': '2',
+        '৩': '3',
+        '৪': '4',
+        '৫': '5',
+        '৬': '6',
+        '৭': '7',
+        '৮': '8',
+        '৯': '9',
+        '০': '0',
+    };
+
+export default moment.defineLocale('bn', {
+    months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split(
+        '_'
+    ),
+    monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split(
+        '_'
+    ),
+    weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split(
+        '_'
+    ),
+    weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
+    weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'),
+    longDateFormat: {
+        LT: 'A h:mm সময়',
+        LTS: 'A h:mm:ss সময়',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY, A h:mm সময়',
+        LLLL: 'dddd, D MMMM YYYY, A h:mm সময়',
+    },
+    calendar: {
+        sameDay: '[আজ] LT',
+        nextDay: '[আগামীকাল] LT',
+        nextWeek: 'dddd, LT',
+        lastDay: '[গতকাল] LT',
+        lastWeek: '[গত] dddd, LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s পরে',
+        past: '%s আগে',
+        s: 'কয়েক সেকেন্ড',
+        ss: '%d সেকেন্ড',
+        m: 'এক মিনিট',
+        mm: '%d মিনিট',
+        h: 'এক ঘন্টা',
+        hh: '%d ঘন্টা',
+        d: 'এক দিন',
+        dd: '%d দিন',
+        M: 'এক মাস',
+        MM: '%d মাস',
+        y: 'এক বছর',
+        yy: '%d বছর',
+    },
+    preparse: function (string) {
+        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
+            return numberMap[match];
+        });
+    },
+    postformat: function (string) {
+        return string.replace(/\d/g, function (match) {
+            return symbolMap[match];
+        });
+    },
+    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (
+            (meridiem === 'রাত' && hour >= 4) ||
+            (meridiem === 'দুপুর' && hour < 5) ||
+            meridiem === 'বিকাল'
+        ) {
+            return hour + 12;
+        } else {
+            return hour;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'রাত';
+        } else if (hour < 10) {
+            return 'সকাল';
+        } else if (hour < 17) {
+            return 'দুপুর';
+        } else if (hour < 20) {
+            return 'বিকাল';
+        } else {
+            return 'রাত';
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 122 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bo.js

@@ -0,0 +1,122 @@
+//! moment.js locale configuration
+//! locale : Tibetan [bo]
+//! author : Thupten N. Chakrishar : https://github.com/vajradog
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '༡',
+        2: '༢',
+        3: '༣',
+        4: '༤',
+        5: '༥',
+        6: '༦',
+        7: '༧',
+        8: '༨',
+        9: '༩',
+        0: '༠',
+    },
+    numberMap = {
+        '༡': '1',
+        '༢': '2',
+        '༣': '3',
+        '༤': '4',
+        '༥': '5',
+        '༦': '6',
+        '༧': '7',
+        '༨': '8',
+        '༩': '9',
+        '༠': '0',
+    };
+
+export default moment.defineLocale('bo', {
+    months: 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split(
+        '_'
+    ),
+    monthsShort: 'ཟླ་1_ཟླ་2_ཟླ་3_ཟླ་4_ཟླ་5_ཟླ་6_ཟླ་7_ཟླ་8_ཟླ་9_ཟླ་10_ཟླ་11_ཟླ་12'.split(
+        '_'
+    ),
+    monthsShortRegex: /^(ཟླ་\d{1,2})/,
+    monthsParseExact: true,
+    weekdays: 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split(
+        '_'
+    ),
+    weekdaysShort: 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split(
+        '_'
+    ),
+    weekdaysMin: 'ཉི_ཟླ_མིག_ལྷག_ཕུར_སངས_སྤེན'.split('_'),
+    longDateFormat: {
+        LT: 'A h:mm',
+        LTS: 'A h:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY, A h:mm',
+        LLLL: 'dddd, D MMMM YYYY, A h:mm',
+    },
+    calendar: {
+        sameDay: '[དི་རིང] LT',
+        nextDay: '[སང་ཉིན] LT',
+        nextWeek: '[བདུན་ཕྲག་རྗེས་མ], LT',
+        lastDay: '[ཁ་སང] LT',
+        lastWeek: '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s ལ་',
+        past: '%s སྔན་ལ',
+        s: 'ལམ་སང',
+        ss: '%d སྐར་ཆ།',
+        m: 'སྐར་མ་གཅིག',
+        mm: '%d སྐར་མ',
+        h: 'ཆུ་ཚོད་གཅིག',
+        hh: '%d ཆུ་ཚོད',
+        d: 'ཉིན་གཅིག',
+        dd: '%d ཉིན་',
+        M: 'ཟླ་བ་གཅིག',
+        MM: '%d ཟླ་བ',
+        y: 'ལོ་གཅིག',
+        yy: '%d ལོ',
+    },
+    preparse: function (string) {
+        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
+            return numberMap[match];
+        });
+    },
+    postformat: function (string) {
+        return string.replace(/\d/g, function (match) {
+            return symbolMap[match];
+        });
+    },
+    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (
+            (meridiem === 'མཚན་མོ' && hour >= 4) ||
+            (meridiem === 'ཉིན་གུང' && hour < 5) ||
+            meridiem === 'དགོང་དག'
+        ) {
+            return hour + 12;
+        } else {
+            return hour;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'མཚན་མོ';
+        } else if (hour < 10) {
+            return 'ཞོགས་ཀས';
+        } else if (hour < 17) {
+            return 'ཉིན་གུང';
+        } else if (hour < 20) {
+            return 'དགོང་དག';
+        } else {
+            return 'མཚན་མོ';
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 165 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/br.js

@@ -0,0 +1,165 @@
+//! moment.js locale configuration
+//! locale : Breton [br]
+//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
+
+import moment from '../moment';
+
+function relativeTimeWithMutation(number, withoutSuffix, key) {
+    var format = {
+        mm: 'munutenn',
+        MM: 'miz',
+        dd: 'devezh',
+    };
+    return number + ' ' + mutation(format[key], number);
+}
+function specialMutationForYears(number) {
+    switch (lastNumber(number)) {
+        case 1:
+        case 3:
+        case 4:
+        case 5:
+        case 9:
+            return number + ' bloaz';
+        default:
+            return number + ' vloaz';
+    }
+}
+function lastNumber(number) {
+    if (number > 9) {
+        return lastNumber(number % 10);
+    }
+    return number;
+}
+function mutation(text, number) {
+    if (number === 2) {
+        return softMutation(text);
+    }
+    return text;
+}
+function softMutation(text) {
+    var mutationTable = {
+        m: 'v',
+        b: 'v',
+        d: 'z',
+    };
+    if (mutationTable[text.charAt(0)] === undefined) {
+        return text;
+    }
+    return mutationTable[text.charAt(0)] + text.substring(1);
+}
+
+var monthsParse = [
+        /^gen/i,
+        /^c[ʼ\']hwe/i,
+        /^meu/i,
+        /^ebr/i,
+        /^mae/i,
+        /^(mez|eve)/i,
+        /^gou/i,
+        /^eos/i,
+        /^gwe/i,
+        /^her/i,
+        /^du/i,
+        /^ker/i,
+    ],
+    monthsRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,
+    monthsStrictRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i,
+    monthsShortStrictRegex = /^(gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,
+    fullWeekdaysParse = [
+        /^sul/i,
+        /^lun/i,
+        /^meurzh/i,
+        /^merc[ʼ\']her/i,
+        /^yaou/i,
+        /^gwener/i,
+        /^sadorn/i,
+    ],
+    shortWeekdaysParse = [
+        /^Sul/i,
+        /^Lun/i,
+        /^Meu/i,
+        /^Mer/i,
+        /^Yao/i,
+        /^Gwe/i,
+        /^Sad/i,
+    ],
+    minWeekdaysParse = [
+        /^Su/i,
+        /^Lu/i,
+        /^Me([^r]|$)/i,
+        /^Mer/i,
+        /^Ya/i,
+        /^Gw/i,
+        /^Sa/i,
+    ];
+
+export default moment.defineLocale('br', {
+    months: 'Genver_Cʼhwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split(
+        '_'
+    ),
+    monthsShort: 'Gen_Cʼhwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
+    weekdays: 'Sul_Lun_Meurzh_Mercʼher_Yaou_Gwener_Sadorn'.split('_'),
+    weekdaysShort: 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
+    weekdaysMin: 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
+    weekdaysParse: minWeekdaysParse,
+    fullWeekdaysParse: fullWeekdaysParse,
+    shortWeekdaysParse: shortWeekdaysParse,
+    minWeekdaysParse: minWeekdaysParse,
+
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: monthsStrictRegex,
+    monthsShortStrictRegex: monthsShortStrictRegex,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D [a viz] MMMM YYYY',
+        LLL: 'D [a viz] MMMM YYYY HH:mm',
+        LLLL: 'dddd, D [a viz] MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Hiziv da] LT',
+        nextDay: '[Warcʼhoazh da] LT',
+        nextWeek: 'dddd [da] LT',
+        lastDay: '[Decʼh da] LT',
+        lastWeek: 'dddd [paset da] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'a-benn %s',
+        past: '%s ʼzo',
+        s: 'un nebeud segondennoù',
+        ss: '%d eilenn',
+        m: 'ur vunutenn',
+        mm: relativeTimeWithMutation,
+        h: 'un eur',
+        hh: '%d eur',
+        d: 'un devezh',
+        dd: relativeTimeWithMutation,
+        M: 'ur miz',
+        MM: relativeTimeWithMutation,
+        y: 'ur bloaz',
+        yy: specialMutationForYears,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/,
+    ordinal: function (number) {
+        var output = number === 1 ? 'añ' : 'vet';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+    meridiemParse: /a.m.|g.m./, // goude merenn | a-raok merenn
+    isPM: function (token) {
+        return token === 'g.m.';
+    },
+    meridiem: function (hour, minute, isLower) {
+        return hour < 12 ? 'a.m.' : 'g.m.';
+    },
+});

+ 149 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/bs.js

@@ -0,0 +1,149 @@
+//! moment.js locale configuration
+//! locale : Bosnian [bs]
+//! author : Nedim Cholich : https://github.com/frontyard
+//! based on (hr) translation by Bojan Marković
+
+import moment from '../moment';
+
+function translate(number, withoutSuffix, key) {
+    var result = number + ' ';
+    switch (key) {
+        case 'ss':
+            if (number === 1) {
+                result += 'sekunda';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sekunde';
+            } else {
+                result += 'sekundi';
+            }
+            return result;
+        case 'm':
+            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minuta';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'jedan sat' : 'jednog sata';
+        case 'hh':
+            if (number === 1) {
+                result += 'sat';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sata';
+            } else {
+                result += 'sati';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dana';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mjesec';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'mjeseca';
+            } else {
+                result += 'mjeseci';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'godina';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'godine';
+            } else {
+                result += 'godina';
+            }
+            return result;
+    }
+}
+
+export default moment.defineLocale('bs', {
+    months: 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split(
+        '_'
+    ),
+    monthsShort: 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split(
+        '_'
+    ),
+    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
+    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY H:mm',
+        LLLL: 'dddd, D. MMMM YYYY H:mm',
+    },
+    calendar: {
+        sameDay: '[danas u] LT',
+        nextDay: '[sutra u] LT',
+        nextWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[u] [nedjelju] [u] LT';
+                case 3:
+                    return '[u] [srijedu] [u] LT';
+                case 6:
+                    return '[u] [subotu] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[u] dddd [u] LT';
+            }
+        },
+        lastDay: '[jučer u] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                case 3:
+                    return '[prošlu] dddd [u] LT';
+                case 6:
+                    return '[prošle] [subote] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prošli] dddd [u] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'za %s',
+        past: 'prije %s',
+        s: 'par sekundi',
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: translate,
+        hh: translate,
+        d: 'dan',
+        dd: translate,
+        M: 'mjesec',
+        MM: translate,
+        y: 'godinu',
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 97 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ca.js

@@ -0,0 +1,97 @@
+//! moment.js locale configuration
+//! locale : Catalan [ca]
+//! author : Juan G. Hurtado : https://github.com/juanghurtado
+
+import moment from '../moment';
+
+export default moment.defineLocale('ca', {
+    months: {
+        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split(
+            '_'
+        ),
+        format: "de gener_de febrer_de març_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split(
+            '_'
+        ),
+        isFormat: /D[oD]?(\s)+MMMM/,
+    },
+    monthsShort: 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split(
+        '_'
+    ),
+    weekdaysShort: 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
+    weekdaysMin: 'dg_dl_dt_dc_dj_dv_ds'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM [de] YYYY',
+        ll: 'D MMM YYYY',
+        LLL: 'D MMMM [de] YYYY [a les] H:mm',
+        lll: 'D MMM YYYY, H:mm',
+        LLLL: 'dddd D MMMM [de] YYYY [a les] H:mm',
+        llll: 'ddd D MMM YYYY, H:mm',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[avui a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
+        },
+        nextDay: function () {
+            return '[demà a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
+        },
+        lastDay: function () {
+            return '[ahir a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[el] dddd [passat a ' +
+                (this.hours() !== 1 ? 'les' : 'la') +
+                '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: "d'aquí %s",
+        past: 'fa %s',
+        s: 'uns segons',
+        ss: '%d segons',
+        m: 'un minut',
+        mm: '%d minuts',
+        h: 'una hora',
+        hh: '%d hores',
+        d: 'un dia',
+        dd: '%d dies',
+        M: 'un mes',
+        MM: '%d mesos',
+        y: 'un any',
+        yy: '%d anys',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/,
+    ordinal: function (number, period) {
+        var output =
+            number === 1
+                ? 'r'
+                : number === 2
+                ? 'n'
+                : number === 3
+                ? 'r'
+                : number === 4
+                ? 't'
+                : 'è';
+        if (period === 'w' || period === 'W') {
+            output = 'a';
+        }
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 171 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cs.js

@@ -0,0 +1,171 @@
+//! moment.js locale configuration
+//! locale : Czech [cs]
+//! author : petrbela : https://github.com/petrbela
+
+import moment from '../moment';
+
+var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split(
+        '_'
+    ),
+    monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'),
+    monthsParse = [
+        /^led/i,
+        /^úno/i,
+        /^bře/i,
+        /^dub/i,
+        /^kvě/i,
+        /^(čvn|červen$|června)/i,
+        /^(čvc|červenec|července)/i,
+        /^srp/i,
+        /^zář/i,
+        /^říj/i,
+        /^lis/i,
+        /^pro/i,
+    ],
+    // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
+    // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
+    monthsRegex = /^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i;
+
+function plural(n) {
+    return n > 1 && n < 5 && ~~(n / 10) !== 1;
+}
+function translate(number, withoutSuffix, key, isFuture) {
+    var result = number + ' ';
+    switch (key) {
+        case 's': // a few seconds / in a few seconds / a few seconds ago
+            return withoutSuffix || isFuture ? 'pár sekund' : 'pár sekundami';
+        case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'sekundy' : 'sekund');
+            } else {
+                return result + 'sekundami';
+            }
+        case 'm': // a minute / in a minute / a minute ago
+            return withoutSuffix ? 'minuta' : isFuture ? 'minutu' : 'minutou';
+        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'minuty' : 'minut');
+            } else {
+                return result + 'minutami';
+            }
+        case 'h': // an hour / in an hour / an hour ago
+            return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou';
+        case 'hh': // 9 hours / in 9 hours / 9 hours ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'hodiny' : 'hodin');
+            } else {
+                return result + 'hodinami';
+            }
+        case 'd': // a day / in a day / a day ago
+            return withoutSuffix || isFuture ? 'den' : 'dnem';
+        case 'dd': // 9 days / in 9 days / 9 days ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'dny' : 'dní');
+            } else {
+                return result + 'dny';
+            }
+        case 'M': // a month / in a month / a month ago
+            return withoutSuffix || isFuture ? 'měsíc' : 'měsícem';
+        case 'MM': // 9 months / in 9 months / 9 months ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'měsíce' : 'měsíců');
+            } else {
+                return result + 'měsíci';
+            }
+        case 'y': // a year / in a year / a year ago
+            return withoutSuffix || isFuture ? 'rok' : 'rokem';
+        case 'yy': // 9 years / in 9 years / 9 years ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'roky' : 'let');
+            } else {
+                return result + 'lety';
+            }
+    }
+}
+
+export default moment.defineLocale('cs', {
+    months: months,
+    monthsShort: monthsShort,
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
+    // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
+    monthsStrictRegex: /^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i,
+    monthsShortStrictRegex: /^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
+    weekdaysShort: 'ne_po_út_st_čt_pá_so'.split('_'),
+    weekdaysMin: 'ne_po_út_st_čt_pá_so'.split('_'),
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY H:mm',
+        LLLL: 'dddd D. MMMM YYYY H:mm',
+        l: 'D. M. YYYY',
+    },
+    calendar: {
+        sameDay: '[dnes v] LT',
+        nextDay: '[zítra v] LT',
+        nextWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[v neděli v] LT';
+                case 1:
+                case 2:
+                    return '[v] dddd [v] LT';
+                case 3:
+                    return '[ve středu v] LT';
+                case 4:
+                    return '[ve čtvrtek v] LT';
+                case 5:
+                    return '[v pátek v] LT';
+                case 6:
+                    return '[v sobotu v] LT';
+            }
+        },
+        lastDay: '[včera v] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[minulou neděli v] LT';
+                case 1:
+                case 2:
+                    return '[minulé] dddd [v] LT';
+                case 3:
+                    return '[minulou středu v] LT';
+                case 4:
+                case 5:
+                    return '[minulý] dddd [v] LT';
+                case 6:
+                    return '[minulou sobotu v] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'za %s',
+        past: 'před %s',
+        s: translate,
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: translate,
+        hh: translate,
+        d: translate,
+        dd: translate,
+        M: translate,
+        MM: translate,
+        y: translate,
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 62 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cv.js

@@ -0,0 +1,62 @@
+//! moment.js locale configuration
+//! locale : Chuvash [cv]
+//! author : Anatoly Mironov : https://github.com/mirontoli
+
+import moment from '../moment';
+
+export default moment.defineLocale('cv', {
+    months: 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split(
+        '_'
+    ),
+    monthsShort: 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
+    weekdays: 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split(
+        '_'
+    ),
+    weekdaysShort: 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
+    weekdaysMin: 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD-MM-YYYY',
+        LL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
+        LLL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+        LLLL: 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+    },
+    calendar: {
+        sameDay: '[Паян] LT [сехетре]',
+        nextDay: '[Ыран] LT [сехетре]',
+        lastDay: '[Ӗнер] LT [сехетре]',
+        nextWeek: '[Ҫитес] dddd LT [сехетре]',
+        lastWeek: '[Иртнӗ] dddd LT [сехетре]',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: function (output) {
+            var affix = /сехет$/i.exec(output)
+                ? 'рен'
+                : /ҫул$/i.exec(output)
+                ? 'тан'
+                : 'ран';
+            return output + affix;
+        },
+        past: '%s каялла',
+        s: 'пӗр-ик ҫеккунт',
+        ss: '%d ҫеккунт',
+        m: 'пӗр минут',
+        mm: '%d минут',
+        h: 'пӗр сехет',
+        hh: '%d сехет',
+        d: 'пӗр кун',
+        dd: '%d кун',
+        M: 'пӗр уйӑх',
+        MM: '%d уйӑх',
+        y: 'пӗр ҫул',
+        yy: '%d ҫул',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}-мӗш/,
+    ordinal: '%d-мӗш',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 97 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/cy.js

@@ -0,0 +1,97 @@
+//! moment.js locale configuration
+//! locale : Welsh [cy]
+//! author : Robert Allen : https://github.com/robgallen
+//! author : https://github.com/ryangreaves
+
+import moment from '../moment';
+
+export default moment.defineLocale('cy', {
+    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split(
+        '_'
+    ),
+    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split(
+        '_'
+    ),
+    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
+    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
+    weekdaysParseExact: true,
+    // time formats are the same as en-gb
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Heddiw am] LT',
+        nextDay: '[Yfory am] LT',
+        nextWeek: 'dddd [am] LT',
+        lastDay: '[Ddoe am] LT',
+        lastWeek: 'dddd [diwethaf am] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'mewn %s',
+        past: '%s yn ôl',
+        s: 'ychydig eiliadau',
+        ss: '%d eiliad',
+        m: 'munud',
+        mm: '%d munud',
+        h: 'awr',
+        hh: '%d awr',
+        d: 'diwrnod',
+        dd: '%d diwrnod',
+        M: 'mis',
+        MM: '%d mis',
+        y: 'blwyddyn',
+        yy: '%d flynedd',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
+    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
+    ordinal: function (number) {
+        var b = number,
+            output = '',
+            lookup = [
+                '',
+                'af',
+                'il',
+                'ydd',
+                'ydd',
+                'ed',
+                'ed',
+                'ed',
+                'fed',
+                'fed',
+                'fed', // 1af to 10fed
+                'eg',
+                'fed',
+                'eg',
+                'eg',
+                'fed',
+                'eg',
+                'eg',
+                'fed',
+                'eg',
+                'fed', // 11eg to 20fed
+            ];
+        if (b > 20) {
+            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
+                output = 'fed'; // not 30ain, 70ain or 90ain
+            } else {
+                output = 'ain';
+            }
+        } else if (b > 0) {
+            output = lookup[b];
+        }
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 53 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/da.js

@@ -0,0 +1,53 @@
+//! moment.js locale configuration
+//! locale : Danish [da]
+//! author : Ulrik Nielsen : https://github.com/mrbase
+
+import moment from '../moment';
+
+export default moment.defineLocale('da', {
+    months: 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split(
+        '_'
+    ),
+    monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
+    weekdays: 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
+    weekdaysShort: 'søn_man_tir_ons_tor_fre_lør'.split('_'),
+    weekdaysMin: 'sø_ma_ti_on_to_fr_lø'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY HH:mm',
+        LLLL: 'dddd [d.] D. MMMM YYYY [kl.] HH:mm',
+    },
+    calendar: {
+        sameDay: '[i dag kl.] LT',
+        nextDay: '[i morgen kl.] LT',
+        nextWeek: 'på dddd [kl.] LT',
+        lastDay: '[i går kl.] LT',
+        lastWeek: '[i] dddd[s kl.] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'om %s',
+        past: '%s siden',
+        s: 'få sekunder',
+        ss: '%d sekunder',
+        m: 'et minut',
+        mm: '%d minutter',
+        h: 'en time',
+        hh: '%d timer',
+        d: 'en dag',
+        dd: '%d dage',
+        M: 'en måned',
+        MM: '%d måneder',
+        y: 'et år',
+        yy: '%d år',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 79 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de-at.js

@@ -0,0 +1,79 @@
+//! moment.js locale configuration
+//! locale : German (Austria) [de-at]
+//! author : lluchs : https://github.com/lluchs
+//! author: Menelion Elensúle: https://github.com/Oire
+//! author : Martin Groller : https://github.com/MadMG
+//! author : Mikolaj Dadela : https://github.com/mik01aj
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        m: ['eine Minute', 'einer Minute'],
+        h: ['eine Stunde', 'einer Stunde'],
+        d: ['ein Tag', 'einem Tag'],
+        dd: [number + ' Tage', number + ' Tagen'],
+        w: ['eine Woche', 'einer Woche'],
+        M: ['ein Monat', 'einem Monat'],
+        MM: [number + ' Monate', number + ' Monaten'],
+        y: ['ein Jahr', 'einem Jahr'],
+        yy: [number + ' Jahre', number + ' Jahren'],
+    };
+    return withoutSuffix ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('de-at', {
+    months: 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
+        '_'
+    ),
+    monthsShort: 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
+        '_'
+    ),
+    weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
+    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY HH:mm',
+        LLLL: 'dddd, D. MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[heute um] LT [Uhr]',
+        sameElse: 'L',
+        nextDay: '[morgen um] LT [Uhr]',
+        nextWeek: 'dddd [um] LT [Uhr]',
+        lastDay: '[gestern um] LT [Uhr]',
+        lastWeek: '[letzten] dddd [um] LT [Uhr]',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: 'vor %s',
+        s: 'ein paar Sekunden',
+        ss: '%d Sekunden',
+        m: processRelativeTime,
+        mm: '%d Minuten',
+        h: processRelativeTime,
+        hh: '%d Stunden',
+        d: processRelativeTime,
+        dd: processRelativeTime,
+        w: processRelativeTime,
+        ww: '%d Wochen',
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 78 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de-ch.js

@@ -0,0 +1,78 @@
+//! moment.js locale configuration
+//! locale : German (Switzerland) [de-ch]
+//! author : sschueller : https://github.com/sschueller
+
+// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        m: ['eine Minute', 'einer Minute'],
+        h: ['eine Stunde', 'einer Stunde'],
+        d: ['ein Tag', 'einem Tag'],
+        dd: [number + ' Tage', number + ' Tagen'],
+        w: ['eine Woche', 'einer Woche'],
+        M: ['ein Monat', 'einem Monat'],
+        MM: [number + ' Monate', number + ' Monaten'],
+        y: ['ein Jahr', 'einem Jahr'],
+        yy: [number + ' Jahre', number + ' Jahren'],
+    };
+    return withoutSuffix ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('de-ch', {
+    months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
+        '_'
+    ),
+    monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
+        '_'
+    ),
+    weekdaysShort: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
+    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY HH:mm',
+        LLLL: 'dddd, D. MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[heute um] LT [Uhr]',
+        sameElse: 'L',
+        nextDay: '[morgen um] LT [Uhr]',
+        nextWeek: 'dddd [um] LT [Uhr]',
+        lastDay: '[gestern um] LT [Uhr]',
+        lastWeek: '[letzten] dddd [um] LT [Uhr]',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: 'vor %s',
+        s: 'ein paar Sekunden',
+        ss: '%d Sekunden',
+        m: processRelativeTime,
+        mm: '%d Minuten',
+        h: processRelativeTime,
+        hh: '%d Stunden',
+        d: processRelativeTime,
+        dd: processRelativeTime,
+        w: processRelativeTime,
+        ww: '%d Wochen',
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 78 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/de.js

@@ -0,0 +1,78 @@
+//! moment.js locale configuration
+//! locale : German [de]
+//! author : lluchs : https://github.com/lluchs
+//! author: Menelion Elensúle: https://github.com/Oire
+//! author : Mikolaj Dadela : https://github.com/mik01aj
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        m: ['eine Minute', 'einer Minute'],
+        h: ['eine Stunde', 'einer Stunde'],
+        d: ['ein Tag', 'einem Tag'],
+        dd: [number + ' Tage', number + ' Tagen'],
+        w: ['eine Woche', 'einer Woche'],
+        M: ['ein Monat', 'einem Monat'],
+        MM: [number + ' Monate', number + ' Monaten'],
+        y: ['ein Jahr', 'einem Jahr'],
+        yy: [number + ' Jahre', number + ' Jahren'],
+    };
+    return withoutSuffix ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('de', {
+    months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
+        '_'
+    ),
+    monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
+        '_'
+    ),
+    weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
+    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY HH:mm',
+        LLLL: 'dddd, D. MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[heute um] LT [Uhr]',
+        sameElse: 'L',
+        nextDay: '[morgen um] LT [Uhr]',
+        nextWeek: 'dddd [um] LT [Uhr]',
+        lastDay: '[gestern um] LT [Uhr]',
+        lastWeek: '[letzten] dddd [um] LT [Uhr]',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: 'vor %s',
+        s: 'ein paar Sekunden',
+        ss: '%d Sekunden',
+        m: processRelativeTime,
+        mm: '%d Minuten',
+        h: processRelativeTime,
+        hh: '%d Stunden',
+        d: processRelativeTime,
+        dd: processRelativeTime,
+        w: processRelativeTime,
+        ww: '%d Wochen',
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 90 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/dv.js

@@ -0,0 +1,90 @@
+//! moment.js locale configuration
+//! locale : Maldivian [dv]
+//! author : Jawish Hameed : https://github.com/jawish
+
+import moment from '../moment';
+
+var months = [
+        'ޖެނުއަރީ',
+        'ފެބްރުއަރީ',
+        'މާރިޗު',
+        'އޭޕްރީލު',
+        'މޭ',
+        'ޖޫން',
+        'ޖުލައި',
+        'އޯގަސްޓު',
+        'ސެޕްޓެމްބަރު',
+        'އޮކްޓޯބަރު',
+        'ނޮވެމްބަރު',
+        'ޑިސެމްބަރު',
+    ],
+    weekdays = [
+        'އާދިއްތަ',
+        'ހޯމަ',
+        'އަންގާރަ',
+        'ބުދަ',
+        'ބުރާސްފަތި',
+        'ހުކުރު',
+        'ހޮނިހިރު',
+    ];
+
+export default moment.defineLocale('dv', {
+    months: months,
+    monthsShort: months,
+    weekdays: weekdays,
+    weekdaysShort: weekdays,
+    weekdaysMin: 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'D/M/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /މކ|މފ/,
+    isPM: function (input) {
+        return 'މފ' === input;
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'މކ';
+        } else {
+            return 'މފ';
+        }
+    },
+    calendar: {
+        sameDay: '[މިއަދު] LT',
+        nextDay: '[މާދަމާ] LT',
+        nextWeek: 'dddd LT',
+        lastDay: '[އިއްޔެ] LT',
+        lastWeek: '[ފާއިތުވި] dddd LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'ތެރޭގައި %s',
+        past: 'ކުރިން %s',
+        s: 'ސިކުންތުކޮޅެއް',
+        ss: 'd% ސިކުންތު',
+        m: 'މިނިޓެއް',
+        mm: 'މިނިޓު %d',
+        h: 'ގަޑިއިރެއް',
+        hh: 'ގަޑިއިރު %d',
+        d: 'ދުވަހެއް',
+        dd: 'ދުވަސް %d',
+        M: 'މަހެއް',
+        MM: 'މަސް %d',
+        y: 'އަހަރެއް',
+        yy: 'އަހަރު %d',
+    },
+    preparse: function (string) {
+        return string.replace(/،/g, ',');
+    },
+    postformat: function (string) {
+        return string.replace(/,/g, '،');
+    },
+    week: {
+        dow: 7, // Sunday is the first day of the week.
+        doy: 12, // The week that contains Jan 12th is the first week of the year.
+    },
+});

+ 104 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/el.js

@@ -0,0 +1,104 @@
+//! moment.js locale configuration
+//! locale : Greek [el]
+//! author : Aggelos Karalias : https://github.com/mehiel
+
+import moment from '../moment';
+
+function isFunction(input) {
+    return (
+        (typeof Function !== 'undefined' && input instanceof Function) ||
+        Object.prototype.toString.call(input) === '[object Function]'
+    );
+}
+
+export default moment.defineLocale('el', {
+    monthsNominativeEl: 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split(
+        '_'
+    ),
+    monthsGenitiveEl: 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split(
+        '_'
+    ),
+    months: function (momentToFormat, format) {
+        if (!momentToFormat) {
+            return this._monthsNominativeEl;
+        } else if (
+            typeof format === 'string' &&
+            /D/.test(format.substring(0, format.indexOf('MMMM')))
+        ) {
+            // if there is a day number before 'MMMM'
+            return this._monthsGenitiveEl[momentToFormat.month()];
+        } else {
+            return this._monthsNominativeEl[momentToFormat.month()];
+        }
+    },
+    monthsShort: 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
+    weekdays: 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split(
+        '_'
+    ),
+    weekdaysShort: 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
+    weekdaysMin: 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
+    meridiem: function (hours, minutes, isLower) {
+        if (hours > 11) {
+            return isLower ? 'μμ' : 'ΜΜ';
+        } else {
+            return isLower ? 'πμ' : 'ΠΜ';
+        }
+    },
+    isPM: function (input) {
+        return (input + '').toLowerCase()[0] === 'μ';
+    },
+    meridiemParse: /[ΠΜ]\.?Μ?\.?/i,
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY h:mm A',
+        LLLL: 'dddd, D MMMM YYYY h:mm A',
+    },
+    calendarEl: {
+        sameDay: '[Σήμερα {}] LT',
+        nextDay: '[Αύριο {}] LT',
+        nextWeek: 'dddd [{}] LT',
+        lastDay: '[Χθες {}] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 6:
+                    return '[το προηγούμενο] dddd [{}] LT';
+                default:
+                    return '[την προηγούμενη] dddd [{}] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    calendar: function (key, mom) {
+        var output = this._calendarEl[key],
+            hours = mom && mom.hours();
+        if (isFunction(output)) {
+            output = output.apply(mom);
+        }
+        return output.replace('{}', hours % 12 === 1 ? 'στη' : 'στις');
+    },
+    relativeTime: {
+        future: 'σε %s',
+        past: '%s πριν',
+        s: 'λίγα δευτερόλεπτα',
+        ss: '%d δευτερόλεπτα',
+        m: 'ένα λεπτό',
+        mm: '%d λεπτά',
+        h: 'μία ώρα',
+        hh: '%d ώρες',
+        d: 'μία μέρα',
+        dd: '%d μέρες',
+        M: 'ένας μήνας',
+        MM: '%d μήνες',
+        y: 'ένας χρόνος',
+        yy: '%d χρόνια',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}η/,
+    ordinal: '%dη',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4st is the first week of the year.
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-au.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (Australia) [en-au]
+//! author : Jared Morse : https://github.com/jarcoal
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-au', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY h:mm A',
+        LLLL: 'dddd, D MMMM YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 64 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-ca.js

@@ -0,0 +1,64 @@
+//! moment.js locale configuration
+//! locale : English (Canada) [en-ca]
+//! author : Jonathan Abourbih : https://github.com/jonbca
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-ca', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'YYYY-MM-DD',
+        LL: 'MMMM D, YYYY',
+        LLL: 'MMMM D, YYYY h:mm A',
+        LLLL: 'dddd, MMMM D, YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-gb.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (United Kingdom) [en-gb]
+//! author : Chris Gedrim : https://github.com/chrisgedrim
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-gb', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-ie.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (Ireland) [en-ie]
+//! author : Chris Cartlidge : https://github.com/chriscartlidge
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-ie', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 64 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-il.js

@@ -0,0 +1,64 @@
+//! moment.js locale configuration
+//! locale : English (Israel) [en-il]
+//! author : Chris Gedrim : https://github.com/chrisgedrim
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-il', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-in.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (India) [en-in]
+//! author : Jatin Agrawal : https://github.com/jatinag22
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-in', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY h:mm A',
+        LLLL: 'dddd, D MMMM YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 1st is the first week of the year.
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-nz.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (New Zealand) [en-nz]
+//! author : Luke McGregor : https://github.com/lukemcgregor
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-nz', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY h:mm A',
+        LLLL: 'dddd, D MMMM YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/en-sg.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : English (Singapore) [en-sg]
+//! author : Matthew Castrillon-Madrigal : https://github.com/techdimension
+
+import moment from '../moment';
+
+export default moment.defineLocale('en-sg', {
+    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
+    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
+        '_'
+    ),
+    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
+    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        ss: '%d seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
+    ordinal: function (number) {
+        var b = number % 10,
+            output =
+                ~~((number % 100) / 10) === 1
+                    ? 'th'
+                    : b === 1
+                    ? 'st'
+                    : b === 2
+                    ? 'nd'
+                    : b === 3
+                    ? 'rd'
+                    : 'th';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 68 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/eo.js

@@ -0,0 +1,68 @@
+//! moment.js locale configuration
+//! locale : Esperanto [eo]
+//! author : Colin Dean : https://github.com/colindean
+//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia
+//! comment : miestasmia corrected the translation by colindean
+//! comment : Vivakvo corrected the translation by colindean and miestasmia
+
+import moment from '../moment';
+
+export default moment.defineLocale('eo', {
+    months: 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split(
+        '_'
+    ),
+    monthsShort: 'jan_feb_mart_apr_maj_jun_jul_aŭg_sept_okt_nov_dec'.split('_'),
+    weekdays: 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),
+    weekdaysShort: 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),
+    weekdaysMin: 'di_lu_ma_me_ĵa_ve_sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'YYYY-MM-DD',
+        LL: '[la] D[-an de] MMMM, YYYY',
+        LLL: '[la] D[-an de] MMMM, YYYY HH:mm',
+        LLLL: 'dddd[n], [la] D[-an de] MMMM, YYYY HH:mm',
+        llll: 'ddd, [la] D[-an de] MMM, YYYY HH:mm',
+    },
+    meridiemParse: /[ap]\.t\.m/i,
+    isPM: function (input) {
+        return input.charAt(0).toLowerCase() === 'p';
+    },
+    meridiem: function (hours, minutes, isLower) {
+        if (hours > 11) {
+            return isLower ? 'p.t.m.' : 'P.T.M.';
+        } else {
+            return isLower ? 'a.t.m.' : 'A.T.M.';
+        }
+    },
+    calendar: {
+        sameDay: '[Hodiaŭ je] LT',
+        nextDay: '[Morgaŭ je] LT',
+        nextWeek: 'dddd[n je] LT',
+        lastDay: '[Hieraŭ je] LT',
+        lastWeek: '[pasintan] dddd[n je] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'post %s',
+        past: 'antaŭ %s',
+        s: 'kelkaj sekundoj',
+        ss: '%d sekundoj',
+        m: 'unu minuto',
+        mm: '%d minutoj',
+        h: 'unu horo',
+        hh: '%d horoj',
+        d: 'unu tago', //ne 'diurno', ĉar estas uzita por proksimumo
+        dd: '%d tagoj',
+        M: 'unu monato',
+        MM: '%d monatoj',
+        y: 'unu jaro',
+        yy: '%d jaroj',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}a/,
+    ordinal: '%da',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 104 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-do.js

@@ -0,0 +1,104 @@
+//! moment.js locale configuration
+//! locale : Spanish (Dominican Republic) [es-do]
+
+import moment from '../moment';
+
+var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
+        '_'
+    ),
+    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
+    monthsParse = [
+        /^ene/i,
+        /^feb/i,
+        /^mar/i,
+        /^abr/i,
+        /^may/i,
+        /^jun/i,
+        /^jul/i,
+        /^ago/i,
+        /^sep/i,
+        /^oct/i,
+        /^nov/i,
+        /^dic/i,
+    ],
+    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
+
+export default moment.defineLocale('es-do', {
+    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
+        '_'
+    ),
+    monthsShort: function (m, format) {
+        if (!m) {
+            return monthsShortDot;
+        } else if (/-MMM-/.test(format)) {
+            return monthsShort[m.month()];
+        } else {
+            return monthsShortDot[m.month()];
+        }
+    },
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
+    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
+    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
+    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'DD/MM/YYYY',
+        LL: 'D [de] MMMM [de] YYYY',
+        LLL: 'D [de] MMMM [de] YYYY h:mm A',
+        LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextDay: function () {
+            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastDay: function () {
+            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[el] dddd [pasado a la' +
+                (this.hours() !== 1 ? 's' : '') +
+                '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'en %s',
+        past: 'hace %s',
+        s: 'unos segundos',
+        ss: '%d segundos',
+        m: 'un minuto',
+        mm: '%d minutos',
+        h: 'una hora',
+        hh: '%d horas',
+        d: 'un día',
+        dd: '%d días',
+        w: 'una semana',
+        ww: '%d semanas',
+        M: 'un mes',
+        MM: '%d meses',
+        y: 'un año',
+        yy: '%d años',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 106 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-mx.js

@@ -0,0 +1,106 @@
+//! moment.js locale configuration
+//! locale : Spanish (Mexico) [es-mx]
+//! author : JC Franco : https://github.com/jcfranco
+
+import moment from '../moment';
+
+var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
+        '_'
+    ),
+    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
+    monthsParse = [
+        /^ene/i,
+        /^feb/i,
+        /^mar/i,
+        /^abr/i,
+        /^may/i,
+        /^jun/i,
+        /^jul/i,
+        /^ago/i,
+        /^sep/i,
+        /^oct/i,
+        /^nov/i,
+        /^dic/i,
+    ],
+    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
+
+export default moment.defineLocale('es-mx', {
+    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
+        '_'
+    ),
+    monthsShort: function (m, format) {
+        if (!m) {
+            return monthsShortDot;
+        } else if (/-MMM-/.test(format)) {
+            return monthsShort[m.month()];
+        } else {
+            return monthsShortDot[m.month()];
+        }
+    },
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
+    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
+    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
+    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D [de] MMMM [de] YYYY',
+        LLL: 'D [de] MMMM [de] YYYY H:mm',
+        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextDay: function () {
+            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastDay: function () {
+            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[el] dddd [pasado a la' +
+                (this.hours() !== 1 ? 's' : '') +
+                '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'en %s',
+        past: 'hace %s',
+        s: 'unos segundos',
+        ss: '%d segundos',
+        m: 'un minuto',
+        mm: '%d minutos',
+        h: 'una hora',
+        hh: '%d horas',
+        d: 'un día',
+        dd: '%d días',
+        w: 'una semana',
+        ww: '%d semanas',
+        M: 'un mes',
+        MM: '%d meses',
+        y: 'un año',
+        yy: '%d años',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+    invalidDate: 'Fecha inválida',
+});

+ 106 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es-us.js

@@ -0,0 +1,106 @@
+//! moment.js locale configuration
+//! locale : Spanish (United States) [es-us]
+//! author : bustta : https://github.com/bustta
+//! author : chrisrodz : https://github.com/chrisrodz
+
+import moment from '../moment';
+
+var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
+        '_'
+    ),
+    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
+    monthsParse = [
+        /^ene/i,
+        /^feb/i,
+        /^mar/i,
+        /^abr/i,
+        /^may/i,
+        /^jun/i,
+        /^jul/i,
+        /^ago/i,
+        /^sep/i,
+        /^oct/i,
+        /^nov/i,
+        /^dic/i,
+    ],
+    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
+
+export default moment.defineLocale('es-us', {
+    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
+        '_'
+    ),
+    monthsShort: function (m, format) {
+        if (!m) {
+            return monthsShortDot;
+        } else if (/-MMM-/.test(format)) {
+            return monthsShort[m.month()];
+        } else {
+            return monthsShortDot[m.month()];
+        }
+    },
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
+    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
+    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
+    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'h:mm A',
+        LTS: 'h:mm:ss A',
+        L: 'MM/DD/YYYY',
+        LL: 'D [de] MMMM [de] YYYY',
+        LLL: 'D [de] MMMM [de] YYYY h:mm A',
+        LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextDay: function () {
+            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastDay: function () {
+            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[el] dddd [pasado a la' +
+                (this.hours() !== 1 ? 's' : '') +
+                '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'en %s',
+        past: 'hace %s',
+        s: 'unos segundos',
+        ss: '%d segundos',
+        m: 'un minuto',
+        mm: '%d minutos',
+        h: 'una hora',
+        hh: '%d horas',
+        d: 'un día',
+        dd: '%d días',
+        w: 'una semana',
+        ww: '%d semanas',
+        M: 'un mes',
+        MM: '%d meses',
+        y: 'un año',
+        yy: '%d años',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 106 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/es.js

@@ -0,0 +1,106 @@
+//! moment.js locale configuration
+//! locale : Spanish [es]
+//! author : Julio Napurí : https://github.com/julionc
+
+import moment from '../moment';
+
+var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
+        '_'
+    ),
+    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
+    monthsParse = [
+        /^ene/i,
+        /^feb/i,
+        /^mar/i,
+        /^abr/i,
+        /^may/i,
+        /^jun/i,
+        /^jul/i,
+        /^ago/i,
+        /^sep/i,
+        /^oct/i,
+        /^nov/i,
+        /^dic/i,
+    ],
+    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
+
+export default moment.defineLocale('es', {
+    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
+        '_'
+    ),
+    monthsShort: function (m, format) {
+        if (!m) {
+            return monthsShortDot;
+        } else if (/-MMM-/.test(format)) {
+            return monthsShort[m.month()];
+        } else {
+            return monthsShortDot[m.month()];
+        }
+    },
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
+    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
+    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
+    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D [de] MMMM [de] YYYY',
+        LLL: 'D [de] MMMM [de] YYYY H:mm',
+        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextDay: function () {
+            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastDay: function () {
+            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[el] dddd [pasado a la' +
+                (this.hours() !== 1 ? 's' : '') +
+                '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'en %s',
+        past: 'hace %s',
+        s: 'unos segundos',
+        ss: '%d segundos',
+        m: 'un minuto',
+        mm: '%d minutos',
+        h: 'una hora',
+        hh: '%d horas',
+        d: 'un día',
+        dd: '%d días',
+        w: 'una semana',
+        ww: '%d semanas',
+        M: 'un mes',
+        MM: '%d meses',
+        y: 'un año',
+        yy: '%d años',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+    invalidDate: 'Fecha inválida',
+});

+ 78 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/et.js

@@ -0,0 +1,78 @@
+//! moment.js locale configuration
+//! locale : Estonian [et]
+//! author : Henry Kehlmann : https://github.com/madhenry
+//! improvements : Illimar Tambek : https://github.com/ragulka
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        s: ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
+        ss: [number + 'sekundi', number + 'sekundit'],
+        m: ['ühe minuti', 'üks minut'],
+        mm: [number + ' minuti', number + ' minutit'],
+        h: ['ühe tunni', 'tund aega', 'üks tund'],
+        hh: [number + ' tunni', number + ' tundi'],
+        d: ['ühe päeva', 'üks päev'],
+        M: ['kuu aja', 'kuu aega', 'üks kuu'],
+        MM: [number + ' kuu', number + ' kuud'],
+        y: ['ühe aasta', 'aasta', 'üks aasta'],
+        yy: [number + ' aasta', number + ' aastat'],
+    };
+    if (withoutSuffix) {
+        return format[key][2] ? format[key][2] : format[key][1];
+    }
+    return isFuture ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('et', {
+    months: 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split(
+        '_'
+    ),
+    monthsShort: 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split(
+        '_'
+    ),
+    weekdays: 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split(
+        '_'
+    ),
+    weekdaysShort: 'P_E_T_K_N_R_L'.split('_'),
+    weekdaysMin: 'P_E_T_K_N_R_L'.split('_'),
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY H:mm',
+        LLLL: 'dddd, D. MMMM YYYY H:mm',
+    },
+    calendar: {
+        sameDay: '[Täna,] LT',
+        nextDay: '[Homme,] LT',
+        nextWeek: '[Järgmine] dddd LT',
+        lastDay: '[Eile,] LT',
+        lastWeek: '[Eelmine] dddd LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s pärast',
+        past: '%s tagasi',
+        s: processRelativeTime,
+        ss: processRelativeTime,
+        m: processRelativeTime,
+        mm: processRelativeTime,
+        h: processRelativeTime,
+        hh: processRelativeTime,
+        d: processRelativeTime,
+        dd: '%d päeva',
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 63 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/eu.js

@@ -0,0 +1,63 @@
+//! moment.js locale configuration
+//! locale : Basque [eu]
+//! author : Eneko Illarramendi : https://github.com/eillarra
+
+import moment from '../moment';
+
+export default moment.defineLocale('eu', {
+    months: 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split(
+        '_'
+    ),
+    monthsShort: 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split(
+        '_'
+    ),
+    weekdaysShort: 'ig._al._ar._az._og._ol._lr.'.split('_'),
+    weekdaysMin: 'ig_al_ar_az_og_ol_lr'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'YYYY-MM-DD',
+        LL: 'YYYY[ko] MMMM[ren] D[a]',
+        LLL: 'YYYY[ko] MMMM[ren] D[a] HH:mm',
+        LLLL: 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
+        l: 'YYYY-M-D',
+        ll: 'YYYY[ko] MMM D[a]',
+        lll: 'YYYY[ko] MMM D[a] HH:mm',
+        llll: 'ddd, YYYY[ko] MMM D[a] HH:mm',
+    },
+    calendar: {
+        sameDay: '[gaur] LT[etan]',
+        nextDay: '[bihar] LT[etan]',
+        nextWeek: 'dddd LT[etan]',
+        lastDay: '[atzo] LT[etan]',
+        lastWeek: '[aurreko] dddd LT[etan]',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s barru',
+        past: 'duela %s',
+        s: 'segundo batzuk',
+        ss: '%d segundo',
+        m: 'minutu bat',
+        mm: '%d minutu',
+        h: 'ordu bat',
+        hh: '%d ordu',
+        d: 'egun bat',
+        dd: '%d egun',
+        M: 'hilabete bat',
+        MM: '%d hilabete',
+        y: 'urte bat',
+        yy: '%d urte',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 110 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fa.js

@@ -0,0 +1,110 @@
+//! moment.js locale configuration
+//! locale : Persian [fa]
+//! author : Ebrahim Byagowi : https://github.com/ebraminio
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '۱',
+        2: '۲',
+        3: '۳',
+        4: '۴',
+        5: '۵',
+        6: '۶',
+        7: '۷',
+        8: '۸',
+        9: '۹',
+        0: '۰',
+    },
+    numberMap = {
+        '۱': '1',
+        '۲': '2',
+        '۳': '3',
+        '۴': '4',
+        '۵': '5',
+        '۶': '6',
+        '۷': '7',
+        '۸': '8',
+        '۹': '9',
+        '۰': '0',
+    };
+
+export default moment.defineLocale('fa', {
+    months: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split(
+        '_'
+    ),
+    monthsShort: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split(
+        '_'
+    ),
+    weekdays: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split(
+        '_'
+    ),
+    weekdaysShort: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split(
+        '_'
+    ),
+    weekdaysMin: 'ی_د_س_چ_پ_ج_ش'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    meridiemParse: /قبل از ظهر|بعد از ظهر/,
+    isPM: function (input) {
+        return /بعد از ظهر/.test(input);
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 12) {
+            return 'قبل از ظهر';
+        } else {
+            return 'بعد از ظهر';
+        }
+    },
+    calendar: {
+        sameDay: '[امروز ساعت] LT',
+        nextDay: '[فردا ساعت] LT',
+        nextWeek: 'dddd [ساعت] LT',
+        lastDay: '[دیروز ساعت] LT',
+        lastWeek: 'dddd [پیش] [ساعت] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'در %s',
+        past: '%s پیش',
+        s: 'چند ثانیه',
+        ss: '%d ثانیه',
+        m: 'یک دقیقه',
+        mm: '%d دقیقه',
+        h: 'یک ساعت',
+        hh: '%d ساعت',
+        d: 'یک روز',
+        dd: '%d روز',
+        M: 'یک ماه',
+        MM: '%d ماه',
+        y: 'یک سال',
+        yy: '%d سال',
+    },
+    preparse: function (string) {
+        return string
+            .replace(/[۰-۹]/g, function (match) {
+                return numberMap[match];
+            })
+            .replace(/،/g, ',');
+    },
+    postformat: function (string) {
+        return string
+            .replace(/\d/g, function (match) {
+                return symbolMap[match];
+            })
+            .replace(/,/g, '،');
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}م/,
+    ordinal: '%dم',
+    week: {
+        dow: 6, // Saturday is the first day of the week.
+        doy: 12, // The week that contains Jan 12th is the first week of the year.
+    },
+});

+ 121 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fi.js

@@ -0,0 +1,121 @@
+//! moment.js locale configuration
+//! locale : Finnish [fi]
+//! author : Tarmo Aidantausta : https://github.com/bleadof
+
+import moment from '../moment';
+
+var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(
+        ' '
+    ),
+    numbersFuture = [
+        'nolla',
+        'yhden',
+        'kahden',
+        'kolmen',
+        'neljän',
+        'viiden',
+        'kuuden',
+        numbersPast[7],
+        numbersPast[8],
+        numbersPast[9],
+    ];
+function translate(number, withoutSuffix, key, isFuture) {
+    var result = '';
+    switch (key) {
+        case 's':
+            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
+        case 'ss':
+            result = isFuture ? 'sekunnin' : 'sekuntia';
+            break;
+        case 'm':
+            return isFuture ? 'minuutin' : 'minuutti';
+        case 'mm':
+            result = isFuture ? 'minuutin' : 'minuuttia';
+            break;
+        case 'h':
+            return isFuture ? 'tunnin' : 'tunti';
+        case 'hh':
+            result = isFuture ? 'tunnin' : 'tuntia';
+            break;
+        case 'd':
+            return isFuture ? 'päivän' : 'päivä';
+        case 'dd':
+            result = isFuture ? 'päivän' : 'päivää';
+            break;
+        case 'M':
+            return isFuture ? 'kuukauden' : 'kuukausi';
+        case 'MM':
+            result = isFuture ? 'kuukauden' : 'kuukautta';
+            break;
+        case 'y':
+            return isFuture ? 'vuoden' : 'vuosi';
+        case 'yy':
+            result = isFuture ? 'vuoden' : 'vuotta';
+            break;
+    }
+    result = verbalNumber(number, isFuture) + ' ' + result;
+    return result;
+}
+function verbalNumber(number, isFuture) {
+    return number < 10
+        ? isFuture
+            ? numbersFuture[number]
+            : numbersPast[number]
+        : number;
+}
+
+export default moment.defineLocale('fi', {
+    months: 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split(
+        '_'
+    ),
+    monthsShort: 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split(
+        '_'
+    ),
+    weekdays: 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split(
+        '_'
+    ),
+    weekdaysShort: 'su_ma_ti_ke_to_pe_la'.split('_'),
+    weekdaysMin: 'su_ma_ti_ke_to_pe_la'.split('_'),
+    longDateFormat: {
+        LT: 'HH.mm',
+        LTS: 'HH.mm.ss',
+        L: 'DD.MM.YYYY',
+        LL: 'Do MMMM[ta] YYYY',
+        LLL: 'Do MMMM[ta] YYYY, [klo] HH.mm',
+        LLLL: 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
+        l: 'D.M.YYYY',
+        ll: 'Do MMM YYYY',
+        lll: 'Do MMM YYYY, [klo] HH.mm',
+        llll: 'ddd, Do MMM YYYY, [klo] HH.mm',
+    },
+    calendar: {
+        sameDay: '[tänään] [klo] LT',
+        nextDay: '[huomenna] [klo] LT',
+        nextWeek: 'dddd [klo] LT',
+        lastDay: '[eilen] [klo] LT',
+        lastWeek: '[viime] dddd[na] [klo] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s päästä',
+        past: '%s sitten',
+        s: translate,
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: translate,
+        hh: translate,
+        d: translate,
+        dd: translate,
+        M: translate,
+        MM: translate,
+        y: translate,
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 58 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fil.js

@@ -0,0 +1,58 @@
+//! moment.js locale configuration
+//! locale : Filipino [fil]
+//! author : Dan Hagman : https://github.com/hagmandan
+//! author : Matthew Co : https://github.com/matthewdeeco
+
+import moment from '../moment';
+
+export default moment.defineLocale('fil', {
+    months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split(
+        '_'
+    ),
+    monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
+    weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split(
+        '_'
+    ),
+    weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
+    weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'MM/D/YYYY',
+        LL: 'MMMM D, YYYY',
+        LLL: 'MMMM D, YYYY HH:mm',
+        LLLL: 'dddd, MMMM DD, YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: 'LT [ngayong araw]',
+        nextDay: '[Bukas ng] LT',
+        nextWeek: 'LT [sa susunod na] dddd',
+        lastDay: 'LT [kahapon]',
+        lastWeek: 'LT [noong nakaraang] dddd',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'sa loob ng %s',
+        past: '%s ang nakalipas',
+        s: 'ilang segundo',
+        ss: '%d segundo',
+        m: 'isang minuto',
+        mm: '%d minuto',
+        h: 'isang oras',
+        hh: '%d oras',
+        d: 'isang araw',
+        dd: '%d araw',
+        M: 'isang buwan',
+        MM: '%d buwan',
+        y: 'isang taon',
+        yy: '%d taon',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}/,
+    ordinal: function (number) {
+        return number;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 56 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fo.js

@@ -0,0 +1,56 @@
+//! moment.js locale configuration
+//! locale : Faroese [fo]
+//! author : Ragnar Johannesen : https://github.com/ragnar123
+//! author : Kristian Sakarisson : https://github.com/sakarisson
+
+import moment from '../moment';
+
+export default moment.defineLocale('fo', {
+    months: 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split(
+        '_'
+    ),
+    monthsShort: 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
+    weekdays: 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split(
+        '_'
+    ),
+    weekdaysShort: 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
+    weekdaysMin: 'su_má_tý_mi_hó_fr_le'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D. MMMM, YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Í dag kl.] LT',
+        nextDay: '[Í morgin kl.] LT',
+        nextWeek: 'dddd [kl.] LT',
+        lastDay: '[Í gjár kl.] LT',
+        lastWeek: '[síðstu] dddd [kl] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'um %s',
+        past: '%s síðani',
+        s: 'fá sekund',
+        ss: '%d sekundir',
+        m: 'ein minuttur',
+        mm: '%d minuttir',
+        h: 'ein tími',
+        hh: '%d tímar',
+        d: 'ein dagur',
+        dd: '%d dagar',
+        M: 'ein mánaður',
+        MM: '%d mánaðir',
+        y: 'eitt ár',
+        yy: '%d ár',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 69 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr-ca.js

@@ -0,0 +1,69 @@
+//! moment.js locale configuration
+//! locale : French (Canada) [fr-ca]
+//! author : Jonathan Abourbih : https://github.com/jonbca
+
+import moment from '../moment';
+
+export default moment.defineLocale('fr-ca', {
+    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
+        '_'
+    ),
+    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
+    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
+    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'YYYY-MM-DD',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Aujourd’hui à] LT',
+        nextDay: '[Demain à] LT',
+        nextWeek: 'dddd [à] LT',
+        lastDay: '[Hier à] LT',
+        lastWeek: 'dddd [dernier à] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'dans %s',
+        past: 'il y a %s',
+        s: 'quelques secondes',
+        ss: '%d secondes',
+        m: 'une minute',
+        mm: '%d minutes',
+        h: 'une heure',
+        hh: '%d heures',
+        d: 'un jour',
+        dd: '%d jours',
+        M: 'un mois',
+        MM: '%d mois',
+        y: 'un an',
+        yy: '%d ans',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            // Words with masculine grammatical gender: mois, trimestre, jour
+            default:
+            case 'M':
+            case 'Q':
+            case 'D':
+            case 'DDD':
+            case 'd':
+                return number + (number === 1 ? 'er' : 'e');
+
+            // Words with feminine grammatical gender: semaine
+            case 'w':
+            case 'W':
+                return number + (number === 1 ? 're' : 'e');
+        }
+    },
+});

+ 73 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr-ch.js

@@ -0,0 +1,73 @@
+//! moment.js locale configuration
+//! locale : French (Switzerland) [fr-ch]
+//! author : Gaspard Bucher : https://github.com/gaspard
+
+import moment from '../moment';
+
+export default moment.defineLocale('fr-ch', {
+    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
+        '_'
+    ),
+    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
+    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
+    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Aujourd’hui à] LT',
+        nextDay: '[Demain à] LT',
+        nextWeek: 'dddd [à] LT',
+        lastDay: '[Hier à] LT',
+        lastWeek: 'dddd [dernier à] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'dans %s',
+        past: 'il y a %s',
+        s: 'quelques secondes',
+        ss: '%d secondes',
+        m: 'une minute',
+        mm: '%d minutes',
+        h: 'une heure',
+        hh: '%d heures',
+        d: 'un jour',
+        dd: '%d jours',
+        M: 'un mois',
+        MM: '%d mois',
+        y: 'un an',
+        yy: '%d ans',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            // Words with masculine grammatical gender: mois, trimestre, jour
+            default:
+            case 'M':
+            case 'Q':
+            case 'D':
+            case 'DDD':
+            case 'd':
+                return number + (number === 1 ? 'er' : 'e');
+
+            // Words with feminine grammatical gender: semaine
+            case 'w':
+            case 'W':
+                return number + (number === 1 ? 're' : 'e');
+        }
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 104 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fr.js

@@ -0,0 +1,104 @@
+//! moment.js locale configuration
+//! locale : French [fr]
+//! author : John Fischer : https://github.com/jfroffice
+
+import moment from '../moment';
+
+var monthsStrictRegex = /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
+    monthsShortStrictRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,
+    monthsRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
+    monthsParse = [
+        /^janv/i,
+        /^févr/i,
+        /^mars/i,
+        /^avr/i,
+        /^mai/i,
+        /^juin/i,
+        /^juil/i,
+        /^août/i,
+        /^sept/i,
+        /^oct/i,
+        /^nov/i,
+        /^déc/i,
+    ];
+
+export default moment.defineLocale('fr', {
+    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
+        '_'
+    ),
+    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
+        '_'
+    ),
+    monthsRegex: monthsRegex,
+    monthsShortRegex: monthsRegex,
+    monthsStrictRegex: monthsStrictRegex,
+    monthsShortStrictRegex: monthsShortStrictRegex,
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: monthsParse,
+    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
+    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
+    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Aujourd’hui à] LT',
+        nextDay: '[Demain à] LT',
+        nextWeek: 'dddd [à] LT',
+        lastDay: '[Hier à] LT',
+        lastWeek: 'dddd [dernier à] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'dans %s',
+        past: 'il y a %s',
+        s: 'quelques secondes',
+        ss: '%d secondes',
+        m: 'une minute',
+        mm: '%d minutes',
+        h: 'une heure',
+        hh: '%d heures',
+        d: 'un jour',
+        dd: '%d jours',
+        w: 'une semaine',
+        ww: '%d semaines',
+        M: 'un mois',
+        MM: '%d mois',
+        y: 'un an',
+        yy: '%d ans',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            // TODO: Return 'e' when day of month > 1. Move this case inside
+            // block for masculine words below.
+            // See https://github.com/moment/moment/issues/3375
+            case 'D':
+                return number + (number === 1 ? 'er' : '');
+
+            // Words with masculine grammatical gender: mois, trimestre, jour
+            default:
+            case 'M':
+            case 'Q':
+            case 'DDD':
+            case 'd':
+                return number + (number === 1 ? 'er' : 'e');
+
+            // Words with feminine grammatical gender: semaine
+            case 'w':
+            case 'W':
+                return number + (number === 1 ? 're' : 'e');
+        }
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 77 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/fy.js

@@ -0,0 +1,77 @@
+//! moment.js locale configuration
+//! locale : Frisian [fy]
+//! author : Robin van der Vliet : https://github.com/robin0van0der0v
+
+import moment from '../moment';
+
+var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split(
+        '_'
+    ),
+    monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split(
+        '_'
+    );
+
+export default moment.defineLocale('fy', {
+    months: 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split(
+        '_'
+    ),
+    monthsShort: function (m, format) {
+        if (!m) {
+            return monthsShortWithDots;
+        } else if (/-MMM-/.test(format)) {
+            return monthsShortWithoutDots[m.month()];
+        } else {
+            return monthsShortWithDots[m.month()];
+        }
+    },
+    monthsParseExact: true,
+    weekdays: 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split(
+        '_'
+    ),
+    weekdaysShort: 'si._mo._ti._wo._to._fr._so.'.split('_'),
+    weekdaysMin: 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD-MM-YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[hjoed om] LT',
+        nextDay: '[moarn om] LT',
+        nextWeek: 'dddd [om] LT',
+        lastDay: '[juster om] LT',
+        lastWeek: '[ôfrûne] dddd [om] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'oer %s',
+        past: '%s lyn',
+        s: 'in pear sekonden',
+        ss: '%d sekonden',
+        m: 'ien minút',
+        mm: '%d minuten',
+        h: 'ien oere',
+        hh: '%d oeren',
+        d: 'ien dei',
+        dd: '%d dagen',
+        M: 'ien moanne',
+        MM: '%d moannen',
+        y: 'ien jier',
+        yy: '%d jierren',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
+    ordinal: function (number) {
+        return (
+            number +
+            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
+        );
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 95 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/ga.js

@@ -0,0 +1,95 @@
+//! moment.js locale configuration
+//! locale : Irish or Irish Gaelic [ga]
+//! author : André Silva : https://github.com/askpt
+
+import moment from '../moment';
+
+var months = [
+        'Eanáir',
+        'Feabhra',
+        'Márta',
+        'Aibreán',
+        'Bealtaine',
+        'Meitheamh',
+        'Iúil',
+        'Lúnasa',
+        'Meán Fómhair',
+        'Deireadh Fómhair',
+        'Samhain',
+        'Nollaig',
+    ],
+    monthsShort = [
+        'Ean',
+        'Feabh',
+        'Márt',
+        'Aib',
+        'Beal',
+        'Meith',
+        'Iúil',
+        'Lún',
+        'M.F.',
+        'D.F.',
+        'Samh',
+        'Noll',
+    ],
+    weekdays = [
+        'Dé Domhnaigh',
+        'Dé Luain',
+        'Dé Máirt',
+        'Dé Céadaoin',
+        'Déardaoin',
+        'Dé hAoine',
+        'Dé Sathairn',
+    ],
+    weekdaysShort = ['Domh', 'Luan', 'Máirt', 'Céad', 'Déar', 'Aoine', 'Sath'],
+    weekdaysMin = ['Do', 'Lu', 'Má', 'Cé', 'Dé', 'A', 'Sa'];
+
+export default moment.defineLocale('ga', {
+    months: months,
+    monthsShort: monthsShort,
+    monthsParseExact: true,
+    weekdays: weekdays,
+    weekdaysShort: weekdaysShort,
+    weekdaysMin: weekdaysMin,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Inniu ag] LT',
+        nextDay: '[Amárach ag] LT',
+        nextWeek: 'dddd [ag] LT',
+        lastDay: '[Inné ag] LT',
+        lastWeek: 'dddd [seo caite] [ag] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'i %s',
+        past: '%s ó shin',
+        s: 'cúpla soicind',
+        ss: '%d soicind',
+        m: 'nóiméad',
+        mm: '%d nóiméad',
+        h: 'uair an chloig',
+        hh: '%d uair an chloig',
+        d: 'lá',
+        dd: '%d lá',
+        M: 'mí',
+        MM: '%d míonna',
+        y: 'bliain',
+        yy: '%d bliain',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/,
+    ordinal: function (number) {
+        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 95 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gd.js

@@ -0,0 +1,95 @@
+//! moment.js locale configuration
+//! locale : Scottish Gaelic [gd]
+//! author : Jon Ashdown : https://github.com/jonashdown
+
+import moment from '../moment';
+
+var months = [
+        'Am Faoilleach',
+        'An Gearran',
+        'Am Màrt',
+        'An Giblean',
+        'An Cèitean',
+        'An t-Ògmhios',
+        'An t-Iuchar',
+        'An Lùnastal',
+        'An t-Sultain',
+        'An Dàmhair',
+        'An t-Samhain',
+        'An Dùbhlachd',
+    ],
+    monthsShort = [
+        'Faoi',
+        'Gear',
+        'Màrt',
+        'Gibl',
+        'Cèit',
+        'Ògmh',
+        'Iuch',
+        'Lùn',
+        'Sult',
+        'Dàmh',
+        'Samh',
+        'Dùbh',
+    ],
+    weekdays = [
+        'Didòmhnaich',
+        'Diluain',
+        'Dimàirt',
+        'Diciadain',
+        'Diardaoin',
+        'Dihaoine',
+        'Disathairne',
+    ],
+    weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'],
+    weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
+
+export default moment.defineLocale('gd', {
+    months: months,
+    monthsShort: monthsShort,
+    monthsParseExact: true,
+    weekdays: weekdays,
+    weekdaysShort: weekdaysShort,
+    weekdaysMin: weekdaysMin,
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd, D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[An-diugh aig] LT',
+        nextDay: '[A-màireach aig] LT',
+        nextWeek: 'dddd [aig] LT',
+        lastDay: '[An-dè aig] LT',
+        lastWeek: 'dddd [seo chaidh] [aig] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'ann an %s',
+        past: 'bho chionn %s',
+        s: 'beagan diogan',
+        ss: '%d diogan',
+        m: 'mionaid',
+        mm: '%d mionaidean',
+        h: 'uair',
+        hh: '%d uairean',
+        d: 'latha',
+        dd: '%d latha',
+        M: 'mìos',
+        MM: '%d mìosan',
+        y: 'bliadhna',
+        yy: '%d bliadhna',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/,
+    ordinal: function (number) {
+        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
+        return number + output;
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 74 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gl.js

@@ -0,0 +1,74 @@
+//! moment.js locale configuration
+//! locale : Galician [gl]
+//! author : Juan G. Hurtado : https://github.com/juanghurtado
+
+import moment from '../moment';
+
+export default moment.defineLocale('gl', {
+    months: 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split(
+        '_'
+    ),
+    monthsShort: 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),
+    weekdaysShort: 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),
+    weekdaysMin: 'do_lu_ma_mé_xo_ve_sá'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D [de] MMMM [de] YYYY',
+        LLL: 'D [de] MMMM [de] YYYY H:mm',
+        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
+    },
+    calendar: {
+        sameDay: function () {
+            return '[hoxe ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT';
+        },
+        nextDay: function () {
+            return '[mañá ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT';
+        },
+        nextWeek: function () {
+            return 'dddd [' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT';
+        },
+        lastDay: function () {
+            return '[onte ' + (this.hours() !== 1 ? 'á' : 'a') + '] LT';
+        },
+        lastWeek: function () {
+            return (
+                '[o] dddd [pasado ' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT'
+            );
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: function (str) {
+            if (str.indexOf('un') === 0) {
+                return 'n' + str;
+            }
+            return 'en ' + str;
+        },
+        past: 'hai %s',
+        s: 'uns segundos',
+        ss: '%d segundos',
+        m: 'un minuto',
+        mm: '%d minutos',
+        h: 'unha hora',
+        hh: '%d horas',
+        d: 'un día',
+        dd: '%d días',
+        M: 'un mes',
+        MM: '%d meses',
+        y: 'un ano',
+        yy: '%d anos',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 124 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gom-deva.js

@@ -0,0 +1,124 @@
+//! moment.js locale configuration
+//! locale : Konkani Devanagari script [gom-deva]
+//! author : The Discoverer : https://github.com/WikiDiscoverer
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        s: ['थोडया सॅकंडांनी', 'थोडे सॅकंड'],
+        ss: [number + ' सॅकंडांनी', number + ' सॅकंड'],
+        m: ['एका मिणटान', 'एक मिनूट'],
+        mm: [number + ' मिणटांनी', number + ' मिणटां'],
+        h: ['एका वरान', 'एक वर'],
+        hh: [number + ' वरांनी', number + ' वरां'],
+        d: ['एका दिसान', 'एक दीस'],
+        dd: [number + ' दिसांनी', number + ' दीस'],
+        M: ['एका म्हयन्यान', 'एक म्हयनो'],
+        MM: [number + ' म्हयन्यानी', number + ' म्हयने'],
+        y: ['एका वर्सान', 'एक वर्स'],
+        yy: [number + ' वर्सांनी', number + ' वर्सां'],
+    };
+    return isFuture ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('gom-deva', {
+    months: {
+        standalone: 'जानेवारी_फेब्रुवारी_मार्च_एप्रील_मे_जून_जुलय_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split(
+            '_'
+        ),
+        format: 'जानेवारीच्या_फेब्रुवारीच्या_मार्चाच्या_एप्रीलाच्या_मेयाच्या_जूनाच्या_जुलयाच्या_ऑगस्टाच्या_सप्टेंबराच्या_ऑक्टोबराच्या_नोव्हेंबराच्या_डिसेंबराच्या'.split(
+            '_'
+        ),
+        isFormat: /MMMM(\s)+D[oD]?/,
+    },
+    monthsShort: 'जाने._फेब्रु._मार्च_एप्री._मे_जून_जुल._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'आयतार_सोमार_मंगळार_बुधवार_बिरेस्तार_सुक्रार_शेनवार'.split('_'),
+    weekdaysShort: 'आयत._सोम._मंगळ._बुध._ब्रेस्त._सुक्र._शेन.'.split('_'),
+    weekdaysMin: 'आ_सो_मं_बु_ब्रे_सु_शे'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'A h:mm [वाजतां]',
+        LTS: 'A h:mm:ss [वाजतां]',
+        L: 'DD-MM-YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY A h:mm [वाजतां]',
+        LLLL: 'dddd, MMMM Do, YYYY, A h:mm [वाजतां]',
+        llll: 'ddd, D MMM YYYY, A h:mm [वाजतां]',
+    },
+    calendar: {
+        sameDay: '[आयज] LT',
+        nextDay: '[फाल्यां] LT',
+        nextWeek: '[फुडलो] dddd[,] LT',
+        lastDay: '[काल] LT',
+        lastWeek: '[फाटलो] dddd[,] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s',
+        past: '%s आदीं',
+        s: processRelativeTime,
+        ss: processRelativeTime,
+        m: processRelativeTime,
+        mm: processRelativeTime,
+        h: processRelativeTime,
+        hh: processRelativeTime,
+        d: processRelativeTime,
+        dd: processRelativeTime,
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(वेर)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            // the ordinal 'वेर' only applies to day of the month
+            case 'D':
+                return number + 'वेर';
+            default:
+            case 'M':
+            case 'Q':
+            case 'DDD':
+            case 'd':
+            case 'w':
+            case 'W':
+                return number;
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week
+        doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4)
+    },
+    meridiemParse: /राती|सकाळीं|दनपारां|सांजे/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'राती') {
+            return hour < 4 ? hour : hour + 12;
+        } else if (meridiem === 'सकाळीं') {
+            return hour;
+        } else if (meridiem === 'दनपारां') {
+            return hour > 12 ? hour : hour + 12;
+        } else if (meridiem === 'सांजे') {
+            return hour + 12;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'राती';
+        } else if (hour < 12) {
+            return 'सकाळीं';
+        } else if (hour < 16) {
+            return 'दनपारां';
+        } else if (hour < 20) {
+            return 'सांजे';
+        } else {
+            return 'राती';
+        }
+    },
+});

+ 124 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gom-latn.js

@@ -0,0 +1,124 @@
+//! moment.js locale configuration
+//! locale : Konkani Latin script [gom-latn]
+//! author : The Discoverer : https://github.com/WikiDiscoverer
+
+import moment from '../moment';
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+    var format = {
+        s: ['thoddea sekondamni', 'thodde sekond'],
+        ss: [number + ' sekondamni', number + ' sekond'],
+        m: ['eka mintan', 'ek minut'],
+        mm: [number + ' mintamni', number + ' mintam'],
+        h: ['eka voran', 'ek vor'],
+        hh: [number + ' voramni', number + ' voram'],
+        d: ['eka disan', 'ek dis'],
+        dd: [number + ' disamni', number + ' dis'],
+        M: ['eka mhoinean', 'ek mhoino'],
+        MM: [number + ' mhoineamni', number + ' mhoine'],
+        y: ['eka vorsan', 'ek voros'],
+        yy: [number + ' vorsamni', number + ' vorsam'],
+    };
+    return isFuture ? format[key][0] : format[key][1];
+}
+
+export default moment.defineLocale('gom-latn', {
+    months: {
+        standalone: 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split(
+            '_'
+        ),
+        format: 'Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea'.split(
+            '_'
+        ),
+        isFormat: /MMMM(\s)+D[oD]?/,
+    },
+    monthsShort: 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: "Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split('_'),
+    weekdaysShort: 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),
+    weekdaysMin: 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'A h:mm [vazta]',
+        LTS: 'A h:mm:ss [vazta]',
+        L: 'DD-MM-YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY A h:mm [vazta]',
+        LLLL: 'dddd, MMMM Do, YYYY, A h:mm [vazta]',
+        llll: 'ddd, D MMM YYYY, A h:mm [vazta]',
+    },
+    calendar: {
+        sameDay: '[Aiz] LT',
+        nextDay: '[Faleam] LT',
+        nextWeek: '[Fuddlo] dddd[,] LT',
+        lastDay: '[Kal] LT',
+        lastWeek: '[Fattlo] dddd[,] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s',
+        past: '%s adim',
+        s: processRelativeTime,
+        ss: processRelativeTime,
+        m: processRelativeTime,
+        mm: processRelativeTime,
+        h: processRelativeTime,
+        hh: processRelativeTime,
+        d: processRelativeTime,
+        dd: processRelativeTime,
+        M: processRelativeTime,
+        MM: processRelativeTime,
+        y: processRelativeTime,
+        yy: processRelativeTime,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}(er)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            // the ordinal 'er' only applies to day of the month
+            case 'D':
+                return number + 'er';
+            default:
+            case 'M':
+            case 'Q':
+            case 'DDD':
+            case 'd':
+            case 'w':
+            case 'W':
+                return number;
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week
+        doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4)
+    },
+    meridiemParse: /rati|sokallim|donparam|sanje/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'rati') {
+            return hour < 4 ? hour : hour + 12;
+        } else if (meridiem === 'sokallim') {
+            return hour;
+        } else if (meridiem === 'donparam') {
+            return hour > 12 ? hour : hour + 12;
+        } else if (meridiem === 'sanje') {
+            return hour + 12;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'rati';
+        } else if (hour < 12) {
+            return 'sokallim';
+        } else if (hour < 16) {
+            return 'donparam';
+        } else if (hour < 20) {
+            return 'sanje';
+        } else {
+            return 'rati';
+        }
+    },
+});

+ 121 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/gu.js

@@ -0,0 +1,121 @@
+//! moment.js locale configuration
+//! locale : Gujarati [gu]
+//! author : Kaushik Thanki : https://github.com/Kaushik1987
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '૧',
+        2: '૨',
+        3: '૩',
+        4: '૪',
+        5: '૫',
+        6: '૬',
+        7: '૭',
+        8: '૮',
+        9: '૯',
+        0: '૦',
+    },
+    numberMap = {
+        '૧': '1',
+        '૨': '2',
+        '૩': '3',
+        '૪': '4',
+        '૫': '5',
+        '૬': '6',
+        '૭': '7',
+        '૮': '8',
+        '૯': '9',
+        '૦': '0',
+    };
+
+export default moment.defineLocale('gu', {
+    months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split(
+        '_'
+    ),
+    monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split(
+        '_'
+    ),
+    weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'),
+    weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'),
+    longDateFormat: {
+        LT: 'A h:mm વાગ્યે',
+        LTS: 'A h:mm:ss વાગ્યે',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY, A h:mm વાગ્યે',
+        LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે',
+    },
+    calendar: {
+        sameDay: '[આજ] LT',
+        nextDay: '[કાલે] LT',
+        nextWeek: 'dddd, LT',
+        lastDay: '[ગઇકાલે] LT',
+        lastWeek: '[પાછલા] dddd, LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s મા',
+        past: '%s પહેલા',
+        s: 'અમુક પળો',
+        ss: '%d સેકંડ',
+        m: 'એક મિનિટ',
+        mm: '%d મિનિટ',
+        h: 'એક કલાક',
+        hh: '%d કલાક',
+        d: 'એક દિવસ',
+        dd: '%d દિવસ',
+        M: 'એક મહિનો',
+        MM: '%d મહિનો',
+        y: 'એક વર્ષ',
+        yy: '%d વર્ષ',
+    },
+    preparse: function (string) {
+        return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) {
+            return numberMap[match];
+        });
+    },
+    postformat: function (string) {
+        return string.replace(/\d/g, function (match) {
+            return symbolMap[match];
+        });
+    },
+    // Gujarati notation for meridiems are quite fuzzy in practice. While there exists
+    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati.
+    meridiemParse: /રાત|બપોર|સવાર|સાંજ/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'રાત') {
+            return hour < 4 ? hour : hour + 12;
+        } else if (meridiem === 'સવાર') {
+            return hour;
+        } else if (meridiem === 'બપોર') {
+            return hour >= 10 ? hour : hour + 12;
+        } else if (meridiem === 'સાંજ') {
+            return hour + 12;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'રાત';
+        } else if (hour < 10) {
+            return 'સવાર';
+        } else if (hour < 17) {
+            return 'બપોર';
+        } else if (hour < 20) {
+            return 'સાંજ';
+        } else {
+            return 'રાત';
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 94 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/he.js

@@ -0,0 +1,94 @@
+//! moment.js locale configuration
+//! locale : Hebrew [he]
+//! author : Tomer Cohen : https://github.com/tomer
+//! author : Moshe Simantov : https://github.com/DevelopmentIL
+//! author : Tal Ater : https://github.com/TalAter
+
+import moment from '../moment';
+
+export default moment.defineLocale('he', {
+    months: 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split(
+        '_'
+    ),
+    monthsShort: 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split(
+        '_'
+    ),
+    weekdays: 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
+    weekdaysShort: 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
+    weekdaysMin: 'א_ב_ג_ד_ה_ו_ש'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D [ב]MMMM YYYY',
+        LLL: 'D [ב]MMMM YYYY HH:mm',
+        LLLL: 'dddd, D [ב]MMMM YYYY HH:mm',
+        l: 'D/M/YYYY',
+        ll: 'D MMM YYYY',
+        lll: 'D MMM YYYY HH:mm',
+        llll: 'ddd, D MMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[היום ב־]LT',
+        nextDay: '[מחר ב־]LT',
+        nextWeek: 'dddd [בשעה] LT',
+        lastDay: '[אתמול ב־]LT',
+        lastWeek: '[ביום] dddd [האחרון בשעה] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'בעוד %s',
+        past: 'לפני %s',
+        s: 'מספר שניות',
+        ss: '%d שניות',
+        m: 'דקה',
+        mm: '%d דקות',
+        h: 'שעה',
+        hh: function (number) {
+            if (number === 2) {
+                return 'שעתיים';
+            }
+            return number + ' שעות';
+        },
+        d: 'יום',
+        dd: function (number) {
+            if (number === 2) {
+                return 'יומיים';
+            }
+            return number + ' ימים';
+        },
+        M: 'חודש',
+        MM: function (number) {
+            if (number === 2) {
+                return 'חודשיים';
+            }
+            return number + ' חודשים';
+        },
+        y: 'שנה',
+        yy: function (number) {
+            if (number === 2) {
+                return 'שנתיים';
+            } else if (number % 10 === 0 && number !== 10) {
+                return number + ' שנה';
+            }
+            return number + ' שנים';
+        },
+    },
+    meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,
+    isPM: function (input) {
+        return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input);
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 5) {
+            return 'לפנות בוקר';
+        } else if (hour < 10) {
+            return 'בבוקר';
+        } else if (hour < 12) {
+            return isLower ? 'לפנה"צ' : 'לפני הצהריים';
+        } else if (hour < 18) {
+            return isLower ? 'אחה"צ' : 'אחרי הצהריים';
+        } else {
+            return 'בערב';
+        }
+    },
+});

+ 164 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hi.js

@@ -0,0 +1,164 @@
+//! moment.js locale configuration
+//! locale : Hindi [hi]
+//! author : Mayank Singhal : https://github.com/mayanksinghal
+
+import moment from '../moment';
+
+var symbolMap = {
+        1: '१',
+        2: '२',
+        3: '३',
+        4: '४',
+        5: '५',
+        6: '६',
+        7: '७',
+        8: '८',
+        9: '९',
+        0: '०',
+    },
+    numberMap = {
+        '१': '1',
+        '२': '2',
+        '३': '3',
+        '४': '4',
+        '५': '5',
+        '६': '6',
+        '७': '7',
+        '८': '8',
+        '९': '9',
+        '०': '0',
+    },
+    monthsParse = [
+        /^जन/i,
+        /^फ़र|फर/i,
+        /^मार्च/i,
+        /^अप्रै/i,
+        /^मई/i,
+        /^जून/i,
+        /^जुल/i,
+        /^अग/i,
+        /^सितं|सित/i,
+        /^अक्टू/i,
+        /^नव|नवं/i,
+        /^दिसं|दिस/i,
+    ],
+    shortMonthsParse = [
+        /^जन/i,
+        /^फ़र/i,
+        /^मार्च/i,
+        /^अप्रै/i,
+        /^मई/i,
+        /^जून/i,
+        /^जुल/i,
+        /^अग/i,
+        /^सित/i,
+        /^अक्टू/i,
+        /^नव/i,
+        /^दिस/i,
+    ];
+
+export default moment.defineLocale('hi', {
+    months: {
+        format: 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split(
+            '_'
+        ),
+        standalone: 'जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर'.split(
+            '_'
+        ),
+    },
+    monthsShort: 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split(
+        '_'
+    ),
+    weekdays: 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
+    weekdaysShort: 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
+    weekdaysMin: 'र_सो_मं_बु_गु_शु_श'.split('_'),
+    longDateFormat: {
+        LT: 'A h:mm बजे',
+        LTS: 'A h:mm:ss बजे',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY, A h:mm बजे',
+        LLLL: 'dddd, D MMMM YYYY, A h:mm बजे',
+    },
+
+    monthsParse: monthsParse,
+    longMonthsParse: monthsParse,
+    shortMonthsParse: shortMonthsParse,
+
+    monthsRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,
+
+    monthsShortRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,
+
+    monthsStrictRegex: /^(जनवरी?|फ़रवरी|फरवरी?|मार्च?|अप्रैल?|मई?|जून?|जुलाई?|अगस्त?|सितम्बर|सितंबर|सित?\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर?|दिसम्बर|दिसंबर?)/i,
+
+    monthsShortStrictRegex: /^(जन\.?|फ़र\.?|मार्च?|अप्रै\.?|मई?|जून?|जुल\.?|अग\.?|सित\.?|अक्टू\.?|नव\.?|दिस\.?)/i,
+
+    calendar: {
+        sameDay: '[आज] LT',
+        nextDay: '[कल] LT',
+        nextWeek: 'dddd, LT',
+        lastDay: '[कल] LT',
+        lastWeek: '[पिछले] dddd, LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s में',
+        past: '%s पहले',
+        s: 'कुछ ही क्षण',
+        ss: '%d सेकंड',
+        m: 'एक मिनट',
+        mm: '%d मिनट',
+        h: 'एक घंटा',
+        hh: '%d घंटे',
+        d: 'एक दिन',
+        dd: '%d दिन',
+        M: 'एक महीने',
+        MM: '%d महीने',
+        y: 'एक वर्ष',
+        yy: '%d वर्ष',
+    },
+    preparse: function (string) {
+        return string.replace(/[१२३४५६७८९०]/g, function (match) {
+            return numberMap[match];
+        });
+    },
+    postformat: function (string) {
+        return string.replace(/\d/g, function (match) {
+            return symbolMap[match];
+        });
+    },
+    // Hindi notation for meridiems are quite fuzzy in practice. While there exists
+    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
+    meridiemParse: /रात|सुबह|दोपहर|शाम/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'रात') {
+            return hour < 4 ? hour : hour + 12;
+        } else if (meridiem === 'सुबह') {
+            return hour;
+        } else if (meridiem === 'दोपहर') {
+            return hour >= 10 ? hour : hour + 12;
+        } else if (meridiem === 'शाम') {
+            return hour + 12;
+        }
+    },
+    meridiem: function (hour, minute, isLower) {
+        if (hour < 4) {
+            return 'रात';
+        } else if (hour < 10) {
+            return 'सुबह';
+        } else if (hour < 17) {
+            return 'दोपहर';
+        } else if (hour < 20) {
+            return 'शाम';
+        } else {
+            return 'रात';
+        }
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 154 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hr.js

@@ -0,0 +1,154 @@
+//! moment.js locale configuration
+//! locale : Croatian [hr]
+//! author : Bojan Marković : https://github.com/bmarkovic
+
+import moment from '../moment';
+
+function translate(number, withoutSuffix, key) {
+    var result = number + ' ';
+    switch (key) {
+        case 'ss':
+            if (number === 1) {
+                result += 'sekunda';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sekunde';
+            } else {
+                result += 'sekundi';
+            }
+            return result;
+        case 'm':
+            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minuta';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'jedan sat' : 'jednog sata';
+        case 'hh':
+            if (number === 1) {
+                result += 'sat';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sata';
+            } else {
+                result += 'sati';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dana';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mjesec';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'mjeseca';
+            } else {
+                result += 'mjeseci';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'godina';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'godine';
+            } else {
+                result += 'godina';
+            }
+            return result;
+    }
+}
+
+export default moment.defineLocale('hr', {
+    months: {
+        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split(
+            '_'
+        ),
+        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split(
+            '_'
+        ),
+    },
+    monthsShort: 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split(
+        '_'
+    ),
+    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
+    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
+    weekdaysParseExact: true,
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'Do MMMM YYYY',
+        LLL: 'Do MMMM YYYY H:mm',
+        LLLL: 'dddd, Do MMMM YYYY H:mm',
+    },
+    calendar: {
+        sameDay: '[danas u] LT',
+        nextDay: '[sutra u] LT',
+        nextWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[u] [nedjelju] [u] LT';
+                case 3:
+                    return '[u] [srijedu] [u] LT';
+                case 6:
+                    return '[u] [subotu] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[u] dddd [u] LT';
+            }
+        },
+        lastDay: '[jučer u] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[prošlu] [nedjelju] [u] LT';
+                case 3:
+                    return '[prošlu] [srijedu] [u] LT';
+                case 6:
+                    return '[prošle] [subote] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prošli] dddd [u] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'za %s',
+        past: 'prije %s',
+        s: 'par sekundi',
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: translate,
+        hh: translate,
+        d: 'dan',
+        dd: translate,
+        M: 'mjesec',
+        MM: translate,
+        y: 'godinu',
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 118 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hu.js

@@ -0,0 +1,118 @@
+//! moment.js locale configuration
+//! locale : Hungarian [hu]
+//! author : Adam Brunner : https://github.com/adambrunner
+//! author : Peter Viszt  : https://github.com/passatgt
+
+import moment from '../moment';
+
+var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(
+    ' '
+);
+function translate(number, withoutSuffix, key, isFuture) {
+    var num = number;
+    switch (key) {
+        case 's':
+            return isFuture || withoutSuffix
+                ? 'néhány másodperc'
+                : 'néhány másodperce';
+        case 'ss':
+            return num + (isFuture || withoutSuffix)
+                ? ' másodperc'
+                : ' másodperce';
+        case 'm':
+            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
+        case 'mm':
+            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
+        case 'h':
+            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
+        case 'hh':
+            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
+        case 'd':
+            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
+        case 'dd':
+            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
+        case 'M':
+            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+        case 'MM':
+            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+        case 'y':
+            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
+        case 'yy':
+            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
+    }
+    return '';
+}
+function week(isFuture) {
+    return (
+        (isFuture ? '' : '[múlt] ') +
+        '[' +
+        weekEndings[this.day()] +
+        '] LT[-kor]'
+    );
+}
+
+export default moment.defineLocale('hu', {
+    months: 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split(
+        '_'
+    ),
+    monthsShort: 'jan._feb._márc._ápr._máj._jún._júl._aug._szept._okt._nov._dec.'.split(
+        '_'
+    ),
+    monthsParseExact: true,
+    weekdays: 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
+    weekdaysShort: 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
+    weekdaysMin: 'v_h_k_sze_cs_p_szo'.split('_'),
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'YYYY.MM.DD.',
+        LL: 'YYYY. MMMM D.',
+        LLL: 'YYYY. MMMM D. H:mm',
+        LLLL: 'YYYY. MMMM D., dddd H:mm',
+    },
+    meridiemParse: /de|du/i,
+    isPM: function (input) {
+        return input.charAt(1).toLowerCase() === 'u';
+    },
+    meridiem: function (hours, minutes, isLower) {
+        if (hours < 12) {
+            return isLower === true ? 'de' : 'DE';
+        } else {
+            return isLower === true ? 'du' : 'DU';
+        }
+    },
+    calendar: {
+        sameDay: '[ma] LT[-kor]',
+        nextDay: '[holnap] LT[-kor]',
+        nextWeek: function () {
+            return week.call(this, true);
+        },
+        lastDay: '[tegnap] LT[-kor]',
+        lastWeek: function () {
+            return week.call(this, false);
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s múlva',
+        past: '%s',
+        s: translate,
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: translate,
+        hh: translate,
+        d: translate,
+        dd: translate,
+        M: translate,
+        MM: translate,
+        y: translate,
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 92 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/hy-am.js

@@ -0,0 +1,92 @@
+//! moment.js locale configuration
+//! locale : Armenian [hy-am]
+//! author : Armendarabyan : https://github.com/armendarabyan
+
+import moment from '../moment';
+
+export default moment.defineLocale('hy-am', {
+    months: {
+        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split(
+            '_'
+        ),
+        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split(
+            '_'
+        ),
+    },
+    monthsShort: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),
+    weekdays: 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split(
+        '_'
+    ),
+    weekdaysShort: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
+    weekdaysMin: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D MMMM YYYY թ.',
+        LLL: 'D MMMM YYYY թ., HH:mm',
+        LLLL: 'dddd, D MMMM YYYY թ., HH:mm',
+    },
+    calendar: {
+        sameDay: '[այսօր] LT',
+        nextDay: '[վաղը] LT',
+        lastDay: '[երեկ] LT',
+        nextWeek: function () {
+            return 'dddd [օրը ժամը] LT';
+        },
+        lastWeek: function () {
+            return '[անցած] dddd [օրը ժամը] LT';
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: '%s հետո',
+        past: '%s առաջ',
+        s: 'մի քանի վայրկյան',
+        ss: '%d վայրկյան',
+        m: 'րոպե',
+        mm: '%d րոպե',
+        h: 'ժամ',
+        hh: '%d ժամ',
+        d: 'օր',
+        dd: '%d օր',
+        M: 'ամիս',
+        MM: '%d ամիս',
+        y: 'տարի',
+        yy: '%d տարի',
+    },
+    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
+    isPM: function (input) {
+        return /^(ցերեկվա|երեկոյան)$/.test(input);
+    },
+    meridiem: function (hour) {
+        if (hour < 4) {
+            return 'գիշերվա';
+        } else if (hour < 12) {
+            return 'առավոտվա';
+        } else if (hour < 17) {
+            return 'ցերեկվա';
+        } else {
+            return 'երեկոյան';
+        }
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
+    ordinal: function (number, period) {
+        switch (period) {
+            case 'DDD':
+            case 'w':
+            case 'W':
+            case 'DDDo':
+                if (number === 1) {
+                    return number + '-ին';
+                }
+                return number + '-րդ';
+            default:
+                return number;
+        }
+    },
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 7, // The week that contains Jan 7th is the first week of the year.
+    },
+});

+ 76 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/id.js

@@ -0,0 +1,76 @@
+//! moment.js locale configuration
+//! locale : Indonesian [id]
+//! author : Mohammad Satrio Utomo : https://github.com/tyok
+//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
+
+import moment from '../moment';
+
+export default moment.defineLocale('id', {
+    months: 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split(
+        '_'
+    ),
+    monthsShort: 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'),
+    weekdays: 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
+    weekdaysShort: 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
+    weekdaysMin: 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
+    longDateFormat: {
+        LT: 'HH.mm',
+        LTS: 'HH.mm.ss',
+        L: 'DD/MM/YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY [pukul] HH.mm',
+        LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm',
+    },
+    meridiemParse: /pagi|siang|sore|malam/,
+    meridiemHour: function (hour, meridiem) {
+        if (hour === 12) {
+            hour = 0;
+        }
+        if (meridiem === 'pagi') {
+            return hour;
+        } else if (meridiem === 'siang') {
+            return hour >= 11 ? hour : hour + 12;
+        } else if (meridiem === 'sore' || meridiem === 'malam') {
+            return hour + 12;
+        }
+    },
+    meridiem: function (hours, minutes, isLower) {
+        if (hours < 11) {
+            return 'pagi';
+        } else if (hours < 15) {
+            return 'siang';
+        } else if (hours < 19) {
+            return 'sore';
+        } else {
+            return 'malam';
+        }
+    },
+    calendar: {
+        sameDay: '[Hari ini pukul] LT',
+        nextDay: '[Besok pukul] LT',
+        nextWeek: 'dddd [pukul] LT',
+        lastDay: '[Kemarin pukul] LT',
+        lastWeek: 'dddd [lalu pukul] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'dalam %s',
+        past: '%s yang lalu',
+        s: 'beberapa detik',
+        ss: '%d detik',
+        m: 'semenit',
+        mm: '%d menit',
+        h: 'sejam',
+        hh: '%d jam',
+        d: 'sehari',
+        dd: '%d hari',
+        M: 'sebulan',
+        MM: '%d bulan',
+        y: 'setahun',
+        yy: '%d tahun',
+    },
+    week: {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6, // The week that contains Jan 6th is the first week of the year.
+    },
+});

+ 139 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/is.js

@@ -0,0 +1,139 @@
+//! moment.js locale configuration
+//! locale : Icelandic [is]
+//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
+
+import moment from '../moment';
+
+function plural(n) {
+    if (n % 100 === 11) {
+        return true;
+    } else if (n % 10 === 1) {
+        return false;
+    }
+    return true;
+}
+function translate(number, withoutSuffix, key, isFuture) {
+    var result = number + ' ';
+    switch (key) {
+        case 's':
+            return withoutSuffix || isFuture
+                ? 'nokkrar sekúndur'
+                : 'nokkrum sekúndum';
+        case 'ss':
+            if (plural(number)) {
+                return (
+                    result +
+                    (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum')
+                );
+            }
+            return result + 'sekúnda';
+        case 'm':
+            return withoutSuffix ? 'mínúta' : 'mínútu';
+        case 'mm':
+            if (plural(number)) {
+                return (
+                    result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum')
+                );
+            } else if (withoutSuffix) {
+                return result + 'mínúta';
+            }
+            return result + 'mínútu';
+        case 'hh':
+            if (plural(number)) {
+                return (
+                    result +
+                    (withoutSuffix || isFuture
+                        ? 'klukkustundir'
+                        : 'klukkustundum')
+                );
+            }
+            return result + 'klukkustund';
+        case 'd':
+            if (withoutSuffix) {
+                return 'dagur';
+            }
+            return isFuture ? 'dag' : 'degi';
+        case 'dd':
+            if (plural(number)) {
+                if (withoutSuffix) {
+                    return result + 'dagar';
+                }
+                return result + (isFuture ? 'daga' : 'dögum');
+            } else if (withoutSuffix) {
+                return result + 'dagur';
+            }
+            return result + (isFuture ? 'dag' : 'degi');
+        case 'M':
+            if (withoutSuffix) {
+                return 'mánuður';
+            }
+            return isFuture ? 'mánuð' : 'mánuði';
+        case 'MM':
+            if (plural(number)) {
+                if (withoutSuffix) {
+                    return result + 'mánuðir';
+                }
+                return result + (isFuture ? 'mánuði' : 'mánuðum');
+            } else if (withoutSuffix) {
+                return result + 'mánuður';
+            }
+            return result + (isFuture ? 'mánuð' : 'mánuði');
+        case 'y':
+            return withoutSuffix || isFuture ? 'ár' : 'ári';
+        case 'yy':
+            if (plural(number)) {
+                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
+            }
+            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
+    }
+}
+
+export default moment.defineLocale('is', {
+    months: 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split(
+        '_'
+    ),
+    monthsShort: 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
+    weekdays: 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split(
+        '_'
+    ),
+    weekdaysShort: 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
+    weekdaysMin: 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
+    longDateFormat: {
+        LT: 'H:mm',
+        LTS: 'H:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D. MMMM YYYY',
+        LLL: 'D. MMMM YYYY [kl.] H:mm',
+        LLLL: 'dddd, D. MMMM YYYY [kl.] H:mm',
+    },
+    calendar: {
+        sameDay: '[í dag kl.] LT',
+        nextDay: '[á morgun kl.] LT',
+        nextWeek: 'dddd [kl.] LT',
+        lastDay: '[í gær kl.] LT',
+        lastWeek: '[síðasta] dddd [kl.] LT',
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: 'eftir %s',
+        past: 'fyrir %s síðan',
+        s: translate,
+        ss: translate,
+        m: translate,
+        mm: translate,
+        h: 'klukkustund',
+        hh: translate,
+        d: translate,
+        dd: translate,
+        M: translate,
+        MM: translate,
+        y: translate,
+        yy: translate,
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}\./,
+    ordinal: '%d.',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

+ 64 - 0
uniCloud-aliyun/cloudfunctions/uni-card/node_modules/moment/dist/locale/it-ch.js

@@ -0,0 +1,64 @@
+//! moment.js locale configuration
+//! locale : Italian (Switzerland) [it-ch]
+//! author : xfh : https://github.com/xfh
+
+import moment from '../moment';
+
+export default moment.defineLocale('it-ch', {
+    months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split(
+        '_'
+    ),
+    monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
+    weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split(
+        '_'
+    ),
+    weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
+    weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
+    longDateFormat: {
+        LT: 'HH:mm',
+        LTS: 'HH:mm:ss',
+        L: 'DD.MM.YYYY',
+        LL: 'D MMMM YYYY',
+        LLL: 'D MMMM YYYY HH:mm',
+        LLLL: 'dddd D MMMM YYYY HH:mm',
+    },
+    calendar: {
+        sameDay: '[Oggi alle] LT',
+        nextDay: '[Domani alle] LT',
+        nextWeek: 'dddd [alle] LT',
+        lastDay: '[Ieri alle] LT',
+        lastWeek: function () {
+            switch (this.day()) {
+                case 0:
+                    return '[la scorsa] dddd [alle] LT';
+                default:
+                    return '[lo scorso] dddd [alle] LT';
+            }
+        },
+        sameElse: 'L',
+    },
+    relativeTime: {
+        future: function (s) {
+            return (/^[0-9].+$/.test(s) ? 'tra' : 'in') + ' ' + s;
+        },
+        past: '%s fa',
+        s: 'alcuni secondi',
+        ss: '%d secondi',
+        m: 'un minuto',
+        mm: '%d minuti',
+        h: "un'ora",
+        hh: '%d ore',
+        d: 'un giorno',
+        dd: '%d giorni',
+        M: 'un mese',
+        MM: '%d mesi',
+        y: 'un anno',
+        yy: '%d anni',
+    },
+    dayOfMonthOrdinalParse: /\d{1,2}º/,
+    ordinal: '%dº',
+    week: {
+        dow: 1, // Monday is the first day of the week.
+        doy: 4, // The week that contains Jan 4th is the first week of the year.
+    },
+});

部分文件因文件數量過多而無法顯示