master ee31e684f858 cached
564 files
726.0 KB
221.9k tokens
689 symbols
1 requests
Download .txt
Showing preview only (871K chars total). Download the full file or copy to clipboard to get everything.
Repository: Taoshaoji/used-book-secondhand
Branch: master
Commit: ee31e684f858
Files: 564
Total size: 726.0 KB

Directory structure:
gitextract_m91prd5v/

├── .gitignore
├── .vscode/
│   └── settings.json
├── README.md
├── cloudfunctions/
│   ├── his/
│   │   ├── index.js
│   │   └── package.json
│   ├── imgSecCheck/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── login/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── node/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── pay/
│   │   ├── index.js
│   │   └── package.json
│   ├── poking/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── ref/
│   │   ├── index.js
│   │   └── package.json
│   ├── regist/
│   │   ├── RdWXBizDataCrypt.js
│   │   ├── cryptojs/
│   │   │   ├── cryptojs.js
│   │   │   ├── lib/
│   │   │   │   ├── AES.js
│   │   │   │   ├── BlockModes.js
│   │   │   │   ├── Crypto.js
│   │   │   │   ├── CryptoMath.js
│   │   │   │   ├── DES.js
│   │   │   │   ├── HMAC.js
│   │   │   │   ├── MARC4.js
│   │   │   │   ├── MD5.js
│   │   │   │   ├── PBKDF2.js
│   │   │   │   ├── PBKDF2Async.js
│   │   │   │   ├── Rabbit.js
│   │   │   │   ├── SHA1.js
│   │   │   │   └── SHA256.js
│   │   │   ├── package.json
│   │   │   └── test/
│   │   │       └── PBKDF2-test.js
│   │   ├── index.js
│   │   └── package.json
│   ├── removeChat/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── removeOrder/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── sell/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── sendMsg/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   └── sendTip/
│       ├── config.json
│       ├── index.js
│       └── package.json
├── miniprogram/
│   ├── app.js
│   ├── app.json
│   ├── app.wxss
│   ├── common.wxml
│   ├── common.wxs
│   ├── components/
│   │   ├── add_tips/
│   │   │   ├── README.md
│   │   │   ├── index.js
│   │   │   ├── index.json
│   │   │   ├── index.wxml
│   │   │   └── index.wxss
│   │   ├── canvasdrawer/
│   │   │   ├── canvasdrawer.js
│   │   │   ├── canvasdrawer.json
│   │   │   ├── canvasdrawer.wxml
│   │   │   └── canvasdrawer.wxss
│   │   ├── chatroom/
│   │   │   ├── chatroom.js
│   │   │   ├── chatroom.json
│   │   │   ├── chatroom.wxml
│   │   │   └── chatroom.wxss
│   │   └── welcome/
│   │       ├── welcome.js
│   │       ├── welcome.json
│   │       ├── welcome.wxml
│   │       └── welcome.wxss
│   ├── config.js
│   ├── pages/
│   │   ├── about/
│   │   │   ├── about.js
│   │   │   ├── about.json
│   │   │   ├── about.wxml
│   │   │   └── about.wxss
│   │   ├── appreciateCode/
│   │   │   ├── appreciateCode.js
│   │   │   ├── appreciateCode.json
│   │   │   ├── appreciateCode.wxml
│   │   │   └── appreciateCode.wxss
│   │   ├── detail/
│   │   │   ├── detail.js
│   │   │   ├── detail.json
│   │   │   ├── detail.wxml
│   │   │   ├── detail.wxss
│   │   │   └── room/
│   │   │       ├── room.js
│   │   │       ├── room.json
│   │   │       ├── room.wxml
│   │   │       └── room.wxss
│   │   ├── edit/
│   │   │   ├── edit.js
│   │   │   ├── edit.json
│   │   │   ├── edit.wxml
│   │   │   └── edit.wxss
│   │   ├── help/
│   │   │   ├── help.js
│   │   │   ├── help.json
│   │   │   ├── help.wxml
│   │   │   └── help.wxss
│   │   ├── index/
│   │   │   ├── index.js
│   │   │   ├── index.json
│   │   │   ├── index.wxml
│   │   │   └── index.wxss
│   │   ├── kefu/
│   │   │   ├── kefu.js
│   │   │   ├── kefu.json
│   │   │   ├── kefu.wxml
│   │   │   └── kefu.wxss
│   │   ├── login/
│   │   │   ├── login.js
│   │   │   ├── login.json
│   │   │   ├── login.wxml
│   │   │   └── login.wxss
│   │   ├── message/
│   │   │   ├── message.js
│   │   │   ├── message.json
│   │   │   ├── message.wxml
│   │   │   └── message.wxss
│   │   ├── my/
│   │   │   ├── my.js
│   │   │   ├── my.json
│   │   │   ├── my.wxml
│   │   │   └── my.wxss
│   │   ├── order/
│   │   │   ├── detail/
│   │   │   │   ├── detail.js
│   │   │   │   ├── detail.json
│   │   │   │   ├── detail.wxml
│   │   │   │   └── detail.wxss
│   │   │   └── list/
│   │   │       ├── list.js
│   │   │       ├── list.json
│   │   │       ├── list.wxml
│   │   │       └── list.wxss
│   │   ├── publish/
│   │   │   ├── publish.js
│   │   │   ├── publish.json
│   │   │   ├── publish.wxml
│   │   │   └── publish.wxss
│   │   ├── search/
│   │   │   ├── search.js
│   │   │   ├── search.json
│   │   │   ├── search.wxml
│   │   │   └── search.wxss
│   │   ├── sell/
│   │   │   ├── detail/
│   │   │   │   ├── detail.js
│   │   │   │   ├── detail.json
│   │   │   │   ├── detail.wxml
│   │   │   │   └── detail.wxss
│   │   │   └── list/
│   │   │       ├── list.js
│   │   │       ├── list.json
│   │   │       ├── list.wxml
│   │   │       └── list.wxss
│   │   ├── start/
│   │   │   ├── start.js
│   │   │   ├── start.json
│   │   │   ├── start.wxml
│   │   │   └── start.wxss
│   │   ├── use/
│   │   │   ├── use.js
│   │   │   ├── use.json
│   │   │   ├── use.wxml
│   │   │   └── use.wxss
│   │   └── web/
│   │       ├── web.js
│   │       ├── web.json
│   │       ├── web.wxml
│   │       └── web.wxss
│   ├── sitemap.json
│   ├── utils/
│   │   └── util.js
│   └── vant/
│       ├── action-sheet/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── area/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── button/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── calendar/
│       │   ├── calendar.wxml
│       │   ├── components/
│       │   │   ├── header/
│       │   │   │   ├── index.d.ts
│       │   │   │   ├── index.js
│       │   │   │   ├── index.json
│       │   │   │   ├── index.wxml
│       │   │   │   └── index.wxss
│       │   │   └── month/
│       │   │       ├── index.d.ts
│       │   │       ├── index.js
│       │   │       ├── index.json
│       │   │       ├── index.wxml
│       │   │       ├── index.wxs
│       │   │       └── index.wxss
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   ├── index.wxss
│       │   ├── utils.d.ts
│       │   ├── utils.js
│       │   └── utils.wxs
│       ├── card/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── cell/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── cell-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── checkbox/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── checkbox-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── circle/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── col/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── collapse/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── collapse-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── common/
│       │   ├── color.d.ts
│       │   ├── color.js
│       │   ├── component.d.ts
│       │   ├── component.js
│       │   ├── index.wxss
│       │   ├── style/
│       │   │   ├── clearfix.wxss
│       │   │   ├── ellipsis.wxss
│       │   │   ├── hairline.wxss
│       │   │   ├── mixins/
│       │   │   │   ├── clearfix.wxss
│       │   │   │   ├── ellipsis.wxss
│       │   │   │   └── hairline.wxss
│       │   │   ├── theme.wxss
│       │   │   └── var.wxss
│       │   ├── utils.d.ts
│       │   ├── utils.js
│       │   ├── version.d.ts
│       │   └── version.js
│       ├── count-down/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── utils.d.ts
│       │   └── utils.js
│       ├── datetime-picker/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── definitions/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── weapp.d.ts
│       │   └── weapp.js
│       ├── dialog/
│       │   ├── dialog.d.ts
│       │   ├── dialog.js
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── divider/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── dropdown-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── dropdown-menu/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── field/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   ├── index.wxss
│       │   ├── props.d.ts
│       │   └── props.js
│       ├── goods-action/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── goods-action-button/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── goods-action-icon/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── grid/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── grid-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── icon/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── image/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── index-anchor/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── index-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── info/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── loading/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── mixins/
│       │   ├── basic.d.ts
│       │   ├── basic.js
│       │   ├── button.d.ts
│       │   ├── button.js
│       │   ├── link.d.ts
│       │   ├── link.js
│       │   ├── open-type.d.ts
│       │   ├── open-type.js
│       │   ├── page-scroll.d.ts
│       │   ├── page-scroll.js
│       │   ├── touch.d.ts
│       │   ├── touch.js
│       │   ├── transition.d.ts
│       │   └── transition.js
│       ├── nav-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── notice-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── notify/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── notify.d.ts
│       │   └── notify.js
│       ├── overlay/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── panel/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── picker/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── shared.d.ts
│       │   ├── shared.js
│       │   └── toolbar.wxml
│       ├── picker-column/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── popup/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── progress/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── radio/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── radio-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── rate/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── row/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── search/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sidebar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sidebar-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── skeleton/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── slider/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── stepper/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── steps/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sticky/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── submit-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── swipe-cell/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── switch/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tab/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabbar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabbar-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabs/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── tag/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── toast/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── toast.d.ts
│       │   └── toast.js
│       ├── transition/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tree-select/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── uploader/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── shared.d.ts
│       │   ├── shared.js
│       │   ├── utils.d.ts
│       │   └── utils.js
│       └── wxs/
│           ├── add-unit.wxs
│           ├── array.wxs
│           ├── bem.wxs
│           ├── memoize.wxs
│           ├── object.wxs
│           └── utils.wxs
└── project.config.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
node_modules/*

================================================
FILE: .vscode/settings.json
================================================
{
  "git.ignoreLimitWarning": true
}

================================================
FILE: README.md
================================================
# Secondary_trading_applet

基于微信小程序的校园二手交易平台

## 校园二手商城微信小程序成果(云开发)
图片看不到可在B站搜索易珠观看效果

### 功能

**(1)用户登陆注册**:在小程序个人主页点击登录或注册,填写相关信息,即可登录或注册,拥有个人账号进行买卖操作。后续也可以修改用户资料。

**(2)用户(卖家)出售商品**:在小程序发布页面,上传商品图片,填写商品各种详细即可发布商品。在个人主页的发布信息中即可查看商品交易信息,可以删除订单,重新上架商品,删除商品。

**(3)用户浏览商品**:商城主页,用户可以通过分类查看各个商品信息,也可以搜索商品名,得到筛选后的商品。点击商品进入商品详情页,可查看商品详细信息。

**(4)用户(买家)购买商品**:在商品详情页,买家可点击立即购买,预定这个商品,可在个人主页的购买信息中查看自己的购买记录,也可以在放弃购买时删除该订单,或在收到商品交易达成后,点击确认收货。交易完成。

**(5)用户交流**:买家可在商品详情页点击聊天与卖家进行沟通。在个人主页的消息中心中,都可以查看聊天信息,进入聊天室。

### 用户操作举例

首先进入小程序进行登录授权,授权进入后,显示商城主页,当前为未登陆注册状态不能发布和购买商品。

<img src="README.assets/image-20200920220005803.png" alt="image-20200920220005803" style="zoom: 50%;" /> <img src="https://github.com/Taoshaoji/CloudIMG/blob/master/image-20200920220722873.png" alt="image-20200920220722873" style="zoom:50%;" />

点击下方导航栏‘我的’进入个人主页,点击**登录**,填写信息,注册或登录账号,登录注册成功,个人主页显示用户微信头像及昵称

<img src="README.assets/image-20200920220841085.png" alt="image-20200920220841085" style="zoom:50%;" /><img src="README.assets/image-20200920220948222.png" alt="image-20200920220948222" style="zoom:50%;" />



用户想要**出售商品**,可在商城主页导航栏点击‘发布’,填写信息发布商品,在个人主页我的发布中查看出售情况,如不想出售也可在我的发布处点击删除,商品下架。

<img src="README.assets/image-20200920221442425.png" alt="image-20200920221442425" style="zoom:50%;" /><img src="README.assets/image-20200920221738182.png" alt="image-20200920221738182" style="zoom:50%;" /><img src="README.assets/image-20200920221751633.png" alt="image-20200920221751633" style="zoom:50%;" />



用户想要**入手商品**,可回到商城首页,分类浏览商品,也可以通过上方搜索栏搜索商品,用户可以点击商品,进入商品详情页,查看物品详情,卖家信息,备注等等

<img src="README.assets/image-20200920221852958.png" alt="image-20200920221852958" style="zoom:50%;" /><img src="README.assets/image-20200920221938299.png" alt="image-20200920221938299" style="zoom:50%;" /><img src="README.assets/image-20200920222108667.png" alt="image-20200920222108667" style="zoom:50%;" />



买卖双方**交易过程:**

1.买家购买商品:

买家购买商品后,如在线下收到商品,则可以通过确认收货通知卖家

<img src="README.assets/image-20200920222151402.png" alt="image-20200920222151402" style="zoom:50%;" /><img src="README.assets/image-20200920222300547.png" alt="image-20200920222300547" style="zoom:50%;" /><img src="README.assets/image-20200920222352110.png" alt="image-20200920222352110" style="zoom:50%;" />



2.买家中止交易:

买家可以点击取消订单按钮中途取消交易,卖家会收到消息提醒。商品会自动上架。

<img src="README.assets/image-20200920222529192.png" alt="image-20200920222529192" style="zoom:50%;" />

3.卖家中止交易:

卖家可中途中止交易。然后点击重新上架按钮,重新发布到首页展示。

<img src="README.assets/image-20200920222737231.png" alt="image-20200920222737231" style="zoom:50%;" /><img src="README.assets/image-20200920222748670.png" alt="image-20200920222748670" style="zoom:50%;" /><img src="README.assets/image-20200920222804302.png" alt="image-20200920222804302" style="zoom:50%;" />



买家可在商品详情页点击‘聊天’与卖家沟通

<img src="README.assets/image-20200920222934149.png" alt="image-20200920222934149" style="zoom:50%;" />

卖家可在个人主页消息中心中,看到买家的信息,进入聊天室与之交流。

<img src="README.assets/image-20200920223013113.png" alt="image-20200920223013113" style="zoom: 50%;" />





### 部署教程:

本小程序已经上线,可先预览:

<img src="README.assets/image-20200920223554236.png" alt="image-20200920223554236" style="zoom:50%;" />



## 一、小程序端

### 1、下载导入

直接下载到本地,然后导入开发者工具

> 小程序开发综合文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/

### 2、开通云环境

不罗嗦,这都是基础,直接看官方说明操作即可

> 云开发官方文档说明:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html

### 3、配置前端config

找到config.js文件,然后按照我写的注释更改为你自己的

<img src="README.assets/image-20200920223633305.png" alt="image-20200920223633305" style="zoom:67%;" />

## 二、云函数

### 1、修改基础信息

每个云函数要修改的部分,我都捻出来放在了顶部,直接根据我做的注释信息进行修改,如下图所示

<img src="README.assets/image-20200920223729148.png" alt="image-20200920223729148" style="zoom:67%;" />



### 2、上传全部文件

挨个提交每个云函数,其中依赖包我已经一起上传了,无需再挨个本地去安装,直接上传所有文件即可

<img src="README.assets/image-20200920223930768.png" alt="image-20200920223930768" style="zoom:67%;" />



## 三、云开发数据库

### 1、创建集合 设置权限

分别创建下图所示的集合,然后将所有集合的权限设置为所有可读

<img src="README.assets/image-20200920224111392.png" alt="image-20200920224111392" style="zoom:67%;" />

### 2、设置banner

#### ①在banner集合下新增一条记录

#### ②按照下图所示添加字段

<img src="README.assets/image-20200920224159506.png" alt="image-20200920224159506" style="zoom:67%;" />

#### 补充说明

list数组下的img为图片地址,id为唯一区分字段,url为点击轮播后跳转的地址,这个地址必须为与此小程序关联的公众号文章或者为业务域名地址,如果没有就留空即可



### 3、设置启动页图片

#### ①在start集合下新增一条记录

#### ②按照下图所示添加字段

<img src="README.assets/image-20200920224235782.png" alt="image-20200920224235782" style="zoom: 67%;" />



## 四、公众平台配置(小程序不上线则不需要执行此步骤)

### 1、设置基本信息

| 名称   | 配置                         |
| ------ | ---------------------------- |
| 类目   | 生活服务 > 环保回收/废品回收 |
| 基础库 | 2.4.3                        |

### 2、提交审核

审核页面路径:pages/index/index

### 3、设置在线客服

打开【设置】--【客服】--【添加】,绑定成功后,打开小程序【客服小助手】,状态设置为在线即可,到时候有客户咨询自动会推送到你的微信号上的

<img src="README.assets/image-20200920224525938.png" alt="image-20200920224525938" style="zoom:50%;" />



## 五、服务与反馈

#### 如果需要提供安装服务,直接联系我微信:XXXXXXXXXX  如果觉得对你有帮助可以支持一下!感谢!**(代码开源,但时间不“开源”,伸手党勿扰!)**
<img src="https://i.loli.net/2021/02/24/b6xh5ZnQoJXceOu.jpg" alt="image-2020092022458"  style="zoom:25%; size=25%" />



================================================
FILE: cloudfunctions/his/index.js
================================================
const envid = 'taoshaoji-46f0r'; //云开发环境id

/*
下
面
不
用
管
*/

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
      env: envid,
})
const TcbRouter = require('tcb-router'); //云函数路由
const db = cloud.database();
// 云函数入口函数
exports.main = async(event, context) => {
      const app = new TcbRouter({
            event
      });
      //钱包充值
      app.router('recharge', async(ctx) => {
            const wxContext = cloud.getWXContext()
            const openid = wxContext.OPENID;
            const userinfo = await db.collection('user').where({
                  _openid: openid // 填入当前用户 openid
            }).get()
            try {
                  ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
                        data: {
                              parse: userinfo.data[0].parse + parseInt(event.num)
                        }
                  });
            } catch (e) {
                  console.error(e)
            }
      });
      //买家确认收货
      app.router('toseller', async(ctx) => {
            //先增加历史记录
            await db.collection('history').add({
                  // data 字段表示需新增的 JSON 数据
                  data: {
                        oid: event.seller,
                        name: '出售书籍',
                        num: event.num,
                        stamp: new Date().getTime(),
                        type: 1,
                  }
            })

            //再修改钱包值
            let userinfo = await db.collection('user').where({
                  _openid: event.seller, // 卖家openid
            }).get()
            ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
                  data: {
                        parse: userinfo.data[0].parse + parseInt(event.num)
                  }
            });
      });
      //卖家取消订单退款
      app.router('tobuyer', async(ctx) => {
            //先增加历史记录
            await db.collection('history').add({
                  // data 字段表示需新增的 JSON 数据
                  data: {
                        oid: event.buyer,
                        name: '卖家取消交易退款',
                        num: event.num,
                        stamp: new Date().getTime(),
                        type: 1,
                  }
            })
            //再修改钱包值
            let userinfo = await db.collection('user').where({
                  _openid: event.buyer,
            }).get()
            ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
                  data: {
                        parse: userinfo.data[0].parse + parseInt(event.num)
                  }
            });
      });
      return app.serve();
}

================================================
FILE: cloudfunctions/his/package.json
================================================
{
      "name": "his",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
            "tcb-router": "^1.1.2",
            "wx-server-sdk": "^1.1.0"
      }
}


================================================
FILE: cloudfunctions/imgSecCheck/config.json
================================================
{
  "permissions": {
    "openapi": [
      "security.imgSecCheck"
    ]
  }
}


================================================
FILE: cloudfunctions/imgSecCheck/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  try {
    const result = await cloud.openapi.security.imgSecCheck({
      media: {
        contentType: 'image/png',
        value: Buffer.from(event.img)   // 这里必须要将小程序端传过来的进行Buffer转化,否则就会报错,接口异常
      }
      
    })

    if (result && result.errCode.toString() === '87014') {
      return { code: 500, msg: '内容含有违法违规内容', data: result }
    } else {
      return { code: 200, msg: '内容ok', data: result }
    }
  } catch (err) {
    // 错误处理
    if (err.errCode.toString() === '87014') {
      return { code: 500, msg: '内容含有违法违规内容', data: err }
    }
    return { code: 502, msg: '调用imgSecCheck接口异常', data: err }
  }
}


================================================
FILE: cloudfunctions/imgSecCheck/package.json
================================================
{
  "name": "imgSecCheck",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.2.0"
  }
}

================================================
FILE: cloudfunctions/login/config.json
================================================
{
  "permissions": {
    "openapi": []
  }
}


================================================
FILE: cloudfunctions/login/index.js
================================================
// 云函数模板
// 部署:在 cloud-functions/login 文件夹右击选择 “上传并部署”

const cloud = require('wx-server-sdk')

// 初始化 cloud
cloud.init({
  // API 调用都保持和云函数当前所在环境一致
  env: "taoshaoji-46f0r"
})

/**
 * 这个示例将经自动鉴权过的小程序用户 openid 返回给小程序端
 * 
 * event 参数包含小程序端调用传入的 data
 * 
 */
exports.main = (event, context) => {
  console.log(event)
  console.log(context)

  // 可执行其他自定义逻辑
  // console.log 的内容可以在云开发云函数调用日志查看

  // 获取 WX Context (微信调用上下文),包括 OPENID、APPID、及 UNIONID(需满足 UNIONID 获取条件)等信息
  const wxContext = cloud.getWXContext()

  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.appid,
    unionid: wxContext.UNIONID,
    env: wxContext.ENV,
  }
}



================================================
FILE: cloudfunctions/login/package.json
================================================
{
  "name": "login",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "latest"
  }
}


================================================
FILE: cloudfunctions/node/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/node/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
  
cloud.init()
  
const db = cloud.database()
const _ = db.command
  
// 云函数入口函数
exports.main = async (event, _context) => {
 try {
  return await db.collection('publish').doc(event._id).update({
   // data 传入需要局部更新的数据
   data: {
      status:event.status
   }
  })
 } catch (e) {
  console.error(e)
 }
}

================================================
FILE: cloudfunctions/node/package.json
================================================
{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.1.2"
  }
}

================================================
FILE: cloudfunctions/pay/index.js
================================================
const config = {
      appid: 'xxxxxxx', //服务商公众号Appid
      envName: 'taoshaoji-46f0r', // 小程序云开发环境ID
      mchid: 'xxxxxxxx', //商户号
      partnerKey: 'xxxxxxxxxxxxx', //此处填服务商密钥
      notify_url: 'https://mp.weixin.qq.com', //这个不要管
      spbill_create_ip: '127.0.0.1'//这个不要管
};

/*
下
面
不
用
管
*/

const cloud = require('wx-server-sdk');
cloud.init({
      env: config.envName
})
const db = cloud.database();
const TcbRouter = require('tcb-router'); //云函数路由
const rq = require('request');
const tenpay = require('tenpay');//支付核心模块

exports.main = async (event, context) => {
      const app = new TcbRouter({
            event
      });
      //支付回调
      app.router('pay', async (ctx) => {
            const wxContext = cloud.getWXContext();
            // 在云函数参数中,提取商品 ID
            const goodId = event.goodId;
            // 根据商品的数据库_id将其它数据提取出来
            let goods = await db.collection('publish').doc(goodId).get();
            // 在云函数中提取数据,包括名称、价格才更合理安全,
            // 因为从端里传过来的商品数据都是不可靠的
            let good=goods.data;
            const curTime = Date.now();
            const api = tenpay.init(config)
            let result = await api.getPayParams({
                  //商户订单号,我这里是定义的boolk+商品发布时间+当前时间戳
                  //微信这里限制订单号一次性不能重复,只需要唯一即可
                  out_trade_no: 'book'+good.creat + '' + curTime,     
                  body: good.bookinfo.title,       //商品名称,我设置的书名
                  total_fee: parseInt(good.price)*100,     //金额,注意是数字,不是字符串
                 openid: wxContext.OPENID //***用户的openid
            });
            ctx.body = result;//返回前端结果
      });
      //充值钱包
      app.router('recharge', async (ctx) => {
            const wxContext = cloud.getWXContext();
            const curTime = Date.now();
            const api = tenpay.init(config)
            let result = await api.getPayParams({
                  //商户订单号
                  out_trade_no: 'bookcz' + event.num + '' + curTime,
                  body: '充值钱包',       //商品名称
                   total_fee: parseInt(event.num)*100,     //金额,注意是数字,不是字符串
                  openid: wxContext.OPENID //***用户的openid
            });
            ctx.body = result;//返回前端结果
      });
      //修改卖家在售状态
      app.router('changeP', async (ctx) => {
            try {
                  return await db.collection('publish').doc(event._id).update({
                        data: {
                              status:event.status
                        }
                  })
            } catch (e) {
                  console.error(e)
            }
      });
      //修改订单状态
      app.router('changeO', async (ctx) => {
            try {
                  return await db.collection('order').doc(event._id).update({
                        data: {
                              status: event.status
                        }
                  })
            } catch (e) {
                  console.error(e)
            }
      });
      return app.serve();
}

================================================
FILE: cloudfunctions/pay/package.json
================================================
{
      "name": "pay",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
            "request": "^2.88.0",
            "tcb-router": "^1.1.2",
            "tenpay": "^2.1.18",
            "wx-server-sdk": "latest"
      }
}


================================================
FILE: cloudfunctions/poking/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/poking/index.js
================================================
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
  try {
    const result = await cloud.openapi.subscribeMessage.send({
      touser: event.openid, //要推送给那个用户
      page: 'pages/index/index', //要跳转到那个小程序页面
      data: {//推送的内容
        thing1: {
          value: event.nickName
        },
        phrase2: {
          value: event.phrase,
        },
        thing3: {
          value: event.tip
        }
      },
      templateId: 'XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q' //模板id
    })
    console.log(result)
    return result
  } catch (err) {
    console.log(err)
    return err
  }
}

================================================
FILE: cloudfunctions/poking/package.json
================================================
{
  "name": "poking",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.2.0"
  }
}

================================================
FILE: cloudfunctions/ref/index.js
================================================
const config = {
      appid: 'wxd6beb52c8602bff4', //小程序Appid
      envName: 'taoshaoji-46f0r', // 小程序云开发环境ID
      mchid: '1111111111', //商户号
      partnerKey: '1111111111111111111111', //此处填服务商密钥
      pfx: '', //证书初始化
      fileID: 'cloud://taoshaoji-46f0r.7461-taoshaoji-46f0r-1302243411/apiclient_cert.p12', //证书云存储id
      actionName:'吉珠二手书商城小程序提现',
      rate:1 //提现收取利率,1指的是每笔收取1%
};

/*
下
面
不
用
管
*/
const cloud = require('wx-server-sdk')
cloud.init({
      env: config.envName
})

const db = cloud.database();
const tenpay = require('tenpay'); //支付核心模块
exports.main = async(event, context) => {

      let userInfo = (await db.collection('user').doc(event.userid).get()).data;
      if (parseInt(userInfo.parse)<=parseInt(event.num)){
            return 0;
      }
      //首先获取证书文件
     let fileres = await cloud.downloadFile({
            fileID: config.fileID,
      })
      config.pfx = fileres.fileContent
      let pay = new tenpay(config,true)
      let result = await pay.transfers({
            partner_trade_no: 'bookreflect' + Date.now() + event.num,
            openid: userInfo._openid,
            check_name: 'NO_CHECK',
            amount: parseInt(event.num) * (100 - config.rate),
            desc: config.actionName,
      });
      if (result.result_code == 'SUCCESS') {
            //成功后操作
            //以下是进行余额计算
            let re=await db.collection('user').doc(event.userid).update({
                  data: {
                        parse: userInfo.parse - parseInt(event.num)
                  }
            });
            return re
      }
}


================================================
FILE: cloudfunctions/ref/package.json
================================================
{
      "name": "ref",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
            "tenpay": "^2.1.18",
            "wx-server-sdk": "^1.2.1"
      }
}


================================================
FILE: cloudfunctions/regist/RdWXBizDataCrypt.js
================================================

// 引入CryptoJS
var Crypto = require('cryptojs/cryptojs.js').Crypto;

function RdWXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}

RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  encryptedData = encryptedData.replace(/%/g, '%25')
  // base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
  var encryptedData = Crypto.util.base64ToBytes(encryptedData)
  var key = Crypto.util.base64ToBytes(this.sessionKey);
  var iv = Crypto.util.base64ToBytes(iv);

  // 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);

  try {
    // 解密
    var bytes = Crypto.AES.decrypt(encryptedData, key, {
      asBpytes: true,
      iv: iv,
      mode: mode
    });

    var decryptResult = JSON.parse(bytes);

  } catch (err) {
    console.log(err)
  }

  if (decryptResult.watermark.appid !== this.appId) {
    console.log(err)
  }

  return decryptResult
}

module.exports = RdWXBizDataCrypt

================================================
FILE: cloudfunctions/regist/cryptojs/cryptojs.js
================================================
var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;

[ 'CryptoMath'
, 'BlockModes'
, 'DES'
, 'AES'
, 'HMAC'
, 'MARC4'
, 'MD5'
, 'PBKDF2'
, 'PBKDF2Async'
, 'Rabbit'
, 'SHA1'
, 'SHA256'
].forEach( function (path) {
	require('./lib/' + path);
});


================================================
FILE: cloudfunctions/regist/cryptojs/lib/AES.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8;

// Precomputed SBOX
var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
             0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
             0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
             0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
             0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
             0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
             0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
             0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
             0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
             0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
             0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
             0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
             0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
             0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
             0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
             0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
             0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
             0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
             0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
             0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
             0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
             0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
             0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
             0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
             0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
             0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
             0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
             0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
             0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
             0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
             0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
             0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];

// Compute inverse SBOX lookup table
for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;

// Compute mulitplication in GF(2^8) lookup tables
var MULT2 = [],
    MULT3 = [],
    MULT9 = [],
    MULTB = [],
    MULTD = [],
    MULTE = [];

function xtime(a, b) {
	for (var result = 0, i = 0; i < 8; i++) {
		if (b & 1) result ^= a;
		var hiBitSet = a & 0x80;
		a = (a << 1) & 0xFF;
		if (hiBitSet) a ^= 0x1b;
		b >>>= 1;
	}
	return result;
}

for (var i = 0; i < 256; i++) {
	MULT2[i] = xtime(i,2);
	MULT3[i] = xtime(i,3);
	MULT9[i] = xtime(i,9);
	MULTB[i] = xtime(i,0xB);
	MULTD[i] = xtime(i,0xD);
	MULTE[i] = xtime(i,0xE);
}

// Precomputed RCon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];

// Inner state
var state = [[], [], [], []],
    keylength,
    nrounds,
    keyschedule;

var AES = C.AES = {

	/**
	 * Public API
	 */

	encrypt: function (message, password, options) {

		options = options || {};

		// Determine mode
		var mode = options.mode || new C.mode.OFB;

		// Allow mode to override options
		if (mode.fixOptions) mode.fixOptions(options);

		var

			// Convert to bytes if message is a string
			m = (
				message.constructor == String ?
				UTF8.stringToBytes(message) :
				message
			),

			// Generate random IV
			iv = options.iv || util.randomBytes(AES._blocksize * 4),

			// Generate key
			k = (
				password.constructor == String ?
				// Derive key from passphrase
				C.PBKDF2(password, iv, 32, { asBytes: true }) :
				// else, assume byte array representing cryptographic key
				password
			);

		// Encrypt
		AES._init(k);
		mode.encrypt(AES, m, iv);

		// Return ciphertext
		m = options.iv ? m : iv.concat(m);
		return (options && options.asBytes) ? m : util.bytesToBase64(m);

	},

	decrypt: function (ciphertext, password, options) {

		options = options || {};

		// Determine mode
		var mode = options.mode || new C.mode.OFB;

		// Allow mode to override options
		if (mode.fixOptions) mode.fixOptions(options);

		var

			// Convert to bytes if ciphertext is a string
			c = (
				ciphertext.constructor == String ?
				util.base64ToBytes(ciphertext):
			    ciphertext
			),

			// Separate IV and message
			iv = options.iv || c.splice(0, AES._blocksize * 4),

			// Generate key
			k = (
				password.constructor == String ?
				// Derive key from passphrase
				C.PBKDF2(password, iv, 32, { asBytes: true }) :
				// else, assume byte array representing cryptographic key
				password
			);

		// Decrypt
		AES._init(k);
		mode.decrypt(AES, c, iv);

		// Return plaintext
		return (options && options.asBytes) ? c : UTF8.bytesToString(c);

	},


	/**
	 * Package private methods and properties
	 */

	_blocksize: 4,

	_encryptblock: function (m, offset) {

		// Set input
		for (var row = 0; row < AES._blocksize; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] = m[offset + col * 4 + row];
		}

		// Add round key
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] ^= keyschedule[col][row];
		}

		for (var round = 1; round < nrounds; round++) {

			// Sub bytes
			for (var row = 0; row < 4; row++) {
				for (var col = 0; col < 4; col++)
					state[row][col] = SBOX[state[row][col]];
			}

			// Shift rows
			state[1].push(state[1].shift());
			state[2].push(state[2].shift());
			state[2].push(state[2].shift());
			state[3].unshift(state[3].pop());

			// Mix columns
			for (var col = 0; col < 4; col++) {

				var s0 = state[0][col],
				    s1 = state[1][col],
				    s2 = state[2][col],
				    s3 = state[3][col];

				state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
				state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
				state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
				state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];

			}

			// Add round key
			for (var row = 0; row < 4; row++) {
				for (var col = 0; col < 4; col++)
					state[row][col] ^= keyschedule[round * 4 + col][row];
			}

		}

		// Sub bytes
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] = SBOX[state[row][col]];
		}

		// Shift rows
		state[1].push(state[1].shift());
		state[2].push(state[2].shift());
		state[2].push(state[2].shift());
		state[3].unshift(state[3].pop());

		// Add round key
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
		}

		// Set output
		for (var row = 0; row < AES._blocksize; row++) {
			for (var col = 0; col < 4; col++)
				m[offset + col * 4 + row] = state[row][col];
		}

	},

	_decryptblock: function (c, offset) {

		// Set input
		for (var row = 0; row < AES._blocksize; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] = c[offset + col * 4 + row];
		}

		// Add round key
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
		}

		for (var round = 1; round < nrounds; round++) {

			// Inv shift rows
			state[1].unshift(state[1].pop());
			state[2].push(state[2].shift());
			state[2].push(state[2].shift());
			state[3].push(state[3].shift());

			// Inv sub bytes
			for (var row = 0; row < 4; row++) {
				for (var col = 0; col < 4; col++)
					state[row][col] = INVSBOX[state[row][col]];
			}

			// Add round key
			for (var row = 0; row < 4; row++) {
				for (var col = 0; col < 4; col++)
					state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
			}

			// Inv mix columns
			for (var col = 0; col < 4; col++) {

				var s0 = state[0][col],
				    s1 = state[1][col],
				    s2 = state[2][col],
				    s3 = state[3][col];

				state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
				state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
				state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
				state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];

			}

		}

		// Inv shift rows
		state[1].unshift(state[1].pop());
		state[2].push(state[2].shift());
		state[2].push(state[2].shift());
		state[3].push(state[3].shift());

		// Inv sub bytes
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] = INVSBOX[state[row][col]];
		}

		// Add round key
		for (var row = 0; row < 4; row++) {
			for (var col = 0; col < 4; col++)
				state[row][col] ^= keyschedule[col][row];
		}

		// Set output
		for (var row = 0; row < AES._blocksize; row++) {
			for (var col = 0; col < 4; col++)
				c[offset + col * 4 + row] = state[row][col];
		}

	},


	/**
	 * Private methods
	 */

	_init: function (k) {
		keylength = k.length / 4;
		nrounds = keylength + 6;
		AES._keyexpansion(k);
	},

	// Generate a key schedule
	_keyexpansion: function (k) {

		keyschedule = [];

		for (var row = 0; row < keylength; row++) {
			keyschedule[row] = [
				k[row * 4],
				k[row * 4 + 1],
				k[row * 4 + 2],
				k[row * 4 + 3]
			];
		}

		for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {

			var temp = [
				keyschedule[row - 1][0],
				keyschedule[row - 1][1],
				keyschedule[row - 1][2],
				keyschedule[row - 1][3]
			];

			if (row % keylength == 0) {

				// Rot word
				temp.push(temp.shift());

				// Sub word
				temp[0] = SBOX[temp[0]];
				temp[1] = SBOX[temp[1]];
				temp[2] = SBOX[temp[2]];
				temp[3] = SBOX[temp[3]];

				temp[0] ^= RCON[row / keylength];

			} else if (keylength > 6 && row % keylength == 4) {

				// Sub word
				temp[0] = SBOX[temp[0]];
				temp[1] = SBOX[temp[1]];
				temp[2] = SBOX[temp[2]];
				temp[3] = SBOX[temp[3]];

			}

			keyschedule[row] = [
				keyschedule[row - keylength][0] ^ temp[0],
				keyschedule[row - keylength][1] ^ temp[1],
				keyschedule[row - keylength][2] ^ temp[2],
				keyschedule[row - keylength][3] ^ temp[3]
			];

		}

	}

};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/BlockModes.js
================================================
/*!
 * Crypto-JS contribution from Simon Greatrix
 */

(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Create pad namespace
var C_pad = C.pad = {};

// Calculate the number of padding bytes required.
function _requiredPadding(cipher, message) {
    var blockSizeInBytes = cipher._blocksize * 4;
    var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
    return reqd;
};

// Remove padding when the final byte gives the number of padding bytes.
var _unpadLength = function (message) {
        var pad = message.pop();
        for (var i = 1; i < pad; i++) {
            message.pop();
        }
    };

// No-operation padding, used for stream ciphers
C_pad.NoPadding = {
        pad : function (cipher,message) {},
        unpad : function (message) {}
    };

// Zero Padding.
//
// If the message is not an exact number of blocks, the final block is
// completed with 0x00 bytes. There is no unpadding.
C_pad.ZeroPadding = {
    pad : function (cipher, message) {
        var blockSizeInBytes = cipher._blocksize * 4;
        var reqd = message.length % blockSizeInBytes;
        if( reqd!=0 ) {
            for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
                message.push(0x00);
            }
        }
    },

    unpad : function (message) {}
};

// ISO/IEC 7816-4 padding.
//
// Pads the plain text with an 0x80 byte followed by as many 0x00
// bytes are required to complete the block.
C_pad.iso7816 = {
    pad : function (cipher, message) {
        var reqd = _requiredPadding(cipher, message);
        message.push(0x80);
        for (; reqd > 1; reqd--) {
            message.push(0x00);
        }
    },

    unpad : function (message) {
        while (message.pop() != 0x80) {}
    }
};

// ANSI X.923 padding
//
// The final block is padded with zeros except for the last byte of the
// last block which contains the number of padding bytes.
C_pad.ansix923 = {
    pad : function (cipher, message) {
        var reqd = _requiredPadding(cipher, message);
        for (var i = 1; i < reqd; i++) {
            message.push(0x00);
        }
        message.push(reqd);
    },

    unpad : _unpadLength
};

// ISO 10126
//
// The final block is padded with random bytes except for the last
// byte of the last block which contains the number of padding bytes.
C_pad.iso10126 = {
    pad : function (cipher, message) {
        var reqd = _requiredPadding(cipher, message);
        for (var i = 1; i < reqd; i++) {
            message.push(Math.floor(Math.random() * 256));
        }
        message.push(reqd);
    },

    unpad : _unpadLength
};

// PKCS7 padding
//
// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
// value of each added byte is the number of bytes that are added,
// i.e. N bytes, each of value N are added.
C_pad.pkcs7 = {
    pad : function (cipher, message) {
        var reqd = _requiredPadding(cipher, message);
        for (var i = 0; i < reqd; i++) {
            message.push(reqd);
        }
    },

    unpad : _unpadLength
};

// Create mode namespace
var C_mode = C.mode = {};

/**
 * Mode base "class".
 */
var Mode = C_mode.Mode = function (padding) {
    if (padding) {
        this._padding = padding;
    }
};

Mode.prototype = {
    encrypt: function (cipher, m, iv) {
        this._padding.pad(cipher, m);
        this._doEncrypt(cipher, m, iv);
    },

    decrypt: function (cipher, m, iv) {
        this._doDecrypt(cipher, m, iv);
        this._padding.unpad(m);
    },

    // Default padding
    _padding: C_pad.iso7816
};


/**
 * Electronic Code Book mode.
 * 
 * ECB applies the cipher directly against each block of the input.
 * 
 * ECB does not require an initialization vector.
 */
var ECB = C_mode.ECB = function () {
    // Call parent constructor
    Mode.apply(this, arguments);
};

// Inherit from Mode
var ECB_prototype = ECB.prototype = new Mode;

// Concrete steps for Mode template
ECB_prototype._doEncrypt = function (cipher, m, iv) {
    var blockSizeInBytes = cipher._blocksize * 4;
    // Encrypt each block
    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
        cipher._encryptblock(m, offset);
    }
};
ECB_prototype._doDecrypt = function (cipher, c, iv) {
    var blockSizeInBytes = cipher._blocksize * 4;
    // Decrypt each block
    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
        cipher._decryptblock(c, offset);
    }
};

// ECB never uses an IV
ECB_prototype.fixOptions = function (options) {
    options.iv = [];
};


/**
 * Cipher block chaining
 * 
 * The first block is XORed with the IV. Subsequent blocks are XOR with the
 * previous cipher output.
 */
var CBC = C_mode.CBC = function () {
    // Call parent constructor
    Mode.apply(this, arguments);
};

// Inherit from Mode
var CBC_prototype = CBC.prototype = new Mode;

// Concrete steps for Mode template
CBC_prototype._doEncrypt = function (cipher, m, iv) {
    var blockSizeInBytes = cipher._blocksize * 4;

    // Encrypt each block
    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
        if (offset == 0) {
            // XOR first block using IV
            for (var i = 0; i < blockSizeInBytes; i++)
            m[i] ^= iv[i];
        } else {
            // XOR this block using previous crypted block
            for (var i = 0; i < blockSizeInBytes; i++)
            m[offset + i] ^= m[offset + i - blockSizeInBytes];
        }
        // Encrypt block
        cipher._encryptblock(m, offset);
    }
};
CBC_prototype._doDecrypt = function (cipher, c, iv) {
    var blockSizeInBytes = cipher._blocksize * 4;

    // At the start, the previously crypted block is the IV
    var prevCryptedBlock = iv;

    // Decrypt each block
    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
        // Save this crypted block
        var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
        // Decrypt block
        cipher._decryptblock(c, offset);
        // XOR decrypted block using previous crypted block
        for (var i = 0; i < blockSizeInBytes; i++) {
            c[offset + i] ^= prevCryptedBlock[i];
        }
        prevCryptedBlock = thisCryptedBlock;
    }
};


/**
 * Cipher feed back
 * 
 * The cipher output is XORed with the plain text to produce the cipher output,
 * which is then fed back into the cipher to produce a bit pattern to XOR the
 * next block with.
 * 
 * This is a stream cipher mode and does not require padding.
 */
var CFB = C_mode.CFB = function () {
    // Call parent constructor
    Mode.apply(this, arguments);
};

// Inherit from Mode
var CFB_prototype = CFB.prototype = new Mode;

// Override padding
CFB_prototype._padding = C_pad.NoPadding;

// Concrete steps for Mode template
CFB_prototype._doEncrypt = function (cipher, m, iv) {
    var blockSizeInBytes = cipher._blocksize * 4,
        keystream = iv.slice(0);

    // Encrypt each byte
    for (var i = 0; i < m.length; i++) {

        var j = i % blockSizeInBytes;
        if (j == 0) cipher._encryptblock(keystream, 0);

        m[i] ^= keystream[j];
        keystream[j] = m[i];
    }
};
CFB_prototype._doDecrypt = function (cipher, c, iv) {
    var blockSizeInBytes = cipher._blocksize * 4,
        keystream = iv.slice(0);

    // Encrypt each byte
    for (var i = 0; i < c.length; i++) {

        var j = i % blockSizeInBytes;
        if (j == 0) cipher._encryptblock(keystream, 0);

        var b = c[i];
        c[i] ^= keystream[j];
        keystream[j] = b;
    }
};


/**
 * Output feed back
 * 
 * The cipher repeatedly encrypts its own output. The output is XORed with the
 * plain text to produce the cipher text.
 * 
 * This is a stream cipher mode and does not require padding.
 */
var OFB = C_mode.OFB = function () {
    // Call parent constructor
    Mode.apply(this, arguments);
};

// Inherit from Mode
var OFB_prototype = OFB.prototype = new Mode;

// Override padding
OFB_prototype._padding = C_pad.NoPadding;

// Concrete steps for Mode template
OFB_prototype._doEncrypt = function (cipher, m, iv) {

    var blockSizeInBytes = cipher._blocksize * 4,
        keystream = iv.slice(0);

    // Encrypt each byte
    for (var i = 0; i < m.length; i++) {

        // Generate keystream
        if (i % blockSizeInBytes == 0)
            cipher._encryptblock(keystream, 0);

        // Encrypt byte
        m[i] ^= keystream[i % blockSizeInBytes];

    }
};
OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;

/**
 * Counter
 * @author Gergely Risko
 *
 * After every block the last 4 bytes of the IV is increased by one
 * with carry and that IV is used for the next block.
 *
 * This is a stream cipher mode and does not require padding.
 */
var CTR = C_mode.CTR = function () {
    // Call parent constructor
    Mode.apply(this, arguments);
};

// Inherit from Mode
var CTR_prototype = CTR.prototype = new Mode;

// Override padding
CTR_prototype._padding = C_pad.NoPadding;

CTR_prototype._doEncrypt = function (cipher, m, iv) {
    var blockSizeInBytes = cipher._blocksize * 4;
    var counter = iv.slice(0);

    for (var i = 0; i < m.length;) {
        // do not lose iv
        var keystream = counter.slice(0);

        // Generate keystream for next block
        cipher._encryptblock(keystream, 0);

        // XOR keystream with block
        for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
            m[i] ^= keystream[j];
        }

        // Increase counter
        if(++(counter[blockSizeInBytes-1]) == 256) {
            counter[blockSizeInBytes-1] = 0;
            if(++(counter[blockSizeInBytes-2]) == 256) {
                counter[blockSizeInBytes-2] = 0;
                if(++(counter[blockSizeInBytes-3]) == 256) {
                    counter[blockSizeInBytes-3] = 0;
                    ++(counter[blockSizeInBytes-4]);
                }
            }
        }
    }
};
CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/Crypto.js
================================================
if (typeof Crypto == "undefined" || ! Crypto.util)
{
(function(){

var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// Global Crypto object
// with browser window or with node module
var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {}; 

// Crypto utilities
var util = Crypto.util = {

	// Bit-wise rotate left
	rotl: function (n, b) {
		return (n << b) | (n >>> (32 - b));
	},

	// Bit-wise rotate right
	rotr: function (n, b) {
		return (n << (32 - b)) | (n >>> b);
	},

	// Swap big-endian to little-endian and vice versa
	endian: function (n) {

		// If number given, swap endian
		if (n.constructor == Number) {
			return util.rotl(n,  8) & 0x00FF00FF |
			       util.rotl(n, 24) & 0xFF00FF00;
		}

		// Else, assume array and swap all items
		for (var i = 0; i < n.length; i++)
			n[i] = util.endian(n[i]);
		return n;

	},

	// Generate an array of any length of random bytes
	randomBytes: function (n) {
		for (var bytes = []; n > 0; n--)
			bytes.push(Math.floor(Math.random() * 256));
		return bytes;
	},

	// Convert a byte array to big-endian 32-bit words
	bytesToWords: function (bytes) {
		for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
			words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
		return words;
	},

	// Convert big-endian 32-bit words to a byte array
	wordsToBytes: function (words) {
		for (var bytes = [], b = 0; b < words.length * 32; b += 8)
			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
		return bytes;
	},

	// Convert a byte array to a hex string
	bytesToHex: function (bytes) {
		for (var hex = [], i = 0; i < bytes.length; i++) {
			hex.push((bytes[i] >>> 4).toString(16));
			hex.push((bytes[i] & 0xF).toString(16));
		}
		return hex.join("");
	},

	// Convert a hex string to a byte array
	hexToBytes: function (hex) {
		for (var bytes = [], c = 0; c < hex.length; c += 2)
			bytes.push(parseInt(hex.substr(c, 2), 16));
		return bytes;
	},

	// Convert a byte array to a base-64 string
	bytesToBase64: function (bytes) {

		// Use browser-native function if it exists
		if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));

		for(var base64 = [], i = 0; i < bytes.length; i += 3) {
			var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
			for (var j = 0; j < 4; j++) {
				if (i * 8 + j * 6 <= bytes.length * 8)
					base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
				else base64.push("=");
			}
		}

		return base64.join("");

	},

	// Convert a base-64 string to a byte array
	base64ToBytes: function (base64) {

		// Use browser-native function if it exists
		if (typeof atob == "function") return Binary.stringToBytes(atob(base64));

		// Remove non-base-64 characters
		base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");

		for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
			if (imod4 == 0) continue;
			bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
			           (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
		}

		return bytes;

	}

};

// Crypto character encodings
var charenc = Crypto.charenc = {};

// UTF-8 encoding
var UTF8 = charenc.UTF8 = {

	// Convert a string to a byte array
	stringToBytes: function (str) {
		return Binary.stringToBytes(unescape(encodeURIComponent(str)));
	},

	// Convert a byte array to a string
	bytesToString: function (bytes) {
		return decodeURIComponent(escape(Binary.bytesToString(bytes)));
	}

};

// Binary encoding
var Binary = charenc.Binary = {

	// Convert a string to a byte array
	stringToBytes: function (str) {
		for (var bytes = [], i = 0; i < str.length; i++)
			bytes.push(str.charCodeAt(i) & 0xFF);
		return bytes;
	},

	// Convert a byte array to a string
	bytesToString: function (bytes) {
		for (var str = [], i = 0; i < bytes.length; i++)
			str.push(String.fromCharCode(bytes[i]));
		return str.join("");
	}

};

})();
}


================================================
FILE: cloudfunctions/regist/cryptojs/lib/CryptoMath.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcut
var util = C.util;

// Convert n to unsigned 32-bit integer
util.u32 = function (n) {
	return n >>> 0;
};

// Unsigned 32-bit addition
util.add = function () {
	var result = this.u32(arguments[0]);
	for (var i = 1; i < arguments.length; i++)
		result = this.u32(result + this.u32(arguments[i]));
	return result;
};

// Unsigned 32-bit multiplication
util.mult = function (m, n) {
	return this.add((n & 0xFFFF0000) * m,
			(n & 0x0000FFFF) * m);
};

// Unsigned 32-bit greater than (>) comparison
util.gt = function (m, n) {
	return this.u32(m) > this.u32(n);
};

// Unsigned 32-bit less than (<) comparison
util.lt = function (m, n) {
	return this.u32(m) < this.u32(n);
};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/DES.js
================================================
/**
 * Definition of Data Encryption Standard (DES) taken from:
 * http://www.itl.nist.gov/fipspubs/fip46-2.htm
 */

(function() {

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

    // Shortcuts
    var util = C.util, charenc = C.charenc, UTF8 = charenc.UTF8;

    /***************************************************************************
     * 
     * DES Key Schedule.
     * 
     * The Key consists of 16 sub-keys of 48 bits each. As each sub-key is
     * applied to an expanded 32-bit value where each 4 bits of input is
     * expanded into 6 bits of output the sub-key can be broken down into 8
     * 32-bit values which allows the key to be used without expansion.
     * 
     * To create the 16 sub-keys, 56 bits are selected from the input 64 bit key
     * according to <i>PC1</i>. Each sub-key is generated by left rotating the
     * bits a different amount and then selecting 48 bits according to <i>PC2</i>.
     * 
     **************************************************************************/

    var KeySchedule;

    /**
     * Representation of a DES key schedule.
     * 
     * @param {Array
     *            of 8 bytes} key The cipher key
     * 
     * @constructor
     */
    KeySchedule = function(key) {
        /**
         * The schedule of 16 keys
         */
        this.keys = new Array(16);
        this._initialiseKeys(key);
    };

    /**
     * Permuted Choice 1 (PC1) byte offsets into the key. Each of the 56 entries
     * selects one bit of DES's 56 bit key.
     * <p>
     * 
     * <pre>
     * The PC1 is defined as:
     * 
     * 57,   49,    41,   33,    25,    17,    9,
     *  1,   58,    50,   42,    34,    26,   18,
     * 10,    2,    59,   51,    43,    35,   27,
     * 19,   11,     3,   60,    52,    44,   36,
     * 63,   55,    47,   39,    31,    23,   15,
     *  7,   62,    54,   46,    38,    30,   22,
     * 14,    6,    61,   53,    45,    37,   29,
     * 21,   13,     5,   28,    20,    12,    4
     * </pre>
     * 
     * We represent this as an offset into an 8-byte array and a bit mask upon
     * that byte. For example 57=(7*8)+1 so is the first (MSB) of the 7th byte.
     * 
     * @constant
     */
    KeySchedule.PC1_offsets = [ 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
            7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6,
            5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1, 0 ];

    /**
     * Permuted Choice 1 (PC1) bit masks. Each of the 56 entries selects one bit
     * of DES's 56 bit key.
     * 
     * @constant
     */
    KeySchedule.PC1_masks = [ 128, 128, 128, 128, 128, 128, 128, 128, 64, 64,
            64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16,
            16, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
            8, 8, 8, 16, 16, 16, 16 ];

    /**
     * Permuted Choice 2 (PC2) selects the active 48 bits from the 56 bits of
     * the key.
     * <p>
     * 
     * <pre>
     * The PC2 is defined as:
     * 
     * 14,   17,   11,   24,    1,    5,
     *  3,   28,   15,    6,   21,   10,
     * 23,   19,   12,    4,   26,    8,
     * 16,    7,   27,   20,   13,    2,
     * 41,   52,   31,   37,   47,   55,
     * 30,   40,   51,   45,   33,   48,
     * 44,   49,   39,   56,   34,   53,
     * 46,   42,   50,   36,   29,   32
     * </pre>
     * 
     * We invert the choice to specify what each bit adds to each 6-bit value of
     * the key. For example, bit 1 is the 5th bit selected so this add 2 to the
     * first 6-bit value.
     * 
     * @constant
     */
    KeySchedule.PC2_offsets1 = [ 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 0, 2, 3, 0, 1,
            3, 0, 0, 2, 3, 1, 0, 2, 0, 0, 2, 3, 1 ];

    /**
     * PC2 offsets for 2nd block.
     * 
     * @constant
     */
    KeySchedule.PC2_offsets2 = [ 7, 5, 4, 7, 5, 6, 0, 7, 4, 0, 6, 5, 4, 7, 0,
            6, 5, 7, 4, 5, 6, 7, 5, 4, 6, 0, 4, 6 ];

    /**
     * Permuted Choice 2 (PC2) masks for 1st block.
     * 
     * @constant
     */
    KeySchedule.PC2_masks1 = [ 2, 1, 32, 4, 1, 4, 16, 1, 0, 1, 8, 8, 2, 32, 8,
            32, 16, 0, 16, 4, 2, 0, 32, 4, 0, 2, 8, 16 ];

    /**
     * PC2 masks for 2nd block.
     * 
     * @constant
     */
    KeySchedule.PC2_masks2 = [ 2, 32, 8, 1, 2, 2, 0, 4, 4, 0, 8, 16, 32, 16, 0,
            32, 4, 32, 2, 1, 16, 8, 8, 16, 1, 0, 1, 4 ];

    /**
     * Cumulative key shifts.
     * 
     * @constant
     */
    KeySchedule.keyShifts = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23,
            25, 27, 28 ];

    KeySchedule.prototype._initialiseKeys = function(key) {
        var i;

        // extract 56 key bits in order determined by PC1
        var bits = new Array(56);
        for (i = 0; i < 56; i++) {
            bits[i] = (key[KeySchedule.PC1_offsets[i]] & KeySchedule.PC1_masks[i]) != 0;
        }

        // split 56 bits into two 28-bit chunks
        var bits1 = bits.slice(0, 28);
        var bits2 = bits.slice(28, 56);

        // duplicate each half to allow for easy bit shifts
        bits1 = bits1.concat(bits1);
        bits2 = bits2.concat(bits2);

        // assemble the 16 keys
        for (i = 0; i < 16; i++) {
            var k = [ 0, 0, 0, 0, 0, 0, 0, 0 ];

            // select the bits of the key according to PC2
            var s = KeySchedule.keyShifts[i];
            for ( var j = 0; j < 28; j++) {
                if (bits1[j + s]) {
                    k[KeySchedule.PC2_offsets1[j]] += KeySchedule.PC2_masks1[j];
                }
                if (bits2[j + s]) {
                    k[KeySchedule.PC2_offsets2[j]] += KeySchedule.PC2_masks2[j];
                }
            }

            // Scale each of the 8 blocks to a 32-bit mask.
            k[0] = ((k[0] & 0x1f) << 27) + ((k[0] & 0x20) >> 5);
            for ( var j = 1; j <= 6; j++) {
                k[j] = k[j] << (27 - 4 * j);
            }
            k[7] = ((k[7] & 0x3e) >> 1) + ((k[7] & 0x1) << 31);
            this.keys[i] = k;
        }
    };

    /**
     * Retrieve the key for a specified round
     * 
     * @param i
     *            the round
     * @returns the key
     */
    KeySchedule.prototype.getKey = function(i) {
        return this.keys[i];
    };

    /***************************************************************************
     * 
     * DES Engine State
     * 
     **************************************************************************/

    var State;

    /**
     * The algorithm's state. DES operates on two sets of 32-bits, with each
     * block of 32-bits treated as a single number.
     * 
     * @class
     */
    State = function() {
        /** The LHS of the Feistel scheme */
        this.lhs = 0;
        /** The RHS of the Feistel scheme */
        this.rhs = 0;
    };

    /**
     * The masks that select the SBOX input. Each SBOX accepts 6 bits from the
     * input.
     * 
     * @constant
     */
    State.SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
            0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ];

    /**
     * The SBOXes. The 8 SBOXes each map 6 bit masked bit of the input to 4 bits
     * of output. These SBOXes include the post SBOX permutation and benefit
     * from JavaScript's sparse arrays to make specifying the input match
     * simple.
     * 
     * @constant
     */
    State.SBOX = new Array(8);

    var SBOX = State.SBOX;

    SBOX[0] = new Array();
    SBOX[0][0] = 0x808200; // 0 (0, 0) = 14
    SBOX[0][268435456] = 0x8000; // 10000000 (0, 1) = 4
    SBOX[0][536870912] = 0x808002; // 20000000 (0, 2) = 13
    SBOX[0][805306368] = 0x2; // 30000000 (0, 3) = 1
    SBOX[0][1073741824] = 0x200; // 40000000 (0, 4) = 2
    SBOX[0][1342177280] = 0x808202; // 50000000 (0, 5) = 15
    SBOX[0][1610612736] = 0x800202; // 60000000 (0, 6) = 11
    SBOX[0][1879048192] = 0x800000; // 70000000 (0, 7) = 8
    SBOX[0][-2147483648] = 0x202; // 80000000 (0, 8) = 3
    SBOX[0][-1879048192] = 0x800200; // 90000000 (0, 9) = 10
    SBOX[0][-1610612736] = 0x8200; // a0000000 (0, 10) = 6
    SBOX[0][-1342177280] = 0x808000; // b0000000 (0, 11) = 12
    SBOX[0][-1073741824] = 0x8002; // c0000000 (0, 12) = 5
    SBOX[0][-805306368] = 0x800002; // d0000000 (0, 13) = 9
    SBOX[0][-536870912] = 0x0; // e0000000 (0, 14) = 0
    SBOX[0][-268435456] = 0x8202; // f0000000 (0, 15) = 7
    SBOX[0][134217728] = 0x0; // 8000000 (1, 0) = 0
    SBOX[0][402653184] = 0x808202; // 18000000 (1, 1) = 15
    SBOX[0][671088640] = 0x8202; // 28000000 (1, 2) = 7
    SBOX[0][939524096] = 0x8000; // 38000000 (1, 3) = 4
    SBOX[0][1207959552] = 0x808200; // 48000000 (1, 4) = 14
    SBOX[0][1476395008] = 0x200; // 58000000 (1, 5) = 2
    SBOX[0][1744830464] = 0x808002; // 68000000 (1, 6) = 13
    SBOX[0][2013265920] = 0x2; // 78000000 (1, 7) = 1
    SBOX[0][-2013265920] = 0x800200; // 88000000 (1, 8) = 10
    SBOX[0][-1744830464] = 0x8200; // 98000000 (1, 9) = 6
    SBOX[0][-1476395008] = 0x808000; // a8000000 (1, 10) = 12
    SBOX[0][-1207959552] = 0x800202; // b8000000 (1, 11) = 11
    SBOX[0][-939524096] = 0x800002; // c8000000 (1, 12) = 9
    SBOX[0][-671088640] = 0x8002; // d8000000 (1, 13) = 5
    SBOX[0][-402653184] = 0x202; // e8000000 (1, 14) = 3
    SBOX[0][-134217728] = 0x800000; // f8000000 (1, 15) = 8
    SBOX[0][1] = 0x8000; // 1 (2, 0) = 4
    SBOX[0][268435457] = 0x2; // 10000001 (2, 1) = 1
    SBOX[0][536870913] = 0x808200; // 20000001 (2, 2) = 14
    SBOX[0][805306369] = 0x800000; // 30000001 (2, 3) = 8
    SBOX[0][1073741825] = 0x808002; // 40000001 (2, 4) = 13
    SBOX[0][1342177281] = 0x8200; // 50000001 (2, 5) = 6
    SBOX[0][1610612737] = 0x200; // 60000001 (2, 6) = 2
    SBOX[0][1879048193] = 0x800202; // 70000001 (2, 7) = 11
    SBOX[0][-2147483647] = 0x808202; // 80000001 (2, 8) = 15
    SBOX[0][-1879048191] = 0x808000; // 90000001 (2, 9) = 12
    SBOX[0][-1610612735] = 0x800002; // a0000001 (2, 10) = 9
    SBOX[0][-1342177279] = 0x8202; // b0000001 (2, 11) = 7
    SBOX[0][-1073741823] = 0x202; // c0000001 (2, 12) = 3
    SBOX[0][-805306367] = 0x800200; // d0000001 (2, 13) = 10
    SBOX[0][-536870911] = 0x8002; // e0000001 (2, 14) = 5
    SBOX[0][-268435455] = 0x0; // f0000001 (2, 15) = 0
    SBOX[0][134217729] = 0x808202; // 8000001 (3, 0) = 15
    SBOX[0][402653185] = 0x808000; // 18000001 (3, 1) = 12
    SBOX[0][671088641] = 0x800000; // 28000001 (3, 2) = 8
    SBOX[0][939524097] = 0x200; // 38000001 (3, 3) = 2
    SBOX[0][1207959553] = 0x8000; // 48000001 (3, 4) = 4
    SBOX[0][1476395009] = 0x800002; // 58000001 (3, 5) = 9
    SBOX[0][1744830465] = 0x2; // 68000001 (3, 6) = 1
    SBOX[0][2013265921] = 0x8202; // 78000001 (3, 7) = 7
    SBOX[0][-2013265919] = 0x8002; // 88000001 (3, 8) = 5
    SBOX[0][-1744830463] = 0x800202; // 98000001 (3, 9) = 11
    SBOX[0][-1476395007] = 0x202; // a8000001 (3, 10) = 3
    SBOX[0][-1207959551] = 0x808200; // b8000001 (3, 11) = 14
    SBOX[0][-939524095] = 0x800200; // c8000001 (3, 12) = 10
    SBOX[0][-671088639] = 0x0; // d8000001 (3, 13) = 0
    SBOX[0][-402653183] = 0x8200; // e8000001 (3, 14) = 6
    SBOX[0][-134217727] = 0x808002; // f8000001 (3, 15) = 13

    SBOX[1] = new Array();
    SBOX[1][0] = 0x40084010; // 0 (0, 0) = 15
    SBOX[1][16777216] = 0x4000; // 1000000 (0, 1) = 1
    SBOX[1][33554432] = 0x80000; // 2000000 (0, 2) = 8
    SBOX[1][50331648] = 0x40080010; // 3000000 (0, 3) = 14
    SBOX[1][67108864] = 0x40000010; // 4000000 (0, 4) = 6
    SBOX[1][83886080] = 0x40084000; // 5000000 (0, 5) = 11
    SBOX[1][100663296] = 0x40004000; // 6000000 (0, 6) = 3
    SBOX[1][117440512] = 0x10; // 7000000 (0, 7) = 4
    SBOX[1][134217728] = 0x84000; // 8000000 (0, 8) = 9
    SBOX[1][150994944] = 0x40004010; // 9000000 (0, 9) = 7
    SBOX[1][167772160] = 0x40000000; // a000000 (0, 10) = 2
    SBOX[1][184549376] = 0x84010; // b000000 (0, 11) = 13
    SBOX[1][201326592] = 0x80010; // c000000 (0, 12) = 12
    SBOX[1][218103808] = 0x0; // d000000 (0, 13) = 0
    SBOX[1][234881024] = 0x4010; // e000000 (0, 14) = 5
    SBOX[1][251658240] = 0x40080000; // f000000 (0, 15) = 10
    SBOX[1][8388608] = 0x40004000; // 800000 (1, 0) = 3
    SBOX[1][25165824] = 0x84010; // 1800000 (1, 1) = 13
    SBOX[1][41943040] = 0x10; // 2800000 (1, 2) = 4
    SBOX[1][58720256] = 0x40004010; // 3800000 (1, 3) = 7
    SBOX[1][75497472] = 0x40084010; // 4800000 (1, 4) = 15
    SBOX[1][92274688] = 0x40000000; // 5800000 (1, 5) = 2
    SBOX[1][109051904] = 0x80000; // 6800000 (1, 6) = 8
    SBOX[1][125829120] = 0x40080010; // 7800000 (1, 7) = 14
    SBOX[1][142606336] = 0x80010; // 8800000 (1, 8) = 12
    SBOX[1][159383552] = 0x0; // 9800000 (1, 9) = 0
    SBOX[1][176160768] = 0x4000; // a800000 (1, 10) = 1
    SBOX[1][192937984] = 0x40080000; // b800000 (1, 11) = 10
    SBOX[1][209715200] = 0x40000010; // c800000 (1, 12) = 6
    SBOX[1][226492416] = 0x84000; // d800000 (1, 13) = 9
    SBOX[1][243269632] = 0x40084000; // e800000 (1, 14) = 11
    SBOX[1][260046848] = 0x4010; // f800000 (1, 15) = 5
    SBOX[1][268435456] = 0x0; // 10000000 (2, 0) = 0
    SBOX[1][285212672] = 0x40080010; // 11000000 (2, 1) = 14
    SBOX[1][301989888] = 0x40004010; // 12000000 (2, 2) = 7
    SBOX[1][318767104] = 0x40084000; // 13000000 (2, 3) = 11
    SBOX[1][335544320] = 0x40080000; // 14000000 (2, 4) = 10
    SBOX[1][352321536] = 0x10; // 15000000 (2, 5) = 4
    SBOX[1][369098752] = 0x84010; // 16000000 (2, 6) = 13
    SBOX[1][385875968] = 0x4000; // 17000000 (2, 7) = 1
    SBOX[1][402653184] = 0x4010; // 18000000 (2, 8) = 5
    SBOX[1][419430400] = 0x80000; // 19000000 (2, 9) = 8
    SBOX[1][436207616] = 0x80010; // 1a000000 (2, 10) = 12
    SBOX[1][452984832] = 0x40000010; // 1b000000 (2, 11) = 6
    SBOX[1][469762048] = 0x84000; // 1c000000 (2, 12) = 9
    SBOX[1][486539264] = 0x40004000; // 1d000000 (2, 13) = 3
    SBOX[1][503316480] = 0x40000000; // 1e000000 (2, 14) = 2
    SBOX[1][520093696] = 0x40084010; // 1f000000 (2, 15) = 15
    SBOX[1][276824064] = 0x84010; // 10800000 (3, 0) = 13
    SBOX[1][293601280] = 0x80000; // 11800000 (3, 1) = 8
    SBOX[1][310378496] = 0x40080000; // 12800000 (3, 2) = 10
    SBOX[1][327155712] = 0x4000; // 13800000 (3, 3) = 1
    SBOX[1][343932928] = 0x40004000; // 14800000 (3, 4) = 3
    SBOX[1][360710144] = 0x40084010; // 15800000 (3, 5) = 15
    SBOX[1][377487360] = 0x10; // 16800000 (3, 6) = 4
    SBOX[1][394264576] = 0x40000000; // 17800000 (3, 7) = 2
    SBOX[1][411041792] = 0x40084000; // 18800000 (3, 8) = 11
    SBOX[1][427819008] = 0x40000010; // 19800000 (3, 9) = 6
    SBOX[1][444596224] = 0x40004010; // 1a800000 (3, 10) = 7
    SBOX[1][461373440] = 0x80010; // 1b800000 (3, 11) = 12
    SBOX[1][478150656] = 0x0; // 1c800000 (3, 12) = 0
    SBOX[1][494927872] = 0x4010; // 1d800000 (3, 13) = 5
    SBOX[1][511705088] = 0x40080010; // 1e800000 (3, 14) = 14
    SBOX[1][528482304] = 0x84000; // 1f800000 (3, 15) = 9

    SBOX[2] = new Array();
    SBOX[2][0] = 0x104; // 0 (0, 0) = 10
    SBOX[2][1048576] = 0x0; // 100000 (0, 1) = 0
    SBOX[2][2097152] = 0x4000100; // 200000 (0, 2) = 9
    SBOX[2][3145728] = 0x10104; // 300000 (0, 3) = 14
    SBOX[2][4194304] = 0x10004; // 400000 (0, 4) = 6
    SBOX[2][5242880] = 0x4000004; // 500000 (0, 5) = 3
    SBOX[2][6291456] = 0x4010104; // 600000 (0, 6) = 15
    SBOX[2][7340032] = 0x4010000; // 700000 (0, 7) = 5
    SBOX[2][8388608] = 0x4000000; // 800000 (0, 8) = 1
    SBOX[2][9437184] = 0x4010100; // 900000 (0, 9) = 13
    SBOX[2][10485760] = 0x10100; // a00000 (0, 10) = 12
    SBOX[2][11534336] = 0x4010004; // b00000 (0, 11) = 7
    SBOX[2][12582912] = 0x4000104; // c00000 (0, 12) = 11
    SBOX[2][13631488] = 0x10000; // d00000 (0, 13) = 4
    SBOX[2][14680064] = 0x4; // e00000 (0, 14) = 2
    SBOX[2][15728640] = 0x100; // f00000 (0, 15) = 8
    SBOX[2][524288] = 0x4010100; // 80000 (1, 0) = 13
    SBOX[2][1572864] = 0x4010004; // 180000 (1, 1) = 7
    SBOX[2][2621440] = 0x0; // 280000 (1, 2) = 0
    SBOX[2][3670016] = 0x4000100; // 380000 (1, 3) = 9
    SBOX[2][4718592] = 0x4000004; // 480000 (1, 4) = 3
    SBOX[2][5767168] = 0x10000; // 580000 (1, 5) = 4
    SBOX[2][6815744] = 0x10004; // 680000 (1, 6) = 6
    SBOX[2][7864320] = 0x104; // 780000 (1, 7) = 10
    SBOX[2][8912896] = 0x4; // 880000 (1, 8) = 2
    SBOX[2][9961472] = 0x100; // 980000 (1, 9) = 8
    SBOX[2][11010048] = 0x4010000; // a80000 (1, 10) = 5
    SBOX[2][12058624] = 0x10104; // b80000 (1, 11) = 14
    SBOX[2][13107200] = 0x10100; // c80000 (1, 12) = 12
    SBOX[2][14155776] = 0x4000104; // d80000 (1, 13) = 11
    SBOX[2][15204352] = 0x4010104; // e80000 (1, 14) = 15
    SBOX[2][16252928] = 0x4000000; // f80000 (1, 15) = 1
    SBOX[2][16777216] = 0x4010100; // 1000000 (2, 0) = 13
    SBOX[2][17825792] = 0x10004; // 1100000 (2, 1) = 6
    SBOX[2][18874368] = 0x10000; // 1200000 (2, 2) = 4
    SBOX[2][19922944] = 0x4000100; // 1300000 (2, 3) = 9
    SBOX[2][20971520] = 0x100; // 1400000 (2, 4) = 8
    SBOX[2][22020096] = 0x4010104; // 1500000 (2, 5) = 15
    SBOX[2][23068672] = 0x4000004; // 1600000 (2, 6) = 3
    SBOX[2][24117248] = 0x0; // 1700000 (2, 7) = 0
    SBOX[2][25165824] = 0x4000104; // 1800000 (2, 8) = 11
    SBOX[2][26214400] = 0x4000000; // 1900000 (2, 9) = 1
    SBOX[2][27262976] = 0x4; // 1a00000 (2, 10) = 2
    SBOX[2][28311552] = 0x10100; // 1b00000 (2, 11) = 12
    SBOX[2][29360128] = 0x4010000; // 1c00000 (2, 12) = 5
    SBOX[2][30408704] = 0x104; // 1d00000 (2, 13) = 10
    SBOX[2][31457280] = 0x10104; // 1e00000 (2, 14) = 14
    SBOX[2][32505856] = 0x4010004; // 1f00000 (2, 15) = 7
    SBOX[2][17301504] = 0x4000000; // 1080000 (3, 0) = 1
    SBOX[2][18350080] = 0x104; // 1180000 (3, 1) = 10
    SBOX[2][19398656] = 0x4010100; // 1280000 (3, 2) = 13
    SBOX[2][20447232] = 0x0; // 1380000 (3, 3) = 0
    SBOX[2][21495808] = 0x10004; // 1480000 (3, 4) = 6
    SBOX[2][22544384] = 0x4000100; // 1580000 (3, 5) = 9
    SBOX[2][23592960] = 0x100; // 1680000 (3, 6) = 8
    SBOX[2][24641536] = 0x4010004; // 1780000 (3, 7) = 7
    SBOX[2][25690112] = 0x10000; // 1880000 (3, 8) = 4
    SBOX[2][26738688] = 0x4010104; // 1980000 (3, 9) = 15
    SBOX[2][27787264] = 0x10104; // 1a80000 (3, 10) = 14
    SBOX[2][28835840] = 0x4000004; // 1b80000 (3, 11) = 3
    SBOX[2][29884416] = 0x4000104; // 1c80000 (3, 12) = 11
    SBOX[2][30932992] = 0x4010000; // 1d80000 (3, 13) = 5
    SBOX[2][31981568] = 0x4; // 1e80000 (3, 14) = 2
    SBOX[2][33030144] = 0x10100; // 1f80000 (3, 15) = 12

    SBOX[3] = new Array();
    SBOX[3][0] = 0x80401000; // 0 (0, 0) = 7
    SBOX[3][65536] = 0x80001040; // 10000 (0, 1) = 13
    SBOX[3][131072] = 0x401040; // 20000 (0, 2) = 14
    SBOX[3][196608] = 0x80400000; // 30000 (0, 3) = 3
    SBOX[3][262144] = 0x0; // 40000 (0, 4) = 0
    SBOX[3][327680] = 0x401000; // 50000 (0, 5) = 6
    SBOX[3][393216] = 0x80000040; // 60000 (0, 6) = 9
    SBOX[3][458752] = 0x400040; // 70000 (0, 7) = 10
    SBOX[3][524288] = 0x80000000; // 80000 (0, 8) = 1
    SBOX[3][589824] = 0x400000; // 90000 (0, 9) = 2
    SBOX[3][655360] = 0x40; // a0000 (0, 10) = 8
    SBOX[3][720896] = 0x80001000; // b0000 (0, 11) = 5
    SBOX[3][786432] = 0x80400040; // c0000 (0, 12) = 11
    SBOX[3][851968] = 0x1040; // d0000 (0, 13) = 12
    SBOX[3][917504] = 0x1000; // e0000 (0, 14) = 4
    SBOX[3][983040] = 0x80401040; // f0000 (0, 15) = 15
    SBOX[3][32768] = 0x80001040; // 8000 (1, 0) = 13
    SBOX[3][98304] = 0x40; // 18000 (1, 1) = 8
    SBOX[3][163840] = 0x80400040; // 28000 (1, 2) = 11
    SBOX[3][229376] = 0x80001000; // 38000 (1, 3) = 5
    SBOX[3][294912] = 0x401000; // 48000 (1, 4) = 6
    SBOX[3][360448] = 0x80401040; // 58000 (1, 5) = 15
    SBOX[3][425984] = 0x0; // 68000 (1, 6) = 0
    SBOX[3][491520] = 0x80400000; // 78000 (1, 7) = 3
    SBOX[3][557056] = 0x1000; // 88000 (1, 8) = 4
    SBOX[3][622592] = 0x80401000; // 98000 (1, 9) = 7
    SBOX[3][688128] = 0x400000; // a8000 (1, 10) = 2
    SBOX[3][753664] = 0x1040; // b8000 (1, 11) = 12
    SBOX[3][819200] = 0x80000000; // c8000 (1, 12) = 1
    SBOX[3][884736] = 0x400040; // d8000 (1, 13) = 10
    SBOX[3][950272] = 0x401040; // e8000 (1, 14) = 14
    SBOX[3][1015808] = 0x80000040; // f8000 (1, 15) = 9
    SBOX[3][1048576] = 0x400040; // 100000 (2, 0) = 10
    SBOX[3][1114112] = 0x401000; // 110000 (2, 1) = 6
    SBOX[3][1179648] = 0x80000040; // 120000 (2, 2) = 9
    SBOX[3][1245184] = 0x0; // 130000 (2, 3) = 0
    SBOX[3][1310720] = 0x1040; // 140000 (2, 4) = 12
    SBOX[3][1376256] = 0x80400040; // 150000 (2, 5) = 11
    SBOX[3][1441792] = 0x80401000; // 160000 (2, 6) = 7
    SBOX[3][1507328] = 0x80001040; // 170000 (2, 7) = 13
    SBOX[3][1572864] = 0x80401040; // 180000 (2, 8) = 15
    SBOX[3][1638400] = 0x80000000; // 190000 (2, 9) = 1
    SBOX[3][1703936] = 0x80400000; // 1a0000 (2, 10) = 3
    SBOX[3][1769472] = 0x401040; // 1b0000 (2, 11) = 14
    SBOX[3][1835008] = 0x80001000; // 1c0000 (2, 12) = 5
    SBOX[3][1900544] = 0x400000; // 1d0000 (2, 13) = 2
    SBOX[3][1966080] = 0x40; // 1e0000 (2, 14) = 8
    SBOX[3][2031616] = 0x1000; // 1f0000 (2, 15) = 4
    SBOX[3][1081344] = 0x80400000; // 108000 (3, 0) = 3
    SBOX[3][1146880] = 0x80401040; // 118000 (3, 1) = 15
    SBOX[3][1212416] = 0x0; // 128000 (3, 2) = 0
    SBOX[3][1277952] = 0x401000; // 138000 (3, 3) = 6
    SBOX[3][1343488] = 0x400040; // 148000 (3, 4) = 10
    SBOX[3][1409024] = 0x80000000; // 158000 (3, 5) = 1
    SBOX[3][1474560] = 0x80001040; // 168000 (3, 6) = 13
    SBOX[3][1540096] = 0x40; // 178000 (3, 7) = 8
    SBOX[3][1605632] = 0x80000040; // 188000 (3, 8) = 9
    SBOX[3][1671168] = 0x1000; // 198000 (3, 9) = 4
    SBOX[3][1736704] = 0x80001000; // 1a8000 (3, 10) = 5
    SBOX[3][1802240] = 0x80400040; // 1b8000 (3, 11) = 11
    SBOX[3][1867776] = 0x1040; // 1c8000 (3, 12) = 12
    SBOX[3][1933312] = 0x80401000; // 1d8000 (3, 13) = 7
    SBOX[3][1998848] = 0x400000; // 1e8000 (3, 14) = 2
    SBOX[3][2064384] = 0x401040; // 1f8000 (3, 15) = 14

    SBOX[4] = new Array();
    SBOX[4][0] = 0x80; // 0 (0, 0) = 2
    SBOX[4][4096] = 0x1040000; // 1000 (0, 1) = 12
    SBOX[4][8192] = 0x40000; // 2000 (0, 2) = 4
    SBOX[4][12288] = 0x20000000; // 3000 (0, 3) = 1
    SBOX[4][16384] = 0x20040080; // 4000 (0, 4) = 7
    SBOX[4][20480] = 0x1000080; // 5000 (0, 5) = 10
    SBOX[4][24576] = 0x21000080; // 6000 (0, 6) = 11
    SBOX[4][28672] = 0x40080; // 7000 (0, 7) = 6
    SBOX[4][32768] = 0x1000000; // 8000 (0, 8) = 8
    SBOX[4][36864] = 0x20040000; // 9000 (0, 9) = 5
    SBOX[4][40960] = 0x20000080; // a000 (0, 10) = 3
    SBOX[4][45056] = 0x21040080; // b000 (0, 11) = 15
    SBOX[4][49152] = 0x21040000; // c000 (0, 12) = 13
    SBOX[4][53248] = 0x0; // d000 (0, 13) = 0
    SBOX[4][57344] = 0x1040080; // e000 (0, 14) = 14
    SBOX[4][61440] = 0x21000000; // f000 (0, 15) = 9
    SBOX[4][2048] = 0x1040080; // 800 (1, 0) = 14
    SBOX[4][6144] = 0x21000080; // 1800 (1, 1) = 11
    SBOX[4][10240] = 0x80; // 2800 (1, 2) = 2
    SBOX[4][14336] = 0x1040000; // 3800 (1, 3) = 12
    SBOX[4][18432] = 0x40000; // 4800 (1, 4) = 4
    SBOX[4][22528] = 0x20040080; // 5800 (1, 5) = 7
    SBOX[4][26624] = 0x21040000; // 6800 (1, 6) = 13
    SBOX[4][30720] = 0x20000000; // 7800 (1, 7) = 1
    SBOX[4][34816] = 0x20040000; // 8800 (1, 8) = 5
    SBOX[4][38912] = 0x0; // 9800 (1, 9) = 0
    SBOX[4][43008] = 0x21040080; // a800 (1, 10) = 15
    SBOX[4][47104] = 0x1000080; // b800 (1, 11) = 10
    SBOX[4][51200] = 0x20000080; // c800 (1, 12) = 3
    SBOX[4][55296] = 0x21000000; // d800 (1, 13) = 9
    SBOX[4][59392] = 0x1000000; // e800 (1, 14) = 8
    SBOX[4][63488] = 0x40080; // f800 (1, 15) = 6
    SBOX[4][65536] = 0x40000; // 10000 (2, 0) = 4
    SBOX[4][69632] = 0x80; // 11000 (2, 1) = 2
    SBOX[4][73728] = 0x20000000; // 12000 (2, 2) = 1
    SBOX[4][77824] = 0x21000080; // 13000 (2, 3) = 11
    SBOX[4][81920] = 0x1000080; // 14000 (2, 4) = 10
    SBOX[4][86016] = 0x21040000; // 15000 (2, 5) = 13
    SBOX[4][90112] = 0x20040080; // 16000 (2, 6) = 7
    SBOX[4][94208] = 0x1000000; // 17000 (2, 7) = 8
    SBOX[4][98304] = 0x21040080; // 18000 (2, 8) = 15
    SBOX[4][102400] = 0x21000000; // 19000 (2, 9) = 9
    SBOX[4][106496] = 0x1040000; // 1a000 (2, 10) = 12
    SBOX[4][110592] = 0x20040000; // 1b000 (2, 11) = 5
    SBOX[4][114688] = 0x40080; // 1c000 (2, 12) = 6
    SBOX[4][118784] = 0x20000080; // 1d000 (2, 13) = 3
    SBOX[4][122880] = 0x0; // 1e000 (2, 14) = 0
    SBOX[4][126976] = 0x1040080; // 1f000 (2, 15) = 14
    SBOX[4][67584] = 0x21000080; // 10800 (3, 0) = 11
    SBOX[4][71680] = 0x1000000; // 11800 (3, 1) = 8
    SBOX[4][75776] = 0x1040000; // 12800 (3, 2) = 12
    SBOX[4][79872] = 0x20040080; // 13800 (3, 3) = 7
    SBOX[4][83968] = 0x20000000; // 14800 (3, 4) = 1
    SBOX[4][88064] = 0x1040080; // 15800 (3, 5) = 14
    SBOX[4][92160] = 0x80; // 16800 (3, 6) = 2
    SBOX[4][96256] = 0x21040000; // 17800 (3, 7) = 13
    SBOX[4][100352] = 0x40080; // 18800 (3, 8) = 6
    SBOX[4][104448] = 0x21040080; // 19800 (3, 9) = 15
    SBOX[4][108544] = 0x0; // 1a800 (3, 10) = 0
    SBOX[4][112640] = 0x21000000; // 1b800 (3, 11) = 9
    SBOX[4][116736] = 0x1000080; // 1c800 (3, 12) = 10
    SBOX[4][120832] = 0x40000; // 1d800 (3, 13) = 4
    SBOX[4][124928] = 0x20040000; // 1e800 (3, 14) = 5
    SBOX[4][129024] = 0x20000080; // 1f800 (3, 15) = 3

    SBOX[5] = new Array();
    SBOX[5][0] = 0x10000008; // 0 (0, 0) = 12
    SBOX[5][256] = 0x2000; // 100 (0, 1) = 1
    SBOX[5][512] = 0x10200000; // 200 (0, 2) = 10
    SBOX[5][768] = 0x10202008; // 300 (0, 3) = 15
    SBOX[5][1024] = 0x10002000; // 400 (0, 4) = 9
    SBOX[5][1280] = 0x200000; // 500 (0, 5) = 2
    SBOX[5][1536] = 0x200008; // 600 (0, 6) = 6
    SBOX[5][1792] = 0x10000000; // 700 (0, 7) = 8
    SBOX[5][2048] = 0x0; // 800 (0, 8) = 0
    SBOX[5][2304] = 0x10002008; // 900 (0, 9) = 13
    SBOX[5][2560] = 0x202000; // a00 (0, 10) = 3
    SBOX[5][2816] = 0x8; // b00 (0, 11) = 4
    SBOX[5][3072] = 0x10200008; // c00 (0, 12) = 14
    SBOX[5][3328] = 0x202008; // d00 (0, 13) = 7
    SBOX[5][3584] = 0x2008; // e00 (0, 14) = 5
    SBOX[5][3840] = 0x10202000; // f00 (0, 15) = 11
    SBOX[5][128] = 0x10200000; // 80 (1, 0) = 10
    SBOX[5][384] = 0x10202008; // 180 (1, 1) = 15
    SBOX[5][640] = 0x8; // 280 (1, 2) = 4
    SBOX[5][896] = 0x200000; // 380 (1, 3) = 2
    SBOX[5][1152] = 0x202008; // 480 (1, 4) = 7
    SBOX[5][1408] = 0x10000008; // 580 (1, 5) = 12
    SBOX[5][1664] = 0x10002000; // 680 (1, 6) = 9
    SBOX[5][1920] = 0x2008; // 780 (1, 7) = 5
    SBOX[5][2176] = 0x200008; // 880 (1, 8) = 6
    SBOX[5][2432] = 0x2000; // 980 (1, 9) = 1
    SBOX[5][2688] = 0x10002008; // a80 (1, 10) = 13
    SBOX[5][2944] = 0x10200008; // b80 (1, 11) = 14
    SBOX[5][3200] = 0x0; // c80 (1, 12) = 0
    SBOX[5][3456] = 0x10202000; // d80 (1, 13) = 11
    SBOX[5][3712] = 0x202000; // e80 (1, 14) = 3
    SBOX[5][3968] = 0x10000000; // f80 (1, 15) = 8
    SBOX[5][4096] = 0x10002000; // 1000 (2, 0) = 9
    SBOX[5][4352] = 0x10200008; // 1100 (2, 1) = 14
    SBOX[5][4608] = 0x10202008; // 1200 (2, 2) = 15
    SBOX[5][4864] = 0x2008; // 1300 (2, 3) = 5
    SBOX[5][5120] = 0x200000; // 1400 (2, 4) = 2
    SBOX[5][5376] = 0x10000000; // 1500 (2, 5) = 8
    SBOX[5][5632] = 0x10000008; // 1600 (2, 6) = 12
    SBOX[5][5888] = 0x202000; // 1700 (2, 7) = 3
    SBOX[5][6144] = 0x202008; // 1800 (2, 8) = 7
    SBOX[5][6400] = 0x0; // 1900 (2, 9) = 0
    SBOX[5][6656] = 0x8; // 1a00 (2, 10) = 4
    SBOX[5][6912] = 0x10200000; // 1b00 (2, 11) = 10
    SBOX[5][7168] = 0x2000; // 1c00 (2, 12) = 1
    SBOX[5][7424] = 0x10002008; // 1d00 (2, 13) = 13
    SBOX[5][7680] = 0x10202000; // 1e00 (2, 14) = 11
    SBOX[5][7936] = 0x200008; // 1f00 (2, 15) = 6
    SBOX[5][4224] = 0x8; // 1080 (3, 0) = 4
    SBOX[5][4480] = 0x202000; // 1180 (3, 1) = 3
    SBOX[5][4736] = 0x200000; // 1280 (3, 2) = 2
    SBOX[5][4992] = 0x10000008; // 1380 (3, 3) = 12
    SBOX[5][5248] = 0x10002000; // 1480 (3, 4) = 9
    SBOX[5][5504] = 0x2008; // 1580 (3, 5) = 5
    SBOX[5][5760] = 0x10202008; // 1680 (3, 6) = 15
    SBOX[5][6016] = 0x10200000; // 1780 (3, 7) = 10
    SBOX[5][6272] = 0x10202000; // 1880 (3, 8) = 11
    SBOX[5][6528] = 0x10200008; // 1980 (3, 9) = 14
    SBOX[5][6784] = 0x2000; // 1a80 (3, 10) = 1
    SBOX[5][7040] = 0x202008; // 1b80 (3, 11) = 7
    SBOX[5][7296] = 0x200008; // 1c80 (3, 12) = 6
    SBOX[5][7552] = 0x0; // 1d80 (3, 13) = 0
    SBOX[5][7808] = 0x10000000; // 1e80 (3, 14) = 8
    SBOX[5][8064] = 0x10002008; // 1f80 (3, 15) = 13

    SBOX[6] = new Array();
    SBOX[6][0] = 0x100000; // 0 (0, 0) = 4
    SBOX[6][16] = 0x2000401; // 10 (0, 1) = 11
    SBOX[6][32] = 0x400; // 20 (0, 2) = 2
    SBOX[6][48] = 0x100401; // 30 (0, 3) = 14
    SBOX[6][64] = 0x2100401; // 40 (0, 4) = 15
    SBOX[6][80] = 0x0; // 50 (0, 5) = 0
    SBOX[6][96] = 0x1; // 60 (0, 6) = 8
    SBOX[6][112] = 0x2100001; // 70 (0, 7) = 13
    SBOX[6][128] = 0x2000400; // 80 (0, 8) = 3
    SBOX[6][144] = 0x100001; // 90 (0, 9) = 12
    SBOX[6][160] = 0x2000001; // a0 (0, 10) = 9
    SBOX[6][176] = 0x2100400; // b0 (0, 11) = 7
    SBOX[6][192] = 0x2100000; // c0 (0, 12) = 5
    SBOX[6][208] = 0x401; // d0 (0, 13) = 10
    SBOX[6][224] = 0x100400; // e0 (0, 14) = 6
    SBOX[6][240] = 0x2000000; // f0 (0, 15) = 1
    SBOX[6][8] = 0x2100001; // 8 (1, 0) = 13
    SBOX[6][24] = 0x0; // 18 (1, 1) = 0
    SBOX[6][40] = 0x2000401; // 28 (1, 2) = 11
    SBOX[6][56] = 0x2100400; // 38 (1, 3) = 7
    SBOX[6][72] = 0x100000; // 48 (1, 4) = 4
    SBOX[6][88] = 0x2000001; // 58 (1, 5) = 9
    SBOX[6][104] = 0x2000000; // 68 (1, 6) = 1
    SBOX[6][120] = 0x401; // 78 (1, 7) = 10
    SBOX[6][136] = 0x100401; // 88 (1, 8) = 14
    SBOX[6][152] = 0x2000400; // 98 (1, 9) = 3
    SBOX[6][168] = 0x2100000; // a8 (1, 10) = 5
    SBOX[6][184] = 0x100001; // b8 (1, 11) = 12
    SBOX[6][200] = 0x400; // c8 (1, 12) = 2
    SBOX[6][216] = 0x2100401; // d8 (1, 13) = 15
    SBOX[6][232] = 0x1; // e8 (1, 14) = 8
    SBOX[6][248] = 0x100400; // f8 (1, 15) = 6
    SBOX[6][256] = 0x2000000; // 100 (2, 0) = 1
    SBOX[6][272] = 0x100000; // 110 (2, 1) = 4
    SBOX[6][288] = 0x2000401; // 120 (2, 2) = 11
    SBOX[6][304] = 0x2100001; // 130 (2, 3) = 13
    SBOX[6][320] = 0x100001; // 140 (2, 4) = 12
    SBOX[6][336] = 0x2000400; // 150 (2, 5) = 3
    SBOX[6][352] = 0x2100400; // 160 (2, 6) = 7
    SBOX[6][368] = 0x100401; // 170 (2, 7) = 14
    SBOX[6][384] = 0x401; // 180 (2, 8) = 10
    SBOX[6][400] = 0x2100401; // 190 (2, 9) = 15
    SBOX[6][416] = 0x100400; // 1a0 (2, 10) = 6
    SBOX[6][432] = 0x1; // 1b0 (2, 11) = 8
    SBOX[6][448] = 0x0; // 1c0 (2, 12) = 0
    SBOX[6][464] = 0x2100000; // 1d0 (2, 13) = 5
    SBOX[6][480] = 0x2000001; // 1e0 (2, 14) = 9
    SBOX[6][496] = 0x400; // 1f0 (2, 15) = 2
    SBOX[6][264] = 0x100400; // 108 (3, 0) = 6
    SBOX[6][280] = 0x2000401; // 118 (3, 1) = 11
    SBOX[6][296] = 0x2100001; // 128 (3, 2) = 13
    SBOX[6][312] = 0x1; // 138 (3, 3) = 8
    SBOX[6][328] = 0x2000000; // 148 (3, 4) = 1
    SBOX[6][344] = 0x100000; // 158 (3, 5) = 4
    SBOX[6][360] = 0x401; // 168 (3, 6) = 10
    SBOX[6][376] = 0x2100400; // 178 (3, 7) = 7
    SBOX[6][392] = 0x2000001; // 188 (3, 8) = 9
    SBOX[6][408] = 0x2100000; // 198 (3, 9) = 5
    SBOX[6][424] = 0x0; // 1a8 (3, 10) = 0
    SBOX[6][440] = 0x2100401; // 1b8 (3, 11) = 15
    SBOX[6][456] = 0x100401; // 1c8 (3, 12) = 14
    SBOX[6][472] = 0x400; // 1d8 (3, 13) = 2
    SBOX[6][488] = 0x2000400; // 1e8 (3, 14) = 3
    SBOX[6][504] = 0x100001; // 1f8 (3, 15) = 12

    SBOX[7] = new Array();
    SBOX[7][0] = 0x8000820; // 0 (0, 0) = 13
    SBOX[7][1] = 0x20000; // 1 (0, 1) = 2
    SBOX[7][2] = 0x8000000; // 2 (0, 2) = 8
    SBOX[7][3] = 0x20; // 3 (0, 3) = 4
    SBOX[7][4] = 0x20020; // 4 (0, 4) = 6
    SBOX[7][5] = 0x8020820; // 5 (0, 5) = 15
    SBOX[7][6] = 0x8020800; // 6 (0, 6) = 11
    SBOX[7][7] = 0x800; // 7 (0, 7) = 1
    SBOX[7][8] = 0x8020000; // 8 (0, 8) = 10
    SBOX[7][9] = 0x8000800; // 9 (0, 9) = 9
    SBOX[7][10] = 0x20800; // a (0, 10) = 3
    SBOX[7][11] = 0x8020020; // b (0, 11) = 14
    SBOX[7][12] = 0x820; // c (0, 12) = 5
    SBOX[7][13] = 0x0; // d (0, 13) = 0
    SBOX[7][14] = 0x8000020; // e (0, 14) = 12
    SBOX[7][15] = 0x20820; // f (0, 15) = 7
    SBOX[7][-2147483648] = 0x800; // 80000000 (1, 0) = 1
    SBOX[7][-2147483647] = 0x8020820; // 80000001 (1, 1) = 15
    SBOX[7][-2147483646] = 0x8000820; // 80000002 (1, 2) = 13
    SBOX[7][-2147483645] = 0x8000000; // 80000003 (1, 3) = 8
    SBOX[7][-2147483644] = 0x8020000; // 80000004 (1, 4) = 10
    SBOX[7][-2147483643] = 0x20800; // 80000005 (1, 5) = 3
    SBOX[7][-2147483642] = 0x20820; // 80000006 (1, 6) = 7
    SBOX[7][-2147483641] = 0x20; // 80000007 (1, 7) = 4
    SBOX[7][-2147483640] = 0x8000020; // 80000008 (1, 8) = 12
    SBOX[7][-2147483639] = 0x820; // 80000009 (1, 9) = 5
    SBOX[7][-2147483638] = 0x20020; // 8000000a (1, 10) = 6
    SBOX[7][-2147483637] = 0x8020800; // 8000000b (1, 11) = 11
    SBOX[7][-2147483636] = 0x0; // 8000000c (1, 12) = 0
    SBOX[7][-2147483635] = 0x8020020; // 8000000d (1, 13) = 14
    SBOX[7][-2147483634] = 0x8000800; // 8000000e (1, 14) = 9
    SBOX[7][-2147483633] = 0x20000; // 8000000f (1, 15) = 2
    SBOX[7][16] = 0x20820; // 10 (2, 0) = 7
    SBOX[7][17] = 0x8020800; // 11 (2, 1) = 11
    SBOX[7][18] = 0x20; // 12 (2, 2) = 4
    SBOX[7][19] = 0x800; // 13 (2, 3) = 1
    SBOX[7][20] = 0x8000800; // 14 (2, 4) = 9
    SBOX[7][21] = 0x8000020; // 15 (2, 5) = 12
    SBOX[7][22] = 0x8020020; // 16 (2, 6) = 14
    SBOX[7][23] = 0x20000; // 17 (2, 7) = 2
    SBOX[7][24] = 0x0; // 18 (2, 8) = 0
    SBOX[7][25] = 0x20020; // 19 (2, 9) = 6
    SBOX[7][26] = 0x8020000; // 1a (2, 10) = 10
    SBOX[7][27] = 0x8000820; // 1b (2, 11) = 13
    SBOX[7][28] = 0x8020820; // 1c (2, 12) = 15
    SBOX[7][29] = 0x20800; // 1d (2, 13) = 3
    SBOX[7][30] = 0x820; // 1e (2, 14) = 5
    SBOX[7][31] = 0x8000000; // 1f (2, 15) = 8
    SBOX[7][-2147483632] = 0x20000; // 80000010 (3, 0) = 2
    SBOX[7][-2147483631] = 0x800; // 80000011 (3, 1) = 1
    SBOX[7][-2147483630] = 0x8020020; // 80000012 (3, 2) = 14
    SBOX[7][-2147483629] = 0x20820; // 80000013 (3, 3) = 7
    SBOX[7][-2147483628] = 0x20; // 80000014 (3, 4) = 4
    SBOX[7][-2147483627] = 0x8020000; // 80000015 (3, 5) = 10
    SBOX[7][-2147483626] = 0x8000000; // 80000016 (3, 6) = 8
    SBOX[7][-2147483625] = 0x8000820; // 80000017 (3, 7) = 13
    SBOX[7][-2147483624] = 0x8020820; // 80000018 (3, 8) = 15
    SBOX[7][-2147483623] = 0x8000020; // 80000019 (3, 9) = 12
    SBOX[7][-2147483622] = 0x8000800; // 8000001a (3, 10) = 9
    SBOX[7][-2147483621] = 0x0; // 8000001b (3, 11) = 0
    SBOX[7][-2147483620] = 0x20800; // 8000001c (3, 12) = 3
    SBOX[7][-2147483619] = 0x820; // 8000001d (3, 13) = 5
    SBOX[7][-2147483618] = 0x20020; // 8000001e (3, 14) = 6
    SBOX[7][-2147483617] = 0x8020800; // 8000001f (3, 15) = 11

    State.prototype._exchangeLR = function(v, m) {
        var t = ((this.lhs >> v) ^ this.rhs) & m;
        this.rhs ^= t;
        this.lhs ^= (t << v);
    };

    State.prototype._exchangeRL = function(v, m) {
        var t = ((this.rhs >> v) ^ this.lhs) & m;
        this.lhs ^= t;
        this.rhs ^= (t << v);
    };

    /**
     * Perform the initial permutation of the input to create the starting state
     * of the algorithm. The initial permutation maps each consecutive bit of
     * the input into a different byte of the state.
     * 
     * <pre>
     * The initial permutation is defined to be:
     * 
     *      58    50   42    34    26   18    10    2  
     *      60    52   44    36    28   20    12    4
     *      62    54   46    38    30   22    14    6
     *      64    56   48    40    32   24    16    8
     *      57    49   41    33    25   17     9    1
     *      59    51   43    35    27   19    11    3
     *      61    53   45    37    29   21    13    5
     *      63    55   47    39    31   23    15    7
     * </pre>
     * 
     * 
     * @param message
     *            The message as an array of unsigned bytes.
     * @param offset
     *            The offset into the message that the current 64-bit block
     *            begins.
     * @returns the initial engine state
     */
    State.prototype.initialPerm = function(message, offset) {
        var input = message.slice(offset, offset + 8);

        this.lhs = (input[0] << 24) + (input[1] << 16) + (input[2] << 8)
                + input[3];
        this.rhs = (input[4] << 24) + (input[5] << 16) + (input[6] << 8)
                + input[7];

        this._exchangeLR(4, 0x0f0f0f0f);
        this._exchangeLR(16, 0x0000ffff);
        this._exchangeRL(2, 0x33333333);
        this._exchangeRL(8, 0x00ff00ff);
        this._exchangeLR(1, 0x55555555);
    };

    /**
     * Perform one round of the DES algorithm using the given key. A round is
     * defined as:
     * 
     * <pre>
     * L&amp;rsquo = R
     * R&amp;rsquo = L &circ; f(R, k)
     * </pre>
     * 
     * where f consists of expanding, XORing with the key and contracting back
     * with the SBOXes.
     * 
     * Note that the final round is defined slightly differently as:
     * 
     * <pre>
     * L&amp;rsquo = L &circ; f(R, k)
     * R&amp;rsquo = R
     * </pre>
     * 
     * Therefore in the final round this function produces LHS and RHS the wrong
     * way around.
     * 
     * @param k
     *            the key
     */
    State.prototype.round = function(k) {
        var r = this.rhs, l = this.lhs;
        var f = 0;
        for ( var i = 0; i < 8; i++) {
            var v = (r ^ k[i]) & State.SBOX_MASK[i];
            f += State.SBOX[i][v];
        }

        this.lhs = r;
        this.rhs = l ^ f;
    };

    /**
     * Apply the inverse of the initial permutation.
     * 
     * <pre>
     * The inverse is defined to be:
     * 
     *      40     8   48    16    56   24    64   32
     *      39     7   47    15    55   23    63   31
     *      38     6   46    14    54   22    62   30
     *      37     5   45    13    53   21    61   29
     *      36     4   44    12    52   20    60   28
     *      35     3   43    11    51   19    59   27
     *      34     2   42    10    50   18    58   26
     *      33     1   41     9    49   17    57   25
     * </pre>
     * 
     * @param cipherText
     * @param offset
     */
    State.prototype.finalPerm = function(cipherText, offset) {
        var t = this.lhs;
        this.lhs = this.rhs;
        this.rhs = t;

        this._exchangeLR(1, 0x55555555);
        this._exchangeRL(8, 0x00ff00ff);
        this._exchangeRL(2, 0x33333333);
        this._exchangeLR(16, 0x0000ffff);
        this._exchangeLR(4, 0x0f0f0f0f);

        cipherText[offset] = (this.lhs >> 24) & 0xff;
        cipherText[offset + 1] = (this.lhs >> 16) & 0xff;
        cipherText[offset + 2] = (this.lhs >> 8) & 0xff;
        cipherText[offset + 3] = (this.lhs) & 0xff;
        cipherText[offset + 4] = (this.rhs >> 24) & 0xff;
        cipherText[offset + 5] = (this.rhs >> 16) & 0xff;
        cipherText[offset + 6] = (this.rhs >> 8) & 0xff;
        cipherText[offset + 7] = (this.rhs) & 0xff;
    };

    /**
     * DES cipher
     */
    var DES = C.DES = {
        _blocksize : 2,

        _keyschedule : null,

        _state : new State(),

        _init : function(k) {
            this._keyschedule = new KeySchedule(k);
        },

        encrypt : function(message, password, options) {

            options = options || {};

            // Determine mode
            var mode = options.mode || new C.mode.OFB;

            // Allow mode to override options
            if (mode.fixOptions)
                mode.fixOptions(options);

            var
            // Convert to bytes if message is a string
            m = (message.constructor == String ? UTF8.stringToBytes(message)
                    : message),

            // Generate random IV
            iv = options.iv || util.randomBytes(8),

            // Generate key
            k = (password.constructor == String ?
            // Derive key from passphrase
            C.PBKDF2(password, iv, 8, {
                asBytes : true
            }) :
            // else, assume byte array representing cryptographic key
            password);

            // Create key schedule
            this._keyschedule = new KeySchedule(k);

            // Encrypt
            mode.encrypt(DES, m, iv);

            // Return ciphertext
            m = options.iv ? m : iv.concat(m);
            return (options && options.asBytes) ? m : util.bytesToBase64(m);
        },

        _encryptblock : function(message, offset) {
            this._state.initialPerm(message, offset);
            for ( var i = 0; i <= 15; i++) {
                this._state.round(this._keyschedule.getKey(i));
            }
            this._state.finalPerm(message, offset);
        },

        decrypt : function(ciphertext, password, options) {
            options = options || {};

            // Determine mode
            var mode = options.mode || new C.mode.OFB;

            // Allow mode to override options
            if (mode.fixOptions)
                mode.fixOptions(options);

            var

            // Convert to bytes if ciphertext is a string
            c = (ciphertext.constructor == String ? util
                    .base64ToBytes(ciphertext) : ciphertext),

            // Separate IV and message
            iv = options.iv || c.splice(0, 8),

            // Generate key
            k = (password.constructor == String ?
            // Derive key from passphrase
            C.PBKDF2(password, iv, 32, {
                asBytes : true
            }) :
            // else, assume byte array representing cryptographic key
            password);

            // Create key schedule
            this._keyschedule = new KeySchedule(k);

            mode.decrypt(DES, c, iv);

            // Return plaintext
            return (options && options.asBytes) ? c : UTF8.bytesToString(c);
        },

        _decryptblock : function(message, offset) {
            this._state.initialPerm(message, offset);
            for ( var i = 15; i >= 0; i--) {
                this._state.round(this._keyschedule.getKey(i));
            }
            this._state.finalPerm(message, offset);
        }

    };
})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/HMAC.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

C.HMAC = function (hasher, message, key, options) {

	// Convert to byte arrays
	if (message.constructor == String) message = UTF8.stringToBytes(message);
	if (key.constructor == String) key = UTF8.stringToBytes(key);
	/* else, assume byte arrays already */

	// Allow arbitrary length keys
	if (key.length > hasher._blocksize * 4)
		key = hasher(key, { asBytes: true });

	// XOR keys with pad constants
	var okey = key.slice(0),
	    ikey = key.slice(0);
	for (var i = 0; i < hasher._blocksize * 4; i++) {
		okey[i] ^= 0x5C;
		ikey[i] ^= 0x36;
	}

	var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });

	return options && options.asBytes ? hmacbytes :
	       options && options.asString ? Binary.bytesToString(hmacbytes) :
	       util.bytesToHex(hmacbytes);

};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/MARC4.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

var MARC4 = C.MARC4 = {

	/**
	 * Public API
	 */

	encrypt: function (message, password) {

		var

		    // Convert to bytes
		    m = UTF8.stringToBytes(message),

		    // Generate random IV
		    iv = util.randomBytes(16),

		    // Generate key
		    k = password.constructor == String ?
		        // Derive key from passphrase
		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
		        // else, assume byte array representing cryptographic key
		        password;

		// Encrypt
		MARC4._marc4(m, k, 1536);

		// Return ciphertext
		return util.bytesToBase64(iv.concat(m));

	},

	decrypt: function (ciphertext, password) {

		var

		    // Convert to bytes
		    c = util.base64ToBytes(ciphertext),

		    // Separate IV and message
		    iv = c.splice(0, 16),

		    // Generate key
		    k = password.constructor == String ?
		        // Derive key from passphrase
		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
		        // else, assume byte array representing cryptographic key
		        password;

		// Decrypt
		MARC4._marc4(c, k, 1536);

		// Return plaintext
		return UTF8.bytesToString(c);

	},


	/**
	 * Internal methods
	 */

	// The core
	_marc4: function (m, k, drop) {

		// State variables
		var i, j, s, temp;

		// Key setup
		for (i = 0, s = []; i < 256; i++) s[i] = i;
		for (i = 0, j = 0;  i < 256; i++) {

			j = (j + s[i] + k[i % k.length]) % 256;

			// Swap
			temp = s[i];
			s[i] = s[j];
			s[j] = temp;

		}

		// Clear counters
		i = j = 0;

		// Encryption
		for (var k = -drop; k < m.length; k++) {

			i = (i + 1) % 256;
			j = (j + s[i]) % 256;

			// Swap
			temp = s[i];
			s[i] = s[j];
			s[j] = temp;

			// Stop here if we're still dropping keystream
			if (k < 0) continue;

			// Encrypt
			m[k] ^= s[(s[i] + s[j]) % 256];

		}

	}

};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/MD5.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

// Public API
var MD5 = C.MD5 = function (message, options) {
	var digestbytes = util.wordsToBytes(MD5._md5(message));
	return options && options.asBytes ? digestbytes :
	       options && options.asString ? Binary.bytesToString(digestbytes) :
	       util.bytesToHex(digestbytes);
};

// The core
MD5._md5 = function (message) {

	// Convert to byte array
	if (message.constructor == String) message = UTF8.stringToBytes(message);
	/* else, assume byte array already */

	var m = util.bytesToWords(message),
	    l = message.length * 8,
	    a =  1732584193,
	    b = -271733879,
	    c = -1732584194,
	    d =  271733878;

	// Swap endian
	for (var i = 0; i < m.length; i++) {
		m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
		       ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
	}

	// Padding
	m[l >>> 5] |= 0x80 << (l % 32);
	m[(((l + 64) >>> 9) << 4) + 14] = l;

	// Method shortcuts
	var FF = MD5._ff,
	    GG = MD5._gg,
	    HH = MD5._hh,
	    II = MD5._ii;

	for (var i = 0; i < m.length; i += 16) {

		var aa = a,
		    bb = b,
		    cc = c,
		    dd = d;

		a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
		d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
		c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
		b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
		a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
		d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
		c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
		b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
		a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
		d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
		c = FF(c, d, a, b, m[i+10], 17, -42063);
		b = FF(b, c, d, a, m[i+11], 22, -1990404162);
		a = FF(a, b, c, d, m[i+12],  7,  1804603682);
		d = FF(d, a, b, c, m[i+13], 12, -40341101);
		c = FF(c, d, a, b, m[i+14], 17, -1502002290);
		b = FF(b, c, d, a, m[i+15], 22,  1236535329);

		a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
		d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
		c = GG(c, d, a, b, m[i+11], 14,  643717713);
		b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
		a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
		d = GG(d, a, b, c, m[i+10],  9,  38016083);
		c = GG(c, d, a, b, m[i+15], 14, -660478335);
		b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
		a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
		d = GG(d, a, b, c, m[i+14],  9, -1019803690);
		c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
		b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
		a = GG(a, b, c, d, m[i+13],  5, -1444681467);
		d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
		c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
		b = GG(b, c, d, a, m[i+12], 20, -1926607734);

		a = HH(a, b, c, d, m[i+ 5],  4, -378558);
		d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
		c = HH(c, d, a, b, m[i+11], 16,  1839030562);
		b = HH(b, c, d, a, m[i+14], 23, -35309556);
		a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
		d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
		c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
		b = HH(b, c, d, a, m[i+10], 23, -1094730640);
		a = HH(a, b, c, d, m[i+13],  4,  681279174);
		d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
		c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
		b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
		a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
		d = HH(d, a, b, c, m[i+12], 11, -421815835);
		c = HH(c, d, a, b, m[i+15], 16,  530742520);
		b = HH(b, c, d, a, m[i+ 2], 23, -995338651);

		a = II(a, b, c, d, m[i+ 0],  6, -198630844);
		d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
		c = II(c, d, a, b, m[i+14], 15, -1416354905);
		b = II(b, c, d, a, m[i+ 5], 21, -57434055);
		a = II(a, b, c, d, m[i+12],  6,  1700485571);
		d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
		c = II(c, d, a, b, m[i+10], 15, -1051523);
		b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
		a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
		d = II(d, a, b, c, m[i+15], 10, -30611744);
		c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
		b = II(b, c, d, a, m[i+13], 21,  1309151649);
		a = II(a, b, c, d, m[i+ 4],  6, -145523070);
		d = II(d, a, b, c, m[i+11], 10, -1120210379);
		c = II(c, d, a, b, m[i+ 2], 15,  718787259);
		b = II(b, c, d, a, m[i+ 9], 21, -343485551);

		a = (a + aa) >>> 0;
		b = (b + bb) >>> 0;
		c = (c + cc) >>> 0;
		d = (d + dd) >>> 0;

	}

	return util.endian([a, b, c, d]);

};

// Auxiliary functions
MD5._ff  = function (a, b, c, d, x, s, t) {
	var n = a + (b & c | ~b & d) + (x >>> 0) + t;
	return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._gg  = function (a, b, c, d, x, s, t) {
	var n = a + (b & d | c & ~d) + (x >>> 0) + t;
	return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._hh  = function (a, b, c, d, x, s, t) {
	var n = a + (b ^ c ^ d) + (x >>> 0) + t;
	return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._ii  = function (a, b, c, d, x, s, t) {
	var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
	return ((n << s) | (n >>> (32 - s))) + b;
};

// Package private blocksize
MD5._blocksize = 16;

MD5._digestsize = 16;

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

C.PBKDF2 = function (password, salt, keylen, options) {

	// Convert to byte arrays
	if (password.constructor == String) password = UTF8.stringToBytes(password);
	if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
	/* else, assume byte arrays already */

	// Defaults
	var hasher = options && options.hasher || C.SHA1,
	    iterations = options && options.iterations || 1;

	// Pseudo-random function
	function PRF(password, salt) {
		return C.HMAC(hasher, salt, password, { asBytes: true });
	}

	// Generate key
	var derivedKeyBytes = [],
	    blockindex = 1;
	while (derivedKeyBytes.length < keylen) {
		var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
		for (var u = block, i = 1; i < iterations; i++) {
			u = PRF(password, u);
			for (var j = 0; j < block.length; j++) block[j] ^= u[j];
		}
		derivedKeyBytes = derivedKeyBytes.concat(block);
		blockindex++;
	}

	// Truncate excess bytes
	derivedKeyBytes.length = keylen;

	return options && options.asBytes ? derivedKeyBytes :
	       options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
	       util.bytesToHex(derivedKeyBytes);

};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2Async.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

if (!C.nextTick) {
    // node.js has setTime out but prefer process.nextTick
    if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') {
        C.nextTick = process.nextTick;
    } else if (typeof setTimeout !== 'undefined') {
        C.nextTick = function (callback) {
            setTimeout(callback, 0);
        };
    }
}

C.PBKDF2Async = function (password, salt, keylen, callback, options) {

    // Convert to byte arrays
    if (password.constructor == String) password = UTF8.stringToBytes(password);
    if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
    /* else, assume byte arrays already */

    // Defaults
    var hasher = options && options.hasher || C.SHA1,
        iterations = options && options.iterations || 1;

    // Progress callback option
    var progressChangeHandler = options && options.onProgressChange;
    var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations;
    function fireProgressChange(currentIteration) {
        if (progressChangeHandler) {
            var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration;
            setTimeout(function () {
                progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100));
            }, 0);
        }
    }

    // Pseudo-random function
    function PRF(password, salt) {
        return C.HMAC(hasher, salt, password, { asBytes: true });
    }

    var nextTick = C.nextTick;

    // Generate key
    var derivedKeyBytes = [],
        blockindex = 1;

    var outer, inner;
    nextTick(outer = function () {
        if (derivedKeyBytes.length < keylen) {
            var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
            fireProgressChange(1);

            var u = block, i = 1;
            nextTick(inner = function () {
                if (i < iterations) {
                    u = PRF(password, u);
                    for (var j = 0; j < block.length; j++) block[j] ^= u[j];
                    i++;
                    fireProgressChange(i);

                    nextTick(inner);
                } else {
                    derivedKeyBytes = derivedKeyBytes.concat(block);
                    blockindex++;
                    nextTick(outer);
                }
            });
        } else {
            // Truncate excess bytes
            derivedKeyBytes.length = keylen;
            callback(
                    options && options.asBytes ? derivedKeyBytes :
                    options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
                    util.bytesToHex(derivedKeyBytes));
        }
    });
};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/Rabbit.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

// Inner state
var x = [],
    c = [],
    b;

var Rabbit = C.Rabbit = {

	/**
	 * Public API
	 */

	encrypt: function (message, password) {

		var

		    // Convert to bytes
		    m = UTF8.stringToBytes(message),

		    // Generate random IV
		    iv = util.randomBytes(8),

		    // Generate key
		    k = password.constructor == String ?
		        // Derive key from passphrase
		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
		        // else, assume byte array representing cryptographic key
		        password;

		// Encrypt
		Rabbit._rabbit(m, k, util.bytesToWords(iv));

		// Return ciphertext
		return util.bytesToBase64(iv.concat(m));

	},

	decrypt: function (ciphertext, password) {

		var

		    // Convert to bytes
		    c = util.base64ToBytes(ciphertext),

		    // Separate IV and message
		    iv = c.splice(0, 8),

		    // Generate key
		    k = password.constructor == String ?
		        // Derive key from passphrase
		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
		        // else, assume byte array representing cryptographic key
		        password;

		// Decrypt
		Rabbit._rabbit(c, k, util.bytesToWords(iv));

		// Return plaintext
		return UTF8.bytesToString(c);

	},


	/**
	 * Internal methods
	 */

	// Encryption/decryption scheme
	_rabbit: function (m, k, iv) {

		Rabbit._keysetup(k);
		if (iv) Rabbit._ivsetup(iv);

		for (var s = [], i = 0; i < m.length; i++) {

			if (i % 16 == 0) {

				// Iterate the system
				Rabbit._nextstate();

				// Generate 16 bytes of pseudo-random data
				s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
				s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
				s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
				s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);

				// Swap endian
				for (var j = 0; j < 4; j++) {
					s[j] = ((s[j] <<  8) | (s[j] >>> 24)) & 0x00FF00FF |
					       ((s[j] << 24) | (s[j] >>>  8)) & 0xFF00FF00;
				}

				// Convert words to bytes
				for (var b = 120; b >= 0; b -= 8)
					s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;

			}

			m[i] ^= s[i % 16];

		}

	},

	// Key setup scheme
	_keysetup: function (k) {

		// Generate initial state values
		x[0] = k[0];
		x[2] = k[1];
		x[4] = k[2];
		x[6] = k[3];
		x[1] = (k[3] << 16) | (k[2] >>> 16);
		x[3] = (k[0] << 16) | (k[3] >>> 16);
		x[5] = (k[1] << 16) | (k[0] >>> 16);
		x[7] = (k[2] << 16) | (k[1] >>> 16);

		// Generate initial counter values
		c[0] = util.rotl(k[2], 16);
		c[2] = util.rotl(k[3], 16);
		c[4] = util.rotl(k[0], 16);
		c[6] = util.rotl(k[1], 16);
		c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
		c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
		c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
		c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);

		// Clear carry bit
		b = 0;

		// Iterate the system four times
		for (var i = 0; i < 4; i++) Rabbit._nextstate();

		// Modify the counters
		for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];

	},

	// IV setup scheme
	_ivsetup: function (iv) {

		// Generate four subvectors
		var i0 = util.endian(iv[0]),
		    i2 = util.endian(iv[1]),
		    i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
		    i3 = (i2 <<  16) | (i0 & 0x0000FFFF);

		// Modify counter values
		c[0] ^= i0;
		c[1] ^= i1;
		c[2] ^= i2;
		c[3] ^= i3;
		c[4] ^= i0;
		c[5] ^= i1;
		c[6] ^= i2;
		c[7] ^= i3;

		// Iterate the system four times
		for (var i = 0; i < 4; i++) Rabbit._nextstate();

	},

	// Next-state function
	_nextstate: function () {

		// Save old counter values
		for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];

		// Calculate new counter values
		c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
		c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
		c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
		c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
		c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
		c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
		c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
		c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
		b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;

		// Calculate the g-values
		for (var g = [], i = 0; i < 8; i++) {

			var gx = (x[i] + c[i]) >>> 0;

			// Construct high and low argument for squaring
			var ga = gx & 0xFFFF,
			    gb = gx >>> 16;

			// Calculate high and low result of squaring
			var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
			    gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;

			// High XOR low
			g[i] = gh ^ gl;

		}

		// Calculate new state values
		x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
		x[1] = g[1] + ((g[0] <<  8) | (g[0] >>> 24)) + g[7];
		x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
		x[3] = g[3] + ((g[2] <<  8) | (g[2] >>> 24)) + g[1];
		x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
		x[5] = g[5] + ((g[4] <<  8) | (g[4] >>> 24)) + g[3];
		x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
		x[7] = g[7] + ((g[6] <<  8) | (g[6] >>> 24)) + g[5];

	}

};

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/SHA1.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

// Public API
var SHA1 = C.SHA1 = function (message, options) {
	var digestbytes = util.wordsToBytes(SHA1._sha1(message));
	return options && options.asBytes ? digestbytes :
	       options && options.asString ? Binary.bytesToString(digestbytes) :
	       util.bytesToHex(digestbytes);
};

// The core
SHA1._sha1 = function (message) {

	// Convert to byte array
	if (message.constructor == String) message = UTF8.stringToBytes(message);
	/* else, assume byte array already */

	var m  = util.bytesToWords(message),
	    l  = message.length * 8,
	    w  =  [],
	    H0 =  1732584193,
	    H1 = -271733879,
	    H2 = -1732584194,
	    H3 =  271733878,
	    H4 = -1009589776;

	// Padding
	m[l >> 5] |= 0x80 << (24 - l % 32);
	m[((l + 64 >>> 9) << 4) + 15] = l;

	for (var i = 0; i < m.length; i += 16) {

		var a = H0,
		    b = H1,
		    c = H2,
		    d = H3,
		    e = H4;

		for (var j = 0; j < 80; j++) {

			if (j < 16) w[j] = m[i + j];
			else {
				var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
				w[j] = (n << 1) | (n >>> 31);
			}

			var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
			         j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
			         j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
			         j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
			                  (H1 ^ H2 ^ H3) - 899497514);

			H4 =  H3;
			H3 =  H2;
			H2 = (H1 << 30) | (H1 >>> 2);
			H1 =  H0;
			H0 =  t;

		}

		H0 += a;
		H1 += b;
		H2 += c;
		H3 += d;
		H4 += e;

	}

	return [H0, H1, H2, H3, H4];

};

// Package private blocksize
SHA1._blocksize = 16;

SHA1._digestsize = 20;

})();


================================================
FILE: cloudfunctions/regist/cryptojs/lib/SHA256.js
================================================
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

// Constants
var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
          0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
          0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
          0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
          0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
          0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
          0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
          0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
          0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
          0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
          0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
          0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
          0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
          0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
          0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
          0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];

// Public API
var SHA256 = C.SHA256 = function (message, options) {
	var digestbytes = util.wordsToBytes(SHA256._sha256(message));
	return options && options.asBytes ? digestbytes :
	       options && options.asString ? Binary.bytesToString(digestbytes) :
	       util.bytesToHex(digestbytes);
};

// The core
SHA256._sha256 = function (message) {

	// Convert to byte array
	if (message.constructor == String) message = UTF8.stringToBytes(message);
	/* else, assume byte array already */

	var m = util.bytesToWords(message),
	    l = message.length * 8,
	    H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
	          0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ],
	    w = [],
	    a, b, c, d, e, f, g, h, i, j,
	    t1, t2;

	// Padding
	m[l >> 5] |= 0x80 << (24 - l % 32);
	m[((l + 64 >> 9) << 4) + 15] = l;

	for (var i = 0; i < m.length; i += 16) {

		a = H[0];
		b = H[1];
		c = H[2];
		d = H[3];
		e = H[4];
		f = H[5];
		g = H[6];
		h = H[7];

		for (var j = 0; j < 64; j++) {

			if (j < 16) w[j] = m[j + i];
			else {

				var gamma0x = w[j - 15],
				    gamma1x = w[j - 2],
				    gamma0  = ((gamma0x << 25) | (gamma0x >>>  7)) ^
				              ((gamma0x << 14) | (gamma0x >>> 18)) ^
				               (gamma0x >>> 3),
				    gamma1  = ((gamma1x <<  15) | (gamma1x >>> 17)) ^
				              ((gamma1x <<  13) | (gamma1x >>> 19)) ^
				               (gamma1x >>> 10);

				w[j] = gamma0 + (w[j - 7] >>> 0) +
				       gamma1 + (w[j - 16] >>> 0);

			}

			var ch  = e & f ^ ~e & g,
			    maj = a & b ^ a & c ^ b & c,
			    sigma0 = ((a << 30) | (a >>>  2)) ^
			             ((a << 19) | (a >>> 13)) ^
			             ((a << 10) | (a >>> 22)),
			    sigma1 = ((e << 26) | (e >>>  6)) ^
			             ((e << 21) | (e >>> 11)) ^
			             ((e <<  7) | (e >>> 25));


			t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
			t2 = sigma0 + maj;

			h = g;
			g = f;
			f = e;
			e = (d + t1) >>> 0;
			d = c;
			c = b;
			b = a;
			a = (t1 + t2) >>> 0;

		}

		H[0] += a;
		H[1] += b;
		H[2] += c;
		H[3] += d;
		H[4] += e;
		H[5] += f;
		H[6] += g;
		H[7] += h;

	}

	return H;

};

// Package private blocksize
SHA256._blocksize = 16;

SHA256._digestsize = 32;

})();


================================================
FILE: cloudfunctions/regist/cryptojs/package.json
================================================
{
  "author": "Jeff Guo <gwjjeff@gmail.com>",
  "name": "cryptojs",
  "tags": ["Hash", "MD5", "SHA1", "SHA-1", "SHA256", "SHA-256", "RC4", "Rabbit", "AES", "DES", "PBKDF2", "HMAC", "OFB", "CFB", "CTR", "CBC", "Base64"],
  "description": "Following googlecode project crypto-js, provide standard and secure cryptographic algorithms for NodeJS. Support MD5, SHA-1, SHA-256, RC4, Rabbit, AES, DES, PBKDF2, HMAC, OFB, CFB, CTR, CBC, Base64",
  "version": "2.5.3",
  "homepage": "https://github.com/gwjjeff/cryptojs",
  "repository": {
    "type": "git",
    "url": "git://github.com/gwjjeff/cryptojs.git"
  },
  "main": "cryptojs.js",
  "engines": {
    "node": "*"
  },
  "dependencies": {},
  "devDependencies": {}
}


================================================
FILE: cloudfunctions/regist/cryptojs/test/PBKDF2-test.js
================================================
var assert = require('assert');
var Crypto = require('../cryptojs').Crypto; 

(function test_PBKDF2() {
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8), "cdedb5281bb2f801565a1122b2563515");
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8), "cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837");
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 2	}), "01dbee7f4a9e243e988b62c73cda935d");
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 2 }), "01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86");
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512b");
	assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13");
	assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 128 / 8, {	iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a49");
	assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 256 / 8, {	iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a493f98d203e6be49a6adf4fa574b6e64ee");
	assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 128 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9");
	assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 256 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1");
	assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 128 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be61");
	assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
	assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 128 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39");
	assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 256 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0c41e02c281ff3069e1e94f52");
})(); 

(function test_PBKSD2Async() {
	Crypto.PBKDF2Async("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, function(result) {
		assert.strictEqual(result, "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
	}, { iterations : 1200 });
})();


================================================
FILE: cloudfunctions/regist/index.js
================================================
const appid = 'wxd6beb52c8602bff4'; //你的小程序appid
const secret = 'b00457b478f63f2388ef03476bb5a60c'; //你的小程序secret

/*
下
面
不
用
管
*/

const cloud = require('wx-server-sdk');
cloud.init()//这里后面加的初始化
const TcbRouter = require('tcb-router'); //云函数路由
const rq = require('request');
const wxurl = 'https://api.weixin.qq.com';
var WXBizDataCrypt = require('./RdWXBizDataCrypt') // 用于手机号解密
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
      const app = new TcbRouter({
            event
      });
      //获取电话号码
      app.router('phone', async(ctx) => {
            ctx.body = new Promise(resolve => {
                  rq({
                        url: wxurl + '/sns/jscode2session?appid=' + appid + '&secret=' + secret + '&js_code=' + event.code + '&grant_type=authorization_code',
                        method: "GET",
                        json: true,
                  }, function(error, response, body) {
                        const decrypt1 = new WXBizDataCrypt(appid, body.session_key) // -解密第一步
                        const decrypt2 = decrypt1.decryptData(event.encryptedData, event.iv) // 解密第二步*/
                        resolve({
                              data: decrypt2
                        })
                  });
            });
      });
      //获取openid
      app.router('getid', async(ctx) => {
            const wxContext = cloud.getWXContext()
            ctx.body = wxContext.OPENID;
      });
      return app.serve();
}

================================================
FILE: cloudfunctions/regist/package.json
================================================
{
      "name": "regist",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
            "request": "^2.88.0",
            "tcb-router": "^1.1.2",
            "wx-server-sdk": "^2.0.4"
      }
}


================================================
FILE: cloudfunctions/removeChat/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/removeChat/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
  try {
    await db.collection('rooms').doc(event.id).update({
      data: {
        deleted: 1
      }
    })
    .then(console.log)
    .catch(console.error)
    
  } catch(e) {
    console.error(e)
  }
}

================================================
FILE: cloudfunctions/removeChat/package.json
================================================
{
  "name": "removeChat",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.2.0"
  }
}

================================================
FILE: cloudfunctions/removeOrder/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/removeOrder/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

const db = cloud.database()
const _ = db.command

// 云函数入口函数
exports.main = async (event, _context) => {
  try {
    return await db.collection('order').doc(event._id).remove()
  } catch (e) {
    console.error(e)
  }
}

================================================
FILE: cloudfunctions/removeOrder/package.json
================================================
{
  "name": "removeOrder",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.2.0"
  }
}

================================================
FILE: cloudfunctions/sell/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/sell/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
  
cloud.init()
  
const db = cloud.database()
const _ = db.command
  
// 云函数入口函数
exports.main = async (event, _context) => {
 try {
  return await db.collection('order').doc(event._id).update({
   // data 传入需要局部更新的数据
   data: {
      status:event.status
   }
  })
 } catch (e) {
  console.error(e)
 }
}

================================================
FILE: cloudfunctions/sell/package.json
================================================
{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.1.2"
  }
}

================================================
FILE: cloudfunctions/sendMsg/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/sendMsg/index.js
================================================
//编程小石头微信:2501902696
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
  try {
    const result = await cloud.openapi.subscribeMessage.send({
      touser: event.openid, //要推送给那个用户
      page: 'pages/index/index', //要跳转到那个小程序页面
      data: {//推送的内容
        thing3: {
          value: event.good
        },
        thing1: {
          value: event.status,
          color: event.color
        },
        thing2: {
          value: event.address
        },
        name4: {
          value: event.nickName
        },
        thing6: {
          value: event.describe
        }
      },
      templateId: '6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0' //模板id
    })
    console.log(result)
    return result
  } catch (err) {
    console.log(err)
    return err
  }
}

================================================
FILE: cloudfunctions/sendMsg/package.json
================================================
{
  "name": "sendMsg",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "latest"
  }
}

================================================
FILE: cloudfunctions/sendTip/config.json
================================================
{
  "permissions": {
    "openapi": [
    ]
  }
}

================================================
FILE: cloudfunctions/sendTip/index.js
================================================
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
  try {
    const result = await cloud.openapi.subscribeMessage.send({
      touser: event.openid, //要推送给那个用户
      page: 'pages/index/index', //要跳转到那个小程序页面
      data: {//推送的内容
        thing1: {
          value: event.nickName
        },
        phrase2:{
          value: '申请聊天'
        },
        thing3:{
          value: event.tip
        }
      },
      templateId: 'XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q' //模板id
    })
    console.log(result)
    return result
  } catch (err) {
    console.log(err)
    return err
  }
}

================================================
FILE: cloudfunctions/sendTip/package.json
================================================
{
  "name": "sendTip",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "~2.2.0"
  }
}

================================================
FILE: miniprogram/app.js
================================================
const config = require("config.js");

App({
      openid: '',
      userinfo:'',
      roomlist:[],
      canReflect:true,
      onLaunch: function() {
            if (!wx.cloud) {
                  console.error('请使用 2.2.3 或以上的基础库以使用云能力')
            } else {
                  wx.cloud.init({
                       env: JSON.parse(config.data).env,
                        traceUser: true,
                  })
            }
           this.systeminfo=wx.getSystemInfoSync();
        
      }
})

================================================
FILE: miniprogram/app.json
================================================
{
  "cloud": true,
  "pages": [
    "pages/start/start",
    "pages/index/index",
    "pages/login/login",
    "pages/publish/publish",
    "pages/my/my",
    "pages/detail/detail",
    "pages/order/list/list",
    "pages/order/detail/detail",
    "pages/kefu/kefu",
    "pages/about/about",
    "pages/sell/list/list",
    "pages/sell/detail/detail",
    "pages/search/search",
    "pages/edit/edit",
    "pages/web/web",
    "pages/message/message",
    "pages/detail/room/room",
    "pages/use/use",
    "pages/help/help",
    "pages/appreciateCode/appreciateCode"
  ],
  "window": {
    "backgroundColor": "#fbbd08",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fbbd08",
    "navigationBarTitleText": "吉珠二手交易平台",
    "navigationBarTextStyle": "white"
  },
  "sitemapLocation": "sitemap.json",
  "tabBar": {
    "color": "#707070",
    "selectedColor": "#000000",
    "list": [{
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "/images/tabbar/home.png",
        "selectedIconPath": "/images/tabbar/home_on.png"
      },
      {
        "pagePath": "pages/publish/publish",
        "text": "发布",
        "iconPath": "/images/tabbar/publish.png",
        "selectedIconPath": "/images/tabbar/publish_on.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "/images/tabbar/my.png",
        "selectedIconPath": "/images/tabbar/my_on.png"
      }
    ]
  },
  "usingComponents": {
    "van-steps": "/vant/steps/index",
    "van-transition": "/vant/transition/index",
    "van-stepper": "/vant/stepper/index",
    "van-action-sheet": "/vant/action-sheet/index",
    "van-popup": "/vant/popup/index",
    "canvasdrawer": "/components/canvasdrawer/canvasdrawer",
    "tips": "components/add_tips/index",
    "welcome": "components/welcome/welcome",
    "van-dialog": "/vant/dialog/index",
    "van-button": "/vant/button/index",
    "van-picker": "/vant/picker/index",
    "van-icon": "/vant/icon/index",
    "van-uploader": "/vant/uploader/index",
    "van-checkbox": "/vant/checkbox/index",
    "van-checkbox-group": "/vant/checkbox-group/index",
    "van-divider": "/vant/divider/index",
    "van-notice-bar": "vant/notice-bar/index"
  }
}

================================================
FILE: miniprogram/app.wxss
================================================
page {
      background: #fff;
      width: 100%;
      height: 100%;
}

.shadow {
      box-shadow: 0 0 18rpx rgb(236, 236, 236);
}

.text-cut {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
}

.loadmore {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 30rpx 0;
}

.loadmore image {
      width: 50rpx;
      height: 50rpx;
}

.loadmore view {
      font-size: 28rpx;
      color: #b2b2b2;
      letter-spacing: 4rpx;
}
.totop {
      position: fixed;
      right: 30rpx;
      bottom: 80rpx;
}

.totop image {
      width: 100rpx;
      height: 100rpx;
      z-index: 9;
}

================================================
FILE: miniprogram/common.wxml
================================================
<template name="loadmore">
      <view class="loadmore">
            <image hidden="{{nomore}}" src="/images/more.gif"></image>
            <view hidden="{{!nomore}}">已加载到底</view>
      </view>
</template>

================================================
FILE: miniprogram/common.wxs
================================================
function commentTimeHandle(dateStr) {
      var publishTime = dateStr,
            date = getDate(publishTime), //获取dateStr的标准格式 console.log(date) 打印结果  Thu Sep 06 2018 18:47:00 GMT+0800 (中国标准时间)
            // 获取date 中的 年 月 日 时 分 秒
            Y = date.getFullYear(),
            M = date.getMonth() + 1,
            D = date.getDate(),
            H = date.getHours(),
            m = date.getMinutes(),
            s = date.getSeconds();
      // 对 月 日 时 分 秒 小于10时, 加0显示 例如: 09-09 09:01
      if (M < 10) {
            M = '0' + M;
      }
      if (D < 10) {
            D = '0' + D;
      }
      if (H < 10) {
            H = '0' + H;
      }
      if (m < 10) {
            m = '0' + m;
      }
      if (s < 10) {
            s = '0' + s;
      }
      var nowTime = getDate().getTime(), //获取此时此刻日期的秒数
            diffValue = (nowTime - publishTime) / 1000, // 获取此时 秒数 与 要处理的日期秒数 之间的差值
            diff_days = parseInt(diffValue / 86400), // 一天86400秒 获取相差的天数 取整
            diff_hours = parseInt(diffValue / 3600), // 一时3600秒
            diff_minutes = parseInt(diffValue / 60),
            diff_secodes = parseInt(diffValue);
      if (diff_days > 0 && diff_days < 3) { //相差天数 0 < diff_days < 3 时, 直接返出
            return diff_days + "天前";
      } else if (diff_days <= 0 && diff_hours > 0) {
            return diff_hours + "小时前";
      } else if (diff_hours <= 0 && diff_minutes > 0) {
            return diff_minutes + "分钟前";
      } else if (diff_secodes < 60) {
            if (diff_secodes <= 0) {
                  return "刚刚";
            } else {
                  return diff_secodes + "秒前";
            }
      } else if (diff_days >= 3 && diff_days < 30) {
            return M + '月' + D + '日';
      } else if (diff_days >= 30) {
            return M + '月' + D + '日';
      }
}
function format(dateStr) {
      var publishTime = dateStr,
            date = getDate(publishTime), //获取dateStr的标准格式 console.log(date) 打印结果  Thu Sep 06 2018 18:47:00 GMT+0800 (中国标准时间)
            // 获取date 中的 年 月 日 时 分 秒
            Y = date.getFullYear(),
            M = date.getMonth() + 1,
            D = date.getDate(),
            H = date.getHours(),
            m = date.getMinutes(),
            s = date.getSeconds();
      // 对 月 日 时 分 秒 小于10时, 加0显示 例如: 09-09 09:01
      if (M < 10) {
            M = '0' + M;
      }
      if (D < 10) {
            D = '0' + D;
      }
      if (H < 10) {
            H = '0' + H;
      }
      if (m < 10) {
            m = '0' + m;
      }
      if (s < 10) {
            s = '0' + s;
      }
      
       return Y+'-'+M+'-'+D+' '+H+':'+m
}
module.exports = {
      timelog: commentTimeHandle,
      format:format
}

================================================
FILE: miniprogram/components/add_tips/README.md
================================================
# add-tips
> **微信小程序UI插件**
> 用于提示用户首次进入小程序时,点击右上角菜单进行【添加到我的小程序】操作

## 文档
首先,把这个仓库下载/克隆到你的小程序目录,比如`/components/weplug-add-tips/`    
然后,在首页`index.json`配置文件中,引入该组件:
``` json
{
  "usingComponents": {
    "add-tips": "/components/weplug-add-tips/index"
  }
}
```
最后,在首页`index.wxml`文件中,调用该组件即可:
``` wxml
<add-tips />
```

## 参数
你可以传递两个参数进行自定义操作:

### 1. text:提示的文字内容
``` wxml
<add-tips text="点击添加到小程序" />
```

### 2. duration:提示关闭时间(单位秒)
``` wxml
<add-tips duration="10" />
```

<!-- ## 截图
![](https://i.loli.net/2019/03/29/5c9e0b1924201.png)

## 你也可以扫一扫小程序进行体验效果:
![](https://i.loli.net/2019/03/29/5c9e0b6bbd8f4.jpg) -->

================================================
FILE: miniprogram/components/add_tips/index.js
================================================
const STORAGE_KEY = 'PLUG-ADD-MYAPP-KEY';

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 提示文字
    text: {
      type: String,
      value: '点击「添加小程序」,下次访问更便捷 >'
    },
    // 多少秒后关闭
    duration: {
      type: Number,
      value: 5
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    SHOW_TOP: false,
    SHOW_MODAL: false
  },

  ready: function () {
    // 判断是否已经显示过
    let cache = wx.getStorageSync(STORAGE_KEY);
    if (cache) return;
    // 没显示过,则进行展示
    this.setData({
      SHOW_TOP: true
    });
    // 关闭时间
    setTimeout(() => {
      this.setData({
        SHOW_TOP: false
      })
    }, this.data.duration * 1000);
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 显示全屏添加说明
    showModal: function () {
      this.setData({
        SHOW_TOP: false,
        SHOW_MODAL: true
      });
    },

    okHandler: function () {
      this.setData({
        SHOW_MODAL: false
      });
      wx.setStorage({
        key: STORAGE_KEY,
        data: +new Date,
      });
    }
  }
})


================================================
FILE: miniprogram/components/add_tips/index.json
================================================
{
  "component": true,
  "usingComponents": {}
}

================================================
FILE: miniprogram/components/add_tips/index.wxml
================================================
<view class="box" wx:if="{{SHOW_TOP}}">
  <view class='arrow'></view>
  <view class='body' bindtap='showModal'>
    <text>{{text}}</text>
  </view>
</view>

<!-- modal -->
<view class='modal' wx:if="{{SHOW_MODAL}}">
  <view style='flex-direction: row;align-items:center;'>
    <text>1. 点击</text>
    <image src='./assets/fav-1.jpg' style='width:100px' mode="widthFix"></image>
  </view>
  <view>
    <text>2. 点击「添加到我的小程序」</text>
    <image src='./assets/fav-2.jpg' style='width:100%' mode="widthFix"></image>
  </view>
  <view>
    <text>3. 微信首页下拉,快速进入小程序</text>
    <image src='./assets/fav-3.jpg' style='width:100%' mode="widthFix"></image>
  </view>

  <!-- 知道了 -->
  <view class='ok-btn' hover-class='btn-hover' bindtap='okHandler'>
    <view>
      <text>我知道了!</text>
    </view>
  </view>
</view>

================================================
FILE: miniprogram/components/add_tips/index.wxss
================================================
.box {
  position: fixed;
  top: 0;
  /* left: 0; */
  right: 0;
  z-index: 999;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  flex-direction: column;
  width: 600rpx;
}
.arrow {
  width: 0;
  height: 0;
  margin-right: 120rpx;
  border-width: 20rpx;
  border-style: solid;
  border-color:  transparent transparent  #fbbd08;
}
.body {
  background-color:   #fbbd08;
  box-shadow: 0 10rpx 20rpx -10rpx   #fbbd08;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 84rpx;
  padding: 0 20rpx;
  margin-right: 40rpx;
}
.body > text {
  color: #FFF;
  font-size: 28rpx;
  font-weight: 400;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  background-color: rgba(255, 255, 255, 0.9);
  padding: 20px;
}
.modal > view {
  margin: 10px 0;
  display: flex;
  /* align-items: center; */
  flex-direction: column;
}
.modal > view > text {
  font-size: 16px;
  font-weight: 400;
  margin-bottom: 5px;
  color: #333;
}
.modal > view > image {
  border-radius: 10px;
}

.ok-btn {
  width: 100%;
  margin-top: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ok-btn > view {
  height: 40px;
  width: 120px;
  background-color:   #fbbd08;
  box-shadow: 0 5px 10px -px   #fbbd08;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 40px;
}
.ok-btn > view > text {
  font-size: 14px;
  color: #fff;
  font-weight: 400;
}
.btn-hover {
  opacity: 0.6;
}

================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.js
================================================
/* global Component wx */

Component({
  properties: {
    painting: {
      type: Object,
      value: {view: []},
      observer (newVal, oldVal) {
        if (!this.data.isPainting) {
          if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
            if (newVal && newVal.width && newVal.height) {
              this.setData({
                showCanvas: true,
                isPainting: true
              })
              this.readyPigment()
            }
          } else {
            if (newVal && newVal.mode !== 'same') {
              this.triggerEvent('getImage', {errMsg: 'canvasdrawer:samme params'})
            }
          }
        }
      }
    }
  },
  data: {
    showCanvas: false,

    width: 100,
    height: 100,

    tempFileList: [],

    isPainting: false
  },
  ctx: null,
  cache: {},
  ready () {
    wx.removeStorageSync('canvasdrawer_pic_cache')
    this.cache = wx.getStorageSync('canvasdrawer_pic_cache') || {}
    this.ctx = wx.createCanvasContext('canvasdrawer', this)
  },
  methods: {
    readyPigment () {
      const { width, height, views } = this.data.painting
      this.setData({
        width,
        height
      })

      const inter = setInterval(() => {
        if (this.ctx) {
          clearInterval(inter)
          this.ctx.clearActions()
          this.ctx.save()
          this.getImagesInfo(views)
        }
      }, 100)
    },
    getImagesInfo (views) {
      const imageList = []
      for (let i = 0; i < views.length; i++) {
        if (views[i].type === 'image') {
          imageList.push(this.getImageInfo(views[i].url))
        }
      }

      const loadTask = []
      for (let i = 0; i < Math.ceil(imageList.length / 8); i++) {
        loadTask.push(new Promise((resolve, reject) => {
          Promise.all(imageList.splice(i * 8, 8)).then(res => {
            resolve(res)
          }).catch(res => {
            reject(res)
          })
        }))
      }
      Promise.all(loadTask).then(res => {
        let tempFileList = []
        for (let i = 0; i < res.length; i++) {
          tempFileList = tempFileList.concat(res[i])
        }
        this.setData({
          tempFileList
        })
        this.startPainting()
      })
    },
    startPainting () {
      const { tempFileList, painting: { views } } = this.data
      console.log(tempFileList)
      for (let i = 0, imageIndex = 0; i < views.length; i++) {
        if (views[i].type === 'image') {
          this.drawImage({
            ...views[i],
            url: tempFileList[imageIndex]
          })
          imageIndex++
        } else if (views[i].type === 'text') {
          if (!this.ctx.measureText) {
            wx.showModal({
              title: '提示',
              content: '当前微信版本过低,无法使用 measureText 功能,请升级到最新微信版本后重试。'
            })
            this.triggerEvent('getImage', {errMsg: 'canvasdrawer:version too low'})
            return
          } else {
            this.drawText(views[i])
          }
        } else if (views[i].type === 'rect') {
          this.drawRect(views[i])
        }
      }
      this.ctx.draw(false, () => {
        wx.setStorageSync('canvasdrawer_pic_cache', this.cache)
        const system = wx.getSystemInfoSync().system
        if (/ios/i.test(system)) {
          this.saveImageToLocal()
        } else {
          // 延迟保存图片,解决安卓生成图片错位bug。
          setTimeout(() => {
            this.saveImageToLocal()
          }, 800)
        }
      })
    },
    drawImage (params) {
      this.ctx.save()
      const { url, top = 0, left = 0, width = 0, height = 0, borderRadius = 0, deg = 0 } = params
      // if (borderRadius) {
      //   this.ctx.beginPath()
      //   this.ctx.arc(left + borderRadius, top + borderRadius, borderRadius, 0, 2 * Math.PI)
      //   this.ctx.clip()
      //   this.ctx.drawImage(url, left, top, width, height)
      // } else {
      if (deg !== 0) {
        this.ctx.translate(left + width/2, top + height/2)
        this.ctx.rotate(deg * Math.PI / 180)
        this.ctx.drawImage(url, -width/2, -height/2, width, height)
      } else {
        this.ctx.drawImage(url, left, top, width, height)
      }
      // }
      this.ctx.restore()
    },
    drawText (params) {
      this.ctx.save()
      const {
        MaxLineNumber = 2,
        breakWord = false,
        color = 'black',
        content = '',
        fontSize = 16,
        top = 0,
        left = 0,
        lineHeight = 20,
        textAlign = 'left',
        width,
        bolder = false,
        textDecoration = 'none'
      } = params
      
      this.ctx.beginPath()
      this.ctx.setTextBaseline('top')
      this.ctx.setTextAlign(textAlign)
      this.ctx.setFillStyle(color)
      this.ctx.setFontSize(fontSize)

      if (!breakWord) {
        this.ctx.fillText(content, left, top)
        this.drawTextLine(left, top, textDecoration, color, fontSize, content)
      } else {
        let fillText = ''
        let fillTop = top
        let lineNum = 1
        for (let i = 0; i < content.length; i++) {
          fillText += [content[i]]
          if (this.ctx.measureText(fillText).width > width) {
            if (lineNum === MaxLineNumber) {
              if (i !== content.length) {
                fillText = fillText.substring(0, fillText.length - 1) + '...'
                this.ctx.fillText(fillText, left, fillTop)
                this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
                fillText = ''
                break
              }
            }
            this.ctx.fillText(fillText, left, fillTop)
            this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
            fillText = ''
            fillTop += lineHeight
            lineNum ++
          }
        }
        this.ctx.fillText(fillText, left, fillTop)
        this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
      }
      
      this.ctx.restore()

      if (bolder) {
        this.drawText({
          ...params,
          left: left + 0.3,
          top: top + 0.3,
          bolder: false,
          textDecoration: 'none' 
        })
      }
    },
    drawTextLine (left, top, textDecoration, color, fontSize, content) {
      if (textDecoration === 'underline') {
        this.drawRect({
          background: color,
          top: top + fontSize * 1.2,
          left: left - 1,
          width: this.ctx.measureText(content).width + 3,
          height: 1
        })
      } else if (textDecoration === 'line-through') {
        this.drawRect({
          background: color,
          top: top + fontSize * 0.6,
          left: left - 1,
          width: this.ctx.measureText(content).width + 3,
          height: 1
        })
      }
    },
    drawRect (params) {
      this.ctx.save()
      const { background, top = 0, left = 0, width = 0, height = 0 } = params
      this.ctx.setFillStyle(background)
      this.ctx.fillRect(left, top, width, height)
      this.ctx.restore()
    },
    getImageInfo (url) {
      return new Promise((resolve, reject) => {
        if (this.cache[url]) {
          resolve(this.cache[url])
        } else {
          const objExp = new RegExp(/^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/)
          if (objExp.test(url)) {
            wx.getImageInfo({
              src: url,
              complete: res => {
                if (res.errMsg === 'getImageInfo:ok') {
                  this.cache[url] = res.path
                  resolve(res.path)
                } else {
                  this.triggerEvent('getImage', {errMsg: 'canvasdrawer:download fail'})
                  reject(new Error('getImageInfo fail'))
                }
              }
            })
          } else {
            this.cache[url] = url
            resolve(url)
          }
        }
      })
    },
    saveImageToLocal () {
      const { width, height } = this.data
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width,
        height,
        canvasId: 'canvasdrawer',
        complete: res => {
          if (res.errMsg === 'canvasToTempFilePath:ok') {
            this.setData({
              showCanvas: false,
              isPainting: false,
              tempFileList: []
            })
            this.triggerEvent('getImage', {tempFilePath: res.tempFilePath, errMsg: 'canvasdrawer:ok'})
          } else {
            this.triggerEvent('getImage', {errMsg: 'canvasdrawer:fail'})
          }
        }
      }, this)
    }
  }
})


================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.json
================================================
{
  "component": true
}

================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.wxml
================================================
<canvas canvas-id="canvasdrawer" style="width:{{width}}px;height:{{height}}px;" class="board" wx:if="{{showCanvas}}"></canvas>

================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.wxss
================================================
.board {
  position: fixed;
  top: 2000rpx;
}

================================================
FILE: miniprogram/components/chatroom/chatroom.js
================================================
var time = require('../../utils/util.js');
const FATAL_REBUILD_TOLERANCE = 10
const SETDATA_SCROLL_TO_BOTTOM = {
  scrollTop: 100000,
  scrollWithAnimation: true,
}

Component({
  properties: {
    envId: String,
    collection: String,
    groupId: String,
    groupName: String,
    userInfo: Object,
    onGetUserInfo: {
      type: Function,
    },
    getOpenID: {
      type: Function,
    },
  },

  data: {
    chats: [],
    textInputValue: '',
    openId: '',
    scrollTop: 0,
    scrollToMessage: '',
    hasKeyboard: false,
  },

  methods: {
    onGetUserInfo(e) {
      this.properties.onGetUserInfo(e)
    },

    getOpenID() {
      return this.properties.getOpenID()
    },

    mergeCommonCriteria(criteria) {
      return {
        groupId: this.data.groupId,
        ...criteria,
      }
    },

    async initRoom() {
      this.try(async () => {
        await this.initOpenID()

        const {
          envId,
          collection
        } = this.properties
        const db = this.db = wx.cloud.database({
          env: envId,
        })
        const _ = db.command

        const {
          data: initList
        } = await db.collection(collection).where(this.mergeCommonCriteria()).orderBy('sendTimeTS', 'desc').get()

        console.log('init query chats', initList)

        this.setData({
          chats: initList.reverse(),
          scrollTop: 10000,
        })

        this.initWatch(initList.length ? {
          sendTimeTS: _.gt(initList[initList.length - 1].sendTimeTS),
        } : {})
      }, '初始化失败')
    },

    async initOpenID() {
      return this.try(async () => {
        const openId = await this.getOpenID()

        this.setData({
          openId,
        })
      }, '初始化 openId 失败')
    },

    async initWatch(criteria) {
      this.try(() => {
        const {
          collection
        } = this.properties
        const db = this.db
        const _ = db.command

        console.warn(`开始监听`, criteria)
        this.messageListener = db.collection(collection).where(this.mergeCommonCriteria(criteria)).watch({
          onChange: this.onRealtimeMessageSnapshot.bind(this),
          onError: e => {
            if (!this.inited || this.fatalRebuildCount >= FATAL_REBUILD_TOLERANCE) {
              this.showError(this.inited ? '监听错误,已断开' : '初始化监听失败', e, '重连', () => {
                this.initWatch(this.data.chats.length ? {
                  sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
                } : {})
              })
            } else {
              this.initWatch(this.data.chats.length ? {
                sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
              } : {})
            }
          },
        })
      }, '初始化监听失败')
    },

    onRealtimeMessageSnapshot(snapshot) {
      console.warn(`收到消息`, snapshot)

      if (snapshot.type === 'init') {
        this.setData({
          chats: [
            ...this.data.chats,
            ...[...snapshot.docs].sort((x, y) => x.sendTimeTS - y.sendTimeTS),
          ],
        })
        this.scrollToBottom()
        this.inited = true
      } else {
        let hasNewMessage = false
        let hasOthersMessage = false
        const chats = [...this.data.chats]
        for (const docChange of snapshot.docChanges) {
          switch (docChange.queueType) {
            case 'enqueue': {
              hasOthersMessage = docChange.doc._openid !== this.data.openId
              const ind = chats.findIndex(chat => chat._id === docChange.doc._id)
              if (ind > -1) {
                if (chats[ind].msgType === 'image' && chats[ind].tempFilePath) {
                  chats.splice(ind, 1, {
                    ...docChange.doc,
                    tempFilePath: chats[ind].tempFilePath,
                  })
                } else chats.splice(ind, 1, docChange.doc)
              } else {
                hasNewMessage = true
                chats.push(docChange.doc)
              }
              break
            }
          }
        }
        this.setData({
          chats: chats.sort((x, y) => x.sendTimeTS - y.sendTimeTS),
        })
        if (hasOthersMessage || hasNewMessage) {
          this.scrollToBottom()
        }
      }
    },

    async onConfirmSendText(e) {
      this.try(async () => {
        if (!e.detail.value) {
          return
        }

        const {
          collection
        } = this.properties
        const db = this.db
        const _ = db.command

        const doc = {
          _id: `${Math.random()}_${Date.now()}`,
          groupId: this.data.groupId,
          avatar: this.data.userInfo.avatarUrl,
          nickName: this.data.userInfo.nickName,
          msgType: 'text',
          textContent: e.detail.value,
          sendTime: new Date(),
          sendTimeTS: time.formatTime(new Date(),'Y/M/D h:m:s'), // fallback
        }

        this.setData({
          textInputValue: '',
          chats: [
            ...this.data.chats,
            {
              ...doc,
              _openid: this.data.openId,
              writeStatus: 'pending',
            },
          ],
        })
        this.scrollToBottom(true)

        await db.collection(collection).add({
          data: doc,
        })


        this.setData({
          chats: this.data.chats.map(chat => {
            if (chat._id === doc._id) {
              return {
                ...chat,
                writeStatus: 'written',
              }
            } else return chat
          }),
        })


      }, '发送文字失败')

    },

    async onChooseImage(e) {
      wx.chooseImage({
        count: 1,
        sourceType: ['album', 'camera'],
        success: async res => {
          const {
            envId,
            collection
          } = this.properties
          const doc = {
            _id: `${Math.random()}_${Date.now()}`,
            groupId: this.data.groupId,
            avatar: this.data.userInfo.avatarUrl,
            nickName: this.data.userInfo.nickName,
            msgType: 'image',
            sendTime: new Date(),
            sendTimeTS: time.formatTime(new Date(),'Y/M/D h:m:s'), // fallback
          }

          this.setData({
            chats: [
              ...this.data.chats,
              {
                ...doc,
                _openid: this.data.openId,
                tempFilePath: res.tempFilePaths[0],
                writeStatus: 0,
              },
            ]
          })
          this.scrollToBottom(true)

          const uploadTask = wx.cloud.uploadFile({
            cloudPath: `${this.data.openId}/${Math.random()}_${Date.now()}.${res.tempFilePaths[0].match(/\.(\w+)$/)[1]}`,
            filePath: res.tempFilePaths[0],
            config: {
              env: envId,
            },
            success: res => {
              this.try(async () => {
                await this.db.collection(collection).add({
                  data: {
                    ...doc,
                    imgFileID: res.fileID,
                  },
                })
              }, '发送图片失败')
            },
            fail: e => {
              this.showError('发送图片失败', e)
            },
          })

          uploadTask.onProgressUpdate(({
            progress
          }) => {
            this.setData({
              chats: this.data.chats.map(chat => {
                if (chat._id === doc._id) {
                  return {
                    ...chat,
                    writeStatus: progress,
                  }
                } else return chat
              })
            })
          })
        },
      })
    },

    onMessageImageTap(e) {
      wx.previewImage({
        urls: [e.target.dataset.fileid],
      })
    },

    scrollToBottom(force) {
      if (force) {
        console.log('force scroll to bottom')
        this.setData(SETDATA_SCROLL_TO_BOTTOM)
        return
      }

      this.createSelectorQuery().select('.body').boundingClientRect(bodyRect => {
        this.createSelectorQuery().select(`.body`).scrollOffset(scroll => {
          if (scroll.scrollTop + bodyRect.height * 3 > scroll.scrollHeight) {
            console.log('should scroll to bottom')
            this.setData(SETDATA_SCROLL_TO_BOTTOM)
          }
        }).exec()
      }).exec()
    },

    async onScrollToUpper() {
      if (this.db && this.data.chats.length) {
        const {
          collection
        } = this.properties
        const _ = this.db.command
        const {
          data
        } = await this.db.collection(collection).where(this.mergeCommonCriteria({
          sendTimeTS: _.lt(this.data.chats[0].sendTimeTS),
        })).orderBy('sendTimeTS', 'desc').get()
        this.data.chats.unshift(...data.reverse())
        this.setData({
          chats: this.data.chats,
          scrollToMessage: `item-${data.length}`,
          scrollWithAnimation: false,
        })
      }
    },

    async try (fn, title) {
      try {
        await fn()
      } catch (e) {
        this.showError(title, e)
      }
    },

    showError(title, content, confirmText, confirmCallback) {
      console.error(title, content)
      wx.showModal({
        title,
        content: content.toString(),
        showCancel: confirmText ? true : false,
        confirmText,
        success: res => {
          res.confirm && confirmCallback()
        },
      })
    },
  },

  ready() {
    global.chatroom = this
    this.initRoom()
    this.fatalRebuildCount = 0
  },
})

================================================
FILE: miniprogram/components/chatroom/chatroom.json
================================================
{
  "component": true,
  "usingComponents": {

  }
}

================================================
FILE: miniprogram/components/chatroom/chatroom.wxml
================================================
<view class="chatroom">
	<!-- chats -->
	<scroll-view class="body" scroll-y scroll-with-animation="{{scrollWithAnimation}}" scroll-top="{{scrollTop}}" scroll-into-view="{{scrollToMessage}}" bindscrolltoupper="onScrollToUpper">
		<view wx:for="{{chats}}" wx:key="{{item._id}}" id="item-{{index}}" class="message {{openId == item._openid ? 'message__self' : ''}}">
			<image class="avatar" src="{{item.avatar}}" mode="scaleToFill"></image>
			<view class="main">
				<view class="nickname">{{item.nickName}}</view>
				<block wx:if="{{item.msgType === 'image'}}">
					<view class="image-wrapper">
						<view class="loading" wx:if="{{item.writeStatus > -1}}">{{item.writeStatus}}%</view>
						<image src="{{item.tempFilePath || item.imgFileID}}" data-fileid="{{item.tempFilePath || item.imgFileID}}" class="image-content" style="{{item.imgStyle}}" mode="scallToFill" bindtap="onMessageImageTap"></image>
					</view>
					<view class="time">{{item.sendTimeTS}}</view>
				</block>
				<block wx:else>
					<view class="text-wrapper">
						<view class="loading" wx:if="{{item.writeStatus === 'pending'}}">···</view>
						<view class="text-content">{{item.textContent}}</view>
					</view>
					<view class="time">{{item.sendTimeTS}}</view>
				</block>
			</view>
		</view>
	</scroll-view>

	<!-- message sender -->
	<view class="footer">
		<view class="message-sender" wx:if="{{userInfo}}">

			<image src="./photo.png" class="btn-send-image" mode="scaleToFill" bindtap="onChooseImage"></image>
			<input class="text-input" type="text" confirm-type="send" bindconfirm="onConfirmSendText" cursor-spacing="20" value="{{textInputValue}}"></input>


		</view>

		<view class="message-sender" wx:if="{{!userInfo}}">
			<button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo" class="userinfo">请先登录后参与聊天</button>
		</view>
	</view>

</view>

================================================
FILE: miniprogram/components/chatroom/chatroom.wxss
================================================
.chatroom {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}
/* .chatroom .header {
  flex-basis: fit-content;
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #ddd;
  margin-top: -25px;
  padding: 20rpx 0 30rpx;
  font-size:25 rpx;
} */

.chatroom .header .left {
  flex: 1;
}

.chatroom .header .middle {
  flex: 2;
  text-align: center;
}

.chatroom .header .right {
  flex: 1;
}

.chatroom .body {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: rgb(237,237,237);
  padding-bottom: 16rpx;
}

.body .message {
  display: flex;
  flex-direction: row;
  position: relative;
  margin: 12rpx 0;
}

.body .message.message__self {
  flex-direction: row-reverse;
}

.body .message .avatar {
  position: relative;
  top: 5rpx;
  width: 60rpx;
  height: 60rpx;
  border-radius: 5rpx;
  margin: 15rpx;
}

.body .message .main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.body .message.message__self .main {
  align-items: flex-end;
}

.body .message .nickname {
  font-size: 24rpx;
  color: #444;
}
.body .message .time {
  font-size: 24rpx;
  color: #444;
}

.body .message .text-content {
  border: 1px solid transparent;
  border-radius: 3px;
  background-color: #fff;
  margin: 2px 0 0 0;
  padding: 4px 10px;
  font-size: 30rpx;
  display: inline-block;
}

.body .message.message__self .text-content {
  background-color: paleturquoise;
}

.body .message .text-wrapper {
  display: flex;
  flex-direction: row;
  align-items: center;
  max-width: 80%;
}

.body .message.message__self .text-wrapper .loading{
  font-size: 16rpx;
  margin-right: 18rpx;
}

.body .message .image-wrapper {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.body .message .image-content {
  max-width: 240rpx;
  max-height: 240rpx;
}

.body .message.message__self .image-wrapper .loading {
  font-size: 20rpx;
  margin-right: 18rpx;
}

.chatroom .footer {
  flex-basis: fit-content;
  display: flex;
  flex-direction: row;
  border-top: 1px solid #ddd;
  font-size: 10rpx;
  padding: 20rpx 30rpx;
  background: rgb(246,246,246);
}

.chatroom .footer .message-sender {
  flex: 1;
  display: flex;
  flex-direction: row;
}

.message-sender .text-input {
  flex: 1;
  font-size: 16px;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 3px 6px;
  margin: 0 10px 0 5px;
  background: #fff;
}

.message-sender .btn-send-image {
  width: 50rpx;
  height: 50rpx;
  align-self: center;
}

button {
  font-size: 30rpx;
}

button.userinfo {
  background: darkturquoise;
  color: aliceblue;
  padding: 0 100rpx;
  border: 1px solid #ddd;
  border-radius: 20px;
}


================================================
FILE: miniprogram/components/welcome/welcome.js
================================================
const STORAGE1_KEY = 'PLUG-WELCOME-MYAPP-KEY';

Component({
  /**
   * 组件的属性列表
   */
  // properties: {
  //   // 提示文字
  //   text: {
  //     type: String,
  //     value: '点击「添加小程序」,下次访问更便捷 >'
  //   },
  //   // 多少秒后关闭
  //   duration: {
  //     type: Number,
  //     value: 5
  //   }
  // },

  /**
   * 组件的初始数据
   */
  data: {
    SHOW_MODAL:false
  },

  ready: function () {
    // 判断是否已经显示过
    let cache = wx.getStorageSync(STORAGE1_KEY);
    if (cache) return;
    // 没显示过,则进行展示
    this.setData({
      SHOW_MODAL: true
    });
    this.showModal();
  
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 显示全屏添加说明
    showModal: function () {
      this.setData({
        SHOW_MODAL: true
      });
    },

    okHandler: function () {
      this.setData({
        SHOW_MODAL: false
      });
      wx.setStorage({
        key: STORAGE1_KEY,
        data: +new Date,
      });
      wx.requestSubscribeMessage({
        tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0','XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
        success(res) {          
              console.log('授权成功', res)
        },
        fail(res) {
              console.log('授权失败', res)
        }
  })
      wx.navigateTo({
        url: '/pages/help/help',
      })
    }
  },
  
})


================================================
FILE: miniprogram/components/welcome/welcome.json
================================================
{
  "component": true,
  "usingComponents": {}
}

================================================
FILE: miniprogram/components/welcome/welcome.wxml
================================================
<!-- modal -->
<view class='modal' wx:if="{{SHOW_MODAL}}">
  <view style='flex-direction: row;align-items:center;'>
    <text class="font">1. 欢迎来到 易珠 小程序,感谢您的使用</text>  
  </view>
  <view >
    <text class="font">2.同学们使用前可在(我的—用户手册)页面查看小程序使用详情,注册时请点击授权接受服务通知(并点击不在询问)以便能及时接收到信息 </text>
    <image src='./assets/about_2.jpg' style='width:110px;flex-direction: row;align-items:center;' mode="widthFix"></image>
  </view>
  <view>
    <text class="font">3. 关于为什么有广告出现问题,可在 (我的—使用说明) 页面处了解,感谢您的理解!</text>
    <image src='./assets/ad_1.jpg' style='width:100%' mode="widthFix"></image>
    <image src='./assets/about.jpg' style='width:100%' mode="widthFix"></image>
  </view>

  <!-- 知道了 -->
  <view class='ok-btn' hover-class='btn-hover' bindtap='okHandler'>
    <view>
      <text>现在去康康>></text>
    </view>
  </view>
</view>

================================================
FILE: miniprogram/components/welcome/welcome.wxss
================================================
/* components/welcome.wxss */
.box {
  position: fixed;
  top: 0;
  /* left: 0; */
  right: 0;
  z-index: 999;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  flex-direction: column;
  width: 600rpx;
}
.arrow {
  width: 0;
  height: 0;
  margin-right: 120rpx;
  border-width: 20rpx;
  border-style: solid;
  border-color:  transparent transparent  #fbbd08;
}
.body {
  background-color:   #fbbd08;
  box-shadow: 0 10rpx 20rpx -10rpx   #fbbd08;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 84rpx;
  padding: 0 20rpx;
  margin-right: 40rpx;
}
.body > text {
  color: #FFF;
  font-size: 28rpx;
  font-weight: 400;
}
.font{
  size: 20px;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  background-image: linear-gradient(to top, #dfe9f3 0%, white 100%);
  padding: 10px;
}
.modal > view {
  margin: 10px 0;
  display: flex;
  /* align-items: center; */
  flex-direction: column;
}
.modal > view > text {
  font-size: 16px;
  font-weight: 400;
  margin-bottom: 5px;
  color: rgb(7, 7, 7);
}
.modal > view > image {
  border-radius: 10px;
}

.ok-btn {
  width: 100%;
  margin-top: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ok-btn > view {
  height: 40px;
  width: 120px;
  background-color:   #fbbd08;
  box-shadow: 0 5px 10px -px   #fbbd08;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 40px;
}
.ok-btn > view > text {
  font-size: 14px;
  color: #fff;
  font-weight: 400;
}
.btn-hover {
  opacity: 0.6;
}

================================================
FILE: miniprogram/config.js
================================================
var data = {
      //云开发环境id
      env: 'taoshaoji-46f0r',
      //分享配置
      share_title: '吉珠二手交易平台',
      share_img: '/images/poster.jpg', //可以是网络地址,本地文件路径要填绝对位置
      share_poster:'https://s2.ax1x.com/2019/11/20/Mhpqmt.png',//必须为网络地址
      //客服联系方式
      kefu: {
            qq: '859162716',
            weixin:'ttao527'
      },
      //默认启动页背景图,防止请求失败完全空白 
      //可以是网络地址,本地文件路径要填绝对位置
      bgurl: '',
      //校区
      campus: [{
                  name: '竹园',
                  id: 0
            },
            {
                  name: '康园',
                  id: 1
            },
            {
                  name: '松园',
                  id: 2
            },
            {
                  name: '桂园',
                  id: 3
            },
            {
                  name: '梅园',
                  id: 4
            },
            {
                  name: '榕园',
                  id: 5
            },
            {
                  name: '松园',
                  id: 6
            },

      ],
      //配置学院,建议不要添加太多,不然前端不好看
      college: [{
                  name: '通用',
                  id: -1
            },
            {
                  name: '学习用品',
                  id: 0
            },
            {
                  name: '日用品',
                  id: 1
            },
            {
                  name: '装饰品',
                  id: 2
            },
            {
                  name: '衣物',
                  id: 3
            },
            {
                  name: '运动器材',
                  id: 4
            },
            {
                  name: '化妆品',
                  id: 5
            },
            {
                  name: '其他',
                  id: 6
            },
      ],
}
//下面的就别动了
function formTime(creatTime) {
      let date = new Date(creatTime),
            Y = date.getFullYear(),
            M = date.getMonth() + 1,
            D = date.getDate(),
            H = date.getHours(),
            m = date.getMinutes(),
            s = date.getSeconds();
      if (M < 10) {
            M = '0' + M;
      }
      if (D < 10) {
            D = '0' + D;
      }
      if (H < 10) {
            H = '0' + H;
      }
      if (m < 10) {
            m = '0' + m;
      }
      if (s < 10) {
            s = '0' + s;
      }
      return Y + '-' + M + '-' + D + ' ' + H + ':' + m + ':' + s;
}

function days() {
      let now = new Date();
      let year = now.getFullYear();
      let month = now.getMonth() + 1;
      let day = now.getDate();
      if (month < 10) {
            month = '0' + month;
      }
      if (day < 10) {
            day = '0' + day;
      }
      let date = year + "" + month + day;
      return date;
}
module.exports = {
      data: JSON.stringify(data),
      formTime: formTime,
      days: days
}

================================================
FILE: miniprogram/pages/about/about.js
================================================
// pages/about/about.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    imgs1: [{
        url: 'tao.jpg',
        name: '是芒果千层呀',
        id: "0"
      },
      {
        url: 'chen.jpg',
        name: '楚利略',
        id: "1"
      },
    ],
    des: '随着人们节约环保的消费意识的增强,在商品极丰富的大学校园里,二手物品交易市场迅速发展。大学生的消费金额限制、其节约意识以及每年大量的新生入学和毕业生离校,给予大学二手交易市场巨大的发展空间。然而我们观察发现,当前校园内的二手交易市场缺乏一个可靠实用的校园交易平台。考虑到微信小程序,方便快捷即用即走,速度快,安全性强等的优点,我们选择它作为交易平台。\n注意:\n本微信小程序只是提供物品交易的平台,不涉及金钱交易!主要服务于大学校园的学生与教师。'
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 在页面中定义插屏广告
    let interstitialAd = null

    // 在页面onLoad回调事件中创建插屏广告实例
    if (wx.createInterstitialAd) {
      interstitialAd = wx.createInterstitialAd({
        adUnitId: 'adunit-dfbad1c323913ca2'
      })
      interstitialAd.onLoad(() => {})
      interstitialAd.onError((err) => {})
      interstitialAd.onClose(() => {})
    }

    // 在适合的场景显示插屏广告
    if (interstitialAd) {
      interstitialAd.show().catch((err) => {
        console.error(err)
      })
    }
  },
  
  //图片点击事件
  img: function (event) {
    let arr = [];
    arr.push('https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/appreciate-code/appreciateimg.jpg?sign=7a94d719f891a5b8838fae33a1b79d22&t=1597422871')
    wx.previewImage({
      current: 'current', // 当前显示图片的http链接
      urls: arr // 需要预览的图片http链接列表
    })
  },
  onReady: function () {

  },
  //复制
  copy(e) {
    wx.setClipboardData({
      data: e.currentTarget.dataset.copy,
      success: res => {
        wx.showToast({
          title: '复制' + e.currentTarget.dataset.name + '成功',
          icon: 'success',
          duration: 1000,
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

================================================
FILE: miniprogram/pages/about/about.json
================================================
{
  "usingComponents": {}
}

================================================
FILE: miniprogram/pages/about/about.wxml
================================================
<view class="title">开发:</view>
<view class="main">
	<view class="image">
		<view class="txt" wx:for="{{imgs1}}" wx:key="{{index}}">
			<image class="im" src="{{item.url}}" data-id="{{index}}"></image>
			<view class="t">
				{{item.name}}
			</view>
		</view>
	</view>
</view>
<view class="contain">
	<view class="title">程序简介</view>
	<view class="description">
		<text space="emsp" decode="{{ true }}">{{des}}</text>
	</view>
	<view class="title">打赏我们</view>
	<view class="description">
		<view class='imagesize'>
			<image src="https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/appreciate-code/appreciateimg.jpg?sign=7a94d719f891a5b8838fae33a1b79d22&t=1597422871" class='in-image' bindtap="img" />
		</view>
	</view>
	<view class="title">联系方式</view>
	<view class="description">
		<view class="tip" bindtap="copy" data-copy="拈花我把酒" data-name="微信公众号">
			<view>公众号</view>:
			<text>拈花我把酒</text>
		</view>
		<view class="tip" bindtap="copy" data-copy="859162716" data-name="QQ群">
			<view>QQ群</view>:
			<text>859162716</text>
		</view>
	</view>
</view>

================================================
FILE: miniprogram/pages/about/about.wxss
================================================
page {
      background: #eee;
}

.des_contain {
      width: 618rpx;
      height: 157rpx;
      border-radius: 10rpx;
      background: #fff;
      display: flex;
      box-sizing: border-box;
      flex-direction: column;
      justify-content: center;
      padding: 0 0 0 90rpx;
}

.imagesize {
      display: flex;
      justify-content: center;
}

.imagesize image {
      width: 400rpx;
      height: 400rpx;
}

.name {
      font-size: 36rpx;
      line-height: 50rpx;
}

.sign {
      margin-top: 10rpx;
      font-size: 28rpx;
      letter-spacing: 3rpx;
      line-height: 45rpx;
      color: #b8b8b8;
}

.avator_box {
      position: absolute;
      left: 0rpx;
      top: 0rpx;
      display: flex;
      padding: 44rpx 0 0 40rpx;
}

.avator {
      box-shadow: 0 0 10rpx #b8b8b8;
      width: 110rpx;
      height: 110rpx;
      border-radius: 20rpx;
}

.contain {
      width: 100%;
      background: #eee;
      display: flex;
      flex-direction: column;
      padding: 0 20rpx;
      box-sizing: border-box;
}

.title {
      margin-top: 20rpx;
      line-height: 45rpx;
      padding-left: 20rpx;
      font-size: 32rpx;
      letter-spacing: 3rpx;
      color: #000;
}

.description {
      width: 100%;
      padding: 24rpx 30rpx;
      background: #fff;
      border-radius: 10rpx;
      display: flex;
      box-sizing: border-box;
      flex-direction: column;
}

.description text {
      width: 100%;
      font-size: 28rpx;
      line-height: 44rpx;
      letter-spacing: 3rpx;
}

.tip {
      display: flex;
      align-items: center;
}

.tip view {
      font-size: 30rpx;
      letter-spacing: 2rpx;
      padding: 15rpx 0;
      width: 150rpx;
      display: flex;
      justify-content: space-between;
}

.tip text {
      margin-left: 20rpx;
      font-size: 28rpx;
      color: #008ecf;
      text-decoration-line: underline;
}

.main {
      background: #fff;
      margin: 0 3px;
      position: relative;
      padding: 4rpx 30px;
      color: #1c1111;
      font-size: 12px;
      display: flex;
}

.image {
      display: flex;
      flex-wrap: wrap;
}

.im {
      margin-left: 80rpx;
      margin-top: 35rpx;
      height: 145rpx;
      width: 145rpx;
      border-radius: 50%;
}

.txt {
      width: 230rpx;
      text-align: center
}

.t {
      margin-left: 26px;
      color: lightskyblue;
}

================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.js
================================================
const db = wx.cloud.database();
const app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    bigImg: '',
    isExist: Boolean, //如果存在的话就是真,不存在的话就是假
    openid: app.openid
  },
  onLoad() {
    this.getCodeFromSet()
  },

  getCodeFromSet() {
    let that = this;
    let openid = app.openid
    console.log(openid)
    db.collection('appreciatecode').where({
      _openid: openid,
    }).get().then(res => {
      if (res.data.length > 0) {
        that.setData({
          isExist: true,
          bigImg: res.data[0].bigImg
        })
        console.log(res.data[0].bigImg)
        console.log("isExist---->" + that.data.isExist)
      } else {
        that.setData({
          isExist: false,
        })
        console.log("isExist---->" + that.data.isExist)
      }
    })
  },


  changeBigImg() {
    let that = this;
    let openid = app.openid
    wx.chooseImage({
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        wx.showLoading({
          title: '上传中',
        });
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        let filePath = res.tempFilePaths[0];
        const name = Math.random() * 1000000;
        const cloudPath = 'appreciate-code/' + app.openid + '/' + name + filePath.match(/\.[^.]+?$/)[0]
        wx.cloud.uploadFile({
          cloudPath, //云存储图片名字
          filePath, //临时路径
          success: res => {
            console.log('[上传图片] 成功:', res)
            that.setData({
              bigImg: res.fileID, //云存储图片路径,可以把这个路径存到集合,要用的时候再取出来
            });
            let fileID = res.fileID;
            //把图片存到appreciatecode集合表
            const db = wx.cloud.database();
            if (that.data.isExist == false) {
              db.collection("appreciatecode").add({
                data: {
                  bigImg: fileID,
                },
                success: function () {
                  wx.showToast({
                    title: '赞赏码上传成功',
                    'icon': 'none',
                    duration: 3000
                  })
                  console.log("这里是第一次,用add")
                  that.setData({
                    isExist: true
                  })
                },
                fail: function () {
                  wx.showToast({
                    title: '赞赏码上传失败',
                    'icon': 'none',
                    duration: 3000
                  })
                }
              });
            } else {
              db.collection("appreciatecode").where({
                _openid: openid
              }).update({
                data: {
                  bigImg: fileID,
                },
                success: function () {
                  wx.showToast({
                    title: '赞赏码上传成功',
                    'icon': 'none',
                    duration: 3000
                  })
                  console.log("这里是第二次,用update")
                },
                fail: function () {
                  wx.showToast({
                    title: '赞赏码上传失败',
                    'icon': 'none',
                    duration: 3000
                  })
                }
              });
            }
          },
          fail: e => {
            console.error('[上传图片] 失败:', e)
          },
          complete: () => {
            wx.hideLoading()
          }
        });
      }
    })
  },
})

================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.json
================================================
{
  "usingComponents": {}
}

================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.wxml
================================================
<!-- <view wx:if='{{!isExist}}'>
	<image src='cloud://taoshaoji-46f0r.7461-taoshaoji-46f0r-1302243411/gzh/eg.jpeg' mode="aspectFit" class="image"></image>
</view>
<view wx:elif='{{isExist}}'>
	<image src='{{bigImg}}' mode="aspectFit" class="image"></image>
</view> -->
<view class="space"></view>
<view class='imagesize' wx:if='{{!isExist}}'>
  <image src='cloud://taoshaoji-46f0r.7461-taoshaoji-46f0r-1302243411/gzh/eg.jpeg' class='in-image'/>
</view>
<view class='imagesize' wx:if='{{isExist}}'>
  <image src='{{bigImg}}' class='in-image'/>
</view>

<view class="space"></view>
<button class="btn" style="width:60vw" bindtap='changeBigImg' size="default">{{(!isExist)?"上传赞赏码":"修改赞赏码"}}</button>


<view class="contain">
	<view class="title"><image class="about" src="/images/about.png" />上传申明</view>
	<view class="title">1、为什么要上传赞赏码?</view>
	<view class="description">
		<text space="emsp" decode="{{ true }}">因为微信小程序中无法识别收款码或者提供其它财产交易方式,所以我们采用小程序能够识别的赞赏码来进行付款交易</text>
	</view>
	<view class="title">2、如何获取付款码?</view>
	<view class="description">
		<text space="emsp" decode="{{ true }}">用户可以在微信中我的-支付-钱包中的收付款页面下方选项-赞赏码获取,然后保存赞赏码上传到本小程序中,便可实现在线交易。后续我们会努力拿到微信支付的接口权限,简化交易过程。</text>
	</view>
	<view class="title"><image class="about" src="/images/about.png" />作者声明</view>
	<view class="description">
		<text space="emsp" decode="{{ true }}">赞赏码的用途和收款码类似。只能用于收款,用户不用担心会因此产生不必要的财产损失。我们会将赞赏码附加于订单详情页,买家可以通过扫描赞赏码向卖家进行费用支付。\nTip:如果卖家不想上传赞赏码,可以在线下和买家进行沟通,面对面扫一扫交易也可。</text>
	</view>
	<view class="space"></view>
</view>

================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.wxss
================================================
page {
  background: #eee;
}

.imagesize {
  display: flex; 
  justify-content: center; 
}

.imagesize image {
  width: 400rpx;
  height: 400rpx;
}

.contain {
  width: 100%;
  background: #eee;
  display: flex;
  flex-direction: column;
  padding: 0 20rpx;
  box-sizing: border-box;
}

.btn {
  background-image: linear-gradient(-225deg, #9EFBD3 0%, #57E9F2 48%, #45D4FB 100%);
  margin-bottom: 20rpx;
  width: 100%;
  height: 100rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 100rpx;
  color: #fff;
  font-size: 40rpx;
  letter-spacing: 4rpx;
  border: none;
}

.shen_title {
  margin-top: 40rpx;
  font-size: 32rpx;
  letter-spacing: 2rpx;
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

.about {
  width: 32rpx;
  height: 32rpx;
  padding-right: 10rpx;
}

.title {
  margin-top: 20rpx;
  line-height: 56rpx;
  padding-left: 20rpx;
  font-size: 32rpx;
  letter-spacing: 3rpx;
  color: #000;
}

.description {
  width: 100%;
  padding: 24rpx 30rpx;
  background: #fff;
  border-radius: 10rpx;
  display: flex;
  box-sizing: border-box;
  flex-direction: column;
}

.description text {
  width: 100%;
  font-size: 28rpx;
  line-height: 44rpx;
  letter-spacing: 3rpx;
}

.space {
  width: 100%;
  height: 20rpx;
  background: #eee;
}

.nocontent {
  width: 100%;
  height: calc(100% - 400rpx);
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  box-sizing: border-box;
}

.image {
  display: flex;
  justify-content: center;
  align-items: center;
}

================================================
FILE: miniprogram/pages/detail/detail.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../config.js");
const _ = db.command;
let obj = ''
Page({

      /**
       * 页面的初始数据
       */
      data: {
            first_title: true,
            place: '',
            roomID: '',
            goodssaller: '',
            openid: '',
            imgs: [],
            isShow: true,
            status: 0,
            avatarUrl: '',
            buyerInfo: [],
            isExist: Boolean,
            address:''
      },
      onLoad(e) {
            obj = e;
            this.getuserdetail();
            this.data.id = e.scene;
            this.getPublish(e.scene);
            if (app.openid) {
                  this.setData({
                        openid: app.openid
                  })
            } else {
                  console.log("no openid");
                  wx.showModal({
                        title: '温馨提示',
                        content: '该功能需要注册方可使用,是否马上去注册',
                        success(res) {
                              if (res.confirm) {
                                    wx.navigateTo({
                                          url: '/pages/login/login',
                                    })
                              }
                        }
                  })
                  return false
            }
            this.getBuyer(this.data.openid)
            wx.showShareMenu({
                  withShareTicket: true,
                  menus: ['shareAppMessage', 'shareTimeline']
            })
      },

      //获取买家信息
      getBuyer(m) {
            let that = this;
            db.collection('user').where({
                  _openid: m
            }).get({
                  success: function (res) {
                        wx.hideLoading();
                        that.setData({
                              buyerInfo: res.data[0]
                        })
                  }
            })
      },

      goo(e) {
            var myid = this.data.openid;
            var sallerid = this.data.goodssaller;
            wx.cloud.init({
                  env: 'taoshaoji-46f0r',
                  traceUser: true
            });
            //初始化数据库
            const db = wx.cloud.database();
            if (myid != sallerid) {
                  db.collection('rooms').where({
                        p_b: myid,
                        p_s: sallerid
                  }).get().then(res => {
                        console.log(res.data);
                        if (res.data.length > 0) {
                              this.setData({
                                    roomID: res.data[0]._id
                              })
                              db.collection("rooms").doc(res.data[0]._id).update({
                                    data: {
                                      deleted:0
                                    },
                                  }),
                              wx.navigateTo({
                                    url: 'room/room?id=' + this.data.roomID,
                              })
                        } else {
                              db.collection('rooms').add({
                                    data: {
                                          p_b: myid,
                                          p_s: sallerid,
                                          deleted:0
                                    },
                              }).then(res => {
                                    console.log(res)
                                    this.setData({
                                          roomID: res._id
                                    })
                                    wx.navigateTo({
                                          url: 'room/room?id=' + this.data.roomID,
                                    })
                              })
                        }
                  })
            } else {
                  wx.showToast({
                        title: '无法和自己建立聊天',
                        icon: 'none',
                        duration: 1500
                  })
            }
      },


      changeTitle(e) {
            let that = this;
            that.setData({
                  first_title: e.currentTarget.dataset.id
            })
      },
      //获取发布信息
      getPublish(e) {
            let that = this;
            db.collection('publish').doc(e).get({
                  success: function (res) {
                        that.setData({
                              collegeName: JSON.parse(config.data).college[parseInt(res.data.collegeid) + 1],
                              publishinfo: res.data
                        })
                        that.getSeller(res.data._openid)
                  }
            })
      },
      //获取卖家信息
      getSeller(m, n) {
            let that = this;
            db.collection('user').where({
                  _openid: m
            }).get({
                  success: function (res) {
                        console.log(res.data[0]._openid);
                        that.setData({
                              userinfo: res.data[0],
                              goodssaller: res.data[0]._openid
                        })
                        that.getBook(n)
                  }
            })
      },
      //回到首页
      home() {
            wx.switchTab({
                  url: '/pages/index/index',
            })
      },
      //回到我的
      my() {
            wx.switchTab({
                  url: '/pages/my/my',
            })
      },
      //购买检测
      buy() {
            var myid = this.data.openid;
            var sallerid = this.data.goodssaller;
            let that = this;
            if (myid == sallerid) {
                  wx.showToast({
                        title: '自己买不了自己的噢!',
                        icon: 'none',
                        duration: 1500
                  })
                  return false
            }
            if (!app.openid) {
                  wx.showModal({
                        title: '温馨提示',
                        content: '该功能需要注册方可使用,是否马上去注册',
                        success(res) {
                              if (res.confirm) {
                                    wx.navigateTo({
                                          url: '/pages/login/login',
                                    })
                              }
                        }
                  })
                  return false
            }
            if (that.data.publishinfo.deliveryid == 1) {
                  if (that.data.place == '') {
                        wx.hideLoading();
                        wx.showToast({
                              title: '请输入您的收货地址',
                              icon: 'none'
                        })
                        return false
                  }
            }
            that.getStatus();
      },
      //获取订单状态
      getStatus() {
            let that = this;
            let _id = that.data.publishinfo._id;
            console.log(_id);
            db.collection('publish').doc(_id).get({
                  success(e) {
                        if (e.data.status == 0) {
                              that.creatOrder(_id);
                        }
                        if (e.data.status == 1) {
                              wx.showToast({
                                    title: '该物品刚刚被抢光了~',
                                    icon: 'none'
                              })
                        }
                        if (e.data.status == 2) {
                              wx.showToast({
                                    title: '该物品已出售',
                                    icon: 'none'
                              })
                        }
                        if (e.data.status == 3) {
                              wx.showToast({
                                    title: '该物品已下架',
                                    icon: 'none'
                              })
                        }
                  }
            })
      },
      //创建订单
      creatOrder(iid) {
            let that = this;

            db.collection('order').where({
                  _id: iid
            }).get().then(res => {
                  console.log(res.data);
                  if (res.data.length > 0) {
                        that.setData({
                              isExist: true
                        })
                        console.log("isExist:" + that.data.isExist)
                  } else {
                        that.setData({
                              isExist: false
                        })
                        console.log("isExist:" + that.data.isExist)
                  }
            })

            wx.showModal({
                  title: '确认提示',
                  content: '是否确认下单购买此商品?',
                  success(res) {
                        if (res.confirm) {
                              if (!that.data.isExist) {
                                    wx.cloud.callFunction({
                                          // 云函数名称
                                          name: 'node',
                                          // 传给云函数的参数
                                          data: {
                                                _id: iid,
                                                status: 1
                                          },
                                          success: function (res) {
                                                console.log(res)
                                          },
                                          fail: console.error
                                    })
                                    wx.getUserInfo({
                                          success: function (res) {
                                                that.setData({
                                                      buyerName: res.userInfo.nickName,
                                                      avatarUrl: res.userInfo.avatarUrl,
                                                })
                                          },
                                          fail(){
                                                console.log("调用getUserinfo失败")
                                          }
                                    })
                                    db.collection('publish').doc({
                                          iid
                                    }).update({
                                          data: {
                                                status: 1
                                          },
                                          success() {
                                                wx.hideLoading();
                                                // that.getList();
                                                db.collection('order').add({
                                                      data: {
                                                            creat: new Date().getTime(),
                                                            status: 1, //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
                                                            price: that.data.publishinfo.price, //售价
                                                            deliveryid: that.data.publishinfo.deliveryid, //0自1配
                                                            ztplace: that.data.publishinfo.place, //自提时地址
                                                            psplace: that.data.place, //配送时买家填的地址
                                                            bookinfo: {
                                                                  describe: that.data.publishinfo.bookinfo.describe,
                                                                  pic: that.data.publishinfo.bookinfo.pic,
                                                                  good: that.data.publishinfo.bookinfo.good,
                                                            },
                                                            buyerInfo: that.data.buyerInfo,
                                                            seller: that.data.publishinfo._openid,
                                                            sellid: that.data.publishinfo._id,
                                                            _id: that.data.publishinfo._id,
                                                      },
                                                      success() {
                                                            that.getAddress()
                                                            that.send(that.data.goodssaller)
                                                            wx.showToast({
                                                                  title: '成功预订!',
                                                                  icon: 'success',
                                                                  duration: 3000
                                                            })
                                                            setTimeout(function () {
                                                                  wx.switchTab({
                                                                        url: '/pages/index/index',
                                                                  })
                                                            }, 3000)
                                                      },
                                                      fail() {
                                                            wx.hideLoading();
                                                            wx.showToast({
                                                                  title: '发生异常,请及时和管理人员联系处理',
                                                                  icon: 'none'
                                                            })
                                                      }
                                                })
                                          },
                                          fail() {
                                                wx.hideLoading();
                                                wx.showToast({
                                                      title: '操作失败',
                                                      icon: 'none'
                                                })
                                          }
                                    })
                                    that.onLoad(obj);
                              } else {
                                    wx.cloud.callFunction({
                                          // 云函数名称
                                          name: 'node',
                                          // 传给云函数的参数
                                          data: {
                                                _id: iid,
                                                status: 1
                                          },
                                          success: function (res) {
                                                console.log(res)
                                          },
                                          fail: console.error
                                    })
                                    db.collection('publish').doc({
                                          iid
                                    }).update({
                                          data: {
                                                status: 1
                                          },
                                          success() {
                                                wx.hideLoading();
                                                // that.getList();
                                                wx.cloud.callFunction({
                                                      // 云函数名称
                                                      name: 'pay',
                                                      // 传给云函数的参数
                                                      data: {
                                                            $url: "changeO", //云函数路由参数
                                                            _id: iid,
                                                            status: 1
                                                      },
                                                      success() {
                                                            that.getAddress()
                                                            that.send(that.data.goodssaller)
                                                            wx.showToast({
                                                                  title: '成功预订!',
                                                                  icon: 'success',
                                                                  duration: 3000
                                                            })
                                                      },
                                                      fail() {
                                                            wx.hideLoading();
                                                            wx.showToast({
                                                                  title: '发生异常,请及时和管理人员联系处理',
                                                                  icon: 'none'
                                                            })
                                                      }
                                                })
                                          },
                                          fail() {
                                                wx.hideLoading();
                          
Download .txt
gitextract_m91prd5v/

├── .gitignore
├── .vscode/
│   └── settings.json
├── README.md
├── cloudfunctions/
│   ├── his/
│   │   ├── index.js
│   │   └── package.json
│   ├── imgSecCheck/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── login/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── node/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── pay/
│   │   ├── index.js
│   │   └── package.json
│   ├── poking/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── ref/
│   │   ├── index.js
│   │   └── package.json
│   ├── regist/
│   │   ├── RdWXBizDataCrypt.js
│   │   ├── cryptojs/
│   │   │   ├── cryptojs.js
│   │   │   ├── lib/
│   │   │   │   ├── AES.js
│   │   │   │   ├── BlockModes.js
│   │   │   │   ├── Crypto.js
│   │   │   │   ├── CryptoMath.js
│   │   │   │   ├── DES.js
│   │   │   │   ├── HMAC.js
│   │   │   │   ├── MARC4.js
│   │   │   │   ├── MD5.js
│   │   │   │   ├── PBKDF2.js
│   │   │   │   ├── PBKDF2Async.js
│   │   │   │   ├── Rabbit.js
│   │   │   │   ├── SHA1.js
│   │   │   │   └── SHA256.js
│   │   │   ├── package.json
│   │   │   └── test/
│   │   │       └── PBKDF2-test.js
│   │   ├── index.js
│   │   └── package.json
│   ├── removeChat/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── removeOrder/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── sell/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   ├── sendMsg/
│   │   ├── config.json
│   │   ├── index.js
│   │   └── package.json
│   └── sendTip/
│       ├── config.json
│       ├── index.js
│       └── package.json
├── miniprogram/
│   ├── app.js
│   ├── app.json
│   ├── app.wxss
│   ├── common.wxml
│   ├── common.wxs
│   ├── components/
│   │   ├── add_tips/
│   │   │   ├── README.md
│   │   │   ├── index.js
│   │   │   ├── index.json
│   │   │   ├── index.wxml
│   │   │   └── index.wxss
│   │   ├── canvasdrawer/
│   │   │   ├── canvasdrawer.js
│   │   │   ├── canvasdrawer.json
│   │   │   ├── canvasdrawer.wxml
│   │   │   └── canvasdrawer.wxss
│   │   ├── chatroom/
│   │   │   ├── chatroom.js
│   │   │   ├── chatroom.json
│   │   │   ├── chatroom.wxml
│   │   │   └── chatroom.wxss
│   │   └── welcome/
│   │       ├── welcome.js
│   │       ├── welcome.json
│   │       ├── welcome.wxml
│   │       └── welcome.wxss
│   ├── config.js
│   ├── pages/
│   │   ├── about/
│   │   │   ├── about.js
│   │   │   ├── about.json
│   │   │   ├── about.wxml
│   │   │   └── about.wxss
│   │   ├── appreciateCode/
│   │   │   ├── appreciateCode.js
│   │   │   ├── appreciateCode.json
│   │   │   ├── appreciateCode.wxml
│   │   │   └── appreciateCode.wxss
│   │   ├── detail/
│   │   │   ├── detail.js
│   │   │   ├── detail.json
│   │   │   ├── detail.wxml
│   │   │   ├── detail.wxss
│   │   │   └── room/
│   │   │       ├── room.js
│   │   │       ├── room.json
│   │   │       ├── room.wxml
│   │   │       └── room.wxss
│   │   ├── edit/
│   │   │   ├── edit.js
│   │   │   ├── edit.json
│   │   │   ├── edit.wxml
│   │   │   └── edit.wxss
│   │   ├── help/
│   │   │   ├── help.js
│   │   │   ├── help.json
│   │   │   ├── help.wxml
│   │   │   └── help.wxss
│   │   ├── index/
│   │   │   ├── index.js
│   │   │   ├── index.json
│   │   │   ├── index.wxml
│   │   │   └── index.wxss
│   │   ├── kefu/
│   │   │   ├── kefu.js
│   │   │   ├── kefu.json
│   │   │   ├── kefu.wxml
│   │   │   └── kefu.wxss
│   │   ├── login/
│   │   │   ├── login.js
│   │   │   ├── login.json
│   │   │   ├── login.wxml
│   │   │   └── login.wxss
│   │   ├── message/
│   │   │   ├── message.js
│   │   │   ├── message.json
│   │   │   ├── message.wxml
│   │   │   └── message.wxss
│   │   ├── my/
│   │   │   ├── my.js
│   │   │   ├── my.json
│   │   │   ├── my.wxml
│   │   │   └── my.wxss
│   │   ├── order/
│   │   │   ├── detail/
│   │   │   │   ├── detail.js
│   │   │   │   ├── detail.json
│   │   │   │   ├── detail.wxml
│   │   │   │   └── detail.wxss
│   │   │   └── list/
│   │   │       ├── list.js
│   │   │       ├── list.json
│   │   │       ├── list.wxml
│   │   │       └── list.wxss
│   │   ├── publish/
│   │   │   ├── publish.js
│   │   │   ├── publish.json
│   │   │   ├── publish.wxml
│   │   │   └── publish.wxss
│   │   ├── search/
│   │   │   ├── search.js
│   │   │   ├── search.json
│   │   │   ├── search.wxml
│   │   │   └── search.wxss
│   │   ├── sell/
│   │   │   ├── detail/
│   │   │   │   ├── detail.js
│   │   │   │   ├── detail.json
│   │   │   │   ├── detail.wxml
│   │   │   │   └── detail.wxss
│   │   │   └── list/
│   │   │       ├── list.js
│   │   │       ├── list.json
│   │   │       ├── list.wxml
│   │   │       └── list.wxss
│   │   ├── start/
│   │   │   ├── start.js
│   │   │   ├── start.json
│   │   │   ├── start.wxml
│   │   │   └── start.wxss
│   │   ├── use/
│   │   │   ├── use.js
│   │   │   ├── use.json
│   │   │   ├── use.wxml
│   │   │   └── use.wxss
│   │   └── web/
│   │       ├── web.js
│   │       ├── web.json
│   │       ├── web.wxml
│   │       └── web.wxss
│   ├── sitemap.json
│   ├── utils/
│   │   └── util.js
│   └── vant/
│       ├── action-sheet/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── area/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── button/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── calendar/
│       │   ├── calendar.wxml
│       │   ├── components/
│       │   │   ├── header/
│       │   │   │   ├── index.d.ts
│       │   │   │   ├── index.js
│       │   │   │   ├── index.json
│       │   │   │   ├── index.wxml
│       │   │   │   └── index.wxss
│       │   │   └── month/
│       │   │       ├── index.d.ts
│       │   │       ├── index.js
│       │   │       ├── index.json
│       │   │       ├── index.wxml
│       │   │       ├── index.wxs
│       │   │       └── index.wxss
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   ├── index.wxss
│       │   ├── utils.d.ts
│       │   ├── utils.js
│       │   └── utils.wxs
│       ├── card/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── cell/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── cell-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── checkbox/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── checkbox-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── circle/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── col/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── collapse/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── collapse-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── common/
│       │   ├── color.d.ts
│       │   ├── color.js
│       │   ├── component.d.ts
│       │   ├── component.js
│       │   ├── index.wxss
│       │   ├── style/
│       │   │   ├── clearfix.wxss
│       │   │   ├── ellipsis.wxss
│       │   │   ├── hairline.wxss
│       │   │   ├── mixins/
│       │   │   │   ├── clearfix.wxss
│       │   │   │   ├── ellipsis.wxss
│       │   │   │   └── hairline.wxss
│       │   │   ├── theme.wxss
│       │   │   └── var.wxss
│       │   ├── utils.d.ts
│       │   ├── utils.js
│       │   ├── version.d.ts
│       │   └── version.js
│       ├── count-down/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── utils.d.ts
│       │   └── utils.js
│       ├── datetime-picker/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── definitions/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── weapp.d.ts
│       │   └── weapp.js
│       ├── dialog/
│       │   ├── dialog.d.ts
│       │   ├── dialog.js
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── divider/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── dropdown-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── dropdown-menu/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── field/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   ├── index.wxss
│       │   ├── props.d.ts
│       │   └── props.js
│       ├── goods-action/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── goods-action-button/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── goods-action-icon/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── grid/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── grid-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── icon/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── image/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── index-anchor/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── index-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── info/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── loading/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── mixins/
│       │   ├── basic.d.ts
│       │   ├── basic.js
│       │   ├── button.d.ts
│       │   ├── button.js
│       │   ├── link.d.ts
│       │   ├── link.js
│       │   ├── open-type.d.ts
│       │   ├── open-type.js
│       │   ├── page-scroll.d.ts
│       │   ├── page-scroll.js
│       │   ├── touch.d.ts
│       │   ├── touch.js
│       │   ├── transition.d.ts
│       │   └── transition.js
│       ├── nav-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── notice-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── notify/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── notify.d.ts
│       │   └── notify.js
│       ├── overlay/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── panel/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── picker/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── shared.d.ts
│       │   ├── shared.js
│       │   └── toolbar.wxml
│       ├── picker-column/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── popup/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── progress/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── radio/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── radio-group/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── rate/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── row/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── search/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sidebar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sidebar-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── skeleton/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── slider/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── stepper/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── steps/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── sticky/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── submit-bar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── swipe-cell/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── switch/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tab/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabbar/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabbar-item/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tabs/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── tag/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── toast/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── toast.d.ts
│       │   └── toast.js
│       ├── transition/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   └── index.wxss
│       ├── tree-select/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxs
│       │   └── index.wxss
│       ├── uploader/
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.json
│       │   ├── index.wxml
│       │   ├── index.wxss
│       │   ├── shared.d.ts
│       │   ├── shared.js
│       │   ├── utils.d.ts
│       │   └── utils.js
│       └── wxs/
│           ├── add-unit.wxs
│           ├── array.wxs
│           ├── bem.wxs
│           ├── memoize.wxs
│           ├── object.wxs
│           └── utils.wxs
└── project.config.json
Download .txt
SYMBOL INDEX (689 symbols across 112 files)

FILE: cloudfunctions/regist/RdWXBizDataCrypt.js
  function RdWXBizDataCrypt (line 5) | function RdWXBizDataCrypt(appId, sessionKey) {

FILE: cloudfunctions/regist/cryptojs/lib/AES.js
  function xtime (line 55) | function xtime(a, b) {

FILE: cloudfunctions/regist/cryptojs/lib/BlockModes.js
  function _requiredPadding (line 13) | function _requiredPadding(cipher, message) {

FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2.js
  function PRF (line 23) | function PRF(password, salt) {

FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2Async.js
  function fireProgressChange (line 36) | function fireProgressChange(currentIteration) {
  function PRF (line 46) | function PRF(password, salt) {

FILE: miniprogram/components/add_tips/index.js
  constant STORAGE_KEY (line 1) | const STORAGE_KEY = 'PLUG-ADD-MYAPP-KEY';

FILE: miniprogram/components/canvasdrawer/canvasdrawer.js
  method observer (line 8) | observer (newVal, oldVal) {
  method ready (line 39) | ready () {
  method readyPigment (line 45) | readyPigment () {
  method getImagesInfo (line 61) | getImagesInfo (views) {
  method startPainting (line 90) | startPainting () {
  method drawImage (line 128) | drawImage (params) {
  method drawText (line 147) | drawText (params) {
  method drawTextLine (line 212) | drawTextLine (left, top, textDecoration, color, fontSize, content) {
  method drawRect (line 231) | drawRect (params) {
  method getImageInfo (line 238) | getImageInfo (url) {
  method saveImageToLocal (line 264) | saveImageToLocal () {

FILE: miniprogram/components/chatroom/chatroom.js
  constant FATAL_REBUILD_TOLERANCE (line 2) | const FATAL_REBUILD_TOLERANCE = 10
  constant SETDATA_SCROLL_TO_BOTTOM (line 3) | const SETDATA_SCROLL_TO_BOTTOM = {
  method onGetUserInfo (line 33) | onGetUserInfo(e) {
  method getOpenID (line 37) | getOpenID() {
  method mergeCommonCriteria (line 41) | mergeCommonCriteria(criteria) {
  method initRoom (line 48) | async initRoom() {
  method initOpenID (line 78) | async initOpenID() {
  method initWatch (line 88) | async initWatch(criteria) {
  method onRealtimeMessageSnapshot (line 116) | onRealtimeMessageSnapshot(snapshot) {
  method onConfirmSendText (line 161) | async onConfirmSendText(e) {
  method onChooseImage (line 218) | async onChooseImage(e) {
  method onMessageImageTap (line 289) | onMessageImageTap(e) {
  method scrollToBottom (line 295) | scrollToBottom(force) {
  method onScrollToUpper (line 312) | async onScrollToUpper() {
  method try (line 332) | async try (fn, title) {
  method showError (line 340) | showError(title, content, confirmText, confirmCallback) {
  method ready (line 354) | ready() {

FILE: miniprogram/components/welcome/welcome.js
  constant STORAGE1_KEY (line 1) | const STORAGE1_KEY = 'PLUG-WELCOME-MYAPP-KEY';
  method success (line 60) | success(res) {
  method fail (line 63) | fail(res) {

FILE: miniprogram/config.js
  function formTime (line 83) | function formTime(creatTime) {
  function days (line 109) | function days() {

FILE: miniprogram/pages/about/about.js
  method copy (line 60) | copy(e) {

FILE: miniprogram/pages/appreciateCode/appreciateCode.js
  method onLoad (line 13) | onLoad() {
  method getCodeFromSet (line 17) | getCodeFromSet() {
  method changeBigImg (line 41) | changeBigImg() {

FILE: miniprogram/pages/detail/detail.js
  method onLoad (line 25) | onLoad(e) {
  method getBuyer (line 57) | getBuyer(m) {
  method goo (line 71) | goo(e) {
  method changeTitle (line 126) | changeTitle(e) {
  method getPublish (line 133) | getPublish(e) {
  method getSeller (line 146) | getSeller(m, n) {
  method home (line 162) | home() {
  method my (line 168) | my() {
  method buy (line 174) | buy() {
  method getStatus (line 213) | getStatus() {
  method creatOrder (line 244) | creatOrder(iid) {
  method send (line 420) | send(openid) {
  method go (line 441) | go(e) {
  method placeInput (line 447) | placeInput(e) {
  method getuserdetail (line 451) | getuserdetail() {
  method getAddress (line 492) | getAddress() {

FILE: miniprogram/pages/detail/room/room.js
  method onShareAppMessage (line 91) | onShareAppMessage() {
  method go (line 101) | go(){

FILE: miniprogram/pages/edit/edit.js
  method onChange (line 17) | onChange(event) {
  method choose (line 33) | choose(e) {
  method onLoad (line 41) | onLoad() {
  method getdetail (line 44) | getdetail() {
  method wxInput (line 72) | wxInput(e) {
  method qqInput (line 75) | qqInput(e) {
  method emInput (line 78) | emInput(e) {
  method getUserInfo (line 81) | getUserInfo(e) {
  method check (line 99) | check() {

FILE: miniprogram/pages/help/help.js
  method onReady (line 45) | onReady() {}
  method show (line 47) | show(e) {
  method go (line 61) | go(e) {
  method onLoad (line 66) | onLoad() {

FILE: miniprogram/pages/index/index.js
  method onLoad (line 35) | onLoad() {
  method listkind (line 50) | listkind() {
  method changeCard (line 67) | changeCard() {
  method search (line 88) | search() {
  method collegeSelect (line 94) | collegeSelect(e) {
  method selectAll (line 103) | selectAll() {
  method showlist (line 112) | showlist() {
  method getList (line 124) | getList() {
  method more (line 162) | more() {
  method onReachBottom (line 203) | onReachBottom() {
  method onPullDownRefresh (line 207) | onPullDownRefresh() {
  method gotop (line 210) | gotop() {
  method detail (line 216) | detail(e) {
  method getbanner (line 223) | getbanner() {
  method goweb (line 234) | goweb(e) {
  method onShareAppMessage (line 240) | onShareAppMessage() {
  method onShow (line 248) | onShow() {
  method getTip (line 254) | getTip() {

FILE: miniprogram/pages/kefu/kefu.js
  method onLoad (line 17) | onLoad() {
  method copy (line 22) | copy(e) {
  method preview (line 35) | preview(e) {

FILE: miniprogram/pages/login/login.js
  method onChange (line 18) | onChange(event) {
  method choose (line 35) | choose(e) {
  method wxInput (line 43) | wxInput(e) {
  method qqInput (line 46) | qqInput(e) {
  method emInput (line 49) | emInput(e) {
  method getUserInfo (line 52) | getUserInfo(e) {
  method check (line 71) | check() {
  method shouquan (line 164) | shouquan() {

FILE: miniprogram/pages/message/message.js
  method success (line 28) | success(res) {
  method init_charList (line 68) | init_charList() {
  method slideButtonTap (line 127) | slideButtonTap(e) {
  method findtime (line 163) | findtime() {
  method timesort (line 193) | timesort() {
  method changetime (line 210) | changetime() {
  method go (line 220) | go(e) {
  method onShow (line 225) | onShow() {
  method onPullDownRefresh (line 229) | onPullDownRefresh() {
  method getMyNickName (line 234) | getMyNickName() {
  method sendTip (line 249) | sendTip(e) {
  method onChange (line 282) | onChange() {

FILE: miniprogram/pages/my/my.js
  method onShow (line 15) | onShow() {
  method goo (line 26) | goo() {
  method go (line 48) | go(e) {
  method showShare (line 70) | showShare() {
  method closePop (line 76) | closePop() {
  method preview (line 82) | preview(e) {
  method onShareAppMessage (line 88) | onShareAppMessage() {
  method shouquan (line 114) | shouquan() {

FILE: miniprogram/pages/order/detail/detail.js
  method success (line 30) | success(res) {
  method home (line 44) | home() {
  method getdetail (line 50) | getdetail(_id) {
  method getSeller (line 69) | getSeller(m) {
  method getAddress (line 100) | getAddress() {
  method getBuyerInfo (line 112) | getBuyerInfo(){
  method send (line 122) | send() {
  method confirm (line 142) | confirm() {
  method delete (line 201) | delete() {
  method copy (line 228) | copy(e) {
  method history (line 241) | history(name, num, type) {
  method goo (line 258) | goo(e) {

FILE: miniprogram/pages/order/list/list.js
  method changeTab (line 35) | changeTab(e) {
  method godetail (line 43) | godetail(e) {
  method onShow (line 50) | onShow() {
  method onLoad (line 53) | onLoad() {
  method getlist (line 60) | getlist() {
  method getAddress (line 86) | getAddress() {
  method cancel (line 99) | cancel(ord) {
  method sendCancel (line 162) | sendCancel(openid) {
  method send (line 182) | send() {
  method onPullDownRefresh (line 203) | onPullDownRefresh() {
  method confirm (line 207) | confirm(ord) {
  method delete (line 265) | delete(ord) {
  method gotop (line 287) | gotop() {
  method onReachBottom (line 298) | onReachBottom() {
  method more (line 302) | more() {

FILE: miniprogram/pages/publish/publish.js
  constant MAX_IMG_NUM (line 4) | const MAX_IMG_NUM = 8;
  method initial (line 30) | initial() {
  method onLoad (line 75) | onLoad() {
  method onShow (line 80) | onShow() {
  method priceChange (line 84) | priceChange(e) {
  method duraChange (line 88) | duraChange(e) {
  method placeInput (line 92) | placeInput(e) {
  method goodInput (line 97) | goodInput(e) {
  method kindChange (line 102) | kindChange(e) {
  method choCollege (line 126) | choCollege(e) {
  method delChange (line 133) | delChange(e) {
  method noteInput (line 154) | noteInput(e) {
  method describeInput (line 162) | describeInput(e) {
  method check_pub (line 170) | check_pub() {
  method publish (line 195) | publish() {
  method getCodeFromSet (line 314) | getCodeFromSet() {
  method doUpload (line 336) | doUpload(filePath) {
  method deletePic (line 402) | deletePic(e) {
  method detail (line 422) | detail() {

FILE: miniprogram/pages/search/search.js
  method gethis (line 24) | gethis() {
  method choosekey (line 41) | choosekey(e) {
  method getnew (line 46) | getnew() {
  method detail (line 65) | detail(e) {
  method search (line 72) | search(n) {
  method onReachBottom (line 110) | onReachBottom() {
  method history (line 114) | history(key) {
  method keyInput (line 138) | keyInput(e) {
  method gotop (line 142) | gotop() {
  method more (line 154) | more() {

FILE: miniprogram/pages/sell/detail/detail.js
  method success (line 27) | success(res) {
  method home (line 41) | home() {
  method getdetail (line 47) | getdetail(_id) {
  method getSeller (line 66) | getSeller(m) {
  method confirm (line 81) | confirm() {
  method delete (line 151) | delete() {
  method copy (line 178) | copy(e) {
  method history (line 192) | history(name, num, type) {
  method goo (line 209) | goo(e) {

FILE: miniprogram/pages/sell/list/list.js
  method getBuyerInfo (line 33) | getBuyerInfo(orderid) {
  method getList (line 46) | getList() {
  method del (line 64) | del(e) {
  method crash (line 96) | crash(e) {
  method quxiao (line 132) | quxiao(e) {
  method getSellerInfo (line 188) | getSellerInfo() {
  method getAddress (line 202) | getAddress() {
  method sendCancel (line 215) | sendCancel(openid) {
  method wancheng (line 235) | wancheng(e) {
  method up (line 321) | up(e) {
  method detail (line 356) | detail(e) {
  method onPullDownRefresh (line 371) | onPullDownRefresh() {
  method gotop (line 375) | gotop() {
  method onReachBottom (line 386) | onReachBottom() {
  method more (line 390) | more() {
  method onShow (line 424) | onShow() {

FILE: miniprogram/pages/start/start.js
  method onLoad (line 14) | onLoad(){
  method go (line 19) | go() {
  method getuserdetail (line 38) | getuserdetail() {
  method getimg (line 63) | getimg() {

FILE: miniprogram/utils/util.js
  function formatTime (line 1) | function formatTime(date) {
  function formatNumber (line 14) | function formatNumber(n) {
  function formatTimeTwo (line 24) | function formatTimeTwo(number, format) {

FILE: miniprogram/vant/action-sheet/index.js
  method onSelect (line 41) | onSelect(event) {
  method onCancel (line 51) | onCancel() {
  method onClose (line 54) | onClose() {
  method onClickOverlay (line 57) | onClickOverlay() {

FILE: miniprogram/vant/area/index.js
  constant COLUMNSPLACEHOLDERCODE (line 3) | const COLUMNSPLACEHOLDERCODE = '000000';
  method observer (line 9) | observer(value) {
  method observer (line 22) | observer(value) {
  method observer (line 30) | observer(val) {
  method mounted (line 46) | mounted() {
  method getPicker (line 52) | getPicker() {
  method onCancel (line 58) | onCancel(event) {
  method onConfirm (line 61) | onConfirm(event) {
  method emit (line 67) | emit(type, detail) {
  method parseOutputValues (line 73) | parseOutputValues(values) {
  method onChange (line 86) | onChange(event) {
  method getConfig (line 97) | getConfig(type) {
  method getList (line 101) | getList(type, code) {
  method getIndex (line 134) | getIndex(type, code) {
  method setValues (line 149) | setValues() {
  method getValues (line 191) | getValues() {
  method getDetail (line 195) | getDetail() {
  method reset (line 219) | reset(code) {

FILE: miniprogram/vant/button/index.js
  method observer (line 44) | observer(color) {
  method onClick (line 66) | onClick() {
  method noop (line 71) | noop() {}

FILE: miniprogram/vant/calendar/components/month/index.js
  method onClick (line 46) | onClick(event) {
  method setDays (line 53) | setDays() {
  method getMultipleDayType (line 78) | getMultipleDayType(day) {
  method getRangeDayType (line 100) | getRangeDayType(day) {
  method getDayType (line 127) | getDayType(day) {
  method getBottomInfo (line 143) | getBottomInfo(type) {

FILE: miniprogram/vant/calendar/index.js
  method observer (line 23) | observer(val) {
  method observer (line 38) | observer(val) {
  method created (line 112) | created() {
  method mounted (line 117) | mounted() {
  method reset (line 124) | reset() {
  method initRect (line 128) | initRect() {
  method getInitialDate (line 145) | getInitialDate() {
  method scrollIntoView (line 159) | scrollIntoView() {
  method onOpen (line 184) | onOpen() {
  method onOpened (line 187) | onOpened() {
  method onClose (line 190) | onClose() {
  method onClosed (line 193) | onClosed() {
  method onClickDay (line 196) | onClickDay(event) {
  method unselect (line 233) | unselect(dateArray) {
  method select (line 239) | select(date, complete) {
  method emit (line 260) | emit(date) {
  method checkRange (line 267) | checkRange(date) {
  method onConfirm (line 278) | onConfirm() {

FILE: miniprogram/vant/calendar/utils.js
  constant ROW_HEIGHT (line 1) | const ROW_HEIGHT = 64;
  function formatMonthTitle (line 2) | function formatMonthTitle(date) {
  function compareMonth (line 8) | function compareMonth(date1, date2) {
  function compareDay (line 24) | function compareDay(day1, day2) {
  function getDayByOffset (line 39) | function getDayByOffset(date, offset) {
  function getPrevDay (line 44) | function getPrevDay(date) {
  function getNextDay (line 47) | function getNextDay(date) {
  function calcDateNum (line 50) | function calcDateNum(date) {
  function copyDates (line 55) | function copyDates(dates) {
  function getMonthEndDay (line 66) | function getMonthEndDay(year, month) {
  function getMonths (line 69) | function getMonths(minDate, maxDate) {

FILE: miniprogram/vant/card/index.js
  method updatePrice (line 37) | updatePrice() {
  method onClickThumb (line 45) | onClickThumb() {

FILE: miniprogram/vant/cell/index.js
  method onClick (line 32) | onClick(event) {

FILE: miniprogram/vant/checkbox-group/index.js
  method linked (line 8) | linked(target) {
  method updateChildren (line 24) | updateChildren() {
  method updateChild (line 27) | updateChild(child) {

FILE: miniprogram/vant/checkbox/index.js
  function emit (line 2) | function emit(target, value) {
  method emitChange (line 34) | emitChange(value) {
  method toggle (line 41) | toggle() {
  method onClickLabel (line 47) | onClickLabel() {
  method setParentValue (line 53) | setParentValue(parent, value) {

FILE: miniprogram/vant/circle/index.js
  function format (line 4) | function format(rate) {
  constant PERIMETER (line 7) | const PERIMETER = 2 * Math.PI;
  constant BEGIN_ANGLE (line 8) | const BEGIN_ANGLE = -Math.PI / 2;
  constant STEP (line 9) | const STEP = 1;
  method getContext (line 57) | getContext() {
  method setHoverColor (line 63) | setHoverColor() {
  method presetCanvas (line 78) | presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
  method renderLayerCircle (line 93) | renderLayerCircle(context) {
  method renderHoverCircle (line 97) | renderHoverCircle(context, formatValue) {
  method drawCircle (line 106) | drawCircle(currentValue) {
  method reRender (line 117) | reRender() {
  method clearInterval (line 139) | clearInterval() {
  method created (line 146) | created() {
  method destroyed (line 151) | destroyed() {

FILE: miniprogram/vant/col/index.js
  method setGutter (line 16) | setGutter(gutter) {

FILE: miniprogram/vant/collapse-item/index.js
  method mounted (line 32) | mounted() {
  method updateExpanded (line 44) | updateExpanded() {
  method updateStyle (line 63) | updateStyle(expanded) {
  method onClick (line 77) | onClick() {
  method onTransitionEnd (line 86) | onTransitionEnd() {

FILE: miniprogram/vant/collapse/index.js
  method updateExpanded (line 23) | updateExpanded() {
  method switch (line 28) | switch(name, expanded) {

FILE: miniprogram/vant/common/color.js
  constant RED (line 1) | const RED = '#ee0a24';
  constant BLUE (line 2) | const BLUE = '#1989fa';
  constant WHITE (line 3) | const WHITE = '#fff';
  constant GREEN (line 4) | const GREEN = '#07c160';
  constant ORANGE (line 5) | const ORANGE = '#ff976a';
  constant GRAY (line 6) | const GRAY = '#323233';
  constant GRAY_DARK (line 7) | const GRAY_DARK = '#969799';

FILE: miniprogram/vant/common/component.js
  method linked (line 4) | linked(parent) {
  method unlinked (line 7) | unlinked() {
  method linked (line 12) | linked(child) {
  method unlinked (line 16) | unlinked(child) {
  function mapKeys (line 21) | function mapKeys(source, target, map) {
  function makeRelation (line 28) | function makeRelation(options, vantOptions, relation) {
  function VantComponent (line 58) | function VantComponent(vantOptions = {}) {

FILE: miniprogram/vant/common/utils.js
  function isDef (line 1) | function isDef(value) {
  function isObj (line 4) | function isObj(x) {
  function isNumber (line 8) | function isNumber(value) {
  function range (line 11) | function range(num, min, max) {
  function nextTick (line 14) | function nextTick(fn) {
  function getSystemInfoSync (line 20) | function getSystemInfoSync() {
  function addUnit (line 26) | function addUnit(value) {

FILE: miniprogram/vant/common/version.js
  function compareVersion (line 2) | function compareVersion(v1, v2) {
  function canIUseModel (line 24) | function canIUseModel() {

FILE: miniprogram/vant/count-down/index.js
  function simpleTick (line 3) | function simpleTick(fn) {
  method destroyed (line 27) | destroyed() {
  method start (line 33) | start() {
  method pause (line 42) | pause() {
  method reset (line 47) | reset() {
  method tick (line 55) | tick() {
  method microTick (line 62) | microTick() {
  method macroTick (line 70) | macroTick() {
  method getRemain (line 81) | getRemain() {
  method setRemain (line 84) | setRemain(remain) {

FILE: miniprogram/vant/count-down/utils.d.ts
  type TimeData (line 1) | type TimeData = {

FILE: miniprogram/vant/count-down/utils.js
  function padZero (line 1) | function padZero(num, targetLength = 2) {
  constant SECOND (line 8) | const SECOND = 1000;
  constant MINUTE (line 9) | const MINUTE = 60 * SECOND;
  constant HOUR (line 10) | const HOUR = 60 * MINUTE;
  constant DAY (line 11) | const DAY = 24 * HOUR;
  function parseTimeData (line 12) | function parseTimeData(time) {
  function parseFormat (line 26) | function parseFormat(format, timeData) {
  function isSameSecond (line 51) | function isSameSecond(time1, time2) {

FILE: miniprogram/vant/datetime-picker/index.js
  function isValidDate (line 5) | function isValidDate(date) {
  function range (line 8) | function range(num, min, max) {
  function padZero (line 11) | function padZero(val) {
  function times (line 14) | function times(n, iteratee) {
  function getTrueValue (line 22) | function getTrueValue(formattedValue) {
  function getMonthEndDay (line 29) | function getMonthEndDay(year, month) {
  method updateValue (line 90) | updateValue() {
  method getPicker (line 102) | getPicker() {
  method updateColumns (line 112) | updateColumns() {
  method getOriginColumns (line 119) | getOriginColumns() {
  method getRanges (line 134) | getRanges() {
  method correctValue (line 188) | correctValue(value) {
  method getBoundary (line 210) | getBoundary(type, innerValue) {
  method onCancel (line 244) | onCancel() {
  method onConfirm (line 247) | onConfirm() {
  method onChange (line 250) | onChange() {
  method updateColumnValue (line 282) | updateColumnValue(value) {
  method created (line 311) | created() {

FILE: miniprogram/vant/definitions/index.d.ts
  type RecordToAny (line 3) | type RecordToAny<T> = {
  type CombinedComponentInstance (line 6) | type CombinedComponentInstance<Data, Props, Methods> = Methods & WechatM...
  type VantComponentOptions (line 9) | interface VantComponentOptions<Data, Props, Methods, Instance> {

FILE: miniprogram/vant/definitions/weapp.d.ts
  type FormField (line 3) | interface FormField {
  type Target (line 9) | interface Target {
  type Event (line 16) | interface Event {
  type Touch (line 38) | interface Touch {
  type TouchEvent (line 60) | interface TouchEvent extends Event {
  type RelationOption (line 67) | interface RelationOption<Instance> {
  type Observer (line 82) | type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, chan...
  type MethodOption (line 86) | interface MethodOption<Instance> {
  type ComputedOption (line 89) | interface ComputedOption<Instance> {
  type PropertyType (line 92) | type PropertyType = StringConstructor | NumberConstructor | BooleanConst...
  type PropertyOption (line 93) | interface PropertyOption {

FILE: miniprogram/vant/dialog/dialog.d.ts
  type DialogAction (line 2) | type DialogAction = 'confirm' | 'cancel';
  type DialogOptions (line 3) | type DialogOptions = {
  type Dialog (line 34) | interface Dialog {

FILE: miniprogram/vant/dialog/dialog.js
  function getContext (line 2) | function getContext() {

FILE: miniprogram/vant/dialog/index.js
  method observer (line 10) | observer(show) {
  method onConfirm (line 67) | onConfirm() {
  method onCancel (line 70) | onCancel() {
  method onClickOverlay (line 73) | onClickOverlay() {
  method handleAction (line 76) | handleAction(action) {
  method close (line 84) | close() {
  method stopLoading (line 89) | stopLoading() {
  method onClose (line 97) | onClose(action) {

FILE: miniprogram/vant/dropdown-item/index.js
  method linked (line 8) | linked() {
  method rerender (line 40) | rerender() {
  method updateDataFromParent (line 45) | updateDataFromParent() {
  method onOpen (line 63) | onOpen() {
  method onOpened (line 66) | onOpened() {
  method onClose (line 69) | onClose() {
  method onClosed (line 72) | onClosed() {
  method onOptionTap (line 76) | onOptionTap(event) {
  method toggle (line 87) | toggle(show, options = {}) {

FILE: miniprogram/vant/dropdown-menu/index.js
  constant ARRAY (line 3) | let ARRAY = [];
  method linked (line 10) | linked() {
  method unlinked (line 13) | unlinked() {
  method beforeCreate (line 54) | beforeCreate() {
  method destroyed (line 59) | destroyed() {
  method updateItemListData (line 63) | updateItemListData() {
  method updateChildrenData (line 68) | updateChildrenData() {
  method toggleItem (line 73) | toggleItem(active) {
  method close (line 83) | close() {
  method getChildWrapperStyle (line 88) | getChildWrapperStyle() {
  method onTitleTap (line 102) | onTitleTap(event) {

FILE: miniprogram/vant/field/index.js
  method created (line 54) | created() {
  method onInput (line 59) | onInput(event) {
  method onFocus (line 65) | onFocus(event) {
  method onBlur (line 70) | onBlur(event) {
  method onClickIcon (line 75) | onClickIcon() {
  method onClear (line 78) | onClear() {
  method onConfirm (line 87) | onConfirm(event) {
  method setValue (line 93) | setValue(value) {
  method onLineChange (line 101) | onLineChange(event) {
  method onKeyboardHeightChange (line 104) | onKeyboardHeightChange(event) {
  method emitChange (line 107) | emitChange() {
  method setShowClear (line 116) | setShowClear() {
  method noop (line 123) | noop() {}

FILE: miniprogram/vant/field/props.js
  method observer (line 4) | observer(value) {

FILE: miniprogram/vant/goods-action-button/index.js
  method onClick (line 24) | onClick(event) {
  method updateStyle (line 28) | updateStyle() {

FILE: miniprogram/vant/goods-action-icon/index.js
  method onClick (line 17) | onClick(event) {

FILE: miniprogram/vant/goods-action/index.js
  method linked (line 7) | linked() {
  method unlinked (line 10) | unlinked() {
  method linkChanged (line 13) | linkChanged() {
  method updateStyle (line 24) | updateStyle() {

FILE: miniprogram/vant/grid-item/index.js
  method mounted (line 22) | mounted() {
  method updateStyle (line 26) | updateStyle() {
  method onClick (line 65) | onClick() {

FILE: miniprogram/vant/grid/index.js
  method created (line 42) | created() {
  method updateChildren (line 51) | updateChildren() {

FILE: miniprogram/vant/icon/index.js
  method observer (line 15) | observer(val) {
  method onClick (line 23) | onClick() {

FILE: miniprogram/vant/image/index.js
  constant FIT_MODE_MAP (line 5) | const FIT_MODE_MAP = {
  method observer (line 19) | observer() {
  method mounted (line 59) | mounted() {
  method setMode (line 64) | setMode() {
  method setStyle (line 69) | setStyle() {
  method onLoad (line 84) | onLoad(event) {
  method onError (line 90) | onError(event) {
  method onClick (line 97) | onClick(event) {

FILE: miniprogram/vant/index-anchor/index.js
  method scrollIntoView (line 18) | scrollIntoView(scrollTop) {
  method getBoundingClientRect (line 26) | getBoundingClientRect() {

FILE: miniprogram/vant/index-bar/index.js
  method linked (line 17) | linked() {
  method unlinked (line 20) | unlinked() {
  method created (line 56) | created() {
  method updateData (line 60) | updateData() {
  method setRect (line 75) | setRect() {
  method setAnchorsRect (line 82) | setAnchorsRect() {
  method setListRect (line 94) | setListRect() {
  method setSiderbarRect (line 102) | setSiderbarRect() {
  method setDiffData (line 110) | setDiffData({ target, data }) {
  method getAnchorRect (line 121) | getAnchorRect(anchor) {
  method getActiveAnchorIndex (line 127) | getActiveAnchorIndex() {
  method onScroll (line 139) | onScroll() {
  method onClick (line 218) | onClick(event) {
  method onTouchMove (line 221) | onTouchMove(event) {
  method onTouchStop (line 233) | onTouchStop() {
  method scrollToAnchor (line 236) | scrollToAnchor(index) {

FILE: miniprogram/vant/mixins/basic.js
  method $emit (line 3) | $emit(...args) {
  method set (line 6) | set(data, callback) {
  method getRect (line 10) | getRect(selector, all) {

FILE: miniprogram/vant/mixins/link.js
  method jumpLink (line 10) | jumpLink(urlKey = 'url') {

FILE: miniprogram/vant/mixins/open-type.js
  method bindGetUserInfo (line 6) | bindGetUserInfo(event) {
  method bindContact (line 9) | bindContact(event) {
  method bindGetPhoneNumber (line 12) | bindGetPhoneNumber(event) {
  method bindError (line 15) | bindError(event) {
  method bindLaunchApp (line 18) | bindLaunchApp(event) {
  method bindOpenSetting (line 21) | bindOpenSetting(event) {

FILE: miniprogram/vant/mixins/page-scroll.d.ts
  type IPageScrollOption (line 2) | type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption;
  type Scroller (line 3) | type Scroller = (event: IPageScrollOption) => void;

FILE: miniprogram/vant/mixins/page-scroll.js
  function getCurrentPage (line 1) | function getCurrentPage() {
  function onPageScroll (line 5) | function onPageScroll(event) {
  method attached (line 15) | attached() {
  method detached (line 27) | detached() {

FILE: miniprogram/vant/mixins/touch.js
  constant MIN_DISTANCE (line 1) | const MIN_DISTANCE = 10;
  function getDirection (line 2) | function getDirection(x, y) {
  method resetTouchStatus (line 13) | resetTouchStatus() {
  method touchStart (line 20) | touchStart(event) {
  method touchMove (line 26) | touchMove(event) {

FILE: miniprogram/vant/mixins/transition.js
  method observeShow (line 36) | observeShow(value, old) {
  method enter (line 42) | enter() {
  method leave (line 70) | leave() {
  method checkStatus (line 100) | checkStatus(status) {
  method onTransitionEnd (line 105) | onTransitionEnd() {

FILE: miniprogram/vant/nav-bar/index.js
  method created (line 36) | created() {
  method mounted (line 47) | mounted() {
  method onClickLeft (line 51) | onClickLeft() {
  method onClickRight (line 54) | onClickRight() {
  method setHeight (line 57) | setHeight() {

FILE: miniprogram/vant/notice-bar/index.js
  constant FONT_COLOR (line 2) | const FONT_COLOR = '#ed6a0c';
  constant BG_COLOR (line 3) | const BG_COLOR = '#fffbe8';
  method observer (line 9) | observer() {
  method observer (line 34) | observer() {
  method created (line 61) | created() {
  method destroyed (line 67) | destroyed() {
  method init (line 71) | init() {
  method scroll (line 100) | scroll() {
  method onClickIcon (line 121) | onClickIcon() {
  method onClick (line 126) | onClick(event) {

FILE: miniprogram/vant/notify/index.js
  method created (line 32) | created() {
  method show (line 37) | show() {
  method hide (line 48) | hide() {
  method onTap (line 54) | onTap(event) {

FILE: miniprogram/vant/notify/notify.d.ts
  type NotifyOptions (line 1) | interface NotifyOptions {

FILE: miniprogram/vant/notify/notify.js
  function parseOptions (line 16) | function parseOptions(message) {
  function getContext (line 19) | function getContext() {
  function Notify (line 23) | function Notify(options) {

FILE: miniprogram/vant/overlay/index.js
  method onClick (line 16) | onClick() {
  method noop (line 20) | noop() {}

FILE: miniprogram/vant/picker-column/index.js
  constant DEFAULT_DURATION (line 3) | const DEFAULT_DURATION = 200;
  method observer (line 18) | observer(value) {
  method created (line 31) | created() {
  method getCount (line 41) | getCount() {
  method onTouchStart (line 44) | onTouchStart(event) {
  method onTouchMove (line 51) | onTouchMove(event) {
  method onTouchEnd (line 62) | onTouchEnd() {
  method onClickItem (line 74) | onClickItem(event) {
  method adjustIndex (line 78) | adjustIndex(index) {
  method isDisabled (line 89) | isDisabled(option) {
  method getOptionText (line 92) | getOptionText(option) {
  method setIndex (line 98) | setIndex(index, userAction) {
  method setValue (line 109) | setValue(value) {
  method getValue (line 118) | getValue() {

FILE: miniprogram/vant/picker/index.js
  method observer (line 21) | observer(columns = []) {
  method beforeCreate (line 30) | beforeCreate() {
  method noop (line 34) | noop() {}
  method setColumns (line 35) | setColumns() {
  method emit (line 43) | emit(event) {
  method onChange (line 57) | onChange(event) {
  method getColumn (line 73) | getColumn(index) {
  method getColumnValue (line 77) | getColumnValue(index) {
  method setColumnValue (line 82) | setColumnValue(index, value) {
  method getColumnIndex (line 90) | getColumnIndex(columnIndex) {
  method setColumnIndex (line 94) | setColumnIndex(columnIndex, optionIndex) {
  method getColumnValues (line 102) | getColumnValues(index) {
  method setColumnValues (line 106) | setColumnValues(index, options, needReset = true) {
  method getValues (line 123) | getValues() {
  method setValues (line 127) | setValues(values) {
  method getIndexes (line 134) | getIndexes() {
  method setIndexes (line 138) | setIndexes(indexes) {

FILE: miniprogram/vant/popup/index.js
  method created (line 57) | created() {
  method onClickCloseIcon (line 61) | onClickCloseIcon() {
  method onClickOverlay (line 64) | onClickOverlay() {
  method observeClass (line 70) | observeClass() {

FILE: miniprogram/vant/radio-group/index.js
  method linked (line 8) | linked(target) {
  method updateChildren (line 23) | updateChildren() {
  method updateChild (line 26) | updateChild(child) {

FILE: miniprogram/vant/radio/index.js
  method emitChange (line 31) | emitChange(value) {
  method onChange (line 36) | onChange() {
  method onClickLabel (line 41) | onClickLabel() {

FILE: miniprogram/vant/rate/index.js
  method observer (line 9) | observer(value) {
  method observer (line 42) | observer(value) {
  method onSelect (line 57) | onSelect(event) {
  method onTouchMove (line 71) | onTouchMove(event) {

FILE: miniprogram/vant/row/index.js
  method linked (line 7) | linked(target) {
  method mounted (line 22) | mounted() {
  method setGutter (line 28) | setGutter() {

FILE: miniprogram/vant/search/index.js
  method onChange (line 46) | onChange(event) {
  method onCancel (line 52) | onCancel() {
  method onSearch (line 65) | onSearch(event) {
  method onFocus (line 68) | onFocus(event) {
  method onBlur (line 71) | onBlur(event) {
  method onClear (line 74) | onClear(event) {

FILE: miniprogram/vant/sidebar-item/index.js
  method onClick (line 16) | onClick() {
  method setActive (line 27) | setActive(selected) {

FILE: miniprogram/vant/sidebar/index.js
  method linked (line 7) | linked() {
  method unlinked (line 10) | unlinked() {
  method beforeCreate (line 21) | beforeCreate() {
  method setActive (line 25) | setActive(activeKey) {

FILE: miniprogram/vant/skeleton/index.js
  method observer (line 8) | observer(value) {
  method observer (line 37) | observer(val) {

FILE: miniprogram/vant/slider/index.js
  method created (line 33) | created() {
  method onTouchStart (line 37) | onTouchStart(event) {
  method onTouchMove (line 43) | onTouchMove(event) {
  method onTouchEnd (line 56) | onTouchEnd() {
  method onClick (line 63) | onClick(event) {
  method updateValue (line 72) | updateValue(value, end, drag) {
  method getRange (line 93) | getRange() {
  method format (line 97) | format(value) {

FILE: miniprogram/vant/stepper/index.js
  constant LONG_PRESS_START_TIME (line 3) | const LONG_PRESS_START_TIME = 600;
  constant LONG_PRESS_INTERVAL (line 4) | const LONG_PRESS_INTERVAL = 200;
  function add (line 6) | function add(num1, num2) {
  function equal (line 10) | function equal(value1, value2) {
  method observer (line 19) | observer(value) {
  method created (line 71) | created() {
  method check (line 77) | check() {
  method isDisabled (line 83) | isDisabled(type) {
  method onFocus (line 97) | onFocus(event) {
  method onBlur (line 100) | onBlur(event) {
  method filter (line 109) | filter(value) {
  method format (line 117) | format(value) {
  method onInput (line 128) | onInput(event) {
  method emitChange (line 142) | emitChange(value) {
  method onChange (line 148) | onChange() {
  method longPressStep (line 159) | longPressStep() {
  method onTap (line 165) | onTap(event) {
  method onTouchStart (line 170) | onTouchStart(event) {
  method onTouchEnd (line 184) | onTouchEnd() {

FILE: miniprogram/vant/steps/index.js
  method onClick (line 28) | onClick(event) {

FILE: miniprogram/vant/sticky/index.js
  constant ROOT_ELEMENT (line 3) | const ROOT_ELEMENT = '.van-sticky';
  method observer (line 25) | observer(val) {
  method mounted (line 43) | mounted() {
  method onScroll (line 47) | onScroll({ scrollTop } = {}) {
  method setDataAfterDiff (line 87) | setDataAfterDiff(data) {
  method getContainerRect (line 102) | getContainerRect() {

FILE: miniprogram/vant/submit-bar/index.js
  method updatePrice (line 39) | updatePrice() {
  method updateTip (line 50) | updateTip() {
  method onSubmit (line 53) | onSubmit(event) {

FILE: miniprogram/vant/swipe-cell/index.js
  constant THRESHOLD (line 4) | const THRESHOLD = 0.3;
  constant ARRAY (line 5) | let ARRAY = [];
  method observer (line 12) | observer(leftWidth = 0) {
  method observer (line 21) | observer(rightWidth = 0) {
  method created (line 37) | created() {
  method destroyed (line 41) | destroyed() {
  method open (line 45) | open(position) {
  method close (line 54) | close() {
  method swipeMove (line 57) | swipeMove(offset = 0) {
  method swipeLeaveTransition (line 72) | swipeLeaveTransition() {
  method startDrag (line 84) | startDrag(event) {
  method noop (line 91) | noop() {}
  method onDrag (line 92) | onDrag(event) {
  method endDrag (line 105) | endDrag() {
  method onClick (line 112) | onClick(event) {

FILE: miniprogram/vant/switch/index.js
  method observer (line 9) | observer(value) {
  method created (line 31) | created() {
  method getLoadingColor (line 37) | getLoadingColor(checked) {
  method onClick (line 41) | onClick() {

FILE: miniprogram/vant/tab/index.js
  method getComputedName (line 38) | getComputedName() {
  method updateRender (line 44) | updateRender(active, parent) {
  method update (line 53) | update() {

FILE: miniprogram/vant/tabbar-item/index.js
  method onClick (line 18) | onClick() {
  method updateFromParent (line 24) | updateFromParent() {

FILE: miniprogram/vant/tabbar/index.js
  method linked (line 7) | linked(target) {
  method unlinked (line 11) | unlinked() {
  method updateChildren (line 46) | updateChildren() {
  method onChange (line 53) | onChange(child) {

FILE: miniprogram/vant/tabs/index.js
  method linked (line 11) | linked(target) {
  method unlinked (line 15) | unlinked() {
  method observer (line 31) | observer() {
  method observer (line 53) | observer(name) {
  method observer (line 82) | observer(value) {
  method mounted (line 106) | mounted() {
  method updateContainer (line 113) | updateContainer() {
  method updateTabs (line 118) | updateTabs() {
  method trigger (line 127) | trigger(eventName, child) {
  method onTap (line 139) | onTap(event) {
  method setCurrentIndexByName (line 152) | setCurrentIndexByName(name) {
  method setCurrentIndex (line 161) | setCurrentIndex(currentIndex) {
  method getCurrentName (line 191) | getCurrentName() {
  method setLine (line 197) | setLine(skipTransition) {
  method scrollIntoView (line 240) | scrollIntoView() {
  method onTouchScroll (line 258) | onTouchScroll(event) {
  method onTouchStart (line 261) | onTouchStart(event) {
  method onTouchMove (line 265) | onTouchMove(event) {
  method onTouchEnd (line 270) | onTouchEnd() {

FILE: miniprogram/vant/tag/index.js
  method onClose (line 17) | onClose() {

FILE: miniprogram/vant/toast/index.js
  method noop (line 27) | noop() {}

FILE: miniprogram/vant/toast/toast.d.ts
  type ToastMessage (line 2) | type ToastMessage = string | number;
  type ToastOptions (line 3) | interface ToastOptions {

FILE: miniprogram/vant/toast/toast.js
  function parseOptions (line 16) | function parseOptions(message) {
  function getContext (line 19) | function getContext() {
  function Toast (line 23) | function Toast(toastOptions) {

FILE: miniprogram/vant/tree-select/index.js
  method onSelectItem (line 36) | onSelectItem(event) {
  method onClickNav (line 50) | onClickNav(event) {
  method updateSubItems (line 58) | updateSubItems() {

FILE: miniprogram/vant/uploader/index.js
  method formatFileList (line 73) | formatFileList() {
  method getDetail (line 85) | getDetail(index) {
  method startUpload (line 91) | startUpload() {
  method onBeforeRead (line 112) | onBeforeRead(file) {
  method onAfterRead (line 139) | onAfterRead(file) {
  method deleteItem (line 153) | deleteItem(event) {
  method onPreviewImage (line 162) | onPreviewImage(event) {
  method onClickPreview (line 177) | onClickPreview(event) {

FILE: miniprogram/vant/uploader/utils.d.ts
  type File (line 2) | interface File {

FILE: miniprogram/vant/uploader/utils.js
  constant IMAGE_REGEXP (line 1) | const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;
  function isImageUrl (line 2) | function isImageUrl(url) {
  function isImageFile (line 5) | function isImageFile(item) {
  function isVideo (line 17) | function isVideo(res, accept) {
  function chooseFile (line 20) | function chooseFile({
  function isFunction (line 75) | function isFunction(val) {
  function isObject (line 78) | function isObject(val) {
  function isPromise (line 81) | function isPromise(val) {
Condensed preview — 564 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (836K chars).
[
  {
    "path": ".gitignore",
    "chars": 14,
    "preview": "node_modules/*"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 36,
    "preview": "{\n  \"git.ignoreLimitWarning\": true\n}"
  },
  {
    "path": "README.md",
    "chars": 5132,
    "preview": "# Secondary_trading_applet\n\n基于微信小程序的校园二手交易平台\n\n## 校园二手商城微信小程序成果(云开发)\n图片看不到可在B站搜索易珠观看效果\n\n### 功能\n\n**(1)用户登陆注册**:在小程序个人主页点击登"
  },
  {
    "path": "cloudfunctions/his/index.js",
    "chars": 2673,
    "preview": "const envid = 'taoshaoji-46f0r'; //云开发环境id\n\n/*\n下\n面\n不\n用\n管\n*/\n\n// 云函数入口文件\nconst cloud = require('wx-server-sdk')\ncloud.ini"
  },
  {
    "path": "cloudfunctions/his/package.json",
    "chars": 346,
    "preview": "{\n      \"name\": \"his\",\n      \"version\": \"1.0.0\",\n      \"description\": \"\",\n      \"main\": \"index.js\",\n      \"scripts\": {\n "
  },
  {
    "path": "cloudfunctions/imgSecCheck/config.json",
    "chars": 79,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n      \"security.imgSecCheck\"\n    ]\n  }\n}\n"
  },
  {
    "path": "cloudfunctions/imgSecCheck/index.js",
    "chars": 817,
    "preview": "// 云函数入口文件\nconst cloud = require('wx-server-sdk');\ncloud.init({\n  env: cloud.DYNAMIC_CURRENT_ENV\n})\n\n// 云函数入口函数\nexports."
  },
  {
    "path": "cloudfunctions/imgSecCheck/package.json",
    "chars": 261,
    "preview": "{\n  \"name\": \"imgSecCheck\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \""
  },
  {
    "path": "cloudfunctions/login/config.json",
    "chars": 45,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": []\n  }\n}\n"
  },
  {
    "path": "cloudfunctions/login/index.js",
    "chars": 654,
    "preview": "// 云函数模板\n// 部署:在 cloud-functions/login 文件夹右击选择 “上传并部署”\n\nconst cloud = require('wx-server-sdk')\n\n// 初始化 cloud\ncloud.init("
  },
  {
    "path": "cloudfunctions/login/package.json",
    "chars": 256,
    "preview": "{\n  \"name\": \"login\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\"
  },
  {
    "path": "cloudfunctions/node/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/node/index.js",
    "chars": 355,
    "preview": "// 云函数入口文件\nconst cloud = require('wx-server-sdk')\n  \ncloud.init()\n  \nconst db = cloud.database()\nconst _ = db.command\n  "
  },
  {
    "path": "cloudfunctions/node/package.json",
    "chars": 254,
    "preview": "{\n  \"name\": \"node\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\""
  },
  {
    "path": "cloudfunctions/pay/index.js",
    "chars": 2954,
    "preview": "const config = {\n      appid: 'xxxxxxx', //服务商公众号Appid\n      envName: 'taoshaoji-46f0r', // 小程序云开发环境ID\n      mchid: 'xxx"
  },
  {
    "path": "cloudfunctions/pay/package.json",
    "chars": 413,
    "preview": "{\n      \"name\": \"pay\",\n      \"version\": \"1.0.0\",\n      \"description\": \"\",\n      \"main\": \"index.js\",\n      \"scripts\": {\n "
  },
  {
    "path": "cloudfunctions/poking/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/poking/index.js",
    "chars": 637,
    "preview": "const cloud = require('wx-server-sdk')\ncloud.init()\nexports.main = async(event, context) => {\n  try {\n    const result ="
  },
  {
    "path": "cloudfunctions/poking/package.json",
    "chars": 256,
    "preview": "{\n  \"name\": \"poking\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo "
  },
  {
    "path": "cloudfunctions/ref/index.js",
    "chars": 1582,
    "preview": "const config = {\n      appid: 'wxd6beb52c8602bff4', //小程序Appid\n      envName: 'taoshaoji-46f0r', // 小程序云开发环境ID\n      mch"
  },
  {
    "path": "cloudfunctions/ref/package.json",
    "chars": 343,
    "preview": "{\n      \"name\": \"ref\",\n      \"version\": \"1.0.0\",\n      \"description\": \"\",\n      \"main\": \"index.js\",\n      \"scripts\": {\n "
  },
  {
    "path": "cloudfunctions/regist/RdWXBizDataCrypt.js",
    "chars": 989,
    "preview": "\n// 引入CryptoJS\nvar Crypto = require('cryptojs/cryptojs.js').Crypto;\n\nfunction RdWXBizDataCrypt(appId, sessionKey) {\n  th"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/cryptojs.js",
    "chars": 254,
    "preview": "var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;\n\n[ 'CryptoMath'\n, 'BlockModes'\n, 'DES'\n, 'AES'\n, 'HMAC'\n, "
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/AES.js",
    "chars": 10001,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/BlockModes.js",
    "chars": 9969,
    "preview": "/*!\n * Crypto-JS contribution from Simon Greatrix\n */\n\n(function(){\n\nvar C = (typeof window === 'undefined') ? require('"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/Crypto.js",
    "chars": 3988,
    "preview": "if (typeof Crypto == \"undefined\" || ! Crypto.util)\n{\n(function(){\n\nvar base64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/CryptoMath.js",
    "chars": 793,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcut\nvar uti"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/DES.js",
    "chars": 42222,
    "preview": "/**\n * Definition of Data Encryption Standard (DES) taken from:\n * http://www.itl.nist.gov/fipspubs/fip46-2.htm\n */\n\n(fu"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/HMAC.js",
    "chars": 1038,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/MARC4.js",
    "chars": 2022,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/MD5.js",
    "chars": 5089,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/PBKDF2.js",
    "chars": 1366,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/PBKDF2Async.js",
    "chars": 2905,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/Rabbit.js",
    "chars": 5459,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/SHA1.js",
    "chars": 1806,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/lib/SHA256.js",
    "chars": 3370,
    "preview": "(function(){\n\nvar C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;\n\n// Shortcuts\nvar ut"
  },
  {
    "path": "cloudfunctions/regist/cryptojs/package.json",
    "chars": 715,
    "preview": "{\n  \"author\": \"Jeff Guo <gwjjeff@gmail.com>\",\n  \"name\": \"cryptojs\",\n  \"tags\": [\"Hash\", \"MD5\", \"SHA1\", \"SHA-1\", \"SHA256\","
  },
  {
    "path": "cloudfunctions/regist/cryptojs/test/PBKDF2-test.js",
    "chars": 2864,
    "preview": "var assert = require('assert');\nvar Crypto = require('../cryptojs').Crypto; \n\n(function test_PBKDF2() {\n\tassert.strictEq"
  },
  {
    "path": "cloudfunctions/regist/index.js",
    "chars": 1467,
    "preview": "const appid = 'wxd6beb52c8602bff4'; //你的小程序appid\nconst secret = 'b00457b478f63f2388ef03476bb5a60c'; //你的小程序secret\n\n/*\n下\n"
  },
  {
    "path": "cloudfunctions/regist/package.json",
    "chars": 383,
    "preview": "{\n      \"name\": \"regist\",\n      \"version\": \"1.0.0\",\n      \"description\": \"\",\n      \"main\": \"index.js\",\n      \"scripts\": "
  },
  {
    "path": "cloudfunctions/removeChat/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/removeChat/index.js",
    "chars": 353,
    "preview": "// 云函数入口文件\nconst cloud = require('wx-server-sdk')\n\ncloud.init()\nconst db = cloud.database()\n// 云函数入口函数\nexports.main = as"
  },
  {
    "path": "cloudfunctions/removeChat/package.json",
    "chars": 260,
    "preview": "{\n  \"name\": \"removeChat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"e"
  },
  {
    "path": "cloudfunctions/removeOrder/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/removeOrder/index.js",
    "chars": 284,
    "preview": "// 云函数入口文件\nconst cloud = require('wx-server-sdk')\n\ncloud.init()\n\nconst db = cloud.database()\nconst _ = db.command\n\n// 云函"
  },
  {
    "path": "cloudfunctions/removeOrder/package.json",
    "chars": 261,
    "preview": "{\n  \"name\": \"removeOrder\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \""
  },
  {
    "path": "cloudfunctions/sell/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/sell/index.js",
    "chars": 353,
    "preview": "// 云函数入口文件\nconst cloud = require('wx-server-sdk')\n  \ncloud.init()\n  \nconst db = cloud.database()\nconst _ = db.command\n  "
  },
  {
    "path": "cloudfunctions/sell/package.json",
    "chars": 254,
    "preview": "{\n  \"name\": \"node\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\""
  },
  {
    "path": "cloudfunctions/sendMsg/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/sendMsg/index.js",
    "chars": 807,
    "preview": "//编程小石头微信:2501902696\nconst cloud = require('wx-server-sdk')\ncloud.init()\nexports.main = async(event, context) => {\n  try"
  },
  {
    "path": "cloudfunctions/sendMsg/package.json",
    "chars": 257,
    "preview": "{\n  \"name\": \"sendMsg\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo"
  },
  {
    "path": "cloudfunctions/sendTip/config.json",
    "chars": 49,
    "preview": "{\n  \"permissions\": {\n    \"openapi\": [\n    ]\n  }\n}"
  },
  {
    "path": "cloudfunctions/sendTip/index.js",
    "chars": 628,
    "preview": "const cloud = require('wx-server-sdk')\ncloud.init()\nexports.main = async(event, context) => {\n  try {\n    const result ="
  },
  {
    "path": "cloudfunctions/sendTip/package.json",
    "chars": 257,
    "preview": "{\n  \"name\": \"sendTip\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo"
  },
  {
    "path": "miniprogram/app.js",
    "chars": 498,
    "preview": "const config = require(\"config.js\");\n\nApp({\n      openid: '',\n      userinfo:'',\n      roomlist:[],\n      canReflect:tru"
  },
  {
    "path": "miniprogram/app.json",
    "chars": 2246,
    "preview": "{\n  \"cloud\": true,\n  \"pages\": [\n    \"pages/start/start\",\n    \"pages/index/index\",\n    \"pages/login/login\",\n    \"pages/pu"
  },
  {
    "path": "miniprogram/app.wxss",
    "chars": 676,
    "preview": "page {\n      background: #fff;\n      width: 100%;\n      height: 100%;\n}\n\n.shadow {\n      box-shadow: 0 0 18rpx rgb(236, "
  },
  {
    "path": "miniprogram/common.wxml",
    "chars": 205,
    "preview": "<template name=\"loadmore\">\n      <view class=\"loadmore\">\n            <image hidden=\"{{nomore}}\" src=\"/images/more.gif\"><"
  },
  {
    "path": "miniprogram/common.wxs",
    "chars": 2667,
    "preview": "function commentTimeHandle(dateStr) {\n      var publishTime = dateStr,\n            date = getDate(publishTime), //获取date"
  },
  {
    "path": "miniprogram/components/add_tips/README.md",
    "chars": 616,
    "preview": "# add-tips\n> **微信小程序UI插件**\n> 用于提示用户首次进入小程序时,点击右上角菜单进行【添加到我的小程序】操作\n\n## 文档\n首先,把这个仓库下载/克隆到你的小程序目录,比如`/components/weplug-add"
  },
  {
    "path": "miniprogram/components/add_tips/index.js",
    "chars": 1004,
    "preview": "const STORAGE_KEY = 'PLUG-ADD-MYAPP-KEY';\n\nComponent({\n  /**\n   * 组件的属性列表\n   */\n  properties: {\n    // 提示文字\n    text: {\n"
  },
  {
    "path": "miniprogram/components/add_tips/index.json",
    "chars": 48,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/components/add_tips/index.wxml",
    "chars": 802,
    "preview": "<view class=\"box\" wx:if=\"{{SHOW_TOP}}\">\n  <view class='arrow'></view>\n  <view class='body' bindtap='showModal'>\n    <tex"
  },
  {
    "path": "miniprogram/components/add_tips/index.wxss",
    "chars": 1515,
    "preview": ".box {\n  position: fixed;\n  top: 0;\n  /* left: 0; */\n  right: 0;\n  z-index: 999;\n  display: flex;\n  justify-content: fle"
  },
  {
    "path": "miniprogram/components/canvasdrawer/canvasdrawer.js",
    "chars": 8479,
    "preview": "/* global Component wx */\n\nComponent({\n  properties: {\n    painting: {\n      type: Object,\n      value: {view: []},\n    "
  },
  {
    "path": "miniprogram/components/canvasdrawer/canvasdrawer.json",
    "chars": 23,
    "preview": "{\n  \"component\": true\n}"
  },
  {
    "path": "miniprogram/components/canvasdrawer/canvasdrawer.wxml",
    "chars": 126,
    "preview": "<canvas canvas-id=\"canvasdrawer\" style=\"width:{{width}}px;height:{{height}}px;\" class=\"board\" wx:if=\"{{showCanvas}}\"></c"
  },
  {
    "path": "miniprogram/components/canvasdrawer/canvasdrawer.wxss",
    "chars": 45,
    "preview": ".board {\n  position: fixed;\n  top: 2000rpx;\n}"
  },
  {
    "path": "miniprogram/components/chatroom/chatroom.js",
    "chars": 9458,
    "preview": "var time = require('../../utils/util.js');\nconst FATAL_REBUILD_TOLERANCE = 10\nconst SETDATA_SCROLL_TO_BOTTOM = {\n  scrol"
  },
  {
    "path": "miniprogram/components/chatroom/chatroom.json",
    "chars": 52,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n\n  }\n}"
  },
  {
    "path": "miniprogram/components/chatroom/chatroom.wxml",
    "chars": 1843,
    "preview": "<view class=\"chatroom\">\n\t<!-- chats -->\n\t<scroll-view class=\"body\" scroll-y scroll-with-animation=\"{{scrollWithAnimation"
  },
  {
    "path": "miniprogram/components/chatroom/chatroom.wxss",
    "chars": 2667,
    "preview": ".chatroom {\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n}\n/* .chatroom .header {\n  flex-ba"
  },
  {
    "path": "miniprogram/components/welcome/welcome.js",
    "chars": 1291,
    "preview": "const STORAGE1_KEY = 'PLUG-WELCOME-MYAPP-KEY';\n\nComponent({\n  /**\n   * 组件的属性列表\n   */\n  // properties: {\n  //   // 提示文字\n "
  },
  {
    "path": "miniprogram/components/welcome/welcome.json",
    "chars": 48,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/components/welcome/welcome.wxml",
    "chars": 821,
    "preview": "<!-- modal -->\n<view class='modal' wx:if=\"{{SHOW_MODAL}}\">\n  <view style='flex-direction: row;align-items:center;'>\n    "
  },
  {
    "path": "miniprogram/components/welcome/welcome.wxss",
    "chars": 1690,
    "preview": "/* components/welcome.wxss */\r\n.box {\r\n  position: fixed;\r\n  top: 0;\r\n  /* left: 0; */\r\n  right: 0;\r\n  z-index: 999;\r\n  "
  },
  {
    "path": "miniprogram/config.js",
    "chars": 2787,
    "preview": "var data = {\n      //云开发环境id\n      env: 'taoshaoji-46f0r',\n      //分享配置\n      share_title: '吉珠二手交易平台',\n      share_img: "
  },
  {
    "path": "miniprogram/pages/about/about.js",
    "chars": 2069,
    "preview": "// pages/about/about.js\nPage({\n\n  /**\n   * 页面的初始数据\n   */\n  data: {\n    imgs1: [{\n        url: 'tao.jpg',\n        name: '"
  },
  {
    "path": "miniprogram/pages/about/about.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/about/about.wxml",
    "chars": 1055,
    "preview": "<view class=\"title\">开发:</view>\n<view class=\"main\">\n\t<view class=\"image\">\n\t\t<view class=\"txt\" wx:for=\"{{imgs1}}\" wx:key=\""
  },
  {
    "path": "miniprogram/pages/about/about.wxss",
    "chars": 2338,
    "preview": "page {\n      background: #eee;\n}\n\n.des_contain {\n      width: 618rpx;\n      height: 157rpx;\n      border-radius: 10rpx;\n"
  },
  {
    "path": "miniprogram/pages/appreciateCode/appreciateCode.js",
    "chars": 3424,
    "preview": "const db = wx.cloud.database();\nconst app = getApp();\nPage({\n\n  /**\n   * 页面的初始数据\n   */\n  data: {\n    bigImg: '',\n    isE"
  },
  {
    "path": "miniprogram/pages/appreciateCode/appreciateCode.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/appreciateCode/appreciateCode.wxml",
    "chars": 1512,
    "preview": "<!-- <view wx:if='{{!isExist}}'>\n\t<image src='cloud://taoshaoji-46f0r.7461-taoshaoji-46f0r-1302243411/gzh/eg.jpeg' mode="
  },
  {
    "path": "miniprogram/pages/appreciateCode/appreciateCode.wxss",
    "chars": 1561,
    "preview": "page {\n  background: #eee;\n}\n\n.imagesize {\n  display: flex; \n  justify-content: center; \n}\n\n.imagesize image {\n  width: "
  },
  {
    "path": "miniprogram/pages/detail/detail.js",
    "chars": 21404,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../config.js\");\nconst _ = db.command;\nle"
  },
  {
    "path": "miniprogram/pages/detail/detail.json",
    "chars": 36,
    "preview": "{\n\"navigationBarTitleText\": \"物品详情\"\n}"
  },
  {
    "path": "miniprogram/pages/detail/detail.wxml",
    "chars": 4121,
    "preview": "<wxs src=\"../../common.wxs\" module=\"morejs\" />\n<view class=\"top_contain\">\n      <!--轮播图-->\n      <swiper indicator-dots="
  },
  {
    "path": "miniprogram/pages/detail/detail.wxss",
    "chars": 6825,
    "preview": ".top_contain {\n      display: flex;\n      flex-direction: column;\n      padding: 24rpx;\n      box-sizing: border-box;\n}\n"
  },
  {
    "path": "miniprogram/pages/detail/room/room.js",
    "chars": 2226,
    "preview": "const app = getApp()\n\nPage({\n  data: {\n    avatarUrl: './user-unlogin.png',\n    userInfo: null,\n    logged: false,\n    t"
  },
  {
    "path": "miniprogram/pages/detail/room/room.json",
    "chars": 78,
    "preview": "{\n  \"usingComponents\": {\n    \"chatroom\": \"/components/chatroom/chatroom\"\n  }\n}"
  },
  {
    "path": "miniprogram/pages/detail/room/room.wxml",
    "chars": 422,
    "preview": "\n<view class=\"container\">\n\n<van-notice-bar left-icon=\"volume-o\" text=\"可以在我的——消息中心处 拍一拍 提醒对方上线哦!\" speed=\"30\" />\n  <chatro"
  },
  {
    "path": "miniprogram/pages/detail/room/room.wxss",
    "chars": 272,
    "preview": ".container {\n  height: 98%;\n  position: absolute;\n  /* top: 0; */\n  bottom: 0;\n  left: 0;\n  right: 0;\n  padding-top: 80r"
  },
  {
    "path": "miniprogram/pages/edit/edit.js",
    "chars": 6401,
    "preview": "const db = wx.cloud.database();\nconst app = getApp();\nconst config = require(\"../../config.js\");\nPage({\n\n      /**\n     "
  },
  {
    "path": "miniprogram/pages/edit/edit.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/edit/edit.wxml",
    "chars": 1753,
    "preview": "<view class=\"top-bg\"></view>\n<view class=\"contain\">\n      <view class=\"card\">\n            <view class=\"title\">修改资料</view"
  },
  {
    "path": "miniprogram/pages/edit/edit.wxss",
    "chars": 2791,
    "preview": ".top-bg {\n      position: absolute;\n      top: 0rpx;\n      left: 0rpx;\n      width: 100%;\n      height: 460rpx;\n      ba"
  },
  {
    "path": "miniprogram/pages/help/help.js",
    "chars": 2348,
    "preview": "var app = getApp();\nvar db = wx.cloud.database();\n\nPage({\n      /**\n       * 页面的初始数据\n       */\n      data: {\n           "
  },
  {
    "path": "miniprogram/pages/help/help.json",
    "chars": 132,
    "preview": "{\n      \"navigationBarTitleText\": \"使用说明\",\n      \"navigationBarBackgroundColor\": \"#ffffff\",\n      \"navigationBarTextStyle"
  },
  {
    "path": "miniprogram/pages/help/help.wxml",
    "chars": 1173,
    "preview": "<view class=\"contain\" >\n      <view class=\"contains\" wx:for=\"{{list}}\" wx:key=\"id\">\n            <view class=\"top\" bindta"
  },
  {
    "path": "miniprogram/pages/help/help.wxss",
    "chars": 1440,
    "preview": ".contain {\n     width: 100%;\n     padding: 30rpx 30rpx;\n     box-sizing: border-box;\n}\n\n.top {\n     display: flex;\n     "
  },
  {
    "path": "miniprogram/pages/index/index.js",
    "chars": 8042,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../config.js\");\nconst _ = db.command;\nPa"
  },
  {
    "path": "miniprogram/pages/index/index.json",
    "chars": 35,
    "preview": "{\n  \"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/pages/index/index.wxml",
    "chars": 4673,
    "preview": "<wxs src=\"../../common.wxs\" module=\"morejs\" />\n\n<view class=\"top_box\">\n      <view class=\"search_box\" bindtap=\"search\">\n"
  },
  {
    "path": "miniprogram/pages/index/index.wxss",
    "chars": 5721,
    "preview": ".top_box {\n      width: 100%;\n      background: #fbbd08;\n      display: flex;\n      justify-content: space-between;\n    "
  },
  {
    "path": "miniprogram/pages/kefu/kefu.js",
    "chars": 1300,
    "preview": "var app = getApp();\nconst config = require(\"../../config.js\");\n\nPage({\n\n      /**\n       * 页面的初始数据\n       */\n      data:"
  },
  {
    "path": "miniprogram/pages/kefu/kefu.json",
    "chars": 132,
    "preview": "{\n      \"navigationBarTitleText\": \"联系客服\",\n      \"navigationBarBackgroundColor\": \"#ffffff\",\n      \"navigationBarTextStyle"
  },
  {
    "path": "miniprogram/pages/kefu/kefu.wxml",
    "chars": 2638,
    "preview": "<view class=\"contain\">\n      <view style=\"height:20rpx;\"></view>\n      <!--顶部图-->\n      <image src=\"{{banner}}\" class=\"s"
  },
  {
    "path": "miniprogram/pages/kefu/kefu.wxss",
    "chars": 1389,
    "preview": ".contain{\n    width: 100%;\n    padding: 0 46rpx;\n    box-sizing: border-box;\n}\n.slide-image{\n    width: 100%;\n    height"
  },
  {
    "path": "miniprogram/pages/login/login.js",
    "chars": 5700,
    "preview": "const db = wx.cloud.database();\nconst app = getApp();\nconst config = require(\"../../config.js\");\nPage({\n\n      /**\n     "
  },
  {
    "path": "miniprogram/pages/login/login.json",
    "chars": 30,
    "preview": "{\n\"navigationStyle\":\"custom\"\n}"
  },
  {
    "path": "miniprogram/pages/login/login.wxml",
    "chars": 1469,
    "preview": "<view class=\"top-bg\"></view>\n<view class=\"contain\">\n\t<view class=\"card\">\n\t\t<view class=\"title\">登记注册</view>\n\t\t<picker bin"
  },
  {
    "path": "miniprogram/pages/login/login.wxss",
    "chars": 2966,
    "preview": ".top-bg {\n      position: absolute;\n      top: 0rpx;\n      left: 0rpx;\n      width: 100%;\n      height: 460rpx;\n      ba"
  },
  {
    "path": "miniprogram/pages/message/message.js",
    "chars": 6802,
    "preview": "const app = getApp()\nvar time = require('../../utils/util.js');\nconst db = wx.cloud.database();\nPage({\n\n  data: {\n    ro"
  },
  {
    "path": "miniprogram/pages/message/message.json",
    "chars": 98,
    "preview": "{\n\n  \"usingComponents\": { },\n  \"navigationBarTitleText\": \"消息中心\",\n  \"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/pages/message/message.wxml",
    "chars": 568,
    "preview": "<view class=\"list\">\n\t<view class=\"item\" wx:for=\"{{roomlist}}\">\n\t\t<view class=\"left\">\n\t\t\t<image mode=\"aspectFill\" src=\"{{"
  },
  {
    "path": "miniprogram/pages/message/message.wxss",
    "chars": 1595,
    "preview": ".list {\n      box-sizing: border-box;\n      width: 100%;\n      padding: 30rpx;\n    }\n    \n    .item {\n      display: fle"
  },
  {
    "path": "miniprogram/pages/my/my.js",
    "chars": 3468,
    "preview": "const app = getApp();\nconst config = require(\"../../config.js\");\nPage({\n\n      /**\n       * 页面的初始数据\n       */\n      data"
  },
  {
    "path": "miniprogram/pages/my/my.json",
    "chars": 45,
    "preview": "{\n\"navigationBarBackgroundColor\": \"#ffffff\"\n}"
  },
  {
    "path": "miniprogram/pages/my/my.wxml",
    "chars": 2579,
    "preview": "<view class=\"top_box\">\n\t<view class=\"top_2\">\n\t\t<view class=\"avator\">\n\t\t\t<open-data wx:if=\"{{userinfo}}\" type=\"userAvatar"
  },
  {
    "path": "miniprogram/pages/my/my.wxss",
    "chars": 3340,
    "preview": ".top_box {\n      width: 100%;\n      padding: 0 30rpx 30rpx 30rpx;\n      display: flex;\n      box-sizing: border-box;\n   "
  },
  {
    "path": "miniprogram/pages/order/detail/detail.js",
    "chars": 11741,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../../config.js\");\nconst _ = db.command;"
  },
  {
    "path": "miniprogram/pages/order/detail/detail.json",
    "chars": 40,
    "preview": "{\n    \"navigationBarTitleText\": \"订单详情\"\n}"
  },
  {
    "path": "miniprogram/pages/order/detail/detail.wxml",
    "chars": 2862,
    "preview": "<view class=\"contain\">\n\t<view class=\"card\">\n\t\t<view class=\"goods_box\">\n\t\t\t<image class=\"goods_img\" src=\"{{detail.bookinf"
  },
  {
    "path": "miniprogram/pages/order/detail/detail.wxss",
    "chars": 3498,
    "preview": "page {\n  background-image: linear-gradient(to top, #dad4ec 0%, #dad4ec 1%, #f3e7e9 100%);\n}\n\n.contain {\n  display: flex;"
  },
  {
    "path": "miniprogram/pages/order/list/list.js",
    "chars": 12222,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../../config.js\");\nconst _ = db.command;"
  },
  {
    "path": "miniprogram/pages/order/list/list.json",
    "chars": 79,
    "preview": "{\n      \"navigationBarTitleText\": \"我的购买\",\n      \"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/pages/order/list/list.wxml",
    "chars": 2688,
    "preview": "<wxs src=\"../../../common.wxs\" module=\"morejs\" />\n<view class=\"tab_contain\">\n      <block wx:for=\"{{tab}}\" wx:key=\"id\">\n"
  },
  {
    "path": "miniprogram/pages/order/list/list.wxss",
    "chars": 3839,
    "preview": ".tab_contain {\n      width: 100%;\n      height: 90rpx;\n      display: flex;\n      align-items: center;\n      box-sizing:"
  },
  {
    "path": "miniprogram/pages/publish/publish.js",
    "chars": 15735,
    "preview": "const db = wx.cloud.database();\nconst app = getApp();\nconst config = require(\"../../config.js\");\nconst MAX_IMG_NUM = 8;\n"
  },
  {
    "path": "miniprogram/pages/publish/publish.json",
    "chars": 36,
    "preview": "{\n\"navigationBarTitleText\": \"发布物品\"\n}"
  },
  {
    "path": "miniprogram/pages/publish/publish.wxml",
    "chars": 4249,
    "preview": "<view class=\"top_steps\">\n\t<van-steps steps=\"{{ steps }}\" active=\"{{ active }}\" active-color=\"#000000\" />\n</view>\n<view s"
  },
  {
    "path": "miniprogram/pages/publish/publish.wxss",
    "chars": 8416,
    "preview": "page {\n      background: #f6f7fa;\n}\n\n.top_steps {\n      position: fixed;\n      top: 0rpx;\n      left: 0rpx;\n      width:"
  },
  {
    "path": "miniprogram/pages/search/search.js",
    "chars": 6286,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../config.js\");\nconst _ = db.command;\nPa"
  },
  {
    "path": "miniprogram/pages/search/search.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/search/search.wxml",
    "chars": 4508,
    "preview": "<wxs src=\"../../common.wxs\" module=\"morejs\" />\n<view class=\"top_contain\">\n      <view class=\"search_box\">\n            <i"
  },
  {
    "path": "miniprogram/pages/search/search.wxss",
    "chars": 3328,
    "preview": ".top_contain {\n      width: 100%;\n      display: flex;\n      justify-content: space-between;\n      padding: 20rpx 30rpx;"
  },
  {
    "path": "miniprogram/pages/sell/detail/detail.js",
    "chars": 10645,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../../config.js\");\nconst _ = db.command;"
  },
  {
    "path": "miniprogram/pages/sell/detail/detail.json",
    "chars": 40,
    "preview": "{\n    \"navigationBarTitleText\": \"订单详情\"\n}"
  },
  {
    "path": "miniprogram/pages/sell/detail/detail.wxml",
    "chars": 2043,
    "preview": "<view class=\"contain\">\n\t<view class=\"card\">\n\t\t<view class=\"goods_box\">\n\t\t\t<image class=\"goods_img\" src=\"{{detail.bookinf"
  },
  {
    "path": "miniprogram/pages/sell/detail/detail.wxss",
    "chars": 3222,
    "preview": "page {\n  background-image: linear-gradient(to top, #dad4ec 0%, #dad4ec 1%, #f3e7e9 100%);\n}\n.contain {\n  display: flex;\n"
  },
  {
    "path": "miniprogram/pages/sell/list/list.js",
    "chars": 18787,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../../config.js\");\nconst _ = db.command;"
  },
  {
    "path": "miniprogram/pages/sell/list/list.json",
    "chars": 79,
    "preview": "{\n      \"navigationBarTitleText\": \"我的发布\",\n      \"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/pages/sell/list/list.wxml",
    "chars": 2434,
    "preview": "<wxs src=\"../../../common.wxs\" module=\"morejs\" />\n<view class=\"contain\" wx:if=\"{{list.length!==0}}\">\n      <block wx:for"
  },
  {
    "path": "miniprogram/pages/sell/list/list.wxss",
    "chars": 2826,
    "preview": ".contain {\n      width: 100%;\n      display: flex;\n      box-sizing: border-box;\n      flex-direction: column;\n      pad"
  },
  {
    "path": "miniprogram/pages/start/start.js",
    "chars": 2567,
    "preview": "const app = getApp()\nconst db = wx.cloud.database();\nconst config = require(\"../../config.js\");\nconst _ = db.command;\nPa"
  },
  {
    "path": "miniprogram/pages/start/start.json",
    "chars": 32,
    "preview": "{\n  \"navigationStyle\":\"custom\"\n}"
  },
  {
    "path": "miniprogram/pages/start/start.wxml",
    "chars": 172,
    "preview": "<view class=\"contain\">\n     <view class=\"go\">\n             <button  bindtap=\"go\">跳过{{count}}s</button> \n     </view>\n   "
  },
  {
    "path": "miniprogram/pages/start/start.wxss",
    "chars": 606,
    "preview": ".contain {\n      width: 100%;\n      height: 100%;\n      position: relative;\n}\n.bg {\n      position: absolute;\n      left"
  },
  {
    "path": "miniprogram/pages/use/use.js",
    "chars": 643,
    "preview": "// miniprogram/pages/use/use.js\nPage({\n\n  /**\n   * 页面的初始数据\n   */\n  data: {\n    des:'待补充'\n  },\n\n  /**\n   * 生命周期函数--监听页面加载"
  },
  {
    "path": "miniprogram/pages/use/use.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/use/use.wxml",
    "chars": 78,
    "preview": "\t<web-view src=\"https://mp.weixin.qq.com/s/QFM3vO7-Cl_u8SVetBME9Q\"></web-view>"
  },
  {
    "path": "miniprogram/pages/use/use.wxss",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "miniprogram/pages/web/web.js",
    "chars": 865,
    "preview": "// pages/web/web.js\nPage({\n\n      /**\n       * 页面的初始数据\n       */\n      data: {\n      },\n\n      /**\n       * 生命周期函数--监听页面"
  },
  {
    "path": "miniprogram/pages/web/web.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/pages/web/web.wxml",
    "chars": 35,
    "preview": "<web-view src=\"{{url}}\"></web-view>"
  },
  {
    "path": "miniprogram/pages/web/web.wxss",
    "chars": 24,
    "preview": "/* pages/web/web.wxss */"
  },
  {
    "path": "miniprogram/sitemap.json",
    "chars": 695,
    "preview": "{\n      \"desc\": \"关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html\",\n      \"rules"
  },
  {
    "path": "miniprogram/utils/util.js",
    "chars": 1169,
    "preview": "function formatTime(date) {\n  var date = new Date(date);\n  var year = date.getFullYear()\n  var month = date.getMonth() +"
  },
  {
    "path": "miniprogram/vant/action-sheet/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/action-sheet/index.js",
    "chars": 1268,
    "preview": "import { VantComponent } from '../common/component';\nimport { button } from '../mixins/button';\nimport { openType } from"
  },
  {
    "path": "miniprogram/vant/action-sheet/index.json",
    "chars": 158,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"van-icon\": \"../icon/index\",\n    \"van-popup\": \"../popup/index\",\n    \"v"
  },
  {
    "path": "miniprogram/vant/action-sheet/index.wxml",
    "chars": 2231,
    "preview": "<wxs src=\"../wxs/utils.wxs\" module=\"utils\" />\n\n<van-popup\n  show=\"{{ show }}\"\n  position=\"bottom\"\n  round=\"{{ round }}\"\n"
  },
  {
    "path": "miniprogram/vant/action-sheet/index.wxss",
    "chars": 2276,
    "preview": "@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!"
  },
  {
    "path": "miniprogram/vant/area/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/area/index.js",
    "chars": 6186,
    "preview": "import { VantComponent } from '../common/component';\nimport { pickerProps } from '../picker/shared';\nconst COLUMNSPLACEH"
  },
  {
    "path": "miniprogram/vant/area/index.json",
    "chars": 88,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"van-picker\": \"../picker/index\"\n  }\n}\n"
  },
  {
    "path": "miniprogram/vant/area/index.wxml",
    "chars": 499,
    "preview": "<van-picker\n  class=\"van-area__picker\"\n  active-class=\"active-class\"\n  toolbar-class=\"toolbar-class\"\n  column-class=\"col"
  },
  {
    "path": "miniprogram/vant/area/index.wxss",
    "chars": 31,
    "preview": "@import '../common/index.wxss';"
  },
  {
    "path": "miniprogram/vant/button/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/button/index.js",
    "chars": 1677,
    "preview": "import { VantComponent } from '../common/component';\nimport { button } from '../mixins/button';\nimport { openType } from"
  },
  {
    "path": "miniprogram/vant/button/index.json",
    "chars": 123,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"van-icon\": \"../icon/index\",\n    \"van-loading\": \"../loading/index\"\n  }"
  },
  {
    "path": "miniprogram/vant/button/index.wxml",
    "chars": 1872,
    "preview": "<wxs src=\"../wxs/utils.wxs\" module=\"utils\" />\n\n<button\n  id=\"{{ id }}\"\n  data-detail=\"{{ dataset }}\"\n  class=\"custom-cla"
  },
  {
    "path": "miniprogram/vant/button/index.wxss",
    "chars": 4386,
    "preview": "@import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-ali"
  },
  {
    "path": "miniprogram/vant/calendar/calendar.wxml",
    "chars": 1833,
    "preview": "<wxs src=\"./index.wxs\" module=\"computed\"></wxs>\n\n<template name=\"calendar\">\n  <view class=\"van-calendar\">\n    <header\n  "
  },
  {
    "path": "miniprogram/vant/calendar/components/header/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/calendar/components/header/index.js",
    "chars": 310,
    "preview": "import { VantComponent } from '../../../common/component';\nVantComponent({\n  props: {\n    title: {\n      type: String,\n "
  },
  {
    "path": "miniprogram/vant/calendar/components/header/index.json",
    "chars": 24,
    "preview": "{\n  \"component\": true\n}\n"
  },
  {
    "path": "miniprogram/vant/calendar/components/header/index.wxml",
    "chars": 496,
    "preview": "<view class=\"van-calendar__header\">\n  <block wx:if=\"{{ showTitle }}\">\n    <view class=\"van-calendar__header-title\"><slot"
  },
  {
    "path": "miniprogram/vant/calendar/components/header/index.wxss",
    "chars": 921,
    "preview": "@import '../../../common/index.wxss';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgb"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.js",
    "chars": 4003,
    "preview": "import { VantComponent } from '../../../common/component';\nimport {\n  getMonthEndDay,\n  compareDay,\n  getPrevDay,\n  getN"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.json",
    "chars": 24,
    "preview": "{\n  \"component\": true\n}\n"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.wxml",
    "chars": 1476,
    "preview": "<wxs src=\"./index.wxs\" module=\"computed\"></wxs>\n<wxs src=\"../../../wxs/utils.wxs\" module=\"utils\" />\n\n<view class=\"van-ca"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.wxs",
    "chars": 1435,
    "preview": "/* eslint-disable */\nvar utils = require('../../utils.wxs');\n\nfunction getMark(date) {\n  return getDate(date).getMonth()"
  },
  {
    "path": "miniprogram/vant/calendar/components/month/index.wxss",
    "chars": 3153,
    "preview": "@import '../../../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-"
  },
  {
    "path": "miniprogram/vant/calendar/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/calendar/index.js",
    "chars": 6977,
    "preview": "import { VantComponent } from '../common/component';\nimport {\n  ROW_HEIGHT,\n  getNextDay,\n  compareDay,\n  copyDates,\n  c"
  },
  {
    "path": "miniprogram/vant/calendar/index.json",
    "chars": 207,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"header\": \"./components/header/index\",\n    \"month\": \"./components/mont"
  },
  {
    "path": "miniprogram/vant/calendar/index.wxml",
    "chars": 1070,
    "preview": "<wxs src=\"./index.wxs\" module=\"computed\" />\n\n<import src=\"./calendar.wxml\" />\n\n<van-popup\n  wx:if=\"{{ poppable }}\"\n  cus"
  },
  {
    "path": "miniprogram/vant/calendar/index.wxs",
    "chars": 697,
    "preview": "/* eslint-disable */\nvar utils = require('./utils.wxs');\n\nfunction getMonths(minDate, maxDate) {\n  var months = [];\n  va"
  },
  {
    "path": "miniprogram/vant/calendar/index.wxss",
    "chars": 1192,
    "preview": "@import '../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direct"
  },
  {
    "path": "miniprogram/vant/calendar/utils.d.ts",
    "chars": 768,
    "preview": "export declare const ROW_HEIGHT = 64;\nexport declare function formatMonthTitle(date: Date): string;\nexport declare funct"
  },
  {
    "path": "miniprogram/vant/calendar/utils.js",
    "chars": 2116,
    "preview": "export const ROW_HEIGHT = 64;\nexport function formatMonthTitle(date) {\n  if (!(date instanceof Date)) {\n    date = new D"
  },
  {
    "path": "miniprogram/vant/calendar/utils.wxs",
    "chars": 558,
    "preview": "/* eslint-disable */\nfunction getMonthEndDay(year, month) {\n  return 32 -  getDate(year, month - 1, 32).getDate();\n}\n\nfu"
  },
  {
    "path": "miniprogram/vant/card/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": "miniprogram/vant/card/index.js",
    "chars": 984,
    "preview": "import { link } from '../mixins/link';\nimport { VantComponent } from '../common/component';\nVantComponent({\n  classes: ["
  },
  {
    "path": "miniprogram/vant/card/index.json",
    "chars": 82,
    "preview": "{\n  \"component\": true,\n  \"usingComponents\": {\n    \"van-tag\": \"../tag/index\"\n  }\n}\n"
  },
  {
    "path": "miniprogram/vant/card/index.wxml",
    "chars": 1752,
    "preview": "<wxs src=\"../wxs/utils.wxs\" module=\"utils\" />\n\n<view class=\"custom-class van-card\">\n  <view class=\"{{ utils.bem('card__h"
  }
]

// ... and 364 more files (download for full content)

About this extraction

This page contains the full source code of the Taoshaoji/used-book-secondhand GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 564 files (726.0 KB), approximately 221.9k tokens, and a symbol index with 689 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!