| @@ -1,31 +1,69 @@ | |||||
| // import Request from '../miniprogram/utils/request.js' | |||||
| const request = require('./utils/request') | |||||
| App({ | App({ | ||||
| globalData: { | globalData: { | ||||
| }, | }, | ||||
| onLaunch() { | onLaunch() { | ||||
| const appId = 'wxf288a9b8167ff2ca' | |||||
| // 展示本地存储能力 | |||||
| const logs = wx.getStorageSync('logs') || [] | |||||
| logs.unshift(Date.now()) | |||||
| wx.setStorageSync('logs', logs) | |||||
| const that = this | |||||
| // 登录 | // 登录 | ||||
| wx.login({ | wx.login({ | ||||
| success: res => { | success: res => { | ||||
| // 发送 res.code 到后台换取 openId, sessionKey, unionId | // 发送 res.code 到后台换取 openId, sessionKey, unionId | ||||
| console.log(res.code) | console.log(res.code) | ||||
| doLogin(res.code) | |||||
| }, | }, | ||||
| }) | }) | ||||
| const doLogin = () => { | |||||
| Request.get({ | |||||
| url: '/login' | |||||
| /** | |||||
| * @description 登录 | |||||
| * @param {*} loginData {code , appid} | |||||
| * @returns token , sessionKey , openId | |||||
| */ | |||||
| const doLogin = code => { | |||||
| const data = { | |||||
| code, | |||||
| appId: request.appId | |||||
| } | |||||
| request.post({ | |||||
| url: '/api/user/login', | |||||
| data | |||||
| }).then(res => { | }).then(res => { | ||||
| console.log(res); | |||||
| console.log(res, 'loginSuccess'); | |||||
| // 存储数据 | |||||
| request.setHead(res.data.token, res.data.tenantId) | |||||
| wx.setStorageSync('sessionKey', res.data.sessionKey) | |||||
| that.globalData.sessionKey = res.data.sessionKey | |||||
| wx.setStorageSync('openId', res.data.openId) | |||||
| that.globalData.openId = res.data.openId | |||||
| wx.setStorageSync('AccessToken', res.data.token) | |||||
| that.globalData.AccessToken = res.data.token | |||||
| // 检查用户信息 | |||||
| checkUserInfo() | |||||
| }).catch(err => { | }).catch(err => { | ||||
| console.log(err); | console.log(err); | ||||
| wx.showToast() | |||||
| wx.showToast({ | |||||
| title: '网络错误,请稍后再试', | |||||
| icon: 'none' | |||||
| }) | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 检查用户信息 | |||||
| * @returns userInfo | |||||
| */ | |||||
| const checkUserInfo = () => { | |||||
| request.get({ | |||||
| url: '/api/user/userinfo' | |||||
| }).then(res => { | |||||
| console.log(res, 'userinfo'); | |||||
| const userInfo = res.data | |||||
| that.globalData.userInfo = userInfo | |||||
| // 请求完成后的回调,在index.js中调用防止异步 | |||||
| that.userInfoCallback(res) | |||||
| }).catch(err => { | |||||
| console.log(err, 'err'); | |||||
| }) | }) | ||||
| } | } | ||||
| }, | }, | ||||
| @@ -1,7 +1,8 @@ | |||||
| { | { | ||||
| "pages": [ | "pages": [ | ||||
| "pages/index/index", | "pages/index/index", | ||||
| "pages/logs/logs" | |||||
| "pages/logs/logs", | |||||
| "pages/payOrder/payOrder" | |||||
| ], | ], | ||||
| "window": { | "window": { | ||||
| "backgroundTextStyle": "light", | "backgroundTextStyle": "light", | ||||
| @@ -1,16 +1,14 @@ | |||||
| // index.ts | |||||
| // 获取应用实例 | |||||
| const app = getApp() | const app = getApp() | ||||
| import Request from '../../utils/request' | |||||
| import request from '../../utils/request' | |||||
| Page({ | Page({ | ||||
| data: { | data: { | ||||
| motto: 'Hello World', | |||||
| userInfo: {}, | userInfo: {}, | ||||
| hasUserInfo: false, | hasUserInfo: false, | ||||
| canIUse: wx.canIUse('button.open-type.getUserInfo'), | canIUse: wx.canIUse('button.open-type.getUserInfo'), | ||||
| canIUseGetUserProfile: false, | canIUseGetUserProfile: false, | ||||
| canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false | |||||
| canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName'), | |||||
| isPhone: false | |||||
| }, | }, | ||||
| // 事件处理函数 | // 事件处理函数 | ||||
| bindViewTap() { | bindViewTap() { | ||||
| @@ -19,10 +17,12 @@ Page({ | |||||
| }) | }) | ||||
| }, | }, | ||||
| onLoad() { | onLoad() { | ||||
| // @ts-ignore | |||||
| if (wx.getUserProfile) { | |||||
| this.setData({ | |||||
| canIUseGetUserProfile: true | |||||
| const that = this | |||||
| app.userInfoCallback = res => { | |||||
| console.log(res, 'userInfoCallback') | |||||
| that.setData({ | |||||
| userInfo: res.data, | |||||
| isPhone: that.data.userInfo.phone ? true : false | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -41,13 +41,57 @@ Page({ | |||||
| }) | }) | ||||
| }, | }, | ||||
| // 获取手机号授权 | |||||
| getUserPhone(e) { | |||||
| const sessionKey = wx.getStorageSync('sessionKey') | |||||
| this.doGetUserPhone(e.detail.encryptedData, e.detail.iv, sessionKey, request.appId) | |||||
| }, | |||||
| /** 获取手机号授权 */ | |||||
| doGetUserPhone(encryptedData, iv, sessionKey, appId) { | |||||
| request.post({ | |||||
| url: '/api/user/getUserPhone', | |||||
| data: { | |||||
| encryptedData, | |||||
| iv, | |||||
| sessionKey, | |||||
| appId | |||||
| } | |||||
| }).then(res => { | |||||
| console.log(res, 'getUserPhone'); | |||||
| wx.showToast({ | |||||
| title: '申请成功!', | |||||
| icon: 'success' | |||||
| }) | |||||
| this.checkUserInfo() | |||||
| }).catch(err => { | |||||
| console.log(err, 'err'); | |||||
| }) | |||||
| }, | |||||
| getUserInfo(e) { | |||||
| // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 | |||||
| console.log(e) | |||||
| this.setData({ | |||||
| userInfo: e.detail.userInfo, | |||||
| hasUserInfo: true | |||||
| // 购买会员 | |||||
| goToBuy() { | |||||
| const userInfo = JSON.stringify(this.data.userInfo) | |||||
| wx.navigateTo({ | |||||
| url: `/pages/payOrder/payOrder?userInfo=${userInfo}`, | |||||
| }) | |||||
| }, | |||||
| /** | |||||
| * @description 检查用户信息 | |||||
| * @returns userInfo | |||||
| */ | |||||
| checkUserInfo() { | |||||
| request.get({ | |||||
| url: '/api/user/userinfo' | |||||
| }).then(res => { | |||||
| console.log(res, 'userinfo'); | |||||
| this.setData({ | |||||
| userInfo: res.data, | |||||
| isPhone: this.data.userInfo.phone ? true : false | |||||
| }) | |||||
| }).catch(err => { | |||||
| console.log(err, 'err'); | |||||
| }) | }) | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -1,3 +1,4 @@ | |||||
| { | { | ||||
| "navigationBarTitleText": "首页", | |||||
| "usingComponents": {} | "usingComponents": {} | ||||
| } | } | ||||
| @@ -1,19 +1,45 @@ | |||||
| /**index.wxss**/ | |||||
| .userinfo { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| color: #aaa; | |||||
| } | |||||
| .content { | |||||
| padding: 50rpx 0; | |||||
| .userinfo-avatar { | |||||
| overflow: hidden; | |||||
| width: 128rpx; | |||||
| height: 128rpx; | |||||
| margin: 20rpx; | |||||
| border-radius: 50%; | |||||
| } | |||||
| .logo { | |||||
| width: 500rpx; | |||||
| height: 120rpx; | |||||
| line-height: 120rpx; | |||||
| text-align: center; | |||||
| color: #ffffff; | |||||
| font-size: 50rpx; | |||||
| background-color: red; | |||||
| margin: auto; | |||||
| } | |||||
| .usermotto { | |||||
| margin-top: 200px; | |||||
| .introduction { | |||||
| width: 600rpx; | |||||
| height: 900rpx; | |||||
| background-color: #79f779; | |||||
| margin: 50rpx auto; | |||||
| padding-top: 20rpx; | |||||
| .title { | |||||
| text-align: center; | |||||
| font-size: 45rpx; | |||||
| color: #585858; | |||||
| margin-bottom: 40rpx; | |||||
| } | |||||
| .contain { | |||||
| width: 500rpx; | |||||
| height: 650rpx; | |||||
| background-color: #00ffc8; | |||||
| text-indent: 1cm; | |||||
| margin: auto; | |||||
| padding-top: 20rpx; | |||||
| } | |||||
| } | |||||
| .buttons { | |||||
| .userPhone { | |||||
| text-align: center; | |||||
| margin-bottom: 25rpx; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -1,23 +1,19 @@ | |||||
| <!--index.wxml--> | <!--index.wxml--> | ||||
| <view class="container"> | |||||
| <view class="userinfo"> | |||||
| <block wx:if="{{canIUseOpenData}}"> | |||||
| <view class="userinfo-avatar" bindtap="bindViewTap"> | |||||
| <open-data type="userAvatarUrl"></open-data> | |||||
| </view> | |||||
| <open-data type="userNickName"></open-data> | |||||
| </block> | |||||
| <block wx:elif="{{!hasUserInfo}}"> | |||||
| <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button> | |||||
| <button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> | |||||
| <view wx:else> 请使用1.4.4及以上版本基础库 </view> | |||||
| <view class="content"> | |||||
| <view class="logo"> | |||||
| GPT-Agent | |||||
| </view> | |||||
| <view class="introduction"> | |||||
| <view class="title">简介</view> | |||||
| <view class="contain">正文部分</view> | |||||
| </view> | |||||
| <view class="buttons"> | |||||
| <block wx:if="{{!userInfo.phone}}"> | |||||
| <button type="primary" open-type="getPhoneNumber" bindgetphonenumber="getUserPhone">申请使用</button> | |||||
| </block> | </block> | ||||
| <block wx:else> | <block wx:else> | ||||
| <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> | |||||
| <text class="userinfo-nickname">{{userInfo.nickName}}</text> | |||||
| <view class="userPhone">当前用户:{{userInfo.phone}}</view> | |||||
| <button type="primary" bindtap="goToBuy">购买会员</button> | |||||
| </block> | </block> | ||||
| </view> | </view> | ||||
| <view class="usermotto"> | |||||
| <text class="user-motto">{{motto}}</text> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| @@ -0,0 +1,151 @@ | |||||
| const app = getApp() | |||||
| import request from '../../utils/request' | |||||
| Page({ | |||||
| /** | |||||
| * 页面的初始数据 | |||||
| */ | |||||
| data: { | |||||
| userInfo: {}, | |||||
| orderList: [ | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: true | |||||
| }, | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: false | |||||
| }, | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: false | |||||
| }, | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: false | |||||
| }, | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: false | |||||
| }, | |||||
| { | |||||
| salePrice: '¥30', | |||||
| orignPrice: '¥60', | |||||
| effectiveTime: '30', | |||||
| show: false | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| /** | |||||
| * 生命周期函数--监听页面加载 | |||||
| */ | |||||
| onLoad(options) { | |||||
| this.setData({ | |||||
| userInfo: JSON.parse(options.userInfo) | |||||
| }) | |||||
| }, | |||||
| createPayOrder() { | |||||
| request.post({ | |||||
| url: '/api/pay/createPayOrder', | |||||
| data: { | |||||
| appId: request.appId | |||||
| } | |||||
| }).then(res => { | |||||
| console.log(res, 'createPayOrder'); | |||||
| this.requestPayment(res.data.data) | |||||
| }).catch(err => { | |||||
| console.log(err, 'err'); | |||||
| }) | |||||
| }, | |||||
| requestPayment(data) { | |||||
| wx.requestPayment({ | |||||
| timeStamp: data.timeStamp, | |||||
| nonceStr: data.nonceStr, | |||||
| package: data.package, | |||||
| signType: data.signType ? data.signType : "MD5", | |||||
| paySign: data.paySign, | |||||
| success: res => { | |||||
| wx.showLoading({ | |||||
| title: '订单正在处理中...', | |||||
| }) | |||||
| setTimeout(() => { | |||||
| wx.hideLoading(); | |||||
| }, 2000); | |||||
| }, | |||||
| fail: res => { | |||||
| wx.hideLoading(); | |||||
| wx.showToast({ | |||||
| title: '支付失败', | |||||
| icon: 'error' | |||||
| }) | |||||
| /** | |||||
| * 支付失败,需要更新订单的状态 | |||||
| */ | |||||
| }, | |||||
| complete: res => { } | |||||
| }); | |||||
| }, | |||||
| /** | |||||
| * 生命周期函数--监听页面初次渲染完成 | |||||
| */ | |||||
| onReady() { | |||||
| }, | |||||
| /** | |||||
| * 生命周期函数--监听页面显示 | |||||
| */ | |||||
| onShow() { | |||||
| }, | |||||
| /** | |||||
| * 生命周期函数--监听页面隐藏 | |||||
| */ | |||||
| onHide() { | |||||
| }, | |||||
| /** | |||||
| * 生命周期函数--监听页面卸载 | |||||
| */ | |||||
| onUnload() { | |||||
| }, | |||||
| /** | |||||
| * 页面相关事件处理函数--监听用户下拉动作 | |||||
| */ | |||||
| onPullDownRefresh() { | |||||
| }, | |||||
| /** | |||||
| * 页面上拉触底事件的处理函数 | |||||
| */ | |||||
| onReachBottom() { | |||||
| }, | |||||
| /** | |||||
| * 用户点击右上角分享 | |||||
| */ | |||||
| onShareAppMessage() { | |||||
| } | |||||
| }) | |||||
| @@ -0,0 +1,4 @@ | |||||
| { | |||||
| "navigationBarTitleText": "购买会员", | |||||
| "usingComponents": {} | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| .content { | |||||
| padding: 50rpx 0; | |||||
| .backGround { | |||||
| width: 600rpx; | |||||
| height: 200rpx; | |||||
| line-height: 200rpx; | |||||
| color: #ffffff; | |||||
| text-align: center; | |||||
| font-size: 60rpx; | |||||
| background-color: red; | |||||
| margin: auto; | |||||
| } | |||||
| .orderList { | |||||
| width: 600rpx; | |||||
| margin: 50rpx auto; | |||||
| .btn { | |||||
| display: inline-block; | |||||
| width: 280rpx; | |||||
| margin-right: 22rpx; | |||||
| margin-top: 20rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| <!--pages/payOrder.wxml--> | |||||
| <view class="content"> | |||||
| <view class="backGround">购买会员</view> | |||||
| <view class="orderList"> | |||||
| <block wx:for="{{orderList}}" wx:key="index"> | |||||
| <button class="btn" type="primary" disabled="{{!item.show}}" bindtap="createPayOrder"> | |||||
| <view>售价:{{item.salePrice}}</view> | |||||
| <view>原价:{{item.orignPrice}}</view> | |||||
| <view>时长:{{item.effectiveTime}}天</view> | |||||
| </button> | |||||
| </block> | |||||
| </view> | |||||
| </view> | |||||
| @@ -1,6 +1,6 @@ | |||||
| const url = 'https://gpttest.malls.iformall.com/C' | const url = 'https://gpttest.malls.iformall.com/C' | ||||
| class Request { | |||||
| class request { | |||||
| constructor(address) { | constructor(address) { | ||||
| if (address) { | if (address) { | ||||
| this.address = address; | this.address = address; | ||||
| @@ -18,15 +18,25 @@ class Request { | |||||
| */ | */ | ||||
| headers = { | headers = { | ||||
| "Content-Type": "application/json;charset=UTF-8", | "Content-Type": "application/json;charset=UTF-8", | ||||
| token: "" | |||||
| token: "", | |||||
| tenantId: "" | |||||
| }; | }; | ||||
| /** | /** | ||||
| * 设置token | |||||
| * @param {*} token | |||||
| * @description 设置请求头 | |||||
| * @param {*} data token , tenantId | |||||
| */ | */ | ||||
| setToken(token) { | |||||
| setHead(token, tenantId) { | |||||
| this.headers.token = token; | this.headers.token = token; | ||||
| this.headers.tenantId = tenantId; | |||||
| } | } | ||||
| /** | |||||
| * @description 小程序appId | |||||
| * @returns {string} wxf288a9b8167ff2ca | |||||
| */ | |||||
| appId = 'wxf288a9b8167ff2ca'; | |||||
| /** | /** | ||||
| * @description get | * @description get | ||||
| * @param {*}param url & param | * @param {*}param url & param | ||||
| @@ -90,6 +100,7 @@ class Request { | |||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| /** | /** | ||||
| * 过滤 请求信息 | * 过滤 请求信息 | ||||
| * @param {*} res | * @param {*} res | ||||
| @@ -117,4 +128,4 @@ class Request { | |||||
| /** 日志 */ | /** 日志 */ | ||||
| log(url, body, headers) { } | log(url, body, headers) { } | ||||
| } | } | ||||
| module.exports = new Request(); | |||||
| module.exports = new request(); | |||||
| @@ -5,5 +5,6 @@ | |||||
| "compileHotReLoad": true, | "compileHotReLoad": true, | ||||
| "urlCheck": false | "urlCheck": false | ||||
| }, | }, | ||||
| "libVersion": "2.31.0" | |||||
| "libVersion": "2.31.0", | |||||
| "condition": {} | |||||
| } | } | ||||
| @@ -25,7 +25,12 @@ | |||||
| ] | ] | ||||
| }, | }, | ||||
| "include": [ | "include": [ | ||||
| "./**/*.ts", "miniprogram/app.js", "miniprogram/utils/util.js", "miniprogram/pages/logs/logs.js", "miniprogram/pages/index/index.js", | |||||
| "./**/*.ts", | |||||
| "miniprogram/app.js", | |||||
| "miniprogram/utils/util.js", | |||||
| "miniprogram/pages/logs/logs.js", | |||||
| "miniprogram/pages/index/index.js", | |||||
| "miniprogram/pages/payOrder/payOrder.js", | |||||
| ], | ], | ||||
| "exclude": [ | "exclude": [ | ||||
| "node_modules" | "node_modules" | ||||
| @@ -2,52 +2,3 @@ | |||||
| # yarn lockfile v1 | # yarn lockfile v1 | ||||
| axios-miniprogram-adapter@^0.3.5: | |||||
| version "0.3.5" | |||||
| resolved "https://registry.yarnpkg.com/axios-miniprogram-adapter/-/axios-miniprogram-adapter-0.3.5.tgz#b02fbf61ec8899703c24eaa75fecd384509cacbd" | |||||
| integrity sha512-ZAudH+aTi0QPIy8IQm26F0nxKoTFa/mNhDfxGkG5ndsQe4RVnyyb6f50tIT13nHtNepAjZo9i+UGmTbke5+lbQ== | |||||
| dependencies: | |||||
| axios "^0.19.2" | |||||
| axios@0.26.0: | |||||
| version "0.26.0" | |||||
| resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.0.tgz#9a318f1c69ec108f8cd5f3c3d390366635e13928" | |||||
| integrity sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og== | |||||
| dependencies: | |||||
| follow-redirects "^1.14.8" | |||||
| axios@^0.19.2: | |||||
| version "0.19.2" | |||||
| resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" | |||||
| integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== | |||||
| dependencies: | |||||
| follow-redirects "1.5.10" | |||||
| debug@=3.1.0: | |||||
| version "3.1.0" | |||||
| resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" | |||||
| integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== | |||||
| dependencies: | |||||
| ms "2.0.0" | |||||
| follow-redirects@1.5.10: | |||||
| version "1.5.10" | |||||
| resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" | |||||
| integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== | |||||
| dependencies: | |||||
| debug "=3.1.0" | |||||
| follow-redirects@^1.14.8: | |||||
| version "1.15.2" | |||||
| resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" | |||||
| integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== | |||||
| miniprogram-api-typings@^2.8.3-1: | |||||
| version "2.12.0" | |||||
| resolved "https://registry.yarnpkg.com/miniprogram-api-typings/-/miniprogram-api-typings-2.12.0.tgz#7a29c90f3e5efa36588422d1f01e22d3394aaaa1" | |||||
| integrity sha512-ibvbqeslVFur0IAvTxLMvsbtvVcMo6gwvOnj0YZHV7aeDLu091VQRrETT2QuiG9P6aZWRcxeNGJChRKVPCp9VQ== | |||||
| ms@2.0.0: | |||||
| version "2.0.0" | |||||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | |||||
| integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== | |||||