From 70141bb2cd3f9dd8fd163b4791ab08d5e3f572ed Mon Sep 17 00:00:00 2001 From: MicroMilo Date: Wed, 26 Apr 2023 16:30:11 +0800 Subject: [PATCH] =?UTF-8?q?admin=20uniapp=20=E5=88=9B=E5=BB=BA=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- alpha/admin/.hbuilderx/launch.json | 16 + alpha/admin/App.vue | 78 + alpha/admin/LICENSE | 21 + alpha/admin/README.md | 24 + alpha/admin/admin.config.js | 85 + alpha/admin/changelog.md | 236 + alpha/admin/common/admin-icons.css | 199 + alpha/admin/common/theme.scss | 293 + alpha/admin/common/uni-icons.css | 542 ++ alpha/admin/common/uni.css | 617 ++ .../admin/components/batch-sms/batch-sms.vue | 519 ++ .../download-excel/download-excel.vue | 361 + .../components/download-excel/download.js | 151 + .../components/fix-window/fix-window.vue | 72 + .../admin/components/show-info/show-info.vue | 55 + .../uni-data-menu/uni-data-menu.vue | 186 + alpha/admin/components/uni-data-menu/util.js | 67 + .../uni-menu-group/uni-menu-group.vue | 49 + .../uni-menu-item/uni-menu-item.vue | 133 + .../uni-menu-sidebar/uni-menu-sidebar.vue | 48 + .../uni-nav-menu/mixins/rootParent.js | 29 + .../components/uni-nav-menu/uni-nav-menu.vue | 209 + .../uni-stat-breadcrumb.vue | 36 + .../uni-stat-panel/uni-stat-panel.vue | 116 + .../uni-stat-table/uni-stat-table.vue | 71 + .../uni-stat-tabs/uni-stat-tabs.vue | 361 + .../components/uni-sub-menu/uni-sub-menu.vue | 164 + alpha/admin/i18n/en.json | 107 + alpha/admin/i18n/index.js | 8 + alpha/admin/i18n/zh-Hans.json | 107 + alpha/admin/i18n/zh-Hant.json | 107 + alpha/admin/index.html | 20 + alpha/admin/js_sdk/uni-admin/constants.js | 66 + alpha/admin/js_sdk/uni-admin/error.js | 42 + alpha/admin/js_sdk/uni-admin/fetchMock.js | 23 + alpha/admin/js_sdk/uni-admin/interceptor.js | 15 + alpha/admin/js_sdk/uni-admin/permission.js | 27 + alpha/admin/js_sdk/uni-admin/plugin.js | 34 + alpha/admin/js_sdk/uni-admin/request.js | 77 + alpha/admin/js_sdk/uni-admin/util.js | 29 + alpha/admin/js_sdk/uni-id-pages/store.js | 13 + alpha/admin/js_sdk/uni-stat/timeUtil.js | 186 + alpha/admin/js_sdk/uni-stat/util.js | 483 ++ .../js_sdk/validator/opendb-admin-menus.js | 77 + .../admin/js_sdk/validator/opendb-app-list.js | 123 + .../js_sdk/validator/opendb-app-versions.js | 157 + alpha/admin/js_sdk/validator/uni-id-log.js | 38 + .../js_sdk/validator/uni-id-permissions.js | 84 + alpha/admin/js_sdk/validator/uni-id-roles.js | 99 + alpha/admin/js_sdk/validator/uni-id-tag.js | 84 + alpha/admin/js_sdk/validator/uni-id-users.js | 191 + .../admin/js_sdk/validator/uni-pay-orders.js | 304 + .../validator/uni-stat-app-crash-logs.js | 264 + alpha/admin/main.js | 43 + alpha/admin/manifest.json | 82 + alpha/admin/mock/uni-stat/appOverview.json | 14 + alpha/admin/mock/uni-stat/appsDetail.json | 17 + alpha/admin/mock/uni-stat/db.js | 11 + alpha/admin/mock/uni-stat/event.json | 87 + alpha/admin/mock/uni-stat/pageContent.json | 508 ++ alpha/admin/mock/uni-stat/pageEnt.json | 337 + alpha/admin/mock/uni-stat/pageRes.json | 397 + alpha/admin/mock/uni-stat/pageRule.json | 132 + alpha/admin/mock/uni-stat/userActivity.json | 73 + alpha/admin/package.json | 93 + alpha/admin/pages.json | 491 ++ alpha/admin/pages/demo/icons/icons.vue | 111 + alpha/admin/pages/demo/icons/uni-icons.js | 132 + alpha/admin/pages/demo/table/table.vue | 144 + alpha/admin/pages/demo/table/tableData.js | 193 + alpha/admin/pages/error/404.vue | 41 + alpha/admin/pages/index/fieldsMap.js | 82 + alpha/admin/pages/index/index.vue | 361 + alpha/admin/pages/system/app/add.vue | 490 ++ alpha/admin/pages/system/app/list.vue | 292 + .../app/mixin/publish_add_detail_mixin.js | 273 + .../system/app/uni-portal/uni-portal.vue | 161 + alpha/admin/pages/system/menu/add.vue | 164 + alpha/admin/pages/system/menu/edit.vue | 188 + alpha/admin/pages/system/menu/list.vue | 487 ++ .../pages/system/menu/originalMenuList.json | 416 + alpha/admin/pages/system/permission/add.vue | 98 + alpha/admin/pages/system/permission/edit.vue | 128 + alpha/admin/pages/system/permission/list.vue | 234 + alpha/admin/pages/system/role/add.vue | 102 + alpha/admin/pages/system/role/edit.vue | 132 + alpha/admin/pages/system/role/list.vue | 237 + alpha/admin/pages/system/safety/list.vue | 132 + alpha/admin/pages/system/tag/add.vue | 100 + alpha/admin/pages/system/tag/edit.vue | 129 + alpha/admin/pages/system/tag/list.vue | 241 + alpha/admin/pages/system/user/add.vue | 193 + alpha/admin/pages/system/user/edit.vue | 338 + alpha/admin/pages/system/user/list.vue | 462 + .../admin/pages/uni-stat/channel/channel.vue | 476 + .../admin/pages/uni-stat/channel/fieldsMap.js | 74 + .../uni-stat/device/activity/activity.vue | 442 + .../uni-stat/device/activity/fieldsMap.js | 48 + .../uni-stat/device/comparison/comparison.vue | 219 + .../uni-stat/device/overview/fieldsMap.js | 122 + .../uni-stat/device/overview/overview.vue | 564 ++ .../uni-stat/device/retention/fieldsMap.js | 57 + .../uni-stat/device/retention/retention.vue | 442 + .../uni-stat/device/stickiness/fieldsMap.js | 48 + .../uni-stat/device/stickiness/stickiness.vue | 423 + .../pages/uni-stat/device/trend/fieldsMap.js | 79 + .../pages/uni-stat/device/trend/trend.vue | 425 + alpha/admin/pages/uni-stat/error/app/app.vue | 577 ++ .../pages/uni-stat/error/app/fieldsMap.js | 210 + .../admin/pages/uni-stat/error/js/detail.vue | 125 + .../pages/uni-stat/error/js/fieldsMap.js | 69 + alpha/admin/pages/uni-stat/error/js/js.vue | 1020 +++ .../pages/uni-stat/error/js/uploadTask.vue | 62 + alpha/admin/pages/uni-stat/event/event.vue | 271 + alpha/admin/pages/uni-stat/event/fieldsMap.js | 43 + .../pages/uni-stat/page-ent/fieldsMap.js | 64 + .../pages/uni-stat/page-ent/page-ent.vue | 322 + .../pages/uni-stat/page-res/fieldsMap.js | 73 + .../pages/uni-stat/page-res/page-res.vue | 364 + .../uni-stat/pay-order/components/test.vue | 64 + .../funnel/components/funnelChart.vue | 217 + .../funnel/components/trendChart.vue | 254 + .../uni-stat/pay-order/funnel/fieldsMap.js | 30 + .../uni-stat/pay-order/funnel/funnel.vue | 119 + .../pages/uni-stat/pay-order/list/list.vue | 514 ++ .../overview/components/statPanelToday.vue | 232 + .../overview/components/statPanelTotal.vue | 317 + .../overview/components/trendChart.vue | 279 + .../uni-stat/pay-order/overview/fieldsMap.js | 77 + .../uni-stat/pay-order/overview/overview.vue | 110 + .../uni-stat/pay-order/ranking/ranking.vue | 348 + alpha/admin/pages/uni-stat/scene/fieldsMap.js | 84 + alpha/admin/pages/uni-stat/scene/scene.vue | 382 + .../pages/uni-stat/user/activity/activity.vue | 447 + .../pages/uni-stat/user/activity/fieldsMap.js | 50 + .../uni-stat/user/comparison/comparison.vue | 205 + .../pages/uni-stat/user/overview/fieldsMap.js | 102 + .../pages/uni-stat/user/overview/overview.vue | 417 + .../uni-stat/user/retention/fieldsMap.js | 56 + .../uni-stat/user/retention/retention.vue | 439 + .../uni-stat/user/stickiness/fieldsMap.js | 48 + .../uni-stat/user/stickiness/stickiness.vue | 419 + .../pages/uni-stat/user/trend/fieldsMap.js | 56 + .../admin/pages/uni-stat/user/trend/trend.vue | 426 + alpha/admin/postcss.config.js | 44 + alpha/admin/static/admin-icons.ttf | Bin 0 -> 18340 bytes alpha/admin/static/logo.png | Bin 0 -> 22521 bytes alpha/admin/store/constants.js | 5 + alpha/admin/store/index.js | 41 + alpha/admin/store/modules/app.js | 67 + alpha/admin/store/modules/error.js | 33 + alpha/admin/store/modules/user.js | 23 + alpha/admin/template.h5.html | 27 + alpha/admin/uni.scss | 102 + .../cloudfunctions/common/uni-stat/index.js | 23 + .../common/uni-stat/package.json | 15 + .../common/uni-stat/shared/create-api.js | 82 + .../common/uni-stat/shared/error.js | 19 + .../common/uni-stat/shared/index.js | 6 + .../common/uni-stat/shared/utils.js | 197 + .../common/uni-stat/stat/lib/date.js | 371 + .../common/uni-stat/stat/lib/index.js | 4 + .../common/uni-stat/stat/lib/uni-crypto.js | 98 + .../common/uni-stat/stat/mod/activeDevices.js | 528 ++ .../common/uni-stat/stat/mod/activeUsers.js | 314 + .../common/uni-stat/stat/mod/appCrashLogs.js | 37 + .../common/uni-stat/stat/mod/base.js | 485 ++ .../common/uni-stat/stat/mod/channel.js | 107 + .../common/uni-stat/stat/mod/device.js | 184 + .../common/uni-stat/stat/mod/errorLog.js | 141 + .../common/uni-stat/stat/mod/errorResult.js | 459 + .../common/uni-stat/stat/mod/event.js | 72 + .../common/uni-stat/stat/mod/eventLog.js | 156 + .../common/uni-stat/stat/mod/eventResult.js | 268 + .../common/uni-stat/stat/mod/index.js | 23 + .../common/uni-stat/stat/mod/loyalty.js | 491 ++ .../common/uni-stat/stat/mod/page.js | 83 + .../common/uni-stat/stat/mod/pageLog.js | 186 + .../common/uni-stat/stat/mod/pageResult.js | 522 ++ .../common/uni-stat/stat/mod/platform.js | 160 + .../common/uni-stat/stat/mod/runErrors.js | 20 + .../common/uni-stat/stat/mod/scenes.js | 80 + .../common/uni-stat/stat/mod/sessionLog.js | 343 + .../common/uni-stat/stat/mod/setting.js | 44 + .../common/uni-stat/stat/mod/shareLog.js | 104 + .../common/uni-stat/stat/mod/statResult.js | 2151 +++++ .../uni-stat/stat/mod/uni-pay/dao/config.js | 12 + .../uni-stat/stat/mod/uni-pay/dao/index.js | 10 + .../stat/mod/uni-pay/dao/uniIdUsers.js | 62 + .../stat/mod/uni-pay/dao/uniPayOrders.js | 99 + .../stat/mod/uni-pay/dao/uniStatPayResult.js | 36 + .../mod/uni-pay/dao/uniStatSessionLogs.js | 78 + .../mod/uni-pay/dao/uniStatUserSessionLogs.js | 78 + .../common/uni-stat/stat/mod/uni-pay/index.js | 6 + .../uni-stat/stat/mod/uni-pay/payResult.js | 500 ++ .../common/uni-stat/stat/mod/uniIDUsers.js | 97 + .../uni-stat/stat/mod/userSessionLog.js | 229 + .../common/uni-stat/stat/mod/version.js | 73 + .../common/uni-stat/stat/receiver.js | 126 + .../common/uni-stat/stat/stat.js | 388 + .../uni-analyse-searchhot/index.js | 49 + .../uni-analyse-searchhot/package.json | 14 + .../uni-portal/createPublishHtml/index.js | 188 + .../createPublishHtml/lib/art-template.js | 2 + .../createPublishHtml/template.html | 238 + .../cloudfunctions/uni-portal/index.js | 25 + .../cloudfunctions/uni-portal/package.json | 7 + .../uni-sms-co/build-template-data.js | 26 + .../cloudfunctions/uni-sms-co/index.obj.js | 414 + .../cloudfunctions/uni-sms-co/package.json | 10 + .../uni-sms-co/preset-condition.js | 82 + .../uni-sms-co/schema-name-adapter.js | 15 + .../cloudfunctions/uni-sms-co/utils.js | 42 + .../cloudfunctions/uni-stat-cron/index.js | 6 + .../cloudfunctions/uni-stat-cron/package.json | 27 + .../uni-stat-receiver/index.obj.js | 29 + .../uni-stat-receiver/package.json | 16 + .../uni-stat-receiver.param.js | 2 + .../uni-upgrade-center/checkVersion/index.js | 167 + .../uni-upgrade-center/index.js | 91 + .../uni-upgrade-center/package.json | 7 + .../uni-app-manager.param.json | 10 + .../database/JQL file Name.jql | 12 + .../uniCloud-aliyun/database/db_init.json | 549 ++ .../database/opendb-admin-menus.schema.json | 59 + .../database/opendb-app-list.schema.json | 325 + .../database/opendb-app-versions.schema.json | 178 + .../database/opendb-banner.schema.json | 54 + .../database/opendb-news-articles.schema.json | 165 + .../opendb-news-categories.schema.json | 50 + .../database/opendb-news-comments.schema.json | 68 + .../database/opendb-news-favorite.schema.json | 46 + .../database/opendb-search-hot.schema.json | 27 + .../database/opendb-search-log.schema.json | 31 + .../database/opendb-sms-log.schema.json | 63 + .../database/opendb-sms-task.schema.json | 81 + .../database/opendb-sms-template.schema.json | 32 + .../database/opendb-tempdata.schema.json | 22 + .../database/read-news-log.schema.json | 35 + .../database/uni-id-scores.schema.json | 44 + .../database/uni-id-tag.schema.json | 52 + .../database/uni-pay-orders.schema.json | 247 + .../uni-stat-active-devices.schema.json | 67 + .../uni-stat-active-users.schema.json | 55 + .../uni-stat-app-channels.schema.json | 44 + .../uni-stat-app-crash-logs.schema.json | 137 + .../uni-stat-app-platforms.schema.json | 46 + .../uni-stat-app-versions.schema.json | 38 + .../database/uni-stat-error-logs.schema.json | 102 + .../uni-stat-error-result.schema.json | 96 + .../uni-stat-error-source-map.schema.ext.js | 29 + .../uni-stat-error-source-map.schema.json | 61 + .../database/uni-stat-event-logs.schema.json | 116 + .../uni-stat-event-result.schema.json | 82 + .../database/uni-stat-events.schema.json | 38 + .../uni-stat-loyalty-result.schema.json | 84 + .../database/uni-stat-mp-scenes.schema.json | 34 + .../database/uni-stat-page-logs.schema.json | 79 + .../database/uni-stat-page-result.schema.json | 114 + .../database/uni-stat-pages.schema.json | 34 + .../database/uni-stat-pay-result.schema.json | 169 + .../database/uni-stat-result.schema.json | 156 + .../database/uni-stat-run-errors.schema.json | 33 + .../uni-stat-session-logs.schema.json | 192 + .../database/uni-stat-share-logs.schema.json | 55 + .../uni-stat-user-session-logs.schema.json | 82 + .../uni_modules/qiun-data-charts/changelog.md | 320 + .../qiun-data-charts/qiun-data-charts.vue | 1625 ++++ .../components/qiun-error/qiun-error.vue | 46 + .../components/qiun-loading/loading1.vue | 162 + .../components/qiun-loading/loading2.vue | 170 + .../components/qiun-loading/loading3.vue | 173 + .../components/qiun-loading/loading4.vue | 222 + .../components/qiun-loading/loading5.vue | 229 + .../components/qiun-loading/qiun-loading.vue | 36 + .../js_sdk/u-charts/config-echarts.js | 422 + .../js_sdk/u-charts/config-ucharts.js | 606 ++ .../js_sdk/u-charts/readme.md | 5 + .../js_sdk/u-charts/u-charts.js | 7706 +++++++++++++++++ .../js_sdk/u-charts/u-charts.min.js | 18 + .../uni_modules/qiun-data-charts/license.md | 201 + .../uni_modules/qiun-data-charts/package.json | 81 + .../uni_modules/qiun-data-charts/readme.md | 84 + .../static/app-plus/echarts.min.js | 23 + .../qiun-data-charts/static/h5/echarts.min.js | 23 + .../admin/uni_modules/uni-badge/changelog.md | 33 + .../components/uni-badge/uni-badge.vue | 268 + .../admin/uni_modules/uni-badge/package.json | 85 + alpha/admin/uni_modules/uni-badge/readme.md | 10 + .../uni_modules/uni-breadcrumb/changelog.md | 6 + .../uni-breadcrumb-item.vue | 121 + .../uni-breadcrumb/uni-breadcrumb.vue | 41 + .../uni_modules/uni-breadcrumb/package.json | 85 + .../uni_modules/uni-breadcrumb/readme.md | 66 + .../uni_modules/uni-captcha/changelog.md | 37 + .../components/uni-captcha/uni-captcha.vue | 167 + .../uni-popup-captcha/uni-popup-captcha.vue | 140 + .../uni_modules/uni-captcha/package.json | 81 + alpha/admin/uni_modules/uni-captcha/readme.md | 3 + .../common/uni-captcha/LICENSE.md | 201 + .../common/uni-captcha/fonts/font.ttf | Bin 0 -> 7080 bytes .../common/uni-captcha/index.js | 1 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../common/uni-captcha/package.json | 16 + .../cloudfunctions/uni-captcha-co/config.js | 17 + .../uni-captcha-co/index.obj.js | 32 + .../uni-captcha-co/package.json | 10 + .../database/opendb-verify-codes.schema.json | 45 + alpha/admin/uni_modules/uni-card/changelog.md | 26 + .../uni-card/components/uni-card/uni-card.vue | 270 + alpha/admin/uni_modules/uni-card/package.json | 90 + alpha/admin/uni_modules/uni-card/readme.md | 12 + .../uni_modules/uni-cloud-router/changelog.md | 4 + .../uni_modules/uni-cloud-router/package.json | 80 + .../uni_modules/uni-cloud-router/readme.md | 1 + .../admin/uni_modules/uni-combox/changelog.md | 15 + .../components/uni-combox/uni-combox.vue | 282 + .../admin/uni_modules/uni-combox/package.json | 90 + alpha/admin/uni_modules/uni-combox/readme.md | 11 + .../uni-config-center/changelog.md | 6 + .../uni-config-center/package.json | 81 + .../uni_modules/uni-config-center/readme.md | 93 + .../common/uni-config-center/index.js | 1 + .../common/uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../uni-data-checkbox/changelog.md | 45 + .../components/uni-data-checkbox/clientdb.js | 316 + .../uni-data-checkbox/uni-data-checkbox.vue | 821 ++ .../uni-data-checkbox/package.json | 84 + .../uni_modules/uni-data-checkbox/readme.md | 18 + .../uni_modules/uni-data-picker/changelog.md | 68 + .../components/uni-data-picker/keypress.js | 45 + .../uni-data-picker/uni-data-picker.vue | 554 ++ .../uni-data-pickerview/uni-data-picker.js | 563 ++ .../uni-data-pickerview.vue | 335 + .../uni_modules/uni-data-picker/package.json | 90 + .../uni_modules/uni-data-picker/readme.md | 22 + .../uni_modules/uni-data-select/changelog.md | 31 + .../uni-data-select/uni-data-select.vue | 502 ++ .../uni_modules/uni-data-select/package.json | 85 + .../uni_modules/uni-data-select/readme.md | 8 + .../uni_modules/uni-dateformat/changelog.md | 10 + .../components/uni-dateformat/date-format.js | 200 + .../uni-dateformat/uni-dateformat.vue | 88 + .../uni_modules/uni-dateformat/package.json | 88 + .../uni_modules/uni-dateformat/readme.md | 11 + .../uni-datetime-picker/changelog.md | 133 + .../uni-datetime-picker/calendar-item.vue | 177 + .../uni-datetime-picker/calendar.js | 546 ++ .../uni-datetime-picker/calendar.vue | 928 ++ .../uni-datetime-picker/i18n/en.json | 22 + .../uni-datetime-picker/i18n/index.js | 8 + .../uni-datetime-picker/i18n/zh-Hans.json | 22 + .../uni-datetime-picker/i18n/zh-Hant.json | 22 + .../uni-datetime-picker/keypress.js | 45 + .../uni-datetime-picker/time-picker.vue | 934 ++ .../uni-datetime-picker.vue | 1026 +++ .../components/uni-datetime-picker/util.js | 403 + .../uni-datetime-picker/package.json | 87 + .../uni_modules/uni-datetime-picker/readme.md | 21 + .../admin/uni_modules/uni-drawer/changelog.md | 13 + .../components/uni-drawer/keypress.js | 45 + .../components/uni-drawer/uni-drawer.vue | 183 + .../admin/uni_modules/uni-drawer/package.json | 87 + alpha/admin/uni_modules/uni-drawer/readme.md | 10 + .../uni_modules/uni-easyinput/changelog.md | 91 + .../components/uni-easyinput/common.js | 56 + .../uni-easyinput/uni-easyinput.vue | 650 ++ .../uni_modules/uni-easyinput/package.json | 87 + .../admin/uni_modules/uni-easyinput/readme.md | 11 + .../uni_modules/uni-feedback/changelog.md | 8 + .../js_sdk/validator/opendb-feedback.js | 98 + .../uni_modules/uni-feedback/package.json | 92 + .../pages/opendb-feedback/detail.vue | 113 + .../pages/opendb-feedback/edit.vue | 167 + .../pages/opendb-feedback/list.vue | 70 + .../pages/opendb-feedback/opendb-feedback.vue | 141 + .../admin/uni_modules/uni-feedback/readme.md | 1 + .../database/opendb-feedback.schema.json | 53 + .../uni_modules/uni-file-picker/changelog.md | 65 + .../uni-file-picker/choose-and-upload-file.js | 224 + .../uni-file-picker/uni-file-picker.vue | 663 ++ .../uni-file-picker/upload-file.vue | 325 + .../uni-file-picker/upload-image.vue | 292 + .../components/uni-file-picker/utils.js | 109 + .../uni_modules/uni-file-picker/package.json | 83 + .../uni_modules/uni-file-picker/readme.md | 11 + .../admin/uni_modules/uni-forms/changelog.md | 90 + .../uni-forms-item/uni-forms-item.vue | 631 ++ .../components/uni-forms/uni-forms.vue | 397 + .../uni-forms/components/uni-forms/utils.js | 293 + .../components/uni-forms/validate.js | 486 ++ .../admin/uni_modules/uni-forms/package.json | 88 + alpha/admin/uni_modules/uni-forms/readme.md | 23 + .../admin/uni_modules/uni-group/changelog.md | 16 + .../components/uni-group/uni-group.vue | 134 + .../admin/uni_modules/uni-group/package.json | 87 + alpha/admin/uni_modules/uni-group/readme.md | 9 + .../admin/uni_modules/uni-icons/changelog.md | 22 + .../uni-icons/components/uni-icons/icons.js | 1169 +++ .../components/uni-icons/uni-icons.vue | 96 + .../uni-icons/components/uni-icons/uni.ttf | Bin 0 -> 26164 bytes .../components/uni-icons/uniicons.css | 663 ++ .../components/uni-icons/uniicons.ttf | Bin 0 -> 35760 bytes .../admin/uni_modules/uni-icons/package.json | 86 + alpha/admin/uni_modules/uni-icons/readme.md | 8 + .../uni_modules/uni-id-common/changelog.md | 26 + .../uni_modules/uni-id-common/package.json | 87 + .../admin/uni_modules/uni-id-common/readme.md | 3 + .../common/uni-id-common/index.js | 1 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../common/uni-id-common/package.json | 16 + .../uni_modules/uni-id-pages/changelog.md | 128 + .../uni_modules/uni-id-pages/common/common.js | 13 + .../uni-id-pages/common/login-page.mixin.js | 88 + .../uni-id-pages/common/login-page.scss | 126 + .../uni-id-pages/common/loginSuccess.js | 45 + .../uni-id-pages/common/password.js | 85 + .../uni_modules/uni-id-pages/common/store.js | 160 + .../components/cloud-image/cloud-image.vue | 73 + .../uni-id-pages-agreements.vue | 167 + .../uni-id-pages-avatar.vue | 183 + .../uni-id-pages-bind-mobile.vue | 160 + .../uni-id-pages-email-form.vue | 248 + .../uni-id-pages-fab-login.vue | 558 ++ .../uni-id-pages-sms-form.vue | 242 + .../uni-id-pages-user-profile.vue | 171 + .../admin/uni_modules/uni-id-pages/config.js | 56 + alpha/admin/uni_modules/uni-id-pages/init.js | 96 + .../uni_modules/uni-id-pages/package.json | 101 + .../pages/common/webview/webview.vue | 35 + .../pages/login/login-smscode.vue | 120 + .../pages/login/login-withoutpwd.vue | 241 + .../pages/login/login-withpwd.vue | 176 + .../pages/register/register-admin.vue | 178 + .../pages/register/register-by-email.vue | 216 + .../uni-id-pages/pages/register/register.vue | 181 + .../uni-id-pages/pages/register/validator.js | 56 + .../pages/retrieve/retrieve-by-email.vue | 218 + .../uni-id-pages/pages/retrieve/retrieve.vue | 241 + .../userinfo/bind-mobile/bind-mobile.vue | 131 + .../pages/userinfo/change_pwd/change_pwd.vue | 130 + .../pages/userinfo/cropImage/cropImage.vue | 39 + .../userinfo/cropImage/limeClipper/README.md | 227 + .../cropImage/limeClipper/images/photo.svg | 19 + .../cropImage/limeClipper/images/rotate.svg | 15 + .../userinfo/cropImage/limeClipper/index.css | 160 + .../cropImage/limeClipper/limeClipper.vue | 820 ++ .../userinfo/cropImage/limeClipper/utils.js | 244 + .../pages/userinfo/deactivate/deactivate.vue | 117 + .../pages/userinfo/set-pwd/set-pwd.vue | 169 + .../uni-id-pages/pages/userinfo/userinfo.vue | 248 + .../admin/uni_modules/uni-id-pages/readme.md | 15 + .../uni-id-pages/static/app-plus/apple.png | Bin 0 -> 10282 bytes .../static/app-plus/uni-fab-login/alipay.png | Bin 0 -> 3978 bytes .../static/app-plus/uni-fab-login/apple.png | Bin 0 -> 3226 bytes .../static/app-plus/uni-fab-login/douyin.png | Bin 0 -> 3163 bytes .../app-plus/uni-fab-login/facebook.png | Bin 0 -> 3065 bytes .../static/app-plus/uni-fab-login/google.png | Bin 0 -> 4333 bytes .../static/app-plus/uni-fab-login/qq.png | Bin 0 -> 3449 bytes .../app-plus/uni-fab-login/sinaweibo.png | Bin 0 -> 4081 bytes .../static/app-plus/uni-fab-login/taobao.png | Bin 0 -> 4339 bytes .../app-plus/uni-fab-login/univerify.png | Bin 0 -> 3365 bytes .../uni-id-pages/static/limeClipper/photo.svg | 19 + .../static/limeClipper/rotate.svg | 15 + .../uni-id-pages/static/login/apple.png | Bin 0 -> 18205 bytes .../static/login/uni-fab-login/sms.png | Bin 0 -> 4285 bytes .../static/login/uni-fab-login/user.png | Bin 0 -> 2997 bytes .../static/login/uni-fab-login/weixin.png | Bin 0 -> 3934 bytes .../uni-id-pages/static/login/weixin.png | Bin 0 -> 11483 bytes .../static/uni-center/defaultAvatarUrl.png | Bin 0 -> 5947 bytes .../uni-id-pages/static/uni-center/grey.png | Bin 0 -> 6669 bytes .../static/uni-center/headers.png | Bin 0 -> 33054 bytes .../static/uni-fab-login/alipay.png | Bin 0 -> 6184 bytes .../static/uni-fab-login/apple.png | Bin 0 -> 9231 bytes .../static/uni-fab-login/douyin.png | Bin 0 -> 5911 bytes .../static/uni-fab-login/facebook.png | Bin 0 -> 4184 bytes .../static/uni-fab-login/google.png | Bin 0 -> 9718 bytes .../uni-id-pages/static/uni-fab-login/qq.png | Bin 0 -> 6441 bytes .../static/uni-fab-login/sinaweibo.png | Bin 0 -> 7920 bytes .../uni-id-pages/static/uni-fab-login/sms.png | Bin 0 -> 18264 bytes .../static/uni-fab-login/taobao.png | Bin 0 -> 12011 bytes .../static/uni-fab-login/univerify.png | Bin 0 -> 8719 bytes .../static/uni-fab-login/user.png | Bin 0 -> 8175 bytes .../static/uni-fab-login/weixin.png | Bin 0 -> 17743 bytes .../uni-id-co/common/constants.js | 92 + .../cloudfunctions/uni-id-co/common/error.js | 60 + .../uni-id-co/common/universal.js | 47 + .../cloudfunctions/uni-id-co/common/utils.js | 214 + .../uni-id-co/common/validator.js | 439 + .../uni-id-co/config/permission.js | 81 + .../cloudfunctions/uni-id-co/index.obj.js | 616 ++ .../cloudfunctions/uni-id-co/lang/en.js | 52 + .../cloudfunctions/uni-id-co/lang/index.js | 22 + .../cloudfunctions/uni-id-co/lang/zh-hans.js | 52 + .../cloudfunctions/uni-id-co/lib/README.md | 3 + .../lib/third-party/alipay/account/index.js | 16 + .../third-party/alipay/account/protocols.js | 10 + .../lib/third-party/alipay/alipayBase.js | 231 + .../lib/third-party/apple/account/index.js | 76 + .../third-party/apple/rsa-public-key-pem.js | 64 + .../uni-id-co/lib/third-party/index.js | 36 + .../lib/third-party/qq/account/index.js | 97 + .../lib/third-party/qq/account/protocol.js | 0 .../uni-id-co/lib/third-party/qq/normalize.js | 85 + .../lib/third-party/share/create-api.js | 73 + .../lib/third-party/weixin/account/index.js | 111 + .../lib/third-party/weixin/normalize.js | 95 + .../uni-id-co/lib/third-party/weixin/utils.js | 87 + .../uni-id-co/lib/utils/account.js | 97 + .../uni-id-co/lib/utils/captcha.js | 76 + .../uni-id-co/lib/utils/config.js | 135 + .../uni-id-co/lib/utils/fission.js | 192 + .../uni-id-co/lib/utils/login.js | 240 + .../uni-id-co/lib/utils/logout.js | 49 + .../uni-id-co/lib/utils/password.js | 261 + .../cloudfunctions/uni-id-co/lib/utils/qq.js | 152 + .../uni-id-co/lib/utils/register.js | 215 + .../uni-id-co/lib/utils/relate.js | 164 + .../cloudfunctions/uni-id-co/lib/utils/sms.js | 81 + .../uni-id-co/lib/utils/unified-login.js | 106 + .../uni-id-co/lib/utils/univerify.js | 27 + .../uni-id-co/lib/utils/update-user-info.js | 25 + .../uni-id-co/lib/utils/utils.js | 18 + .../uni-id-co/lib/utils/verify-code.js | 152 + .../uni-id-co/lib/utils/weixin.js | 234 + .../uni-id-co/middleware/access-control.js | 59 + .../uni-id-co/middleware/auth.js | 17 + .../uni-id-co/middleware/index.js | 8 + .../uni-id-co/middleware/rbac.js | 39 + .../uni-id-co/middleware/uni-id-log.js | 39 + .../uni-id-co/middleware/validate.js | 7 + .../middleware/verify-request-sign.js | 39 + .../uni-id-co/module/account/close-account.js | 16 + .../module/account/get-account-info.js | 69 + .../uni-id-co/module/account/index.js | 8 + .../module/account/reset-pwd-by-email.js | 128 + .../module/account/reset-pwd-by-sms.js | 128 + .../uni-id-co/module/account/set-pwd.js | 83 + .../uni-id-co/module/account/update-pwd.js | 69 + .../uni-id-co/module/admin/add-user.js | 121 + .../uni-id-co/module/admin/index.js | 4 + .../uni-id-co/module/admin/update-user.js | 139 + .../module/dev/get-supported-login-type.js | 71 + .../uni-id-co/module/dev/index.js | 3 + .../uni-id-co/module/external/index.js | 4 + .../uni-id-co/module/external/login.js | 29 + .../uni-id-co/module/external/register.js | 52 + .../uni-id-co/module/fission/accept-invite.js | 25 + .../module/fission/get-invited-user.js | 80 + .../uni-id-co/module/fission/index.js | 4 + .../uni-id-co/module/login/index.js | 20 + .../uni-id-co/module/login/login-by-alipay.js | 70 + .../uni-id-co/module/login/login-by-apple.js | 77 + .../uni-id-co/module/login/login-by-baidu.js | 9 + .../module/login/login-by-dingtalk.js | 9 + .../uni-id-co/module/login/login-by-douyin.js | 9 + .../module/login/login-by-email-code.js | 9 + .../module/login/login-by-email-link.js | 9 + .../module/login/login-by-facebook.js | 9 + .../uni-id-co/module/login/login-by-google.js | 9 + .../uni-id-co/module/login/login-by-qq.js | 164 + .../uni-id-co/module/login/login-by-sms.js | 99 + .../uni-id-co/module/login/login-by-taobao.js | 9 + .../module/login/login-by-toutiao.js | 9 + .../module/login/login-by-univerify.js | 69 + .../uni-id-co/module/login/login-by-weibo.js | 9 + .../module/login/login-by-weixin-mobile.js | 106 + .../uni-id-co/module/login/login-by-weixin.js | 175 + .../uni-id-co/module/login/login.js | 94 + .../uni-id-co/module/logout/index.js | 3 + .../uni-id-co/module/logout/logout.js | 15 + .../module/multi-end/authorize-app-login.js | 37 + .../uni-id-co/module/multi-end/index.js | 5 + .../module/multi-end/remove-authorized-app.js | 30 + .../module/multi-end/set-authorized-app.js | 36 + .../uni-id-co/module/multi-end/utils.js | 38 + .../uni-id-co/module/register/index.js | 5 + .../module/register/register-admin.js | 72 + .../module/register/register-user-by-email.js | 87 + .../module/register/register-user.js | 68 + .../uni-id-co/module/relate/bind-alipay.js | 63 + .../uni-id-co/module/relate/bind-apple.js | 62 + .../module/relate/bind-mobile-by-mp-weixin.js | 104 + .../module/relate/bind-mobile-by-sms.js | 92 + .../module/relate/bind-mobile-by-univerify.js | 70 + .../uni-id-co/module/relate/bind-qq.js | 110 + .../uni-id-co/module/relate/bind-weixin.js | 100 + .../uni-id-co/module/relate/index.js | 13 + .../uni-id-co/module/relate/unbind-alipay.js | 32 + .../uni-id-co/module/relate/unbind-apple.js | 32 + .../uni-id-co/module/relate/unbind-qq.js | 46 + .../uni-id-co/module/relate/unbind-weixin.js | 40 + .../uni-id-co/module/utils/index.js | 5 + .../uni-id-co/module/utils/refresh-token.js | 19 + .../secure-network-handshake-by-weixin.js | 73 + .../uni-id-co/module/utils/set-push-cid.js | 141 + .../uni-id-co/module/verify/create-captcha.js | 34 + .../uni-id-co/module/verify/index.js | 7 + .../module/verify/refresh-captcha.js | 34 + .../module/verify/send-email-code.js | 60 + .../module/verify/send-email-link.js | 12 + .../uni-id-co/module/verify/send-sms-code.js | 71 + .../uni-id-co/node_modules/.bin/semver | 15 + .../uni-id-co/node_modules/.bin/semver.cmd | 17 + .../uni-id-co/node_modules/.bin/semver.ps1 | 18 + .../buffer-equal-constant-time/.npmignore | 2 + .../buffer-equal-constant-time/.travis.yml | 4 + .../buffer-equal-constant-time/LICENSE.txt | 12 + .../buffer-equal-constant-time/README.md | 50 + .../buffer-equal-constant-time/index.js | 41 + .../buffer-equal-constant-time/package.json | 55 + .../buffer-equal-constant-time/test.js | 42 + .../ecdsa-sig-formatter/CODEOWNERS | 1 + .../node_modules/ecdsa-sig-formatter/LICENSE | 201 + .../ecdsa-sig-formatter/README.md | 65 + .../ecdsa-sig-formatter/package.json | 73 + .../src/ecdsa-sig-formatter.d.ts | 17 + .../src/ecdsa-sig-formatter.js | 187 + .../src/param-bytes-for-alg.js | 23 + .../node_modules/jsonwebtoken/CHANGELOG.md | 476 + .../node_modules/jsonwebtoken/LICENSE | 21 + .../node_modules/jsonwebtoken/README.md | 375 + .../node_modules/jsonwebtoken/decode.js | 30 + .../node_modules/jsonwebtoken/index.js | 8 + .../jsonwebtoken/lib/JsonWebTokenError.js | 14 + .../jsonwebtoken/lib/NotBeforeError.js | 13 + .../jsonwebtoken/lib/TokenExpiredError.js | 13 + .../jsonwebtoken/lib/psSupported.js | 3 + .../node_modules/jsonwebtoken/lib/timespan.js | 18 + .../node_modules/jsonwebtoken/package.json | 99 + .../node_modules/jsonwebtoken/sign.js | 206 + .../node_modules/jsonwebtoken/verify.js | 225 + .../uni-id-co/node_modules/jwa/LICENSE | 17 + .../uni-id-co/node_modules/jwa/README.md | 150 + .../uni-id-co/node_modules/jwa/index.js | 252 + .../uni-id-co/node_modules/jwa/package.json | 69 + .../uni-id-co/node_modules/jws/CHANGELOG.md | 34 + .../uni-id-co/node_modules/jws/LICENSE | 17 + .../uni-id-co/node_modules/jws/index.js | 22 + .../node_modules/jws/lib/data-stream.js | 55 + .../node_modules/jws/lib/sign-stream.js | 78 + .../node_modules/jws/lib/tostring.js | 10 + .../node_modules/jws/lib/verify-stream.js | 120 + .../uni-id-co/node_modules/jws/package.json | 64 + .../uni-id-co/node_modules/jws/readme.md | 255 + .../node_modules/lodash.includes/LICENSE | 47 + .../node_modules/lodash.includes/README.md | 18 + .../node_modules/lodash.includes/index.js | 745 ++ .../node_modules/lodash.includes/package.json | 69 + .../node_modules/lodash.isboolean/LICENSE | 22 + .../node_modules/lodash.isboolean/README.md | 18 + .../node_modules/lodash.isboolean/index.js | 70 + .../lodash.isboolean/package.json | 69 + .../node_modules/lodash.isinteger/LICENSE | 47 + .../node_modules/lodash.isinteger/README.md | 18 + .../node_modules/lodash.isinteger/index.js | 265 + .../lodash.isinteger/package.json | 69 + .../node_modules/lodash.isnumber/LICENSE | 22 + .../node_modules/lodash.isnumber/README.md | 18 + .../node_modules/lodash.isnumber/index.js | 79 + .../node_modules/lodash.isnumber/package.json | 69 + .../node_modules/lodash.isplainobject/LICENSE | 47 + .../lodash.isplainobject/README.md | 18 + .../lodash.isplainobject/index.js | 139 + .../lodash.isplainobject/package.json | 69 + .../node_modules/lodash.isstring/LICENSE | 22 + .../node_modules/lodash.isstring/README.md | 18 + .../node_modules/lodash.isstring/index.js | 95 + .../node_modules/lodash.isstring/package.json | 69 + .../node_modules/lodash.merge/LICENSE | 47 + .../node_modules/lodash.merge/README.md | 18 + .../node_modules/lodash.merge/index.js | 1977 +++++ .../node_modules/lodash.merge/package.json | 61 + .../node_modules/lodash.once/LICENSE | 47 + .../node_modules/lodash.once/README.md | 18 + .../node_modules/lodash.once/index.js | 294 + .../node_modules/lodash.once/package.json | 69 + .../uni-id-co/node_modules/ms/index.js | 162 + .../uni-id-co/node_modules/ms/license.md | 21 + .../uni-id-co/node_modules/ms/package.json | 70 + .../uni-id-co/node_modules/ms/readme.md | 59 + .../node_modules/safe-buffer/LICENSE | 21 + .../node_modules/safe-buffer/README.md | 584 ++ .../node_modules/safe-buffer/index.d.ts | 187 + .../node_modules/safe-buffer/index.js | 65 + .../node_modules/safe-buffer/package.json | 78 + .../node_modules/semver/CHANGELOG.md | 39 + .../uni-id-co/node_modules/semver/LICENSE | 15 + .../uni-id-co/node_modules/semver/README.md | 412 + .../uni-id-co/node_modules/semver/bin/semver | 160 + .../node_modules/semver/package.json | 60 + .../uni-id-co/node_modules/semver/range.bnf | 16 + .../uni-id-co/node_modules/semver/semver.js | 1483 ++++ .../node_modules/uni-captcha/LICENSE.md | 201 + .../node_modules/uni-captcha/fonts/font.ttf | Bin 0 -> 7080 bytes .../node_modules/uni-captcha/index.js | 1 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../node_modules/uni-captcha/package.json | 16 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../node_modules/uni-id-common/index.js | 1 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../node_modules/uni-id-common/package.json | 16 + .../uni-open-bridge-common/bridge-error.js | 26 + .../uni-open-bridge-common/config.js | 95 + .../uni-open-bridge-common/consts.js | 26 + .../uni-open-bridge-common/index.js | 221 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../uni-open-bridge-common/package.json | 15 + .../uni-open-bridge-common/storage.js | 117 + .../uni-open-bridge-common/uni-cloud-cache.js | 324 + .../uni-open-bridge-common/validator.js | 31 + .../uni-open-bridge-common/weixin-server.js | 202 + .../uni-id-co/package-lock.json | 148 + .../cloudfunctions/uni-id-co/package.json | 23 + .../database/opendb-department.schema.json | 50 + .../database/opendb-device.schema.json | 142 + .../database/uni-id-device.schema.json | 83 + .../uniCloud/database/uni-id-log.schema.json | 71 + .../database/uni-id-permissions.schema.json | 52 + .../database/uni-id-roles.schema.json | 50 + .../database/uni-id-users.schema.json | 465 + alpha/admin/uni_modules/uni-link/changelog.md | 17 + .../uni-link/components/uni-link/uni-link.vue | 128 + alpha/admin/uni_modules/uni-link/package.json | 87 + alpha/admin/uni_modules/uni-link/readme.md | 11 + alpha/admin/uni_modules/uni-list/changelog.md | 42 + .../components/uni-list-ad/uni-list-ad.vue | 107 + .../uni-list-chat/uni-list-chat.scss | 58 + .../uni-list-chat/uni-list-chat.vue | 586 ++ .../uni-list-item/uni-list-item.vue | 531 ++ .../uni-list/components/uni-list/uni-list.vue | 123 + .../components/uni-list/uni-refresh.vue | 65 + .../components/uni-list/uni-refresh.wxs | 87 + alpha/admin/uni_modules/uni-list/package.json | 88 + alpha/admin/uni_modules/uni-list/readme.md | 346 + .../uni_modules/uni-load-more/changelog.md | 19 + .../components/uni-load-more/i18n/en.json | 5 + .../components/uni-load-more/i18n/index.js | 8 + .../uni-load-more/i18n/zh-Hans.json | 5 + .../uni-load-more/i18n/zh-Hant.json | 5 + .../uni-load-more/uni-load-more.vue | 399 + .../uni_modules/uni-load-more/package.json | 86 + .../admin/uni_modules/uni-load-more/readme.md | 14 + .../uni_modules/uni-notice-bar/changelog.md | 18 + .../uni-notice-bar/uni-notice-bar.vue | 426 + .../uni_modules/uni-notice-bar/package.json | 87 + .../uni_modules/uni-notice-bar/readme.md | 13 + .../uni_modules/uni-number-box/changelog.md | 25 + .../uni-number-box/uni-number-box.vue | 220 + .../uni_modules/uni-number-box/package.json | 85 + .../uni_modules/uni-number-box/readme.md | 13 + .../uni-open-bridge-common/changelog.md | 8 + .../uni-open-bridge-common/package.json | 84 + .../uni-open-bridge-common/readme.md | 5 + .../uni-open-bridge-common/bridge-error.js | 26 + .../common/uni-open-bridge-common/config.js | 95 + .../common/uni-open-bridge-common/consts.js | 26 + .../common/uni-open-bridge-common/index.js | 221 + .../node_modules/uni-config-center/index.js | 1 + .../uni-config-center/package.json | 9 + .../uni-config-center/uni-ad/config.json | 3 + .../uni-config-center/uni-id/config.json | 77 + .../uni-open-bridge/config.json | 12 + .../uni-config-center/uni-sms-co/config.json | 4 + .../uni-config-center/uni-stat/config.json | 101 + .../uni-open-bridge-common/package.json | 15 + .../common/uni-open-bridge-common/storage.js | 117 + .../uni-open-bridge-common/uni-cloud-cache.js | 324 + .../uni-open-bridge-common/validator.js | 31 + .../uni-open-bridge-common/weixin-server.js | 202 + .../database/opendb-open-data.schema.json | 19 + .../uni_modules/uni-pagination/changelog.md | 27 + .../components/uni-pagination/i18n/en.json | 5 + .../components/uni-pagination/i18n/es.json | 5 + .../components/uni-pagination/i18n/fr.json | 5 + .../components/uni-pagination/i18n/index.js | 12 + .../uni-pagination/i18n/zh-Hans.json | 5 + .../uni-pagination/i18n/zh-Hant.json | 5 + .../uni-pagination/uni-pagination.vue | 465 + .../uni_modules/uni-pagination/package.json | 83 + .../uni_modules/uni-pagination/readme.md | 11 + .../admin/uni_modules/uni-popup/changelog.md | 64 + .../components/uni-popup-dialog/keypress.js | 45 + .../uni-popup-dialog/uni-popup-dialog.vue | 276 + .../uni-popup-message/uni-popup-message.vue | 143 + .../uni-popup-share/uni-popup-share.vue | 187 + .../components/uni-popup/i18n/en.json | 7 + .../components/uni-popup/i18n/index.js | 8 + .../components/uni-popup/i18n/zh-Hans.json | 7 + .../components/uni-popup/i18n/zh-Hant.json | 7 + .../components/uni-popup/keypress.js | 45 + .../uni-popup/components/uni-popup/message.js | 22 + .../uni-popup/components/uni-popup/popup.js | 26 + .../uni-popup/components/uni-popup/share.js | 16 + .../components/uni-popup/uni-popup.vue | 474 + .../admin/uni_modules/uni-popup/package.json | 87 + alpha/admin/uni_modules/uni-popup/readme.md | 17 + alpha/admin/uni_modules/uni-scss/changelog.md | 8 + alpha/admin/uni_modules/uni-scss/index.scss | 1 + alpha/admin/uni_modules/uni-scss/package.json | 82 + alpha/admin/uni_modules/uni-scss/readme.md | 4 + .../uni_modules/uni-scss/styles/index.scss | 7 + .../uni-scss/styles/setting/_border.scss | 3 + .../uni-scss/styles/setting/_color.scss | 66 + .../uni-scss/styles/setting/_radius.scss | 55 + .../uni-scss/styles/setting/_space.scss | 56 + .../uni-scss/styles/setting/_styles.scss | 167 + .../uni-scss/styles/setting/_text.scss | 24 + .../uni-scss/styles/setting/_variables.scss | 146 + .../uni-scss/styles/tools/functions.scss | 19 + alpha/admin/uni_modules/uni-scss/theme.scss | 31 + .../admin/uni_modules/uni-scss/variables.scss | 62 + .../uni-segmented-control/changelog.md | 9 + .../uni-segmented-control.vue | 145 + .../uni-segmented-control/package.json | 87 + .../uni-segmented-control/readme.md | 13 + .../uni_modules/uni-sign-in/changelog.md | 12 + .../components/uni-sign-in/uni-sign-in.vue | 307 + .../uni_modules/uni-sign-in/package.json | 84 + .../uni-sign-in/pages/demo/demo.vue | 15 + alpha/admin/uni_modules/uni-sign-in/readme.md | 86 + .../uni-sign-in/static/background.png | Bin 0 -> 93495 bytes .../cloudfunctions/common/sign-in/index.js | 106 + .../common/sign-in/package.json | 12 + .../rewarded-video-ad-notify-url/index.js | 64 + .../rewarded-video-ad-notify-url/package.json | 15 + .../uni-clientDB-actions/signIn.js | 90 + .../database/opendb-sign-in.schema.json | 41 + .../admin/uni_modules/uni-sign-in/utils/ad.js | 253 + .../admin/uni_modules/uni-table/changelog.md | 27 + .../components/uni-table/uni-table.vue | 455 + .../components/uni-tbody/uni-tbody.vue | 29 + .../uni-table/components/uni-td/uni-td.vue | 90 + .../components/uni-th/filter-dropdown.vue | 511 ++ .../uni-table/components/uni-th/uni-th.vue | 285 + .../components/uni-thead/uni-thead.vue | 129 + .../components/uni-tr/table-checkbox.vue | 179 + .../uni-table/components/uni-tr/uni-tr.vue | 171 + .../admin/uni_modules/uni-table/i18n/en.json | 9 + .../admin/uni_modules/uni-table/i18n/es.json | 9 + .../admin/uni_modules/uni-table/i18n/fr.json | 9 + .../admin/uni_modules/uni-table/i18n/index.js | 12 + .../uni_modules/uni-table/i18n/zh-Hans.json | 9 + .../uni_modules/uni-table/i18n/zh-Hant.json | 9 + .../admin/uni_modules/uni-table/package.json | 83 + alpha/admin/uni_modules/uni-table/readme.md | 13 + alpha/admin/uni_modules/uni-tag/changelog.md | 21 + .../uni-tag/components/uni-tag/uni-tag.vue | 252 + alpha/admin/uni_modules/uni-tag/package.json | 87 + alpha/admin/uni_modules/uni-tag/readme.md | 13 + .../uni_modules/uni-tooltip/changelog.md | 10 + .../components/uni-tooltip/uni-tooltip.vue | 68 + .../uni_modules/uni-tooltip/package.json | 83 + alpha/admin/uni_modules/uni-tooltip/readme.md | 8 + .../uni_modules/uni-transition/changelog.md | 20 + .../uni-transition/createAnimation.js | 128 + .../uni-transition/uni-transition.vue | 277 + .../uni_modules/uni-transition/package.json | 87 + .../uni_modules/uni-transition/readme.md | 11 + .../uni-upgrade-center/changelog.md | 51 + .../uni-upgrade-center/package.json | 91 + .../pages/components/show-info.vue | 52 + .../pages/mixin/version_add_detail_mixin.js | 185 + .../uni-upgrade-center/pages/utils.js | 26 + .../uni-upgrade-center/pages/version/add.vue | 413 + .../pages/version/detail.vue | 337 + .../uni-upgrade-center/pages/version/list.vue | 368 + .../uni_modules/uni-upgrade-center/readme.md | 233 + alpha/admin/vue.config.js | 28 + alpha/admin/windows/components/error-log.vue | 62 + alpha/admin/windows/leftWindow.vue | 130 + alpha/admin/windows/topWindow.vue | 464 + 913 files changed, 120387 insertions(+) create mode 100644 alpha/admin/.hbuilderx/launch.json create mode 100644 alpha/admin/App.vue create mode 100644 alpha/admin/LICENSE create mode 100644 alpha/admin/README.md create mode 100644 alpha/admin/admin.config.js create mode 100644 alpha/admin/changelog.md create mode 100644 alpha/admin/common/admin-icons.css create mode 100644 alpha/admin/common/theme.scss create mode 100644 alpha/admin/common/uni-icons.css create mode 100644 alpha/admin/common/uni.css create mode 100644 alpha/admin/components/batch-sms/batch-sms.vue create mode 100644 alpha/admin/components/download-excel/download-excel.vue create mode 100644 alpha/admin/components/download-excel/download.js create mode 100644 alpha/admin/components/fix-window/fix-window.vue create mode 100644 alpha/admin/components/show-info/show-info.vue create mode 100644 alpha/admin/components/uni-data-menu/uni-data-menu.vue create mode 100644 alpha/admin/components/uni-data-menu/util.js create mode 100644 alpha/admin/components/uni-menu-group/uni-menu-group.vue create mode 100644 alpha/admin/components/uni-menu-item/uni-menu-item.vue create mode 100644 alpha/admin/components/uni-menu-sidebar/uni-menu-sidebar.vue create mode 100644 alpha/admin/components/uni-nav-menu/mixins/rootParent.js create mode 100644 alpha/admin/components/uni-nav-menu/uni-nav-menu.vue create mode 100644 alpha/admin/components/uni-stat-breadcrumb/uni-stat-breadcrumb.vue create mode 100644 alpha/admin/components/uni-stat-panel/uni-stat-panel.vue create mode 100644 alpha/admin/components/uni-stat-table/uni-stat-table.vue create mode 100644 alpha/admin/components/uni-stat-tabs/uni-stat-tabs.vue create mode 100644 alpha/admin/components/uni-sub-menu/uni-sub-menu.vue create mode 100644 alpha/admin/i18n/en.json create mode 100644 alpha/admin/i18n/index.js create mode 100644 alpha/admin/i18n/zh-Hans.json create mode 100644 alpha/admin/i18n/zh-Hant.json create mode 100644 alpha/admin/index.html create mode 100644 alpha/admin/js_sdk/uni-admin/constants.js create mode 100644 alpha/admin/js_sdk/uni-admin/error.js create mode 100644 alpha/admin/js_sdk/uni-admin/fetchMock.js create mode 100644 alpha/admin/js_sdk/uni-admin/interceptor.js create mode 100644 alpha/admin/js_sdk/uni-admin/permission.js create mode 100644 alpha/admin/js_sdk/uni-admin/plugin.js create mode 100644 alpha/admin/js_sdk/uni-admin/request.js create mode 100644 alpha/admin/js_sdk/uni-admin/util.js create mode 100644 alpha/admin/js_sdk/uni-id-pages/store.js create mode 100644 alpha/admin/js_sdk/uni-stat/timeUtil.js create mode 100644 alpha/admin/js_sdk/uni-stat/util.js create mode 100644 alpha/admin/js_sdk/validator/opendb-admin-menus.js create mode 100644 alpha/admin/js_sdk/validator/opendb-app-list.js create mode 100644 alpha/admin/js_sdk/validator/opendb-app-versions.js create mode 100644 alpha/admin/js_sdk/validator/uni-id-log.js create mode 100644 alpha/admin/js_sdk/validator/uni-id-permissions.js create mode 100644 alpha/admin/js_sdk/validator/uni-id-roles.js create mode 100644 alpha/admin/js_sdk/validator/uni-id-tag.js create mode 100644 alpha/admin/js_sdk/validator/uni-id-users.js create mode 100644 alpha/admin/js_sdk/validator/uni-pay-orders.js create mode 100644 alpha/admin/js_sdk/validator/uni-stat-app-crash-logs.js create mode 100644 alpha/admin/main.js create mode 100644 alpha/admin/manifest.json create mode 100644 alpha/admin/mock/uni-stat/appOverview.json create mode 100644 alpha/admin/mock/uni-stat/appsDetail.json create mode 100644 alpha/admin/mock/uni-stat/db.js create mode 100644 alpha/admin/mock/uni-stat/event.json create mode 100644 alpha/admin/mock/uni-stat/pageContent.json create mode 100644 alpha/admin/mock/uni-stat/pageEnt.json create mode 100644 alpha/admin/mock/uni-stat/pageRes.json create mode 100644 alpha/admin/mock/uni-stat/pageRule.json create mode 100644 alpha/admin/mock/uni-stat/userActivity.json create mode 100644 alpha/admin/package.json create mode 100644 alpha/admin/pages.json create mode 100644 alpha/admin/pages/demo/icons/icons.vue create mode 100644 alpha/admin/pages/demo/icons/uni-icons.js create mode 100644 alpha/admin/pages/demo/table/table.vue create mode 100644 alpha/admin/pages/demo/table/tableData.js create mode 100644 alpha/admin/pages/error/404.vue create mode 100644 alpha/admin/pages/index/fieldsMap.js create mode 100644 alpha/admin/pages/index/index.vue create mode 100644 alpha/admin/pages/system/app/add.vue create mode 100644 alpha/admin/pages/system/app/list.vue create mode 100644 alpha/admin/pages/system/app/mixin/publish_add_detail_mixin.js create mode 100644 alpha/admin/pages/system/app/uni-portal/uni-portal.vue create mode 100644 alpha/admin/pages/system/menu/add.vue create mode 100644 alpha/admin/pages/system/menu/edit.vue create mode 100644 alpha/admin/pages/system/menu/list.vue create mode 100644 alpha/admin/pages/system/menu/originalMenuList.json create mode 100644 alpha/admin/pages/system/permission/add.vue create mode 100644 alpha/admin/pages/system/permission/edit.vue create mode 100644 alpha/admin/pages/system/permission/list.vue create mode 100644 alpha/admin/pages/system/role/add.vue create mode 100644 alpha/admin/pages/system/role/edit.vue create mode 100644 alpha/admin/pages/system/role/list.vue create mode 100644 alpha/admin/pages/system/safety/list.vue create mode 100644 alpha/admin/pages/system/tag/add.vue create mode 100644 alpha/admin/pages/system/tag/edit.vue create mode 100644 alpha/admin/pages/system/tag/list.vue create mode 100644 alpha/admin/pages/system/user/add.vue create mode 100644 alpha/admin/pages/system/user/edit.vue create mode 100644 alpha/admin/pages/system/user/list.vue create mode 100644 alpha/admin/pages/uni-stat/channel/channel.vue create mode 100644 alpha/admin/pages/uni-stat/channel/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/activity/activity.vue create mode 100644 alpha/admin/pages/uni-stat/device/activity/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/comparison/comparison.vue create mode 100644 alpha/admin/pages/uni-stat/device/overview/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/overview/overview.vue create mode 100644 alpha/admin/pages/uni-stat/device/retention/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/retention/retention.vue create mode 100644 alpha/admin/pages/uni-stat/device/stickiness/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/stickiness/stickiness.vue create mode 100644 alpha/admin/pages/uni-stat/device/trend/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/device/trend/trend.vue create mode 100644 alpha/admin/pages/uni-stat/error/app/app.vue create mode 100644 alpha/admin/pages/uni-stat/error/app/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/error/js/detail.vue create mode 100644 alpha/admin/pages/uni-stat/error/js/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/error/js/js.vue create mode 100644 alpha/admin/pages/uni-stat/error/js/uploadTask.vue create mode 100644 alpha/admin/pages/uni-stat/event/event.vue create mode 100644 alpha/admin/pages/uni-stat/event/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/page-ent/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/page-ent/page-ent.vue create mode 100644 alpha/admin/pages/uni-stat/page-res/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/page-res/page-res.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/components/test.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/funnel/components/funnelChart.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/funnel/components/trendChart.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/funnel/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/pay-order/funnel/funnel.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/list/list.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelToday.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelTotal.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/overview/components/trendChart.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/overview/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/pay-order/overview/overview.vue create mode 100644 alpha/admin/pages/uni-stat/pay-order/ranking/ranking.vue create mode 100644 alpha/admin/pages/uni-stat/scene/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/scene/scene.vue create mode 100644 alpha/admin/pages/uni-stat/user/activity/activity.vue create mode 100644 alpha/admin/pages/uni-stat/user/activity/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/user/comparison/comparison.vue create mode 100644 alpha/admin/pages/uni-stat/user/overview/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/user/overview/overview.vue create mode 100644 alpha/admin/pages/uni-stat/user/retention/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/user/retention/retention.vue create mode 100644 alpha/admin/pages/uni-stat/user/stickiness/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/user/stickiness/stickiness.vue create mode 100644 alpha/admin/pages/uni-stat/user/trend/fieldsMap.js create mode 100644 alpha/admin/pages/uni-stat/user/trend/trend.vue create mode 100644 alpha/admin/postcss.config.js create mode 100644 alpha/admin/static/admin-icons.ttf create mode 100644 alpha/admin/static/logo.png create mode 100644 alpha/admin/store/constants.js create mode 100644 alpha/admin/store/index.js create mode 100644 alpha/admin/store/modules/app.js create mode 100644 alpha/admin/store/modules/error.js create mode 100644 alpha/admin/store/modules/user.js create mode 100644 alpha/admin/template.h5.html create mode 100644 alpha/admin/uni.scss create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/create-api.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/error.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/utils.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/date.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/uni-crypto.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeDevices.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeUsers.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/appCrashLogs.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/base.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/channel.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/device.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/event.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/loyalty.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/page.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/platform.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/runErrors.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/scenes.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/sessionLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/setting.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/shareLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/statResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/config.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniIdUsers.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniPayOrders.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatPayResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatSessionLogs.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatUserSessionLogs.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/payResult.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uniIDUsers.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/userSessionLog.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/version.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/receiver.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/stat.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/lib/art-template.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/template.html create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/build-template-data.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/index.obj.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/preset-condition.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/schema-name-adapter.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/utils.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/index.obj.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/uni-stat-receiver.param.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/checkVersion/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/index.js create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/package.json create mode 100644 alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/uni-app-manager.param.json create mode 100644 alpha/admin/uniCloud-aliyun/database/JQL file Name.jql create mode 100644 alpha/admin/uniCloud-aliyun/database/db_init.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-admin-menus.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-app-list.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-app-versions.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-banner.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-news-articles.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-news-categories.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-news-comments.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-news-favorite.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-search-hot.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-search-log.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-sms-log.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-sms-task.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-sms-template.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/opendb-tempdata.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/read-news-log.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-id-scores.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-id-tag.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-pay-orders.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-active-devices.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-active-users.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-app-channels.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-app-crash-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-app-platforms.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-app-versions.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-error-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-error-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.ext.js create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-event-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-event-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-events.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-loyalty-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-mp-scenes.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-page-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-page-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-pages.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-pay-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-result.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-run-errors.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-session-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-share-logs.schema.json create mode 100644 alpha/admin/uniCloud-aliyun/database/uni-stat-user-session-logs.schema.json create mode 100644 alpha/admin/uni_modules/qiun-data-charts/changelog.md create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue create mode 100644 alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js create mode 100644 alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js create mode 100644 alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md create mode 100644 alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js create mode 100644 alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js create mode 100644 alpha/admin/uni_modules/qiun-data-charts/license.md create mode 100644 alpha/admin/uni_modules/qiun-data-charts/package.json create mode 100644 alpha/admin/uni_modules/qiun-data-charts/readme.md create mode 100644 alpha/admin/uni_modules/qiun-data-charts/static/app-plus/echarts.min.js create mode 100644 alpha/admin/uni_modules/qiun-data-charts/static/h5/echarts.min.js create mode 100644 alpha/admin/uni_modules/uni-badge/changelog.md create mode 100644 alpha/admin/uni_modules/uni-badge/components/uni-badge/uni-badge.vue create mode 100644 alpha/admin/uni_modules/uni-badge/package.json create mode 100644 alpha/admin/uni_modules/uni-badge/readme.md create mode 100644 alpha/admin/uni_modules/uni-breadcrumb/changelog.md create mode 100644 alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue create mode 100644 alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue create mode 100644 alpha/admin/uni_modules/uni-breadcrumb/package.json create mode 100644 alpha/admin/uni_modules/uni-breadcrumb/readme.md create mode 100644 alpha/admin/uni_modules/uni-captcha/changelog.md create mode 100644 alpha/admin/uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue create mode 100644 alpha/admin/uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue create mode 100644 alpha/admin/uni_modules/uni-captcha/package.json create mode 100644 alpha/admin/uni_modules/uni-captcha/readme.md create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/LICENSE.md create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/fonts/font.ttf create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/package.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/config.js create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/index.obj.js create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/package.json create mode 100644 alpha/admin/uni_modules/uni-captcha/uniCloud/database/opendb-verify-codes.schema.json create mode 100644 alpha/admin/uni_modules/uni-card/changelog.md create mode 100644 alpha/admin/uni_modules/uni-card/components/uni-card/uni-card.vue create mode 100644 alpha/admin/uni_modules/uni-card/package.json create mode 100644 alpha/admin/uni_modules/uni-card/readme.md create mode 100644 alpha/admin/uni_modules/uni-cloud-router/changelog.md create mode 100644 alpha/admin/uni_modules/uni-cloud-router/package.json create mode 100644 alpha/admin/uni_modules/uni-cloud-router/readme.md create mode 100644 alpha/admin/uni_modules/uni-combox/changelog.md create mode 100644 alpha/admin/uni_modules/uni-combox/components/uni-combox/uni-combox.vue create mode 100644 alpha/admin/uni_modules/uni-combox/package.json create mode 100644 alpha/admin/uni_modules/uni-combox/readme.md create mode 100644 alpha/admin/uni_modules/uni-config-center/changelog.md create mode 100644 alpha/admin/uni_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-config-center/readme.md create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-data-checkbox/changelog.md create mode 100644 alpha/admin/uni_modules/uni-data-checkbox/components/uni-data-checkbox/clientdb.js create mode 100644 alpha/admin/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue create mode 100644 alpha/admin/uni_modules/uni-data-checkbox/package.json create mode 100644 alpha/admin/uni_modules/uni-data-checkbox/readme.md create mode 100644 alpha/admin/uni_modules/uni-data-picker/changelog.md create mode 100644 alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js create mode 100644 alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue create mode 100644 alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js create mode 100644 alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue create mode 100644 alpha/admin/uni_modules/uni-data-picker/package.json create mode 100644 alpha/admin/uni_modules/uni-data-picker/readme.md create mode 100644 alpha/admin/uni_modules/uni-data-select/changelog.md create mode 100644 alpha/admin/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue create mode 100644 alpha/admin/uni_modules/uni-data-select/package.json create mode 100644 alpha/admin/uni_modules/uni-data-select/readme.md create mode 100644 alpha/admin/uni_modules/uni-dateformat/changelog.md create mode 100644 alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js create mode 100644 alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue create mode 100644 alpha/admin/uni_modules/uni-dateformat/package.json create mode 100644 alpha/admin/uni_modules/uni-dateformat/readme.md create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/changelog.md create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.js create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/package.json create mode 100644 alpha/admin/uni_modules/uni-datetime-picker/readme.md create mode 100644 alpha/admin/uni_modules/uni-drawer/changelog.md create mode 100644 alpha/admin/uni_modules/uni-drawer/components/uni-drawer/keypress.js create mode 100644 alpha/admin/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue create mode 100644 alpha/admin/uni_modules/uni-drawer/package.json create mode 100644 alpha/admin/uni_modules/uni-drawer/readme.md create mode 100644 alpha/admin/uni_modules/uni-easyinput/changelog.md create mode 100644 alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/common.js create mode 100644 alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue create mode 100644 alpha/admin/uni_modules/uni-easyinput/package.json create mode 100644 alpha/admin/uni_modules/uni-easyinput/readme.md create mode 100644 alpha/admin/uni_modules/uni-feedback/changelog.md create mode 100644 alpha/admin/uni_modules/uni-feedback/js_sdk/validator/opendb-feedback.js create mode 100644 alpha/admin/uni_modules/uni-feedback/package.json create mode 100644 alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/detail.vue create mode 100644 alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/edit.vue create mode 100644 alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/list.vue create mode 100644 alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/opendb-feedback.vue create mode 100644 alpha/admin/uni_modules/uni-feedback/readme.md create mode 100644 alpha/admin/uni_modules/uni-feedback/uniCloud/database/opendb-feedback.schema.json create mode 100644 alpha/admin/uni_modules/uni-file-picker/changelog.md create mode 100644 alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js create mode 100644 alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue create mode 100644 alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue create mode 100644 alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue create mode 100644 alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/utils.js create mode 100644 alpha/admin/uni_modules/uni-file-picker/package.json create mode 100644 alpha/admin/uni_modules/uni-file-picker/readme.md create mode 100644 alpha/admin/uni_modules/uni-forms/changelog.md create mode 100644 alpha/admin/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue create mode 100644 alpha/admin/uni_modules/uni-forms/components/uni-forms/uni-forms.vue create mode 100644 alpha/admin/uni_modules/uni-forms/components/uni-forms/utils.js create mode 100644 alpha/admin/uni_modules/uni-forms/components/uni-forms/validate.js create mode 100644 alpha/admin/uni_modules/uni-forms/package.json create mode 100644 alpha/admin/uni_modules/uni-forms/readme.md create mode 100644 alpha/admin/uni_modules/uni-group/changelog.md create mode 100644 alpha/admin/uni_modules/uni-group/components/uni-group/uni-group.vue create mode 100644 alpha/admin/uni_modules/uni-group/package.json create mode 100644 alpha/admin/uni_modules/uni-group/readme.md create mode 100644 alpha/admin/uni_modules/uni-icons/changelog.md create mode 100644 alpha/admin/uni_modules/uni-icons/components/uni-icons/icons.js create mode 100644 alpha/admin/uni_modules/uni-icons/components/uni-icons/uni-icons.vue create mode 100644 alpha/admin/uni_modules/uni-icons/components/uni-icons/uni.ttf create mode 100644 alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.css create mode 100644 alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.ttf create mode 100644 alpha/admin/uni_modules/uni-icons/package.json create mode 100644 alpha/admin/uni_modules/uni-icons/readme.md create mode 100644 alpha/admin/uni_modules/uni-id-common/changelog.md create mode 100644 alpha/admin/uni_modules/uni-id-common/package.json create mode 100644 alpha/admin/uni_modules/uni-id-common/readme.md create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/changelog.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/common.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/login-page.mixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/login-page.scss create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/loginSuccess.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/password.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/common/store.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-agreements/uni-id-pages-agreements.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-avatar/uni-id-pages-avatar.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-bind-mobile/uni-id-pages-bind-mobile.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-sms-form/uni-id-pages-sms-form.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-user-profile/uni-id-pages-user-profile.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/config.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/init.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/common/webview/webview.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/login/login-smscode.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/login/login-withpwd.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/register/register-admin.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/register/register-by-email.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/register/register.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/register/validator.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/photo.svg create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/rotate.svg create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/index.css create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/limeClipper.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/utils.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/pages/userinfo/userinfo.vue create mode 100644 alpha/admin/uni_modules/uni-id-pages/readme.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/apple.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/alipay.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/apple.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/douyin.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/facebook.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/google.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/qq.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/sinaweibo.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/taobao.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/univerify.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/limeClipper/photo.svg create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/limeClipper/rotate.svg create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/login/apple.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/sms.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/user.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/weixin.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/login/weixin.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-center/defaultAvatarUrl.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-center/grey.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-center/headers.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/alipay.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/apple.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/douyin.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/facebook.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/google.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/qq.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/sinaweibo.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/sms.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/taobao.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/univerify.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/user.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/weixin.png create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/constants.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/universal.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/protocols.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/alipayBase.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/account/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/rsa-public-key-pem.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/protocol.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/normalize.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/share/create-api.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/account/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/normalize.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/utils.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/captcha.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/fission.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/password.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/sms.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/univerify.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/update-user-info.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/utils.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/verify-code.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/access-control.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/auth.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/rbac.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/uni-id-log.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/validate.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/verify-request-sign.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/close-account.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/get-account-info.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/set-pwd.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/get-supported-login-type.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/login.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/register.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/accept-invite.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/get-invited-user.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-alipay.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-apple.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-baidu.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-dingtalk.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-douyin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-code.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-link.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-facebook.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-google.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-qq.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-taobao.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-toutiao.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-univerify.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weibo.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin-mobile.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/authorize-app-login.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/set-authorized-app.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-admin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user-by-email.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-alipay.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-apple.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-univerify.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-qq.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-alipay.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-apple.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-qq.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/refresh-token.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/secure-network-handshake-by-weixin.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/create-captcha.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/refresh-captcha.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-code.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-link.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-sms-code.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.cmd create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.ps1 create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.npmignore create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.travis.yml create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/LICENSE.txt create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/test.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/CODEOWNERS create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.d.ts create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/CHANGELOG.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/decode.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/JsonWebTokenError.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/NotBeforeError.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/TokenExpiredError.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/psSupported.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/timespan.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/sign.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/verify.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/CHANGELOG.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/data-stream.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/sign-stream.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/tostring.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/verify-stream.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/readme.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/license.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/readme.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.d.ts create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/CHANGELOG.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/LICENSE create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/README.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/bin/semver create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/range.bnf create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/semver.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/LICENSE.md create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/fonts/font.ttf create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/bridge-error.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/config.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/consts.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/storage.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/uni-cloud-cache.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/validator.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/weixin-server.js create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-department.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-device.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-device.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-log.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-permissions.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-roles.schema.json create mode 100644 alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-users.schema.json create mode 100644 alpha/admin/uni_modules/uni-link/changelog.md create mode 100644 alpha/admin/uni_modules/uni-link/components/uni-link/uni-link.vue create mode 100644 alpha/admin/uni_modules/uni-link/package.json create mode 100644 alpha/admin/uni_modules/uni-link/readme.md create mode 100644 alpha/admin/uni_modules/uni-list/changelog.md create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list/uni-list.vue create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.vue create mode 100644 alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.wxs create mode 100644 alpha/admin/uni_modules/uni-list/package.json create mode 100644 alpha/admin/uni_modules/uni-list/readme.md create mode 100644 alpha/admin/uni_modules/uni-load-more/changelog.md create mode 100644 alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json create mode 100644 alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js create mode 100644 alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json create mode 100644 alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json create mode 100644 alpha/admin/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue create mode 100644 alpha/admin/uni_modules/uni-load-more/package.json create mode 100644 alpha/admin/uni_modules/uni-load-more/readme.md create mode 100644 alpha/admin/uni_modules/uni-notice-bar/changelog.md create mode 100644 alpha/admin/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue create mode 100644 alpha/admin/uni_modules/uni-notice-bar/package.json create mode 100644 alpha/admin/uni_modules/uni-notice-bar/readme.md create mode 100644 alpha/admin/uni_modules/uni-number-box/changelog.md create mode 100644 alpha/admin/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue create mode 100644 alpha/admin/uni_modules/uni-number-box/package.json create mode 100644 alpha/admin/uni_modules/uni-number-box/readme.md create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/changelog.md create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/package.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/readme.md create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/index.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/package.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/uni-ad/config.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/uni-id/config.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/uni-open-bridge/config.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/uni-sms-co/config.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/uni-stat/config.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js create mode 100644 alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json create mode 100644 alpha/admin/uni_modules/uni-pagination/changelog.md create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json create mode 100644 alpha/admin/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue create mode 100644 alpha/admin/uni_modules/uni-pagination/package.json create mode 100644 alpha/admin/uni_modules/uni-pagination/readme.md create mode 100644 alpha/admin/uni_modules/uni-popup/changelog.md create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/en.json create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/index.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/keypress.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/message.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/popup.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/share.js create mode 100644 alpha/admin/uni_modules/uni-popup/components/uni-popup/uni-popup.vue create mode 100644 alpha/admin/uni_modules/uni-popup/package.json create mode 100644 alpha/admin/uni_modules/uni-popup/readme.md create mode 100644 alpha/admin/uni_modules/uni-scss/changelog.md create mode 100644 alpha/admin/uni_modules/uni-scss/index.scss create mode 100644 alpha/admin/uni_modules/uni-scss/package.json create mode 100644 alpha/admin/uni_modules/uni-scss/readme.md create mode 100644 alpha/admin/uni_modules/uni-scss/styles/index.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_border.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_color.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_radius.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_space.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_styles.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_text.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/setting/_variables.scss create mode 100644 alpha/admin/uni_modules/uni-scss/styles/tools/functions.scss create mode 100644 alpha/admin/uni_modules/uni-scss/theme.scss create mode 100644 alpha/admin/uni_modules/uni-scss/variables.scss create mode 100644 alpha/admin/uni_modules/uni-segmented-control/changelog.md create mode 100644 alpha/admin/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue create mode 100644 alpha/admin/uni_modules/uni-segmented-control/package.json create mode 100644 alpha/admin/uni_modules/uni-segmented-control/readme.md create mode 100644 alpha/admin/uni_modules/uni-sign-in/changelog.md create mode 100644 alpha/admin/uni_modules/uni-sign-in/components/uni-sign-in/uni-sign-in.vue create mode 100644 alpha/admin/uni_modules/uni-sign-in/package.json create mode 100644 alpha/admin/uni_modules/uni-sign-in/pages/demo/demo.vue create mode 100644 alpha/admin/uni_modules/uni-sign-in/readme.md create mode 100644 alpha/admin/uni_modules/uni-sign-in/static/background.png create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/index.js create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/package.json create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/index.js create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/package.json create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/uni-clientDB-actions/signIn.js create mode 100644 alpha/admin/uni_modules/uni-sign-in/uniCloud/database/opendb-sign-in.schema.json create mode 100644 alpha/admin/uni_modules/uni-sign-in/utils/ad.js create mode 100644 alpha/admin/uni_modules/uni-table/changelog.md create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-table/uni-table.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-td/uni-td.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-th/filter-dropdown.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-th/uni-th.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-thead/uni-thead.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-tr/table-checkbox.vue create mode 100644 alpha/admin/uni_modules/uni-table/components/uni-tr/uni-tr.vue create mode 100644 alpha/admin/uni_modules/uni-table/i18n/en.json create mode 100644 alpha/admin/uni_modules/uni-table/i18n/es.json create mode 100644 alpha/admin/uni_modules/uni-table/i18n/fr.json create mode 100644 alpha/admin/uni_modules/uni-table/i18n/index.js create mode 100644 alpha/admin/uni_modules/uni-table/i18n/zh-Hans.json create mode 100644 alpha/admin/uni_modules/uni-table/i18n/zh-Hant.json create mode 100644 alpha/admin/uni_modules/uni-table/package.json create mode 100644 alpha/admin/uni_modules/uni-table/readme.md create mode 100644 alpha/admin/uni_modules/uni-tag/changelog.md create mode 100644 alpha/admin/uni_modules/uni-tag/components/uni-tag/uni-tag.vue create mode 100644 alpha/admin/uni_modules/uni-tag/package.json create mode 100644 alpha/admin/uni_modules/uni-tag/readme.md create mode 100644 alpha/admin/uni_modules/uni-tooltip/changelog.md create mode 100644 alpha/admin/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue create mode 100644 alpha/admin/uni_modules/uni-tooltip/package.json create mode 100644 alpha/admin/uni_modules/uni-tooltip/readme.md create mode 100644 alpha/admin/uni_modules/uni-transition/changelog.md create mode 100644 alpha/admin/uni_modules/uni-transition/components/uni-transition/createAnimation.js create mode 100644 alpha/admin/uni_modules/uni-transition/components/uni-transition/uni-transition.vue create mode 100644 alpha/admin/uni_modules/uni-transition/package.json create mode 100644 alpha/admin/uni_modules/uni-transition/readme.md create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/changelog.md create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/package.json create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/components/show-info.vue create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/mixin/version_add_detail_mixin.js create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/utils.js create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/version/add.vue create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/version/detail.vue create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/pages/version/list.vue create mode 100644 alpha/admin/uni_modules/uni-upgrade-center/readme.md create mode 100644 alpha/admin/vue.config.js create mode 100644 alpha/admin/windows/components/error-log.vue create mode 100644 alpha/admin/windows/leftWindow.vue create mode 100644 alpha/admin/windows/topWindow.vue diff --git a/alpha/admin/.hbuilderx/launch.json b/alpha/admin/.hbuilderx/launch.json new file mode 100644 index 0000000..07c1d5f --- /dev/null +++ b/alpha/admin/.hbuilderx/launch.json @@ -0,0 +1,16 @@ +{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version": "0.0", + "configurations": [{ + "default" : + { + "launchtype" : "local" + }, + "h5" : + { + "launchtype" : "local" + }, + "type" : "uniCloud" + } + ] +} diff --git a/alpha/admin/App.vue b/alpha/admin/App.vue new file mode 100644 index 0000000..c499fe0 --- /dev/null +++ b/alpha/admin/App.vue @@ -0,0 +1,78 @@ + + + diff --git a/alpha/admin/LICENSE b/alpha/admin/LICENSE new file mode 100644 index 0000000..96da8cd --- /dev/null +++ b/alpha/admin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 DCloud + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/alpha/admin/README.md b/alpha/admin/README.md new file mode 100644 index 0000000..ad40149 --- /dev/null +++ b/alpha/admin/README.md @@ -0,0 +1,24 @@ +## uni-admin + +uni-admin,是基于 uni-app 和 uniCloud 的管理后台项目模版。 + +对于uniCloud的开发者而言,其后台管理系统应该使用本框架。 + +我们搭建了[uni-admin演示站点](http://hellouniadmin.dcloud.net.cn/admin/),你登录后即可快速体验uni-admin。 + +uni-admin 是开源的,遵循 MIT 协议,你可以从[Github](https://github.com/dcloudio/uni-admin)或[码云](https://gitee.com/dcloud/uni-admin)获取源码,也可以从[DCloud插件市场](https://ext.dcloud.net.cn/plugin?id=3268)快捷下载。 + +## 框架特征 +- 基于 uni-app 的宽屏适配,可自动适配 PC 宽屏和手机各端。了解[宽屏适配](https://uniapp.dcloud.io/adapt) +- 基于 uniCloud,是 serverless 的云开发。了解[uniCloud](https://uniapp.dcloud.io/uniCloud/README) +- 基于 uni-id,使用 uni-id 的用户账户、角色、权限系统。了解[uni-id](https://uniapp.dcloud.io/uniCloud/uni-id) + +## 看视频,15分钟掌握uni-admin + + + uni-admin视频教程 + + +## 官方教程 + +> [bilibili 教程](https://www.bilibili.com/video/BV17p4y1a71x) \ No newline at end of file diff --git a/alpha/admin/admin.config.js b/alpha/admin/admin.config.js new file mode 100644 index 0000000..861b8aa --- /dev/null +++ b/alpha/admin/admin.config.js @@ -0,0 +1,85 @@ +export default { + login: { + url: '/uni_modules/uni-id-pages/pages/login/login-withpwd' // 登录页面路径 + }, + index: { + url: '/pages/index/index' // 登录后跳转的第一个页面 + }, + error: { + url: '/pages/error/404' // 404 Not Found 错误页面路径 + }, + navBar: { // 顶部导航 + logo: '/static/logo.png', // 左侧 Logo + langs: [{ + text: '中文简体', + lang: 'zh-Hans' + }, { + text: '中文繁體', + lang: 'zh-Hant' + }, { + text: 'English', + lang: 'en' + }], + themes: [{ + text: '默认', + value: 'default' + }, { + text: '绿柔', + value: 'green' + }], + debug: { + enable: process.env.NODE_ENV !== 'production', //是否显示错误信息 + engine: [{ // 搜索引擎配置(每条错误信息后,会自动生成搜索链接,点击后跳转至搜索引擎) + name: '百度', + url: 'https://www.baidu.com/baidu?wd=ERR_MSG' + }, { + name: '谷歌', + url: 'https://www.google.com/search?q=ERR_MSG' + }] + } + }, + sideBar: { // 左侧菜单 + // 配置静态菜单列表(放置在用户被授权的菜单列表下边) + staticMenu: [{ + menu_id: "demo", + text: '静态功能演示', + icon: 'admin-icons-kaifashili', + url: "", + children: [{ + menu_id: "icons", + text: '图标', + icon: 'admin-icons-icon', + value: '/pages/demo/icons/icons', + }, { + menu_id: "table", + text: '表格', + icon: 'admin-icons-table', + value: '/pages/demo/table/table', + }] + }, { + menu_id: "admim-doc-pulgin", + text: '文档与插件', + icon: 'admin-icons-eco', + url: "", + children: [{ + menu_id: "admin-doc", + icon: 'admin-icons-doc', + text: 'uni-admin 框架文档', + value: 'https://uniapp.dcloud.net.cn/uniCloud/admin' + }, { + menu_id: "stat-doc", + icon: 'admin-icons-help', + text: 'uni 统计教程', + value: 'https://uniapp.dcloud.net.cn/uni-stat-v2.html' + }, { + menu_id: "admin-pulgin", + icon: 'admin-icons-pulgin', + text: 'uni-admin 插件', + value: 'https://ext.dcloud.net.cn/?cat1=7&cat2=74' + }] + }] + }, + uniStat: { + + } +} diff --git a/alpha/admin/changelog.md b/alpha/admin/changelog.md new file mode 100644 index 0000000..da265e5 --- /dev/null +++ b/alpha/admin/changelog.md @@ -0,0 +1,236 @@ +## 2.3.6(2023-04-10) +- 优化 支付统计-价值用户排行:只统计已支付的订单金额,且去除退款金额。 +## 2.3.5(2023-02-24) +- 修复 升级中心安卓应用商店不显示的Bug +## 2.3.4(2023-02-09) +- 重要 阿里云空间支持上传sourceMap用以分析js错误统计 [详情](https://uniapp.dcloud.net.cn/uni-stat-v2.html#sourcemap-parse-error) +## 2.3.3(2023-02-02) +- 新增 菜单管理新增【更新内置菜单】功能,方便旧版本uni-admin升级至新版本uni-admin后一键同步内置菜单 +- 升级 uni-id-pages 至 1.1.0 +- 优化 uni-admin的storage键名命名规范 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-storage-format.html) +- 优化 安全审计-用户日志 排序规则调整为降序 +- 优化 uni统计-版本选择组件的查询条件短期内多次变更只查询最后一次变更后的结果 +## 2.3.2(2023-01-30) +- 修复 禁用的菜单仍然会在左侧菜单列表中显示的bug +## 2.3.1(2023-01-29) +- 短信群发功能 新增 筛选用户后可以跨分页群发 +## 2.3.0(2023-01-16) +- 重要 新增uni-starter需要的相关依赖和初始化数据(方便uni-starter关联uni-admin后可直接运行) +- 升级 uni-id-pages 至 1.0.40 +- 修复 非H5环境时,点击跳首页会报错的问题。 +- 修复 charts 更新后,vue3模式下无法显示的bug +- 修复 用户管理-编辑时,新增标签后返回报错的问题 +- 修复 用户管理-编辑时,若用户拥有的应用未添加到应用管理时,点击保存会导致用户丢失该应用的appid,进而导致下次登录提示未在该应用注册的问题。 +- 修复 用户管理-编辑时,无法将已禁用的用户恢复成正常状态的问题。 +- 修复 用户管理-编辑时,无法将手机号和邮箱清空的问题。 +- 优化 用户管理-编辑时,禁止将当前登录的admin账户禁用(防止误操作导致无法登录admin) +- 优化 统计报表中的版本选择组件显示的内容,以便更好的区分平台和版本号 +- 优化 新增用户时的表单验证提示 +- 优化 当没有创建任何应用时,首页会友好提示请先创建应用。 +## 2.2.3(2022-12-30) +- 修复 uni统计js报错页面无法正常显示数据的问题 [详情](https://ask.dcloud.net.cn/question/160337) +- 修复 一键部署因database目录有多余的db_init.json 导致部署失败的问题。 +- 优化 uni统计前端页面,减少不必要的请求次数。 +## 2.2.2(2022-12-20) +- 修复 升级中心删除安装包时报错的Bug [详情](https://ask.dcloud.net.cn/question/159918) +## 2.2.1(2022-12-13) +- 修复 因HBX升级3.6.13导致菜单管理加载失败的问题 +- 优化 微信小程序报很多警告的问题 +## 2.2.0(2022-12-12) +- 新增 uni统计新增支付统计 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-pay.html#pay-stat) +- 优化 uni统计UI排版细节 +- 修复 国际化繁体中文 新增一級菜單 文案错误问题 +## 2.1.9(2022-12-06) +- 升级 uni-id-pages 至 1.0.35 +- 优化 去除非必要的日志打印 +- 优化 用户管理、角色管理、日志管理使用getTemp连表,提升查询性能 +- 优化 添加用户时手机号、邮箱选填 +- 优化 添加用户时,昵称允许是中文 +- 修复 运行时提示表不存在的问题 +## 2.1.8(2022-12-01) +- 修复 uni-stat-receiver 无法找到 uni-id 模块的bug +## 2.1.7(2022-11-30) +- 新增 换肤功能 +## 2.1.6(2022-11-28) +- 优化 群发短信功能的 schema 命名规范 +## 2.1.5(2022-11-17) +- 升级 uni-id-pages 至 1.0.31 +- 优化 添加用户时手机号、邮箱必填 +## 2.1.4(2022-11-11) +- 修复 Vue3微信小程序运行报错的bug +## 2.1.3(2022-11-03) +- 修复 微信小程序上运行时错误 `process is not defined` +## 2.1.2(2022-11-02) +- 修复 Vue3无法导入插件菜单 +## 2.1.1(2022-10-17) +- 修复 uni统计 App-Android 平台部分统计数据不准确的Bug [详情](https://ask.dcloud.net.cn/article/40097) +- 修复 uni统计 周/月数据不准确的Bug +## 2.1.0(2022-10-14) +- 新增 群发短信功能 [详情](https://uniapp.dcloud.net.cn//uniCloud/admin.html#batch-sms) +- 修复 无法重置用户密码的bug +## 2.0.5(2022-09-28) +- 修复 导入插件时不显示“待添加菜单”bug +## 2.0.4(2022-09-23) +- 升级 uni-id-pages 至 1.0.22 +## 2.0.3(2022-09-21) +- 修复 云函数请求无返回数据的bug +## 2.0.2(2022-09-20) +- 升级 uni-id-pages 至 1.0.18 +- 优化 导航登录用户名的显示规则:用户昵称 > 用户名 > 手机号 > 邮箱 +## 2.0.1(2022-09-19) +- 升级 uni-id-pages 至 1.0.17 +- 修改 导航登录用户名的显示规则:优先显示用户昵称,其次显示用户名 +- 增加 用户管理列表展示“用户昵称”字段 +- 增加 创建用户支持添加“用户昵称”字段 +## 2.0.0(2022-09-16) +- 升级 uni-id-pages 至 1.0.13 +- 修复 应用中心修改应用无法修改的bug +## 1.10.1(2022-09-08) +- 修复 使用 uniIdRouter 时导致页面无法打开的Bug +## 1.10.0(2022-09-08) +- 升级 uni-id 至 4.0,移除 uni-id、uni-id-cf 插件,增加 uni-id-pages、uni-id-common 插件。[uni-id详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html) +## 1.9.8(2022-08-15) +- 修复 应用管理修改页面报错 +## 1.9.7(2022-08-08) +- 改进 sourceMap 回溯源码功能使用方法,需要在 admin.config.js 中配置相关信息。[详情](https://uniapp.dcloud.net.cn/uni-stat-v2.html#upload-sourcemap) +- 修复 js报错统计报错的Bug +## 1.9.6(2022-08-02) +- 修复 vue3 打包报错的Bug +- 修复 升级中心发布 wgt 时原生 App 最低版本没有必填的Bug +- 修复 升级中心发布 wgt 时显示Android应用市场的Bug +## 1.9.5(2022-07-29) +- 修复 运行到微信小程序控制台报错的Bug +## 1.9.4(2022-07-28) +- 新增 uni-admin uni统计支持上传 sourceMap,报错可准确回溯源码 [详情](https://uniapp.dcloud.io/uni-stat-v2.html#sourcemap-parse-error) +## 1.9.3(2022-07-19) +- 优化 uni-admin 应用管理模块可管理App下载地址、小程序二维码等更多应用信息 [详情](https://uniapp.dcloud.io/uniCloud/admin.html#app-manager) +- 调整 uni-admin 内置 统一发布页(uni-portal)插件 [详情](https://uniapp.dcloud.io/uniCloud/admin.html#uni-portal) +- 调整 uni-admin 内置 App升级中心(uni-upgrade-center)插件,并支持多应用商店更新 [详情](https://uniapp.dcloud.io/uniCloud/admin.html#uni-upgrade-center) +- 升级前最好将旧版 uni-portal、uni-upgrade-center 插件备份并移出 uni_modules 目录 +## 1.9.2(2022-07-11) +- 修复 留存统计跑批任务获取不到版本号的Bug +## 1.9.1(2022-07-06) +- 新增 opendb-device表,开通 uni-push2.0 与 uni统计2.0 自动上报 push_clientid 到 opendb-device表 +## 1.9.0(2022-07-05) +- 【重要】uni-admin 优化 uni统计 版本记录复用uni升级中心的opendb-app-versions表,废弃uni-stat-app-versions表 [详情](https://uniapp.dcloud.net.cn/uni-stat-v2.html#upgrade) +- 新增 uni统计 app崩溃页面,补充崩溃率统计 +- 修复 uni统计 js报错页面,错误率计算不准确的Bug +- 修复 uni统计 切换版本或者修改时间等操作后,趋势图状态显示不正确的Bug +- 修复 uni统计 部分页面首次进入时界面闪烁的问题 +## 1.8.5(2022-06-29) +- 新增 支持 ios 安全区 +## 1.8.4(2022-06-01) +- 新增 uni统计 可通过选择「应用版本」查询数据 +- 新增 uni统计 原生 app 崩溃页各项功能 +- 修复 uni统计 渠道页 table 表格最后一列空白的 bug +- 修复 uni统计 场景分析页趋势图有数据却显示为 0 的 bug +- 修复 系统设置权限只能加载 20 条的 bug +## 1.8.3(2022-05-19) +- 优化 「首页」逻辑调整,无 appid 时提示添加 app 记录,可跳转 app 管理的新增页 +- 优化 移除登录时多余的 init 的逻辑,提升登录速度 +- 优化 「页面统计」添加 「入口页」、「登录页」的提示文字 +- 修复 从「首页」跳转「概况」时,url 的 query 丢失的 bug +## 1.8.2(2022-05-18) +- 优化 uni 统计的「统计首页」菜单移动到应用「首页」,添加了设备概览、注册用户概览 +- 优化 uni 统计的「帮助」菜单移动到「文档与插件」 +- 修复 路由改变后面包屑未响应的 bug +## 1.8.1(2022-05-17) +- 修复 去掉多余的 schema +## 1.8.0(2022-05-17) +**重要更新:** +- 新增 用户日志功能 +- 新增 内置 uni 统计报表体系,开源、免费、可私有化部署,[了解更多](https://uniapp.dcloud.net.cn/uni-stat-v2.html#uni%E7%BB%9F%E8%AE%A1),具体功能如下 + - 统计首页 + - 设备统计 + - 用户统计 + - 页面统计 + - 渠道/场景值分析 + - 自定义事件 + - 错误统计 +## 1.7.13(2022-02-15) +- 修复 新增菜单页‘内置图标’在 vue3 平台不显示的 bug +- 修复 ‘新增一级菜单’ 按钮的文字错误 +## 1.7.12(2022-01-26) +- 修复 uni-admin 的 'registerUser' 接口,注册用户含有多余字段 uid +## 1.7.11(2022-01-19) +- 修复 多个用户的用户名相同时,后注册的同名用户登录时提示“用户不存在”的 bug +- 修复 偶发的验证码输出正确却提示“验证码错误”的 bug +- 修复 刷新页面后验证码消的 bug +## 1.7.10(2021-12-20) +- 优化 支持 vue3 查找并注册的菜单(包括插件菜单) +## 1.7.9(2021-12-07) +- 新增 标签管理功能,可批量为用户添加或移除标签、通过标签过滤用户 +## 1.7.8(2021-11-30) +- 修复 Android 平台切换语言闪退的 bug,该平台暂不支持切换语言 +## 1.7.7(2021-11-29) +- 修复 uni-datetime-picker 国际化未默认英文的问题 +- 修复 uni-datetime-picker 范围选择在表格列头中渲染相同月份的问题 +## 1.7.6(2021-11-11) +- 优化 修改密码功能不再支持查看明文密码 +- 修复 某些屏幕上,input 框中下划线 '_' 被隐藏的 bug +## 1.7.5(2021-10-08) +- 修复 用户管理与角色管理模糊搜索时关联的外键无法搜索的 bug +## 1.7.4(2021-09-30) +- 修复 topwindow 非 h5 端,key 使用表达式报错的 bug +- 优化 topwindow 中英文混排不对齐的问题 +## 1.7.3(2021-09-27) +- 修复 vue3 上加载 PostCSS 插件失败的 bug +## 1.7.2(2021-09-17) +- 优化 取消菜单管理请求数据条数限制 +- 优化 topwindow 菜单文字换行的问题 +- 修复 左侧菜单栏刷新失去打开状态的 bug +## 1.7.1(2021-09-14) +- 修复 vue3 下 i18n 未定义的 bug +- 优化 抛出被 error.js 拦截的报错 +## 1.7.0(2021-08-31) +- 新增 支持国际化 i18n +- 优化 验证码图片边框样式调整 +## 1.6.2(2021-08-26) +- 修复 非 admin 角色的用户无权限访问菜单表,动态菜单不显示的 bug + > 更新后,需上传 opendb-admin-menus.schema.json +- 优化 list 页的表格样式 +## 1.6.1(2021-08-16) +- 修复 uni-id-cf 中无用的node_modules造成的报错 +- 修复 uni.css 中样式穿透造成的 uni-file-picker 不可见的 bug +## 1.6.0(2021-07-31) +**重要更新:** +- 新增 应用管理功能,管理用户可登录的应用(uni-id@3.3.1+ 支持) +- 新增 升级系统管理 list 页的表格功能,支持数据排序、筛选、搜索等功能 +- 新增 同时适配 vue2 和 vue3(HBuilder X 3.2.0+ 支持 vue3) +- 修复 刷新页面时,左侧菜单丢失高亮状态的 bug +- 修复 修改密码失败的 bug +## 1.5.8(2021-07-12) +- 修复 侧边栏菜单查询数据条数一次不超过 20 条的 bug(限制是最大一次 500 条) +## 1.5.7(2021-07-02) +- 修复 菜单管理排序错误的 bug +- 优化 框架设定非 admin 不能创建用户, 用户可自定义 +## 1.5.6(2021-06-28) +- 修复 left-window 在小程序上的编译错误 +## 1.5.5(2021-06-21) +- 修复 角色管理删除功能失效的 bug +- 修复 权限管理删除功能失效的 bug +## 1.5.4(2021-06-21) +- 优化 云函数 uni-id-cf uni_module 化,更新更方便 +## 1.5.3(2021-06-17) +- 优化 opendb-admin-menus.schema 读权限配置默认为 true + > 原因:侧边栏菜单管理功能使用了 clientDB, 默认全部读取,通过用户权限过滤 +## 1.4.6(2021-05-27) +- 修复 未连接服务空间时登录页空白的 bug + +## 1.4.5(2021-05-18) +- 新增 选择表格分页条数功能 +- 修复 切换分页条数当前分页不是1时获取数据出错的 bug +## 1.4.4(2021-05-17) +- 优化 导出 Excel 功能的代码 +- 优化 系统管理 list 页面样式 +- 优化 文案调整 +## 1.4.3(2021-05-14) +- PC 端支持表格导出数据为 Excel +## 1.4.2(2021-04-21) +- 更新 uni-id 3.1.0 + - 增加对用户名、邮箱、密码字段的两端去空格 + - 默认忽略用户名、邮箱的大小写 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=case-sensitive) + - 修复 customToken导出async方法报错的Bug +## 1.4.1(2021-04-16) +- 更新 uni-tabel 1.0.3 +- 新增 根目录下 changelog.md diff --git a/alpha/admin/common/admin-icons.css b/alpha/admin/common/admin-icons.css new file mode 100644 index 0000000..8e0b89d --- /dev/null +++ b/alpha/admin/common/admin-icons.css @@ -0,0 +1,199 @@ +@font-face { + font-family: admin-icons; + src: url('~@/static/admin-icons.ttf') format('truetype'); + font-weight: 400; + font-display: "auto"; + font-style: normal +} + + +[class*="admin-icons-"], +[class^=admin-icons-] { + font-family: admin-icons !important; + speak: none; + font-style: normal; + font-weight: 400; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: baseline; + display: inline-block; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + + + +.admin-icons-stat:before { + content: "\e64a"; +} + +.admin-icons-fl-xitong:before { + content: "\e623"; +} + +.admin-icons-tongji:before { + content: "\e64a"; +} + +.admin-icons-yonghutongji:before { + content: "\e661"; +} + +.admin-icons-dashboard:before { + content: "\e78b"; +} + +.admin-icons-qudaofenxi:before { + content: "\e6c6"; +} + +.admin-icons-shebeitongji:before { + content: "\e6fd"; +} + +.admin-icons-xitongguanli:before { + content: "\e671"; +} + +.admin-icons-kaifashili:before { + content: "\e614"; +} + +.admin-icons-yonghutongji1:before { + content: "\e769"; +} + +.admin-icons-shijianfenxi:before { + content: "\e604"; +} + +.admin-icons-ziyuan:before { + content: "\e619"; +} + +.admin-icons-cuowutongji:before { + content: "\e51f"; +} + +.admin-icons-shijianfenxi1:before { + content: "\e629"; +} + + +.admin-icons-tongjishouye:before { + content: "\e679"; +} + +.admin-icons-yemiantongji:before { + content: "\e684"; +} + + +.admin-icons-manager-user:before { + content: "\e610"; +} + +.admin-icons-manager-role:before { + content: "\e61a"; +} + +.admin-icons-manager-permission:before { + content: "\e637"; +} + +.admin-icons-manager-app:before { + content: "\e65b"; +} + +.admin-icons-manager-tag:before { + content: "\e83c"; +} + +.admin-icons-manager-menu:before { + content: "\e629"; +} + +.admin-icons-overview:before { + content: "\e609"; +} + +.admin-icons-activity:before { + content: "\e70e"; +} + +.admin-icons-trend:before { + content: "\e63c"; +} + +.admin-icons-retention:before { + content: "\e697"; +} + +.admin-icons-comparison:before { + content: "\e955"; +} + +.admin-icons-stickiness:before { + content: "\e770"; +} + +.admin-icons-page-ent:before { + content: "\e767"; +} + +.admin-icons-page-res:before { + content: "\e69b"; +} + +.admin-icons-scene:before { + content: "\e601"; +} + +.admin-icons-channel:before { + content: "\e603"; +} + +.admin-icons-error-js:before { + content: "\ec0c"; +} + +.admin-icons-error-app:before { + content: "\e617"; +} + +.admin-icons-help:before { + content: "\e65c"; +} + +.admin-icons-icon:before { + content: "\e503"; +} + +.admin-icons-table:before { + content: "\e639"; +} + +.admin-icons-eco:before { + content: "\e698"; +} + +.admin-icons-doc:before { + content: "\e656"; +} + +.admin-icons-pulgin:before { + content: "\e648"; +} + +.admin-icons-lang:before { + content: "\e618"; +} + +.admin-icons-user:before { + content: "\e68d"; +} + +.admin-icons-safety:before { + content: "\e769"; +} diff --git a/alpha/admin/common/theme.scss b/alpha/admin/common/theme.scss new file mode 100644 index 0000000..82de492 --- /dev/null +++ b/alpha/admin/common/theme.scss @@ -0,0 +1,293 @@ +@import '@/uni.scss'; + +$theme-map: (); +$primary-key: 'primary'; +$success-key: 'success'; +$warn-key: 'warn'; +$warning-key: 'warning'; +$error-key: 'error'; + +@mixin themeify { + @each $theme-name, $theme-map in $themes { + $theme-map: $theme-map !global; + [data-theme='#{inspect($theme-name)}'] { + @content; + } + } +} +@function getTheme($key) { + @return map-get($theme-map, $key); +} +@mixin uni-button($button-type) { + $button-type-color: getTheme(#{$button-type + '-color'}); + uni-button, + button { + &[type='#{$button-type}'] { + background-color: $button-type-color; + &[disabled] { + background-color: opacify($button-type-color, 0.6); + } + &[plain] { + color: $button-type-color; + border-color: $button-type-color; + background-color: transparent; + } + &[loading] { + background-color: $button-type-color; + &[plain] { + color: $button-type-color; + } + } + &.button-hover { + $hover-color: darken( + $color: $button-type-color, + $amount: 10% + ); + background-color: $hover-color; + &[plain] { + color: $hover-color; + border-color: $hover-color; + background-color: transparent; + } + } + } + } +} +@mixin uni-switch { + $primary-color: getTheme(#{$primary-key + '-color'}); + .uni-switch-input.uni-switch-input-checked { + background-color: $primary-color !important; + border-color: $primary-color !important; + } +} +@mixin uni-ui-checkbox { + $primary-color: getTheme(#{$primary-key + '-color'}); + .checklist-box { + &.is-checked { + .checkbox__inner { + border-color: $primary-color !important; + background-color: $primary-color !important; + } + .radio__inner { + border-color: $primary-color !important; + .radio__inner-icon { + background-color: $primary-color !important; + } + } + .checklist-text { + color: $primary-color !important; + } + } + .checkbox__inner:hover { + border-color: $primary-color !important; + } + } +} +@mixin uni-ui-easyinput { + $primary-color: getTheme(#{$primary-key + '-color'}); + $error-color: getTheme(#{$error-key + '-color'}); + .uni-easyinput { + &.uni-easyinput-error { + color: $error-color !important; + } + .uni-easyinput__content { + &.is-focused { + &.is-input-border { + border-color: $primary-color !important; + } + .uni-icons { + color: $primary-color !important; + } + } + } + } +} +@mixin uni-menu { + $primary-color: getTheme(#{$primary-key + '-color'}); + // 左侧菜单 + .uni-nav-menu { + .uni-menu-item.is-active { + color: $primary-color; + } + } + // 修改密码 + .navbar-menu { + .menu-item.hover-highlight:hover { + color: $primary-color; + } + } +} +@mixin uni-table { + $primary-color: getTheme(#{$primary-key + '-color'}); + .uni-table { + .link-btn-color { + color: $primary-color; + } + .uni-table-checkbox { + .checkbox__inner { + &.checkbox--indeterminate, + &.is-checked { + border-color: $primary-color; + background-color: $primary-color; + } + } + .checkbox__inner:hover { + border-color: $primary-color; + } + } + .uni-table-th-content { + .arrow-box { + .arrow.active ::after { + background-color: $primary-color; + } + } + } + // 表格头部搜索按钮 + .opera-area { + .btn.btn-submit { + background-color: $primary-color; + } + } + .dropdown-btn { + .icon-search.active { + .icon-search-0 { + border-color: $primary-color; + } + .icon-search-1 { + background-color: $primary-color; + } + } + .icon-calendar.active { + .icon-calendar-0 { + border-color: $primary-color; + } + .icon-calendar-1 { + background-color: $primary-color; + } + } + } + .uni-icons.uni-stat-edit--btn { + color: $primary-color !important; + } + } + .uni-pagination { + .uni-pagination__num-current .page--active { + background-color: $primary-color !important; + } + } +} +@mixin uni-picker { + $primary-color: getTheme(#{$primary-key + '-color'}); + .uni-picker-select { + .uni-picker-item.selected { + color: $primary-color; + } + } +} +@mixin uni-calendar { + $primary-color: getTheme(#{$primary-key + '-color'}); + .uni-calendar__button-text { + color: $primary-color; + } + .uni-datetime-picker--btn { + background-color: $primary-color; + } + .uni-calendar-item--multiple { + .uni-calendar-item--before-checked, + .uni-calendar-item--after-checked { + background-color: $primary-color; + } + } + .uni-calendar-item__weeks-box { + .uni-calendar-item--checked { + background-color: $primary-color; + } + &-text { + color: darken($color: $primary-color, $amount: 40%); + } + } +} +@mixin uni-popup { + $primary-color: getTheme(#{$primary-key + '-color'}); + .uni-popup-dialog { + .uni-button-color { + color: $primary-color; + } + } +} +@mixin uni-tag($tag-type) { + $tag-type-color: getTheme(#{$tag-type + '-color'}); + .uni-tag { + &--#{$tag-type} { + &--inverted { + background-color: #fff !important; + color: $tag-type-color !important; + } + background-color: $tag-type-color !important; + border-color: $tag-type-color !important; + } + } +} + +body { + @at-root { + @include themeify { + $primary-color: getTheme(#{$primary-key + '-color'}); + // 组件 + @include uni-button($primary-key); + @include uni-button($warn-key); + @include uni-tag($primary-key); + @include uni-tag($success-key); + @include uni-tag($warning-key); + @include uni-tag($error-key); + @include uni-ui-checkbox; + @include uni-switch; + @include uni-ui-easyinput; + @include uni-menu; + @include uni-table; + @include uni-picker; + @include uni-calendar; + @include uni-popup; + // 页面 + .link-btn { + color: $primary-color !important; + } + .uni-stat--tab-item { + &.uni-stat--tab-item-line-active, + &.uni-stat--tab-item-boldLine-active { + color: $primary-color; + border-color: $primary-color; + } + &.uni-stat--tab-item-box-active { + border-color: $primary-color; + } + } + .uni-title.app-list { + color: $primary-color; + border-color: $primary-color; + } + .uni-link { + color: $primary-color; + } + .uni-selector-select .uni-picker-item.selected { + color: $primary-color; + } + .uni-tabs__item.is-active { + color: $primary-color; + } + .uni-modal__btn_primary { + color: $primary-color !important; + } + .uni-radio-input-checked { + background-color: $primary-color !important; + border-color: $primary-color !important; + } + .uni-container { + .icon-item:hover, + .icon-item:hover .icon-text { + color: $primary-color; + } + } + } + } +} diff --git a/alpha/admin/common/uni-icons.css b/alpha/admin/common/uni-icons.css new file mode 100644 index 0000000..5e678db --- /dev/null +++ b/alpha/admin/common/uni-icons.css @@ -0,0 +1,542 @@ +@font-face { + font-family: uni-icons; + src: url('~@/uni_modules/uni-icons/components/uni-icons/uni.ttf') format('truetype'); + font-weight: 400; + font-display: "auto"; + font-style: normal +} + +[class*=" uni-icons-"], +[class^=uni-icons-] { + font-family: uni-icons !important; + speak: none; + font-style: normal; + font-weight: 400; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: baseline; + display: inline-block; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +.uni-icons-shop:before { + content: "\e609"; +} + +.uni-icons-headphones:before { + content: "\e8bf"; +} + +.uni-icons-pulldown:before { + content: "\e588"; +} + +.uni-icons-scan:before { + content: "\e612"; +} + +.uni-icons-back:before { + content: "\e471"; +} + +.uni-icons-forward:before { + content: "\e470"; +} + +.uni-icons-refreshempty:before { + content: "\e461"; +} + +.uni-icons-checkbox-filled:before { + content: "\e442"; +} + +.uni-icons-checkbox:before { + content: "\e7fa"; +} + +.uni-icons-loop:before { + content: "\e565"; +} + +.uni-icons-arrowthindown:before { + content: "\e585"; +} + +.uni-icons-arrowthinleft:before { + content: "\e586"; +} + +.uni-icons-arrowthinright:before { + content: "\e587"; +} + +.uni-icons-arrowthinup:before { + content: "\e584"; +} + +.uni-icons-bars:before { + content: "\e563"; +} + +.uni-icons-cart-filled:before { + content: "\e7f4"; +} + +.uni-icons-cart:before { + content: "\e7f5"; +} + +.uni-icons-arrowleft:before { + content: "\e582"; +} + +.uni-icons-arrowdown:before { + content: "\e581"; +} + +.uni-icons-arrowright:before { + content: "\e583"; +} + +.uni-icons-arrowup:before { + content: "\e580"; +} + +.uni-icons-eye-filled:before { + content: "\e568"; +} + +.uni-icons-eye-slash-filled:before { + content: "\e822"; +} + +.uni-icons-eye-slash:before { + content: "\e823"; +} + +.uni-icons-eye:before { + content: "\e824"; +} + +.uni-icons-reload:before { + content: "\e462"; +} + +.uni-icons-hand-thumbsdown-filled:before { + content: "\e83b"; +} + +.uni-icons-hand-thumbsdown:before { + content: "\e83c"; +} + +.uni-icons-hand-thumbsup-filled:before { + content: "\e83d"; +} + +.uni-icons-heart-filled:before { + content: "\e83e"; +} + +.uni-icons-hand-thumbsup:before { + content: "\e83f"; +} + +.uni-icons-heart:before { + content: "\e840"; +} + +.uni-icons-mail-open-filled:before { + content: "\e84d"; +} + +.uni-icons-mail-open:before { + content: "\e84e"; +} + +.uni-icons-list:before { + content: "\e562"; +} + +.uni-icons-map-pin:before { + content: "\e85e"; +} + +.uni-icons-map-pin-ellipse:before { + content: "\e864"; +} + +.uni-icons-paperclip:before { + content: "\e567"; +} + +.uni-icons-images-filled:before { + content: "\e87a"; +} + +.uni-icons-images:before { + content: "\e87b"; +} + +.uni-icons-search:before { + content: "\e466"; +} + +.uni-icons-settings:before { + content: "\e560"; +} + +.uni-icons-cloud-download:before { + content: "\e8e4"; +} + +.uni-icons-cloud-upload-filled:before { + content: "\e8e5"; +} + +.uni-icons-cloud-upload:before { + content: "\e8e6"; +} + +.uni-icons-cloud-download-filled:before { + content: "\e8e9"; +} + +.uni-icons-more:before { + content: "\e507"; +} + +.uni-icons-more-filled:before { + content: "\e537"; +} + +.uni-icons-refresh:before { + content: "\e407"; +} + +.uni-icons-refresh-filled:before { + content: "\e437"; +} + +.uni-icons-undo-filled:before { + content: "\e7d6"; +} + +.uni-icons-undo:before { + content: "\e406"; +} + +.uni-icons-redo:before { + content: "\e405"; +} + +.uni-icons-redo-filled:before { + content: "\e7d9"; +} + +.uni-icons-camera:before { + content: "\e301"; +} + +.uni-icons-camera-filled:before { + content: "\e7ef"; +} + +.uni-icons-smallcircle-filled:before { + content: "\e801"; +} + +.uni-icons-circle:before { + content: "\e411"; +} + +.uni-icons-flag-filled:before { + content: "\e825"; +} + +.uni-icons-flag:before { + content: "\e508"; +} + +.uni-icons-gear-filled:before { + content: "\e532"; +} + +.uni-icons-gear:before { + content: "\e502"; +} + +.uni-icons-home:before { + content: "\e500"; +} + +.uni-icons-info:before { + content: "\e504"; +} + +.uni-icons-home-filled:before { + content: "\e530"; +} + +.uni-icons-info-filled:before { + content: "\e534"; +} + +.uni-icons-circle-filled:before { + content: "\e441"; +} + +.uni-icons-chat-filled:before { + content: "\e847"; +} + +.uni-icons-chat:before { + content: "\e263"; +} + +.uni-icons-checkmarkempty:before { + content: "\e472"; +} + +.uni-icons-locked-filled:before { + content: "\e856"; +} + +.uni-icons-locked:before { + content: "\e506"; +} + +.uni-icons-map-filled:before { + content: "\e85c"; +} + +.uni-icons-map:before { + content: "\e364"; +} + +.uni-icons-minus-filled:before { + content: "\e440"; +} + +.uni-icons-mic-filled:before { + content: "\e332"; +} + +.uni-icons-minus:before { + content: "\e410"; +} + +.uni-icons-micoff:before { + content: "\e360"; +} + +.uni-icons-mic:before { + content: "\e302"; +} + +.uni-icons-clear:before { + content: "\e434"; +} + +.uni-icons-smallcircle:before { + content: "\e868"; +} + +.uni-icons-close:before { + content: "\e404"; +} + +.uni-icons-closeempty:before { + content: "\e460"; +} + +.uni-icons-paperplane:before { + content: "\e503"; +} + +.uni-icons-paperplane-filled:before { + content: "\e86e"; +} + +.uni-icons-image:before { + content: "\e363"; +} + +.uni-icons-image-filled:before { + content: "\e877"; +} + +.uni-icons-location-filled:before { + content: "\e333"; +} + +.uni-icons-location:before { + content: "\e303"; +} + +.uni-icons-plus-filled:before { + content: "\e439"; +} + +.uni-icons-plus:before { + content: "\e409"; +} + +.uni-icons-plusempty:before { + content: "\e468"; +} + +.uni-icons-help-filled:before { + content: "\e535"; +} + +.uni-icons-help:before { + content: "\e505"; +} + +.uni-icons-navigate-filled:before { + content: "\e884"; +} + +.uni-icons-navigate:before { + content: "\e501"; +} + +.uni-icons-mic-slash-filled:before { + content: "\e892"; +} + +.uni-icons-sound:before { + content: "\e590"; +} + +.uni-icons-sound-filled:before { + content: "\e8a1"; +} + +.uni-icons-spinner-cycle:before { + content: "\e465"; +} + +.uni-icons-download-filled:before { + content: "\e8a4"; +} + +.uni-icons-videocam-filled:before { + content: "\e8af"; +} + +.uni-icons-upload:before { + content: "\e402"; +} + +.uni-icons-upload-filled:before { + content: "\e8b1"; +} + +.uni-icons-starhalf:before { + content: "\e463"; +} + +.uni-icons-star-filled:before { + content: "\e438"; +} + +.uni-icons-star:before { + content: "\e408"; +} + +.uni-icons-trash:before { + content: "\e401"; +} + +.uni-icons-compose:before { + content: "\e400"; +} + +.uni-icons-videocam:before { + content: "\e300"; +} + +.uni-icons-trash-filled:before { + content: "\e8dc"; +} + +.uni-icons-download:before { + content: "\e403"; +} + +.uni-icons-qq:before { + content: "\e264"; +} + +.uni-icons-weibo:before { + content: "\e260"; +} + +.uni-icons-weixin:before { + content: "\e261"; +} + +.uni-icons-pengyouquan:before { + content: "\e262"; +} + +.uni-icons-chatboxes:before { + content: "\e203"; +} + +.uni-icons-chatboxes-filled:before { + content: "\e233"; +} + +.uni-icons-email-filled:before { + content: "\e231"; +} + +.uni-icons-email:before { + content: "\e201"; +} + +.uni-icons-person-filled:before { + content: "\e131"; +} + +.uni-icons-contact-filled:before { + content: "\e130"; +} + +.uni-icons-person:before { + content: "\e101"; +} + +.uni-icons-contact:before { + content: "\e100"; +} + +.uni-icons-phone:before { + content: "\e200"; +} + +.uni-icons-personadd-filled:before { + content: "\e132"; +} + +.uni-icons-personadd:before { + content: "\e102"; +} + +.uni-icons-phone-filled:before { + content: "\e230"; +} + +.uni-icons-chatbubble-filled:before { + content: "\e232"; +} + +.uni-icons-chatbubble:before { + content: "\e202"; +} diff --git a/alpha/admin/common/uni.css b/alpha/admin/common/uni.css new file mode 100644 index 0000000..68115dd --- /dev/null +++ b/alpha/admin/common/uni.css @@ -0,0 +1,617 @@ +/* 全局公共样式 */ + +body, +html { + -webkit-user-select: auto; + user-select: auto; + font-size: 16px; +} + +/* #ifdef H5 */ + +.uni-app--showleftwindow uni-main { + position: relative; + background-color: #f5f5f5; +} + +.uni-mask + .uni-left-window, +.uni-mask + .uni-right-window { + position: fixed; +} + +.uni-app--showleftwindow uni-page-head .uni-page-head { + color: #333 !important; + /* margin-right: 15px; */ +} + +uni-page-head .uni-btn-icon { + color: #333 !important; +} + +.uni-app--showleftwindow + uni-page-head[uni-page-head-type="default"] + ~ uni-page-wrapper { + height: auto; + padding-top: 44px; +} + +.uni-app--showleftwindow uni-page-head ~ uni-page-wrapper uni-page-body { + /* padding-top: 44px; */ +} + +.uni-app--showleftwindow uni-page-wrapper { + position: absolute; + width: 100%; + top: 0; + bottom: 0; + padding: 15px; + overflow-y: auto; + box-sizing: border-box; + background-color: #f5f5f5; +} + +.uni-app--showleftwindow uni-page-body { + width: 100%; + min-height: 100%; + box-sizing: border-box; + border-radius: 5px; + box-shadow: -1px -1px 5px 0 rgba(0, 0, 0, 0.1); + background-color: #fff; +} + +.uni-app--showleftwindow .uni-container .uni-forms { + padding: 15px; + max-width: 650px; +} + +/* #endif */ + +/* #ifndef H5 */ +.uni-nav-menu { + height: 100vh; +} + +/* #endif */ + +.pointer { + cursor: pointer; +} + +.uni-top-window { + z-index: 999; + overflow: visible; +} + +.uni-tips { + font-size: 12px; + color: #666; +} + +/* 容器 */ +.uni-container { + padding: 15px; + box-sizing: border-box; +} + +/* 标题栏 */ +.uni-header { + padding: 0 15px; + display: flex; + min-height: 55px; + align-items: center; + justify-content: space-between; + border-bottom: 1px #f5f5f5 solid; + flex-wrap: wrap; +} + +.uni-title { + margin-right: 10px; + font-size: 16px; + font-weight: 500; + color: #333; +} + +.uni-sub-title { + margin-top: 3px; + font-size: 14px; + color: #999; +} + +.uni-link { + color: #3a8ee6; + cursor: pointer; + text-decoration: underline; +} + +.uni-group { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + word-break: keep-all; +} + +/* 按钮样式 */ +.uni-button-group { + margin-top: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.uni-button { + padding: 10px 20px; + font-size: 14px; + border-radius: 4px; + line-height: 1; + margin: 0; + box-sizing: border-box; + overflow: initial; +} + +.uni-group .uni-button { + margin: 10px; +} + +.uni-group .uni-search { + margin: 10px; +} + +.uni-group > .uni-button:first-child { + margin-left: 0; +} + +.uni-button:hover, +.uni-button:focus { + opacity: 0.9; +} + +.uni-button:active { + opacity: 1; +} + +.uni-button-full { + width: 100%; +} + +/* 搜索框样式 */ +.uni-search { + width: 268px; + height: 28px; + line-height: 28px; + font-size: 12px; + color: #606266; + padding: 0 10px; + border: 1px #dcdfe6 solid; + /* margin-right: 10px; */ + border-radius: 3px; +} + +/* 分页容器 */ +.uni-pagination-box { + margin-top: 20px; +} + +.uni-input-border, +.uni-textarea-border { + width: 100%; + font-size: 14px; + color: #666; + border: 1px #e5e5e5 solid; + border-radius: 5px; + box-sizing: border-box; +} + +.uni-input-border { + padding: 0 10px; + height: 35px; +} + +.uni-textarea-border { + padding: 10px; + height: 80px; +} + +.uni-disabled { + background-color: #f5f7fa; + color: #c0c4cc; +} + +.uni-icon-password-eye { + position: absolute; + right: 8px; + top: 6px; + font-family: uniicons; + font-size: 20px; + font-weight: normal; + font-style: normal; + width: 24px; + height: 24px; + line-height: 24px; + color: #999999; +} + +.uni-eye-active { + color: #007aff; +} + +.uni-tabs__header { + position: relative; + background-color: #f5f7fa; + border-bottom: 1px solid #e4e7ed; +} + +.uni-tabs__nav-wrap { + overflow: hidden; + margin-bottom: -1px; + position: relative; +} + +.uni-tabs__nav-scroll { + overflow: hidden; +} + +.uni-tabs__nav { + position: relative; + white-space: nowrap; +} + +.uni-tabs__item { + position: relative; + padding: 0 20px; + height: 40px; + box-sizing: border-box; + line-height: 40px; + display: inline-block; + list-style: none; + font-size: 14px; + font-weight: 500; + color: #909399; + margin-top: -1px; + margin-left: -1px; + border: 1px solid transparent; + cursor: pointer; +} + +.uni-tabs__item.is-active { + color: $uni-color-primary; + background-color: #fff; + border-right-color: #dcdfe6; + border-left-color: #dcdfe6; +} + +.uni-form-item-tips { + color: #999; + font-size: 12px; + margin-top: 10px; + /* position: absolute; */ + /* top: 40px; */ +} + +.uni-form-item-empty { + color: #999; + min-height: 36px; + line-height: 36px; +} + +::v-deep .uni-forms-item__label .label-text { + color: #606266 !important; +} + +::v-deep .flex-center-x .uni-forms-item__content { + display: flex; + align-items: center; + flex-wrap: wrap; +} + +.link-btn { + line-height: 26px; + margin-top: 5px; + color: #007aff !important; + text-decoration: underline; + cursor: pointer; +} + +/* button 重置样式 */ +::v-deep button[size="mini"] { + line-height: 2.4; + font-size: 12px; + border-radius: 3px; +} + +button { + background: #fff; + border: 1px solid #dcdfe6; + color: #606266; + box-sizing: border-box; +} + +button[type="primary"] { + background-color: #409eff; + border-color: #409eff; + border-width: 0; +} + +button[type="warn"] { + background-color: #f56c6c; + border-color: #f56c6c; + border-width: 0; +} + +button[type="default"] { + background: #fff; + border: 1px solid #dcdfe6; + color: #606266; + box-sizing: border-box; +} + +button[type="primary"][plain] { + border-color: #409eff; + color: #409eff; +} + +button[type="warn"][plain] { + border-color: #f56c6c; + color: #f56c6c; +} + +button[type="default"][plain] { + border-color: #dcdfe6; + color: #606266; +} + +button[plain] { + border-color: #dcdfe6; + color: #606266; +} + +button:after { + border-width: 0; +} + +.uni-input-placeholder { + color: #999; +} + +.uni-pagination-box { + display: flex; + align-items: center; + justify-content: center; +} + +.select-picker { + margin-right: 20px; +} + +.select-picker button { + margin-top: 5px; + line-height: 29px; + font-size: 14px; +} + +.select-picker button text { + color: #999; +} + +.select-picker-icon { + margin-left: 8px; +} + +/* stat style start */ +.m-m { + margin: 15px !important; +} + +.mb-s { + margin-bottom: 5px; +} + +.mb-m { + margin-bottom: 15px !important; +} + +.mb-l { + margin-bottom: 30px !important; +} + +.ml-s { + margin-left: 5px; +} + +.ml-m { + margin-left: 15px !important; +} + +.ml-l { + margin-left: 30px !important; +} + +.p-m { + padding: 15px; +} + +.p-channel { + padding: 0 15px 15px 15px; +} + +.p-1015 { + padding: 10px 15px; +} + +.uni-charts-box { + width: 100%; + height: 350px; +} + +.uni-stat--x { + border-radius: 4px; + box-shadow: -1px -1px 5px 0 rgba(0, 0, 0, 0.1); + margin-bottom: 15px; +} + +.uni-stat__actived { + /* outline: 1px solid #2979ff; */ +} + +.flex { + display: flex; + flex-wrap: wrap; + align-items: center; +} + +.label-text { + font-size: 14px; + font-weight: bold; + color: #555; + margin: auto 0; + margin-right: 5px; +} + +.uni-stat-edit--x { + display: flex; + justify-content: space-between; +} + +.uni-stat-edit--btn { + cursor: pointer; +} + +.uni-stat-datetime-picker { + margin: 15px; +} + +/* uni-popup modal start */ +.modal { + /* width: 100%; */ + max-width: calc(100vw - 200px); + min-width: 600px; + margin: 0 auto; + background-color: #ffffff; +} + +.modal-header { + padding: 20px 0; + text-align: center; + border-bottom: 1px solid #eee; +} + +.modal-footer { + padding: 20px; + display: flex; + justify-content: flex-end; + align-items: center; + /* border-top: 1px solid #eee; */ +} + +.modal-content { + padding: 15px; + height: 600px; + box-sizing: border-box; +} + +/* uni-popup modal end */ + +.uni-stat-tooltip-s { + width: 160px; + white-space: normal; +} + +/* #ifndef APP-NVUE */ +@media screen and (max-width: 500px) { + .hide-on-phone { + display: none !important; + } + + .uni-charts-box { + width: 100%; + height: 220px; + } + + .uni-group .uni-search { + height: 32px; + line-height: 32px; + width: 100%; + margin: 20px 20px 10px 20px; + } + + .uni-header { + padding-left: 0px; + padding-right: 0px; + border: unset; + } + + .uni-group { + width: 100%; + } + + .uni-stat-breadcrumb-on-phone { + padding: 0 20px !important; + border-bottom: 1px #f5f5f5 solid; + } + + .flex { + width: 100%; + display: flex; + flex-wrap: wrap; + align-items: center; + } +} + +@media screen and (min-width: 500px) { + .dispaly-grid { + display: grid; + /* grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); */ + grid-template-columns: 1fr 1fr; + /* grid-template-rows: 1fr 1fr; */ + column-gap: 15px; + } + + .pc-flex-wrap { + display: flex; + flex-wrap: wrap; + align-items: center; + } + + .uni-stat-datetime-picker { + max-width: 350px; + } + + ::v-deep .uni-pagination-picker-show .uni-picker-container .uni-picker-custom { + width: 100px; + margin: 0 86px; + } + + ::v-deep .uni-pagination-picker-show .uni-picker-container .uni-picker-custom .uni-picker-select + div { + left: 50% !important; + } +} + +/* #endif */ + +/* #ifdef H5 */ +/* fix 弹出层被遮盖 */ +::v-deep .uni-table-scroll { + min-height: calc(100vh - 237px); + box-sizing: border-box; +} +::v-deep .uni-table .tr-table--border { + border-left: 1px #ebeef5 solid; +} +/* #endif */ + +/* #ifdef H5 */ +/* fix 弹出层被遮盖 */ +::v-deep .uni-table-scroll { + min-height: calc(100vh - 237px); + box-sizing: border-box; +} +::v-deep .uni-table .tr-table--border { + border-left: 1px #ebeef5 solid; +} +/* #endif */ + +/* #ifndef H5 */ +.fix-top-window { + margin-top: 85px; +} +/* #endif */ diff --git a/alpha/admin/components/batch-sms/batch-sms.vue b/alpha/admin/components/batch-sms/batch-sms.vue new file mode 100644 index 0000000..79e5c9b --- /dev/null +++ b/alpha/admin/components/batch-sms/batch-sms.vue @@ -0,0 +1,519 @@ + + + + + diff --git a/alpha/admin/components/download-excel/download-excel.vue b/alpha/admin/components/download-excel/download-excel.vue new file mode 100644 index 0000000..cdb51de --- /dev/null +++ b/alpha/admin/components/download-excel/download-excel.vue @@ -0,0 +1,361 @@ + + + diff --git a/alpha/admin/components/download-excel/download.js b/alpha/admin/components/download-excel/download.js new file mode 100644 index 0000000..cc7d4f8 --- /dev/null +++ b/alpha/admin/components/download-excel/download.js @@ -0,0 +1,151 @@ +//download.js v4.2, by dandavis; 2008-2016. [MIT] see http://danml.com/download.html for tests/usage +// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime +// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs +// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling. +// v4 adds AMD/UMD, commonJS, and plain browser support +// v4.1 adds url download capability via solo URL argument (same domain/CORS only) +// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors +// https://github.com/rndme/download + +export default function download(data, strFileName, strMimeType) { + + var self = window, // this script is only for browsers anyway... + defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads + mimeType = strMimeType || defaultMime, + payload = data, + url = !strFileName && !strMimeType && payload, + anchor = document.createElement("a"), + toString = function(a){return String(a);}, + myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString), + fileName = strFileName || "download", + blob, + reader; + myBlob= myBlob.call ? myBlob.bind(self) : Blob ; + + if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback + payload=[payload, mimeType]; + mimeType=payload[0]; + payload=payload[1]; + } + + + if(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument + fileName = url.split("/").pop().split("?")[0]; + anchor.href = url; // assign href prop to temp anchor + if(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path: + var ajax=new XMLHttpRequest(); + ajax.open( "GET", url, true); + ajax.responseType = 'blob'; + ajax.onload= function(e){ + download(e.target.response, fileName, defaultMime); + }; + setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return: + return ajax; + } // end if valid url? + } // end if url? + + + //go ahead and download dataURLs right away + if(/^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(payload)){ + + if(payload.length > (1024*1024*1.999) && myBlob !== toString ){ + payload=dataUrlToBlob(payload); + mimeType=payload.type || defaultMime; + }else{ + return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs: + navigator.msSaveBlob(dataUrlToBlob(payload), fileName) : + saver(payload) ; // everyone else can save dataURLs un-processed + } + + }else{//not data url, is it a string with special needs? + if(/([\x80-\xff])/.test(payload)){ + var i=0, tempUiArr= new Uint8Array(payload.length), mx=tempUiArr.length; + for(i;i + + + + + + + + + + + diff --git a/alpha/admin/components/show-info/show-info.vue b/alpha/admin/components/show-info/show-info.vue new file mode 100644 index 0000000..9fc943e --- /dev/null +++ b/alpha/admin/components/show-info/show-info.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/alpha/admin/components/uni-data-menu/uni-data-menu.vue b/alpha/admin/components/uni-data-menu/uni-data-menu.vue new file mode 100644 index 0000000..c7d0880 --- /dev/null +++ b/alpha/admin/components/uni-data-menu/uni-data-menu.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/alpha/admin/components/uni-data-menu/util.js b/alpha/admin/components/uni-data-menu/util.js new file mode 100644 index 0000000..256d3e8 --- /dev/null +++ b/alpha/admin/components/uni-data-menu/util.js @@ -0,0 +1,67 @@ +function buildMenu(menu, menuList, menuIds) { + let nextLayer = [] + for (let i = menu.length - 1; i > -1; i--) { + const currentMenu = menu[i] + const subMenu = menuList.filter(item => { + if (item.parent_id === currentMenu.menu_id) { + menuIds.push(item.menu_id) + return true + } + }) + nextLayer = nextLayer.concat(subMenu) + currentMenu.children = subMenu + } + if (nextLayer.length) { + buildMenu(nextLayer, menuList, menuIds) + } +} + +function getParentIds(menuItem, menuList) { + const parentArr = [] + let currentItem = menuItem + while (currentItem && currentItem.parent_id) { + parentArr.push(currentItem.parent_id) + currentItem = menuList.find(item => item.menu_id === currentItem.parent_id) + } + return parentArr +} + +function buildMenus(menuList, trim = true) { + // 保证父子级顺序 + menuList = menuList.sort(function(a, b) { + const parentIdsA = getParentIds(a, menuList) + const parentIdsB = getParentIds(b, menuList) + if (parentIdsA.includes(b.menu_id)) { + return 1 + } + return parentIdsA.length - parentIdsB.length || a.sort - b.sort + }) + // 删除无subMenu且非子节点的菜单项 + if (trim) { + for (let i = menuList.length - 1; i > -1; i--) { + const currentMenu = menuList[i] + const subMenu = menuList.filter(subMenuItem => subMenuItem.parent_id === currentMenu.menu_id) + if (!currentMenu.isLeafNode && !subMenu.length) { + menuList.splice(i, 1) + } + } + } + const menuIds = [] + const menu = menuList.filter(item => { + if (!item.parent_id) { + menuIds.push(item.menu_id) + return true + } + }) + buildMenu(menu, menuList, menuIds) + // 包含所有无效菜单 + if (!trim && menuIds.length !== menuList.length) { + menu.push(...menuList.filter(item => !menuIds.includes(item.menu_id))) + } + return menu +} + +export { + buildMenu, + buildMenus +} diff --git a/alpha/admin/components/uni-menu-group/uni-menu-group.vue b/alpha/admin/components/uni-menu-group/uni-menu-group.vue new file mode 100644 index 0000000..78d65b0 --- /dev/null +++ b/alpha/admin/components/uni-menu-group/uni-menu-group.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/alpha/admin/components/uni-menu-item/uni-menu-item.vue b/alpha/admin/components/uni-menu-item/uni-menu-item.vue new file mode 100644 index 0000000..b23121b --- /dev/null +++ b/alpha/admin/components/uni-menu-item/uni-menu-item.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/alpha/admin/components/uni-menu-sidebar/uni-menu-sidebar.vue b/alpha/admin/components/uni-menu-sidebar/uni-menu-sidebar.vue new file mode 100644 index 0000000..8205c44 --- /dev/null +++ b/alpha/admin/components/uni-menu-sidebar/uni-menu-sidebar.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/alpha/admin/components/uni-nav-menu/mixins/rootParent.js b/alpha/admin/components/uni-nav-menu/mixins/rootParent.js new file mode 100644 index 0000000..776b0c3 --- /dev/null +++ b/alpha/admin/components/uni-nav-menu/mixins/rootParent.js @@ -0,0 +1,29 @@ +export default { + methods:{ + /** + * 获取所有父元素 + * @param {Object} name + * @param {Object} parent + */ + getParentAll(name, parent) { + parent = this.getParent(`uni${name}`, parent) + if (parent) { + this.rootMenu[name].push(parent) + this.getParentAll(name, parent) + } + }, + /** + * 获取父元素实例 + */ + getParent(name, parent, type) { + parent = parent.$parent; + let parentName = parent.$options.name; + while (parentName !== name) { + parent = parent.$parent; + if (!parent) return false + parentName = parent.$options.name; + } + return parent; + } + } +} \ No newline at end of file diff --git a/alpha/admin/components/uni-nav-menu/uni-nav-menu.vue b/alpha/admin/components/uni-nav-menu/uni-nav-menu.vue new file mode 100644 index 0000000..7a2fe77 --- /dev/null +++ b/alpha/admin/components/uni-nav-menu/uni-nav-menu.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/alpha/admin/components/uni-stat-breadcrumb/uni-stat-breadcrumb.vue b/alpha/admin/components/uni-stat-breadcrumb/uni-stat-breadcrumb.vue new file mode 100644 index 0000000..294586f --- /dev/null +++ b/alpha/admin/components/uni-stat-breadcrumb/uni-stat-breadcrumb.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/alpha/admin/components/uni-stat-panel/uni-stat-panel.vue b/alpha/admin/components/uni-stat-panel/uni-stat-panel.vue new file mode 100644 index 0000000..9fab7c9 --- /dev/null +++ b/alpha/admin/components/uni-stat-panel/uni-stat-panel.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/alpha/admin/components/uni-stat-table/uni-stat-table.vue b/alpha/admin/components/uni-stat-table/uni-stat-table.vue new file mode 100644 index 0000000..c41e494 --- /dev/null +++ b/alpha/admin/components/uni-stat-table/uni-stat-table.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/alpha/admin/components/uni-stat-tabs/uni-stat-tabs.vue b/alpha/admin/components/uni-stat-tabs/uni-stat-tabs.vue new file mode 100644 index 0000000..f8c26fd --- /dev/null +++ b/alpha/admin/components/uni-stat-tabs/uni-stat-tabs.vue @@ -0,0 +1,361 @@ + + + + + diff --git a/alpha/admin/components/uni-sub-menu/uni-sub-menu.vue b/alpha/admin/components/uni-sub-menu/uni-sub-menu.vue new file mode 100644 index 0000000..97771d3 --- /dev/null +++ b/alpha/admin/components/uni-sub-menu/uni-sub-menu.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/alpha/admin/i18n/en.json b/alpha/admin/i18n/en.json new file mode 100644 index 0000000..91e2352 --- /dev/null +++ b/alpha/admin/i18n/en.json @@ -0,0 +1,107 @@ +{ + "login": { + "text": { + "title": "System Login", + "prompt": "If there is no administrator account, please create an administrator first..." + }, + "field": { + "username": "Account", + "password": "Password", + "captcha": "Captcha" + }, + "button": { + "login": "Log In" + } + }, + "topwindow": { + "text": { + "doc": "Admin doc", + "plugin": "More admin plugin", + "changeLanguage": "Language", + "changePwd": "ChangePwd", + "signOut": "Sign out" + } + }, + "index": { + "text": { + "prompt": "Main content, customizable content and style", + "vesion": "The current version can be viewed in the console and package.json" + } + }, + "updatePwd": { + "text": { + "title": "Change Password" + }, + "field": { + "oldPassword": "Old password", + "newPassword": "New password", + "passwordConfirmation": "Confirm password" + }, + "button": { + "save": "Save", + "back": "Back" + } + }, + "common": { + "placeholder": { + "query": "Enter search content" + }, + "button": { + "search": "Search", + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "batchDelete": "Batch Delete", + "exportExcel": "Export Excel", + "submit": "Submit", + "back": "Back", + "tagManager": "Tag Manager", + "publish": "Publish page management", + "version": "version manager", + "sendSMS": "Send SMS" + }, + "empty": "No more data", + "piecePerPage": "piece/page" + }, + "user": { + "text": { + "userManager": "Users Manager" + } + }, + "role": { + "text": { + "roleManager": "Roles Manager" + } + }, + "permission": { + "text": { + "permissionManager": "Permissions Manager" + } + }, + "app": { + "text": { + "appManager": "App Manager", + "describle": "Manage the apps that users can login" + } + }, + "menu": { + "text": { + "menuManager": "Menus Manager", + "additiveMenu": "Additive Menu" + }, + "button": { + "addFirstLevelMenu": "Add First-level Menu", + "addChildMenu": "Submenu", + "updateBuiltInMenu": "Update built-in Menu" + } + }, + "demo": { + "icons": { + "title": "Icons", + "describle": "Click icons to copy the icon code" + }, + "table": { + "title": "Table" + } + } +} diff --git a/alpha/admin/i18n/index.js b/alpha/admin/i18n/index.js new file mode 100644 index 0000000..8c3b392 --- /dev/null +++ b/alpha/admin/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/i18n/zh-Hans.json b/alpha/admin/i18n/zh-Hans.json new file mode 100644 index 0000000..97ad64d --- /dev/null +++ b/alpha/admin/i18n/zh-Hans.json @@ -0,0 +1,107 @@ +{ + "login": { + "text": { + "title": "系统登录", + "prompt": "如无管理员账号,请先创建管理员" + }, + "field": { + "username": "账号", + "password": "密码", + "captcha": "验证码" + }, + "button": { + "login": "登录" + } + }, + "topwindow": { + "text": { + "doc": "Admin 框架文档", + "plugin": "浏览更多 Admin 插件", + "changeLanguage": "切换语言", + "changePwd": "修改密码", + "signOut": "退出" + } + }, + "index": { + "text": { + "prompt": "内容主体,可自定义内容及样式", + "vesion": "可在控制台和 package.json 中查看当前的版本" + } + }, + "updatePwd": { + "text": { + "title": "修改密码" + }, + "field": { + "oldPassword": "旧密码", + "newPassword": "新密码", + "passwordConfirmation": "确认新密码" + }, + "button": { + "save": "保存", + "back": "返回" + } + }, + "common": { + "placeholder": { + "query": "请输入搜索内容" + }, + "button": { + "search": "搜索", + "add": "新增", + "edit": "修改", + "delete": "删除", + "batchDelete": "批量删除", + "exportExcel": "导出 Excel", + "submit": "提交", + "back": "返回", + "tagManager": "标签管理", + "publish": "发布页管理", + "version": "版本管理", + "sendSMS": "群发短信" + }, + "empty": "没有更多数据", + "piecePerPage": "条/页" + }, + "user": { + "text": { + "userManager": "用户管理" + } + }, + "role": { + "text": { + "roleManager": "角色管理" + } + }, + "permission": { + "text": { + "permissionManager": "权限管理" + } + }, + "app": { + "text": { + "appManager": "应用管理", + "describle": "管理用户可登录的应用" + } + }, + "menu": { + "text": { + "menuManager": "菜单列表", + "additiveMenu": "待添加菜单" + }, + "button": { + "addFirstLevelMenu": "新增一级菜单", + "addChildMenu": "子菜单", + "updateBuiltInMenu": "更新内置菜单" + } + }, + "demo": { + "icons": { + "title": "图标", + "describle": "点击图标即可复制图标代码" + }, + "table": { + "title": "表格" + } + } +} diff --git a/alpha/admin/i18n/zh-Hant.json b/alpha/admin/i18n/zh-Hant.json new file mode 100644 index 0000000..68fbd0c --- /dev/null +++ b/alpha/admin/i18n/zh-Hant.json @@ -0,0 +1,107 @@ +{ + "login": { + "text": { + "title": "系統登錄", + "prompt": "如無管理員賬號,請先創建管理員..." + }, + "field": { + "username": "賬號", + "password": "密碼", + "captcha": "驗證碼" + }, + "button": { + "login": "登錄" + } + }, + "topwindow": { + "text": { + "doc": "Admin 框架文檔", + "plugin": "瀏覽更多 Admin 插件", + "changeLanguage": "切换语言", + "changePwd": "修改密碼", + "signOut": "退出" + } + }, + "index": { + "text": { + "prompt": "內容主體,可自定義內容及樣式", + "vesion": "可在控制台和 package.json 中查看當前的版本" + } + }, + "updatePwd": { + "text": { + "title": "修改密碼" + }, + "field": { + "oldPassword": "舊密碼", + "newPassword": "新密碼", + "passwordConfirmation": "確認新密碼" + }, + "button": { + "save": "保存", + "back": "返回" + } + }, + "common": { + "placeholder": { + "query": "請輸入搜索內容" + }, + "button": { + "search": "檢索", + "add": "新增", + "edit": "修改", + "delete": "刪除", + "batchDelete": "批量刪除", + "exportExcel": "導出 Excel", + "submit": "提交", + "back": "返回", + "tagManager": "標簽管理", + "publish": "發布頁管理", + "version": "版本管理", + "sendSMS": "群發短信" + }, + "empty": "沒有更多數據", + "piecePerPage": "條/頁" + }, + "user": { + "text": { + "userManager": "用戶管理" + } + }, + "role": { + "text": { + "roleManager": "角色管理" + } + }, + "permission": { + "text": { + "permissionManager": "權限管理" + } + }, + "app": { + "text": { + "appManager": "應用管理", + "describle": "管理用戶可登錄的應用" + } + }, + "menu": { + "text": { + "menuManager": "菜單列表", + "additiveMenu": "待添加菜單" + }, + "button": { + "addFirstLevelMenu": "新增一級菜單", + "addChildMenu": "子菜單", + "updateBuiltInMenu": "更新內寘選單" + } + }, + "demo": { + "icons": { + "title": "圖標", + "describle": "點擊圖標即可複製圖標代碼" + }, + "table": { + "title": "表格" + } + } +} diff --git a/alpha/admin/index.html b/alpha/admin/index.html new file mode 100644 index 0000000..c3ff205 --- /dev/null +++ b/alpha/admin/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + +
+ + + diff --git a/alpha/admin/js_sdk/uni-admin/constants.js b/alpha/admin/js_sdk/uni-admin/constants.js new file mode 100644 index 0000000..2c5d0f3 --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/constants.js @@ -0,0 +1,66 @@ +const uniAdminPrefix = 'UNI_ADMIN' + +export const MENU = `${uniAdminPrefix}_MENU` + +/** uni-id 云端错误码 */ +export const UNI_ID_ERR_CODE = { + /** 登陆状态失效,token已过期 */ + TOKEN_EXPIRED: 'UNI-ID-TOKEN-EXPIRED', + /** token校验未通过 */ + CHECK_TOKEN_FAILED: 'uni-id-check-token-failed', + /** 账户已存在 */ + ACCOUNT_EXISTS: 'uni-id-account-exists', + /** 账户不存在 */ + ACCOUNT_NOT_EXISTS: 'uni-id-account-not-exists', + /** 用户账号冲突,可能会由开发者手动更新数据库导致,正常情况下不应 */ + ACCOUNT_CONFLICT: 'uni-id-account-conflict', + /** 此账号已封禁 */ + ACCOUNT_BANNED: 'uni-id-account-banned', + /** 此账号正在审核中 */ + ACCOUNT_AUDITING: 'uni-id-account-auditing', + /** 此账号审核失败 */ + ACCOUNT_AUDIT_FAILED: 'uni-id-account-audit-failed', + /** 此账号已注销 */ + ACCOUNT_CLOSED: 'uni-id-account-closed', + /** 请输入图形验证码 */ + CAPTCHA_REQUIRED: 'uni-id-captcha-required', + /** 用户名或密码错误 */ + PASSWORD_ERROR: 'uni-id-password-error', + /** 用户名不合法 */ + INVALID_USERNAME: 'uni-id-invalid-username', + /** 密码不合法 */ + INVALID_PASSWORD: 'uni-id-invalid-password', + /** 手机号码不合法 */ + INVALID_MOBILE: 'uni-id-invalid-mobile', + /** 邮箱不合法 */ + INVALID_EMAIL: 'uni-id-invalid-email', + /** 昵称不合法 */ + INVALID_NICKNAME: 'uni-id-invalid-nickname', + /** 参数错误 */ + INVALID_PARAM: 'uni-id-invalid-param', + /** 缺少参数 */ + PARAM_REQUIRED: 'uni-id-param-required', + /** 获取第三方账号失败 */ + GET_THIRD_PARTY_ACCOUNT_FAILED: 'uni-id-get-third-party-account-failed', + /** 获取第三方用户信息失败 */ + GET_THIRD_PARTY_USER_INFO_FAILED: 'uni-id-get-third-party-user-info-failed', + /** 手机验证码错误或已过期 */ + MOBILE_VERIFY_CODE_ERROR: 'uni-id-mobile-verify-code-error', + /** 邮箱验证码错误或已过期 */ + EMAIL_VERIFY_CODE_ERROR: 'uni-id-email-verify-code-error', + /** 超级管理员已存在 */ + ADMIN_EXISTS: 'uni-id-admin-exists', + /** 权限错误 */ + PERMISSION_ERROR: 'uni-id-permission-error', + /** 系统错误 */ + SYSTEM_ERROR: 'uni-id-system-error', + /** 设置邀请码失败 */ + SET_INVITE_CODE_FAILED: 'uni-id-set-invite-code-failed', + /** 邀请码不可用 */ + INVALID_INVITE_CODE: 'uni-id-invalid-invite-code', + /** 禁止修改邀请人 */ + CHANGE_INVITER_FORBIDDEN: 'uni-id-change-inviter-forbidden', + /** 此账号(微信、QQ、手机号等)已被绑定 */ + BIND_CONFLICT: 'uni-id-bind-conflict', + +} diff --git a/alpha/admin/js_sdk/uni-admin/error.js b/alpha/admin/js_sdk/uni-admin/error.js new file mode 100644 index 0000000..95c9b64 --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/error.js @@ -0,0 +1,42 @@ +import store from '@/store' +import config from '@/admin.config.js' + +// #ifndef VUE3 +export function initError(Vue) { + const debugOptions = config.navBar.debug + if (debugOptions && debugOptions.enable === true) { + const oldErrorHandler = Vue.config.errorHandler + Vue.config.errorHandler = function errorHandler(err, vm, info) { + console.error(err) + const route = vm.$page && vm.$page.route + store.dispatch('error/add', { + err: err.toString(), + info, + route, + time: new Date().toLocaleTimeString() + }) + return oldErrorHandler(err, vm, info) + } + } +} +// #endif + +// #ifdef VUE3 +export function initError(app) { + const debugOptions = config.navBar.debug + if (debugOptions && debugOptions.enable === true) { + const oldErrorHandler = app.config.errorHandler + app.config.errorHandler = function errorHandler(err, vm, info) { + console.error(err) + const route = vm.$page && vm.$page.route + store.dispatch('error/add', { + err: err.toString(), + info, + route, + time: new Date().toLocaleTimeString() + }) + return oldErrorHandler && oldErrorHandler(err, vm, info) + } + } +} +// #endif diff --git a/alpha/admin/js_sdk/uni-admin/fetchMock.js b/alpha/admin/js_sdk/uni-admin/fetchMock.js new file mode 100644 index 0000000..62749cc --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/fetchMock.js @@ -0,0 +1,23 @@ +function fetchMock(url) { + // return fetch(url) + // .then(response => response.json()) + // .then(res => { + // return Promise.resolve(res) + // }).catch(err => { + // return Promise.resolve([]) + // }) + + return Promise.resolve([]) +} + +// #ifndef VUE3 +export function initFetch(Vue) { + Vue.prototype.$fetch = fetchMock +} +// #endif + +// #ifdef VUE3 +export function initFetch(app) { + app.config.globalProperties.$fetch = fetchMock +} +// #endif diff --git a/alpha/admin/js_sdk/uni-admin/interceptor.js b/alpha/admin/js_sdk/uni-admin/interceptor.js new file mode 100644 index 0000000..37c160b --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/interceptor.js @@ -0,0 +1,15 @@ +import config from '@/admin.config.js' + +export function initInterceptor() { + uni.addInterceptor('navigateTo', { + fail: ({ + errMsg + }) => { + if (errMsg.indexOf('is not found') !== -1) { // 404 + uni.navigateTo({ + url: config.error.url + '?errMsg=' + errMsg + }) + } + } + }) +} diff --git a/alpha/admin/js_sdk/uni-admin/permission.js b/alpha/admin/js_sdk/uni-admin/permission.js new file mode 100644 index 0000000..13eba8c --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/permission.js @@ -0,0 +1,27 @@ +// #ifndef VUE3 +export function initPermission(Vue) { + Vue.prototype.$hasPermission = function hasPermission(name) { + const permission = this.$uniIdPagesStore.store.userInfo.permission || [] + const role = this.$uniIdPagesStore.store.userInfo.role || [] + return role.indexOf('admin') > -1 || permission.indexOf(name) > -1 + } + Vue.prototype.$hasRole = function hasRole(name) { + const role = this.$uniIdPagesStore.store.userInfo.role || [] + return role.indexOf(name) > -1 + } +} +// #endif + +// #ifdef VUE3 +export function initPermission(app) { + app.config.globalProperties.$hasPermission = function hasPermission(name) { + const permission = this.$uniIdPagesStore.store.userInfo.permission || [] + const role = this.$uniIdPagesStore.store.userInfo.role || [] + return role.indexOf('admin') > -1 || permission.indexOf(name) > -1 + } + app.config.globalProperties.$hasRole = function hasRole(name) { + const role = this.$uniIdPagesStore.store.userInfo.role || [] + return role.indexOf(name) > -1 + } +} +// #endif diff --git a/alpha/admin/js_sdk/uni-admin/plugin.js b/alpha/admin/js_sdk/uni-admin/plugin.js new file mode 100644 index 0000000..0de7829 --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/plugin.js @@ -0,0 +1,34 @@ +import { + initUtil +} from './util.js' +import { + initError +} from './error.js' +import { + initRequest +} from './request.js' +import { + initFetch +} from './fetchMock.js' +import { + initPermission +} from './permission.js' +import { + initInterceptor +} from './interceptor.js' + +import { + initUniIdPageStore +} from "../uni-id-pages/store" + +export default { + install(Vue) { + initUtil(Vue) + initError(Vue) + initUniIdPageStore(Vue) + initRequest(Vue) + initFetch(Vue) + initPermission(Vue) + initInterceptor() + } +} diff --git a/alpha/admin/js_sdk/uni-admin/request.js b/alpha/admin/js_sdk/uni-admin/request.js new file mode 100644 index 0000000..5c933db --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/request.js @@ -0,0 +1,77 @@ +import store from '@/store/index.js' +import config from '@/admin.config.js' +const debugOptions = config.navBar.debug + +const db = uniCloud.database() + +export function request (action, params, options) { + const {objectName, functionName, showModal, ...objectOptions} = Object.assign({ + objectName: 'uni-id-co', + functionName: '', + showModal: false, + + customUI: true, + loadingOptions: { + title: 'xxx' + }, + }, options) + + // 兼容 云函数 与 云对象 请求,默认为云对象 + let call + if (functionName) { + call = uniCloud.callFunction({ + name: functionName, + data: { + action, + params + } + }) + } else { + const uniCloudObject = uniCloud.importObject(objectName, objectOptions) + call = uniCloudObject[action](params) + } + + return call.then(result => { + result = functionName ? result.result: result + if (!result) { + return Promise.resolve(result) + } + + if (result.errCode) { + return Promise.reject(result) + } + + return Promise.resolve(result) + + }).catch(err => { + showModal && uni.showModal({ + content: err.errMsg || '请求服务失败', + showCancel: false + }) + // #ifdef H5 + const noDebugPages = ['/uni_modules/uni-id-pages/pages/login/login-withpwd', '/uni_modules/uni-id-pages/pages/register/register'] + const path = location.hash.split('#')[1] + if (debugOptions && debugOptions.enable === true && noDebugPages.indexOf(path) === -1) { + store.dispatch('error/add', { + err: err.toString(), + info: '$request("' + action + '")', + route: '', + time: new Date().toLocaleTimeString() + }) + } + // #endif + return Promise.reject(err) + }) +} + +// #ifndef VUE3 +export function initRequest(Vue) { + Vue.prototype.$request = request +} +// #endif + +// #ifdef VUE3 +export function initRequest(app) { + app.config.globalProperties.$request = request +} +// #endif diff --git a/alpha/admin/js_sdk/uni-admin/util.js b/alpha/admin/js_sdk/uni-admin/util.js new file mode 100644 index 0000000..2f512fd --- /dev/null +++ b/alpha/admin/js_sdk/uni-admin/util.js @@ -0,0 +1,29 @@ +import { + formatDate +} from '@/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js' + +function formatBytes(bytes) { + const sizes = ['B', 'KB', 'MB', 'GB', 'TB'] + if (bytes == 0) { + return 'n/a' + } + const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))) + if (i == 0) { + return bytes + ' ' + sizes[i] + } + return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i] +} + +// #ifndef VUE3 +export function initUtil(Vue) { + Vue.prototype.$formatDate = formatDate + Vue.prototype.$formatBytes = formatBytes +} +// #endif + +// #ifdef VUE3 +export function initUtil(app) { + app.config.globalProperties.$formatDate = formatDate + app.config.globalProperties.$formatBytes = formatBytes +} +// #endif \ No newline at end of file diff --git a/alpha/admin/js_sdk/uni-id-pages/store.js b/alpha/admin/js_sdk/uni-id-pages/store.js new file mode 100644 index 0000000..f11e350 --- /dev/null +++ b/alpha/admin/js_sdk/uni-id-pages/store.js @@ -0,0 +1,13 @@ +import * as uniIdPagesStore from '@/uni_modules/uni-id-pages/common/store' + +// #ifndef VUE3 +export function initUniIdPageStore(Vue) { + Vue.prototype.$uniIdPagesStore = uniIdPagesStore +} +// #endif + +// #ifdef VUE3 +export function initUniIdPageStore(app) { + app.config.globalProperties.$uniIdPagesStore = uniIdPagesStore +} +// #endif diff --git a/alpha/admin/js_sdk/uni-stat/timeUtil.js b/alpha/admin/js_sdk/uni-stat/timeUtil.js new file mode 100644 index 0000000..b0ef066 --- /dev/null +++ b/alpha/admin/js_sdk/uni-stat/timeUtil.js @@ -0,0 +1,186 @@ +/** + * 时间工具类 + */ +var timeUtil = {}; + +// 尽可能的将参数转成正确的时间对象 +timeUtil.getDateObject = function(date) { + if (!date) return ""; + let nowDate; + // 如果是字符串,且纯数字,则强制转数值 + if (typeof date === "string" && !isNaN(date)) date = Number(date); + if (typeof date === "number") { + if (date.toString().length == 10) date *= 1000; + nowDate = new Date(date); // 转时间对象 + } else if (typeof date === "object") { + nowDate = new Date(date.getTime()); // 新建一个时间对象 + } + return nowDate; +}; + +/** + * 日期格式化 + * @param {Date || Number} date 需要格式化的时间 + * timeUtil.timeFormat(new Date(),"yyyy-MM-dd hh:mm:ss"); + */ +timeUtil.timeFormat = function(date, fmt = 'yyyy-MM-dd hh:mm:ss') { + try { + if (!date) return ""; + let nowDate = timeUtil.getDateObject(date); + let opt = { + "M+": nowDate.getMonth() + 1, //月份 + "d+": nowDate.getDate(), //日 + "h+": nowDate.getHours(), //小时 + "m+": nowDate.getMinutes(), //分 + "s+": nowDate.getSeconds(), //秒 + //"w+": nowDate.getDay(), //周 + "q+": Math.floor((nowDate.getMonth() + 3) / 3), //季度 + "S": nowDate.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (nowDate.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + for (let k in opt) { + if (new RegExp("(" + k + ")").test(fmt)) { + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (opt[k]) : (("00" + opt[k]).substr(("" + opt[k]).length))); + } + } + return fmt; + } catch (err) { + // 若格式错误,则原值显示 + return time; + } +}; + +/** + * 解析日期对象属性 + * @param {Date || Number} date 需要转换的时间 + * timeUtil.getDateInfo(new Date()); + */ +timeUtil.getDateInfo = function(date = new Date()) { + let nowDate = timeUtil.getDateObject(date); + let year = nowDate.getFullYear() + ''; + let month = (nowDate.getMonth() + 1 < 10 ? '0' + (nowDate.getMonth() + 1) : nowDate.getMonth() + 1); + let day = (nowDate.getDate() < 10 ? '0' + (nowDate.getDate()) : nowDate.getDate()); + let hour = (nowDate.getHours() < 10 ? '0' + (nowDate.getHours()) : nowDate.getHours()); + let minute = (nowDate.getMinutes() < 10 ? '0' + (nowDate.getMinutes()) : nowDate.getMinutes()); + let second = (nowDate.getSeconds() < 10 ? '0' + (nowDate.getSeconds()) : nowDate.getSeconds()); + let millisecond = nowDate.getMilliseconds(); //毫秒 + let week = nowDate.getDay(); // 周 + let quarter = Math.floor((nowDate.getMonth() + 3) / 3); //季度 + return { + year: Number(year), + month: Number(month), + day: Number(day), + hour: Number(hour), + minute: Number(minute), + second: Number(second), + millisecond: Number(millisecond), + week: Number(week), + quarter: Number(quarter), + }; +}; + +/** + * 获得相对当前时间的偏移 count 小时、天、周、月、季度、年的起止日期(开始和结束时间戳) + * @param {Number} count 偏移量 + * @param {Date || Number} date 指定从哪个时间节点开始计算 + * timeUtil.getOffsetStartAndEnd("hour", 0); + * timeUtil.getOffsetStartAndEnd("day", 0); + * timeUtil.getOffsetStartAndEnd("week", 0); + * timeUtil.getOffsetStartAndEnd("month", 0); + * timeUtil.getOffsetStartAndEnd("quarter", 0); + * timeUtil.getOffsetStartAndEnd("year", 0); + */ +timeUtil.getOffsetStartAndEnd = function(type="day", count = 0, date = new Date()) { + let startTime, endTime; + let nowDate = timeUtil.getDateObject(date); + if (type === "hour") { + // 小时 + // 一小时毫秒数 + let offsetMillisecond = 1000 * 60 * 60; + // 相对于当前日期count个天的日期 + let dateInfo = timeUtil.getDateInfo(new Date(nowDate.getTime() + (offsetMillisecond * 1 * count))); + // 获得当天的起始时间 + startTime = new Date(`${dateInfo.year}/${dateInfo.month}/${dateInfo.day} ${dateInfo.hour}:00:00`).getTime(); + // 获得当天的结束时间 + endTime = new Date(`${dateInfo.year}/${dateInfo.month}/${dateInfo.day} ${dateInfo.hour}:00:00`).getTime() + (offsetMillisecond -1); + } else if (type === "day") { + // 天 + // 一天的毫秒数 + let offsetMillisecond = 1000 * 60 * 60 * 24; + // 相对于当前日期count个天的日期 + let dateInfo = timeUtil.getDateInfo(new Date(nowDate.getTime() + (offsetMillisecond * 1 * count))); + // 获得当天的起始时间 + startTime = new Date(`${dateInfo.year}/${dateInfo.month}/${dateInfo.day}`).getTime(); + // 获得当天的结束时间 + endTime = new Date(`${dateInfo.year}/${dateInfo.month}/${dateInfo.day}`).getTime() + (offsetMillisecond - 1); + } else if (type === "week") { + // 周 + nowDate.setDate(nowDate.getDate() - nowDate.getDay() + 1 + count * 7); + let dateInfo1 = timeUtil.getDateInfo(nowDate); + nowDate.setDate(nowDate.getDate() + 7); + let dateInfo2 = timeUtil.getDateInfo(nowDate); + // 开始时间 + startTime = new Date(`${dateInfo1.year}/${dateInfo1.month}/${dateInfo1.day}`).getTime(); + // 结束时间 + endTime = new Date(`${dateInfo2.year}/${dateInfo2.month}/${dateInfo2.day}`).getTime() - 1; + } else if (type === "month") { + // 月 + let dateInfo = timeUtil.getDateInfo(nowDate); + let month = dateInfo.month + count; + let year = dateInfo.year; + if (month > 12) { + year = year + Math.floor(month / 12); + month = Math.abs(month) % 12; + } else if (month <= 0) { + year = year - 1 - Math.floor(Math.abs(month) / 12); + month = 12 - Math.abs(month) % 12; + } + let month_last_day = new Date(year, month, 0).getDate(); + // 开始时间 + startTime = new Date(`${year}/${month}/1`).getTime(); + // 结束时间 + endTime = new Date(`${year}/${month}/${month_last_day}`).getTime() + (24 * 60 * 60 * 1000 - 1); + } else if (type === "quarter") { + // 季度 + nowDate.setMonth(nowDate.getMonth() + count * 3); + let dateInfo = timeUtil.getDateInfo(nowDate); + let month = dateInfo.month; + if ([1, 2, 3].indexOf(month) > -1) { + // 第1季度 + month = 1; + } else if ([4, 5, 6].indexOf(month) > -1) { + // 第2季度 + month = 4; + } else if ([7, 8, 9].indexOf(month) > -1) { + // 第3季度 + month = 7; + } else if ([10, 11, 12].indexOf(month) > -1) { + // 第4季度 + month = 10; + } + nowDate.setMonth(month - 1); // 因为0代表1月,所以这里要减1 + let dateInfo1 = timeUtil.getDateInfo(nowDate); + nowDate.setMonth(nowDate.getMonth() + 3); + let dateInfo2 = timeUtil.getDateInfo(nowDate); + // 开始时间 + startTime = new Date(`${dateInfo1.year}/${dateInfo1.month}/1`).getTime(); + // 结束时间 + endTime = new Date(`${dateInfo2.year}/${dateInfo2.month}/1`).getTime() - 1; + } else if (type === "year") { + // 年 + let dateInfo = timeUtil.getDateInfo(nowDate); + let year = dateInfo.year + count; + // 开始时间 + startTime = new Date(`${year}/1/1`).getTime(); + // 结束时间 + endTime = new Date(`${year}/12/31`).getTime() + (24 * 60 * 60 * 1000 - 1); + } + return { + startTime, + endTime + }; +}; + +export default timeUtil; diff --git a/alpha/admin/js_sdk/uni-stat/util.js b/alpha/admin/js_sdk/uni-stat/util.js new file mode 100644 index 0000000..46e6bf2 --- /dev/null +++ b/alpha/admin/js_sdk/uni-stat/util.js @@ -0,0 +1,483 @@ +/** + * 以下为 uni-stat 的工具方法 + */ + +// 千分位 +function regexHandleNum(num) { + return String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 3是千分位,4是万分位 +} + +// 新版格式化字段数据函数 +function formatterData(object) { + let { + fieldsMap, + data, + formatter = true + } = object; + let rows = JSON.parse(JSON.stringify(data)); + rows.map((row) => { + for (let key in row) { + let fieldItem = fieldsMap.find((item) => { + return item.field == key; + }); + if (typeof fieldItem === "object") { + let { + fix = 0, + } = fieldItem; + if (typeof fieldItem.multiple === "number" && typeof row[key] === "number") { + row[key] = Number((row[key] * fieldItem.multiple).toFixed(fix)); + } + if (formatter && fieldItem.formatter && typeof row[key] === "number") { + if (fieldItem.formatter === ",") { + row[key] = regexHandleNum(row[key]); + } else if (fieldItem.formatter === "%") { + row[key] = `${(row[key] * 100).toFixed(fix)}%` + } else if (fieldItem.formatter === "-") { + // 时分秒格式 + row[key] = parseDateTime(row[key]); + } + } + } + } + }); + return rows; +} + +// 补全趋势图的数据 +function fillTrendChartData(data, query, fieldsMap) { + let { start_time, dimension } = query; + if (["hour","day"].indexOf(dimension)>-1){ + let timeArr = []; + let oneTime; + if (dimension === "hour"){ + oneTime = 1000*3600; + } else if (dimension === "day"){ + oneTime = 1000*3600*24; + } + let start = start_time[0]; + let end = start_time[1]; + let nowTime = start; + timeArr = [start]; + while ((nowTime+oneTime)<=end){ + nowTime += oneTime; + timeArr.push(nowTime); + } + + let newData = []; + for (let i = 0; i < timeArr.length; i++) { + let time = timeArr[i]; + let dataItem = data.find((item, index) => { + return item.start_time === time; + }); + if (dataItem) { + newData.push(dataItem); + } else { + let obj = { + start_time: time + }; + fieldsMap.map((item, index) => { + obj[item.field] = 0; + }); + + newData.push(obj); + } + } + return newData + } else { + return data; + } +} + + +// 将查询条件拼接为字符串 +function stringifyQuery(query, dimension = false, delArrs = []) { + const queryArr = [] + const keys = Object.keys(query) + const time = query.start_time + keys.forEach(key => { + if (key === 'time_range' || delArrs.indexOf(key) !== -1) return + let val = query[key] + if (val) { + if (typeof val === 'string' && val.indexOf(key) > -1) { + queryArr.push(val) + } else { + if (typeof val === 'string') { + val = `"${val}"` + } + if (Array.isArray(val)) { + if (val.length === 2 && key.indexOf('time') > -1) { + queryArr.push(`${key} >= ${val[0]} && ${key} <= ${val[1]}`) + } else { + val = val.map(item => `${key} == "${item}"`).join(' || ') + val && queryArr.push(`(${val})`) + } + } else if (dimension && key === 'dimension') { + if (maxDeltaDay(time)) { + queryArr.push(`dimension == "hour"`) + } else { + if (val && val !== `"hour"`) { + queryArr.push(`${key} == ${val}`) + } else { + queryArr.push(`dimension == "day"`) + } + } + } else { + queryArr.push(`${key} == ${val}`) + } + } + } + }) + const queryStr = queryArr.join(' && ') + return queryStr || {} +} + +// 根据页面字段配置 fieldsMap 数据计算、格式化字段 +function mapfields(map, data = {}, goal, prefix = '', prop = 'value') { + const goals = [], + argsGoal = goal + map = JSON.parse(JSON.stringify(map)) + const origin = JSON.parse(JSON.stringify(data)) + for (const mapper of map) { + let { + field, + computed, + formatter, + disable, + fix + } = mapper + if (!disable) { + goal = argsGoal || mapper + const hasValue = goal.hasOwnProperty(prop) + const preField = prefix + field + if (data) { + const value = data[preField] + if (computed) { + const computedFields = computed.split('/') + let [dividend, divisor] = computedFields + dividend = Number(origin[prefix + dividend]) + divisor = Number(origin[prefix + divisor]) + const val = format(division(dividend, divisor), formatter, fix) + if (hasValue && field === goal.field) { + goal[prop] = val + } else { + goal[field] = val + } + } else { + if (value) { + const val = format(value, formatter, fix) + if (hasValue) { + if (goal.field === field) { + goal[prop] = val + } + } else { + goal[field] = val + } + } + } + } + if (hasValue) { + goals.push(goal) + } + } + } + return goals +} + +// 将查询条件对象拼接为字符串,给 client db 的 field 属性消费 +function stringifyField(mapping, goal, prop) { + if (goal) { + mapping = mapping.filter(f => f.field === goal) + } + if (prop) { + mapping = mapping.filter(f => f.field && f.hasOwnProperty(prop)) + } + const fieldString = mapping.map(f => { + let fields = [] + if (f.computed) { + fields = f.computed.split('/') + } else { + fields.push(f.field) + } + fields = fields.map(field => { + if (f.stat === -1) { + return field + } else { + return `${field} as ${ 'temp_' + field}` + } + }) + return fields.join() + }) + return fieldString.join() +} + +// 将查询条件对象拼接为字符串,给 client db 的 groupField 属性消费 +function stringifyGroupField(mapping, goal, prop) { + if (goal) { + mapping = mapping.filter(f => f.field === goal) + } + if (prop) { + mapping = mapping.filter(f => f.field && f.hasOwnProperty(prop)) + } + const groupField = mapping.map(f => { + const stat = f.stat + let fields = [] + if (f.computed) { + fields = f.computed.split('/') + } else { + fields.push(f.field) + } + fields = fields.map(field => { + if (stat !== -1) { + return `${stat ? stat : 'sum' }(${'temp_' + field}) as ${field}` + } + }) + return fields.filter(Boolean).join() + }) + .filter(Boolean) + .join() + + return groupField +} + +// 除法函数 +function division(dividend, divisor) { + if (divisor) { + return dividend / divisor + } else { + return 0 + } +} + +// 对数字进行格式化,格式 type 配置在页面 fieldMap.js 中 +function format(num, type = ',', fix) { + // if (!type) return num + if (typeof num !== 'number') return num + if (type === '%') { + // 注意浮点数精度 + num = (num * 100) + if (String(num).indexOf('.') > -1) { + num = num.toFixed(2) + } + num = num ? num + type : num + return num + } else if (type === '%%') { + num = Number(num) + return num.toFixed(2) + '%' + } else if (type === '-') { + return formatDate(num, 'day') + } else if (type === ':') { + num = Math.ceil(num) + let h, m, s + h = m = s = 0 + const wunH = 60 * 60, + wunM = 60 // 单位秒, wun 通 one + if (num >= wunH) { + h = Math.floor(num / wunH) + const remainder = num % wunH + if (remainder >= wunM) { + m = Math.floor(remainder / wunM) + s = remainder % wunM + } else { + s = remainder + } + } else if (wunH >= num && num >= wunM) { + m = Math.floor(num / wunM) + s = num % wunM + } else { + s = num + } + const hms = [h, m, s].map(i => i < 10 ? '0' + i : i) + return hms.join(type) + } else if (type === ',') { + return num.toLocaleString() + } else { + if (String(num).indexOf('.') > -1) { + if (Math.abs(num) > 1) { + num = num.toFixed(fix || 0) + } else { + num = num.toFixed(fix || 2) + } + } + return num + } +} + +// 格式化日期,返回其所在的范围 +function formatDate(date, type) { + let d = new Date(date) + if (type === 'hour') { + let h = d.getHours() + h = h < 10 ? '0' + h : h + return `${h}:00 ~ ${h}:59` + } else if (type === 'week') { + const first = d.getDate() - d.getDay() + 1; // First day is the day of the month - the day of the week + const last = first + 6; // last day is the first day + 6 + let firstday = new Date(d.setDate(first)); + firstday = parseDateTime(firstday) + let lastday = new Date(d.setDate(last)); + lastday = parseDateTime(lastday) + return `${firstday} ~ ${lastday}` + } else if (type === 'month') { + let firstday = new Date(d.getFullYear(), d.getMonth(), 1); + firstday = parseDateTime(firstday) + let lastday = new Date(d.getFullYear(), d.getMonth() + 1, 0); + lastday = parseDateTime(lastday) + return `${firstday} ~ ${lastday}` + } else { + return parseDateTime(d) + } +} + +// 格式化日期,返回其 yyyy-mm-dd 格式 +function parseDateTime(datetime, type, splitor = '-') { + let d = datetime + if (typeof d !== 'object') { + d = new Date(d) + } + const year = d.getFullYear() + const month = d.getMonth() + 1 + const day = d.getDate() + const hour = d.getHours() + const minute = d.getMinutes() + const second = d.getSeconds() + const date = [year, lessTen(month), lessTen(day)].join(splitor) + const time = [lessTen(hour), lessTen(minute), lessTen(second)].join(':') + if (type === "dateTime") { + return date + ' ' + time + } + return date +} + +function lessTen(item) { + return item < 10 ? '0' + item : item +} + +// 获取指定日期当天或 n 天前零点的时间戳,丢弃时分秒 +function getTimeOfSomeDayAgo(days = 0, date = Date.now()) { + const d = new Date(date) + const oneDayTime = 24 * 60 * 60 * 1000 + let ymd = [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('/') + ymd = ymd + ' 00:00:00' + const someDaysAgoTime = new Date(ymd).getTime() - oneDayTime * days + return someDaysAgoTime +} + +// 判断时间差值 delta,单位为天 +function maxDeltaDay(times, delta = 2) { + if (!times.length) return true + const wunDay = 24 * 60 * 60 * 1000 + const [start, end] = times + const max = end - start < wunDay * delta + return max +} + +// 查询 总设备数、总用户数, 通过 field 配置 +function getFieldTotal(query = this.query, field = "total_devices") { + let fieldTotal + if (typeof query === 'object') { + query = stringifyQuery(query, false, ['uni_platform']) + } + const db = uniCloud.database() + return db.collection('uni-stat-result') + .where(query) + .field(`${field} as temp_${field}, start_time`) + .groupBy('start_time') + .groupField(`sum(temp_${field}) as ${field}`) + .orderBy('start_time', 'desc') + .get() + .then(cur => { + const data = cur.result.data + fieldTotal = data.length && data[0][field] + fieldTotal = format(fieldTotal) + this.panelData && this.panelData.forEach(item => { + if (item.field === field) { + item.value = fieldTotal + } + }) + return Promise.resolve(fieldTotal) + }) +} + +// 防抖函数 +function debounce(fn, time = 100) { + let timer = null + return function(...args) { + if (timer) clearTimeout(timer) + timer = setTimeout(() => { + fn.apply(this, args) + }, time) + } +} + + +const files = {} + +function fileToUrl(file) { + for (const key in files) { + if (files.hasOwnProperty(key)) { + const oldFile = files[key] + if (oldFile === file) { + return key + } + } + } + var url = (window.URL || window.webkitURL).createObjectURL(file) + files[url] = file + return url +} +/** + * 获取两个时间戳之间的所有时间 + * let start = new Date(1642694400000) // 2022-01-21 00:00:00 + * let end = new Date(1643644800000) // 2022-02-01 00:00:00 + * dateList = getAllDateCN(date1, date2) + * @param {*} startTime + * @param {*} endTime + */ +function getAllDateCN(startTime, endTime) { + let date_all = []; + let i = 0; + while (endTime.getTime() - startTime.getTime() >= 0) { + // 获取日期和时间 + // let year = startTime.getFullYear() + // let month = startTime.getMonth() + 1 + // let day = startTime.getDate() + // let time = startTime.toLocaleTimeString() + date_all[i] = startTime.getTime() + + // 获取每天00:00:00的时间戳 + // date_all[i] = new Date(startTime.toLocaleDateString()).getTime() / 1000; + + // 天数+1 + startTime.setDate(startTime.getDate() + 1); + i += 1; + } + return date_all; +} + +function createUniStatQuery(object) { + return Object.assign({}, object, { + type: "native_app", + create_env: "uni-stat" + }) +} + + +export { + formatterData, + fillTrendChartData, + stringifyQuery, + stringifyField, + stringifyGroupField, + mapfields, + getTimeOfSomeDayAgo, + division, + format, + formatDate, + parseDateTime, + maxDeltaDay, + debounce, + fileToUrl, + getFieldTotal, + getAllDateCN, + createUniStatQuery +} diff --git a/alpha/admin/js_sdk/validator/opendb-admin-menus.js b/alpha/admin/js_sdk/validator/opendb-admin-menus.js new file mode 100644 index 0000000..ac99690 --- /dev/null +++ b/alpha/admin/js_sdk/validator/opendb-admin-menus.js @@ -0,0 +1,77 @@ +// 校验规则由 schema 生成,请不要直接修改当前文件,如果需要请在uniCloud控制台修改schema +// uniCloud: https://unicloud.dcloud.net.cn/ + + + +export default { + "menu_id": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ] + }, + "name": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ] + }, + "icon": { + "rules": [ + { + "format": "string" + } + ] + }, + "url": { + "rules": [ + { + "format": "string" + }, + { + validateFunction:function(rule,value,data,callback){ + if (value !== "" && value.indexOf("http") === -1 && value.indexOf("/") !==0){ + callback('URL必须以/开头,如/pages/index/index') + } + return true + } + } + ] + }, + "sort": { + "rules": [ + { + "format": "int" + } + ] + }, + "parent_id": { + "rules": [ + { + "format": "string" + } + ] + }, + "permission": { + "rules": [ + { + "format": "array" + } + ] + }, + "enable": { + "rules": [ + { + "format": "bool" + } + ] + } +} diff --git a/alpha/admin/js_sdk/validator/opendb-app-list.js b/alpha/admin/js_sdk/validator/opendb-app-list.js new file mode 100644 index 0000000..dcf7012 --- /dev/null +++ b/alpha/admin/js_sdk/validator/opendb-app-list.js @@ -0,0 +1,123 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "appid": { + "rules": [{ + "required": true + }, + { + "format": "string" + } + ], + "label": "AppID" + }, + "name": { + "rules": [{ + "required": true + }, + { + "format": "string" + } + ], + "label": "应用名称" + }, + "icon_url": { + "rules": [{ + "format": "string" + }], + "label": "应用图标" + }, + "introduction": { + "rules": [{ + "format": "string" + }], + "label": "应用简介" + }, + "description": { + "rules": [{ + "format": "string" + }], + "label": "应用描述" + }, + "screenshot": { + "rules": [{ + "format": "array" + }], + "label": "应用截图" + }, + "create_date": { + "rules": [{ + "format": "timestamp" + }], + "label": "发行时间" + } +} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { + type, + value + } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} +const enumConverter = {} +const mpPlatform = { + 'mp_weixin': '微信小程序', + 'mp_alipay': '支付宝小程序', + 'mp_baidu': '百度小程序', + 'mp_toutiao': '字节小程序', + 'mp_qq': 'QQ小程序', + 'mp_dingtalk': '钉钉小程序', + 'mp_kuaishou': '快手小程序', + 'mp_lark': '飞书小程序', + 'mp_jd': '京东小程序', + 'quickapp': '快应用' +} + +export { + enumConverter, + validator, + filterToWhere, + mpPlatform +} diff --git a/alpha/admin/js_sdk/validator/opendb-app-versions.js b/alpha/admin/js_sdk/validator/opendb-app-versions.js new file mode 100644 index 0000000..dfaeb06 --- /dev/null +++ b/alpha/admin/js_sdk/validator/opendb-app-versions.js @@ -0,0 +1,157 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + + +const validator = { + "appid": { + "rules": [{ + "required": true + }, + { + "format": "string" + } + ], + "label": "AppID" + }, + "name": { + "rules": [{ + "format": "string" + }], + "label": "应用名称" + }, + "title": { + "rules": [{ + "format": "string" + }], + "label": "更新标题" + }, + "contents": { + "rules": [{ + "required": true + }, + { + "format": "string" + } + ], + "label": "更新内容" + }, + "platform": { + "rules": [{ + "required": true + }, + /* 此处不校验数据类型,因为platform在发布app端是单选,在发布wgt时可能是多选 + { + "format": "array" + }, */ + { + "range": [{ + "value": "Android", + "text": "安卓" + }, + { + "value": "iOS", + "text": "苹果" + } + ] + } + ], + "label": "平台" + }, + "type": { + "rules": [{ + "required": true + }, { + "format": "string" + }, + { + "range": [{ + "value": "native_app", + "text": "原生App安装包" + }, + { + "value": "wgt", + "text": "wgt资源包" + } + ] + } + ], + "label": "安装包类型" + }, + "version": { + "rules": [{ + "required": true + }, + { + "format": "string" + } + ], + "label": "版本号" + }, + "min_uni_version": { + "rules": [{ + "format": "string" + }], + "label": "原生App最低版本" + }, + "url": { + "rules": [{ + "required": true + }, { + "format": "string" + }], + "label": "链接" + }, + "stable_publish": { + "rules": [{ + "format": "bool" + }], + "label": "上线发行" + }, + "create_date": { + "rules": [{ + "format": "timestamp" + }], + "label": "上传时间" + }, + "is_silently": { + "rules": [{ + "format": "bool" + }], + "label": "静默更新", + "defaultValue": false + }, + "is_mandatory": { + "rules": [{ + "format": "bool" + }], + "label": "强制更新", + "defaultValue": false + }, + "store_list": { + "rules": [{ + "format": "array" + }], + "label": "应用市场" + }, +} + +const enumConverter = { + "platform_valuetotext": [{ + "value": "Android", + "text": "安卓" + }, + { + "value": "iOS", + "text": "苹果" + } + ], + "type_valuetotext": { + "native_app": "原生App安装包", + "wgt": "wgt资源包" + } +} + +export { + validator, + enumConverter +} diff --git a/alpha/admin/js_sdk/validator/uni-id-log.js b/alpha/admin/js_sdk/validator/uni-id-log.js new file mode 100644 index 0000000..dd4ee2c --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-id-log.js @@ -0,0 +1,38 @@ +// 校验规则由 schema 生成,请不要直接修改当前文件,如果需要请在uniCloud控制台修改schema +// uniCloud: https://unicloud.dcloud.net.cn/ + + + +export default { + "user_name": { + "rules": [ + { + "format": "string" + } + ] + }, + "content": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ] + }, + "ip": { + "rules": [ + { + "format": "string" + } + ] + }, + "create_date": { + "rules": [ + { + "format": "timestamp" + } + ] + } +} diff --git a/alpha/admin/js_sdk/validator/uni-id-permissions.js b/alpha/admin/js_sdk/validator/uni-id-permissions.js new file mode 100644 index 0000000..2147c81 --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-id-permissions.js @@ -0,0 +1,84 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "permission_id": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "权限标识" + }, + "permission_name": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "权限名称" + }, + "comment": { + "rules": [ + { + "format": "string" + } + ], + "label": "备注" + } +} + +const enumConverter = {} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/js_sdk/validator/uni-id-roles.js b/alpha/admin/js_sdk/validator/uni-id-roles.js new file mode 100644 index 0000000..96b594d --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-id-roles.js @@ -0,0 +1,99 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "role_id": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "唯一ID" + }, + "role_name": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "名称" + }, + "permission": { + "rules": [ + { + "format": "array" + } + ], + "label": "权限" + }, + "comment": { + "rules": [ + { + "format": "string" + } + ], + "label": "备注" + }, + "create_date": { + "rules": [ + { + "format": "timestamp" + } + ] + } +} + +const enumConverter = {} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/js_sdk/validator/uni-id-tag.js b/alpha/admin/js_sdk/validator/uni-id-tag.js new file mode 100644 index 0000000..4788f94 --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-id-tag.js @@ -0,0 +1,84 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "tagid": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "标签的tagid" + }, + "name": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "标签名称" + }, + "description": { + "rules": [ + { + "format": "string" + } + ], + "label": "标签描述" + } +} + +const enumConverter = {} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/js_sdk/validator/uni-id-users.js b/alpha/admin/js_sdk/validator/uni-id-users.js new file mode 100644 index 0000000..a8a8d4f --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-id-users.js @@ -0,0 +1,191 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "username": { + "rules": [{ + "required": true, + "errorMessage": '请输入用户名', + }, + { + "minLength": 3, + "maxLength": 32, + "errorMessage": '用户名长度在 {minLength} 到 {maxLength} 个字符', + }, + { + validateFunction: function(rule, value, data, callback) { + // console.log(value); + if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) { + callback('用户名不能是:手机号或邮箱') + }; + if (/^\d+$/.test(value)) { + callback('用户名不能为纯数字') + }; + if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){ + callback('用户名不能包含中文') + } + return true + } + } + ], + "label": "用户名" + }, + "nickname": { + "rules": [{ + minLength: 3, + maxLength: 32, + errorMessage: '昵称长度在 {minLength} 到 {maxLength} 个字符', + }, + { + validateFunction: function(rule, value, data, callback) { + // console.log(value); + if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) { + callback('昵称不能是:手机号或邮箱') + }; + if (/^\d+$/.test(value)) { + callback('昵称不能为纯数字') + }; + // if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){ + // callback('昵称不能包含中文') + // } + return true + } + } + ], + "label": "昵称" + }, + "password": { + "rules": [{ + "required": true, + }, + { + "format": "password" + }, + { + "minLength": 6 + } + ], + "label": "密码" + }, + "mobile": { + "rules": [{ + "format": "string" + }, + { + "pattern": "^\\+?[0-9-]{3,20}$" + } + ], + "label": "手机号码" + }, + "status": { + "rules": [{ + "format": "int" + }, + { + "range": [{ + "text": "正常", + "value": 0 + }, + { + "text": "禁用", + "value": 1 + }, + { + "text": "审核中", + "value": 2 + }, + { + "text": "审核拒绝", + "value": 3 + } + ] + } + ], + "defaultValue": 0, + "label": "用户状态" + }, + "email": { + "rules": [{ + "format": "string" + }, + { + "format": "email" + } + ], + "label": "邮箱" + }, + "role": { + "rules": [{ + "format": "array" + }], + "label": "角色" + }, + "last_login_date": { + "rules": [{ + "format": "timestamp" + }] + } +} + +const enumConverter = { + "status_valuetotext": { + "0": "正常", + "1": "禁用", + "2": "审核中", + "3": "审核拒绝" + } +} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { + type, + value + } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { + validator, + enumConverter, + filterToWhere +} diff --git a/alpha/admin/js_sdk/validator/uni-pay-orders.js b/alpha/admin/js_sdk/validator/uni-pay-orders.js new file mode 100644 index 0000000..83b8033 --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-pay-orders.js @@ -0,0 +1,304 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "user_id": { + "rules": [ + { + "format": "string" + } + ], + "label": "用户ID" + }, + "provider": { + "rules": [ + { + "format": "string" + }, + { + "range": [ + { + "text": "微信支付", + "value": "wxpay" + }, + { + "text": "支付宝", + "value": "alipay" + }, + { + "text": "苹果应用内支付", + "value": "appleiap" + } + ] + } + ], + "label": "支付供应商" + }, + "provider_pay_type": { + "rules": [ + { + "format": "string" + } + ], + "label": "支付方式" + }, + "uni_platform": { + "rules": [ + { + "format": "string" + } + ], + "label": "应用平台" + }, + "status": { + "rules": [ + { + "format": "int" + }, + { + "range": [ + { + "text": "已关闭", + "value": -1 + }, + { + "text": "未支付", + "value": 0 + }, + { + "text": "已支付", + "value": 1 + }, + { + "text": "已部分退款", + "value": 2 + }, + { + "text": "已全额退款", + "value": 3 + } + ] + } + ], + "defaultValue": 0, + "label": "订单状态" + }, + "type": { + "rules": [ + { + "format": "string" + } + ], + "label": "订单类型" + }, + "order_no": { + "rules": [ + { + "format": "string" + }, + { + "minLength": 20, + "maxLength": 28 + } + ], + "label": "业务系统订单号" + }, + "out_trade_no": { + "rules": [ + { + "format": "string" + } + ], + "label": "支付插件订单号" + }, + "transaction_id": { + "rules": [ + { + "format": "string" + } + ], + "label": "交易单号" + }, + "device_id": { + "rules": [ + { + "format": "string" + } + ], + "label": "设备ID" + }, + "client_ip": { + "rules": [ + { + "format": "string" + } + ], + "label": "客户端IP" + }, + "openid": { + "rules": [ + { + "format": "string" + } + ], + "label": "openid" + }, + "description": { + "rules": [ + { + "format": "string" + } + ], + "label": "支付描述" + }, + "err_msg ": { + "rules": [ + { + "format": "string" + } + ], + "label": "支付失败原因" + }, + "total_fee": { + "rules": [ + { + "format": "int" + } + ], + "label": "订单总金额" + }, + "refund_fee": { + "rules": [ + { + "format": "int" + } + ], + "label": "订单总退款金额" + }, + "refund_count": { + "rules": [ + { + "format": "int" + } + ], + "label": "当前退款笔数" + }, + "refund_list": { + "rules": [ + { + "format": "array" + } + ], + "label": "退款详情" + }, + "provider_appid": { + "rules": [ + { + "format": "string" + } + ], + "label": "开放平台appid" + }, + "appid": { + "rules": [ + { + "format": "string" + } + ], + "label": "DCloud AppId" + }, + "user_order_success": { + "rules": [ + { + "format": "bool" + } + ], + "label": "回调状态" + }, + "pay_date": { + "rules": [ + { + "format": "timestamp" + } + ], + "label": "支付时间" + }, + "notify_date": { + "rules": [ + { + "format": "timestamp" + } + ], + "label": "异步通知时间" + }, + "cancel_date": { + "rules": [ + { + "format": "timestamp" + } + ], + "label": "取消时间" + } +} + +const enumConverter = { + "provider_valuetotext": { + "wxpay": "微信支付", + "alipay": "支付宝", + "appleiap": "苹果应用内支付" + }, + "status_valuetotext": { + "0": "未支付", + "1": "已支付", + "2": "已部分退款", + "3": "已全额退款", + "-1": "已关闭" + } +} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/js_sdk/validator/uni-stat-app-crash-logs.js b/alpha/admin/js_sdk/validator/uni-stat-app-crash-logs.js new file mode 100644 index 0000000..ea10ddc --- /dev/null +++ b/alpha/admin/js_sdk/validator/uni-stat-app-crash-logs.js @@ -0,0 +1,264 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "appid": { + "rules": [ + { + "format": "string" + } + ] + }, + "version": { + "rules": [ + { + "format": "string" + } + ] + }, + "platform": { + "rules": [ + { + "format": "string" + } + ] + }, + "channel": { + "rules": [ + { + "format": "string" + } + ] + }, + "sdk_version": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_id": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_net": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_os": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_os_version": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_vendor": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_model": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_is_root": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_os_name": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_batt_level": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_batt_temp": { + "rules": [ + { + "format": "string" + } + ] + }, + "device_memory_use_size": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_memory_total_size": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_disk_use_size": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_disk_total_size": { + "rules": [ + { + "format": "int" + } + ] + }, + "device_abis": { + "rules": [ + { + "format": "string" + } + ] + }, + "app_count": { + "rules": [ + { + "format": "int" + } + ] + }, + "app_use_memory_size": { + "rules": [ + { + "format": "int" + } + ] + }, + "app_webview_count": { + "rules": [ + { + "format": "int" + } + ] + }, + "app_use_duration": { + "rules": [ + { + "format": "int" + } + ] + }, + "app_run_fore": { + "rules": [ + { + "format": "int" + } + ] + }, + "package_name": { + "rules": [ + { + "format": "string" + } + ] + }, + "package_version": { + "rules": [ + { + "format": "string" + } + ] + }, + "page_url": { + "rules": [ + { + "format": "string" + } + ] + }, + "error_msg": { + "rules": [ + { + "format": "string" + } + ] + }, + "create_time": { + "rules": [ + { + "format": "timestamp" + } + ] + } +} + +const enumConverter = {} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/main.js b/alpha/admin/main.js new file mode 100644 index 0000000..0b6daab --- /dev/null +++ b/alpha/admin/main.js @@ -0,0 +1,43 @@ +import App from './App' +import store from './store' +import plugin from './js_sdk/uni-admin/plugin' +import messages from './i18n/index.js' + +const lang = uni.getLocale() +// #ifndef VUE3 +import Vue from 'vue' +import VueI18n from 'vue-i18n' +Vue.config.productionTip = false +Vue.use(VueI18n) +// 通过选项创建 VueI18n 实例 +const i18n = new VueI18n({ + locale: lang, // 设置地区 + messages, // 设置地区信息 +}) +Vue.use(plugin) +App.mpType = 'app' +const app = new Vue({ + i18n, + store, + ...App +}) +app.$mount() +// #endif + +// #ifdef VUE3 +import { createSSRApp } from 'vue' +import { createI18n } from 'vue-i18n' +export function createApp() { + const app = createSSRApp(App) + const i18n = createI18n({ + locale: lang, + messages + }) + app.use(i18n) + app.use(plugin) + app.use(store) + return { + app + } +} +// #endif diff --git a/alpha/admin/manifest.json b/alpha/admin/manifest.json new file mode 100644 index 0000000..7b7c85e --- /dev/null +++ b/alpha/admin/manifest.json @@ -0,0 +1,82 @@ +{ + "name" : "admin", + "appid" : "__UNI__2A45DD3", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : "100", + "transformPx" : false, + /* 5+App特有相关 */ + "app-plus" : { + "usingComponents" : true, + "nvueCompiler" : "uni-app", + "compilerVersion" : 3, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + /* 模块配置 */ + "modules" : {}, + /* 应用发布信息 */ + "distribute" : { + /* android打包配置 */ + "android" : { + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + /* ios打包配置 */ + "ios" : {}, + /* SDK配置 */ + "sdkConfigs" : {} + } + }, + /* 快应用特有相关 */ + "quickapp" : {}, + /* 小程序特有相关 */ + "mp-weixin" : { + "appid" : "", + "setting" : { + "urlCheck" : false + }, + "usingComponents" : true + }, + "mp-alipay" : { + "usingComponents" : true + }, + "mp-baidu" : { + "usingComponents" : true + }, + "mp-toutiao" : { + "usingComponents" : true + }, + "uniStatistics" : { + "enable" : false + }, + "h5" : { + "template" : "template.h5.html", + "router" : { + "mode" : "hash", + "base" : "/admin/" + } + }, + "vueVersion" : "3", + "networkTimeout" : { + "uploadFile" : 1200000 //ms, 如果不配置,上传大文件可能会超时 + } +} diff --git a/alpha/admin/mock/uni-stat/appOverview.json b/alpha/admin/mock/uni-stat/appOverview.json new file mode 100644 index 0000000..18d70e9 --- /dev/null +++ b/alpha/admin/mock/uni-stat/appOverview.json @@ -0,0 +1,14 @@ + { + "yesterday": { + "num_new_visitor": "394", + "num_visitor": "884", + "num_page_views": "21,818", + "num_total_visitor": "726,161" + }, + "today": { + "num_new_visitor": "258", + "num_visitor": "564", + "num_page_views": "14,795", + "num_total_visitor": "781,700" + } + } \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/appsDetail.json b/alpha/admin/mock/uni-stat/appsDetail.json new file mode 100644 index 0000000..aacbd11 --- /dev/null +++ b/alpha/admin/mock/uni-stat/appsDetail.json @@ -0,0 +1,17 @@ +{ + "last_page": 1, + "current_page": 1, + "total": 1, + "item": [{ + "id_app": 3, + "today_num_new_visitor": "245", + "today_num_visitor": "502", + "today_num_page_views": "10,777", + "num_total_visitor": "724,620", + "appid": "__UNI__HelloUniApp", + "name": "Hello uni-app", + "yesterday_num_new_visitor": "666", + "yesterday_num_visitor": "1,170", + "yesterday_num_page_views": "28,699" + }] +} diff --git a/alpha/admin/mock/uni-stat/db.js b/alpha/admin/mock/uni-stat/db.js new file mode 100644 index 0000000..8d9234e --- /dev/null +++ b/alpha/admin/mock/uni-stat/db.js @@ -0,0 +1,11 @@ +module.exports = function() { + return { + appsDetail: require('./appsDetail'), + pageRule: require('./pageRule'), + appOverview: require('./appOverview'), + pageContent: require('./pageContent'), + pageRes: require('./pageRes'), + pageEnt: require('./pageEnt'), + event: require('./event'), + } +} diff --git a/alpha/admin/mock/uni-stat/event.json b/alpha/admin/mock/uni-stat/event.json new file mode 100644 index 0000000..6fbdeae --- /dev/null +++ b/alpha/admin/mock/uni-stat/event.json @@ -0,0 +1,87 @@ +{ + "last_page": 1, + "current_page": 1, + "total": 10, + "item": [ + { + "id_event": 3, + "event_key": "login", + "event_name": "登录事件", + "num_visitor": "65", + "num_visits": "666", + "visitor_avg_hits": "10.25" + }, + { + "id_event": 30, + "event_key": "share", + "event_name": "分享", + "num_visitor": "18", + "num_visits": "164", + "visitor_avg_hits": "9.11" + }, + { + "id_event": 82, + "event_key": "pay_fail", + "event_name": "支付失败", + "num_visitor": "11", + "num_visits": "145", + "visitor_avg_hits": "13.18" + }, + { + "id_event": 841, + "event_key": "加入购物车", + "event_name": "", + "num_visitor": "13", + "num_visits": "74", + "visitor_avg_hits": "5.69" + }, + { + "id_event": 840, + "event_key": "收藏", + "event_name": "", + "num_visitor": "13", + "num_visits": "57", + "visitor_avg_hits": "4.38" + }, + { + "id_event": 842, + "event_key": "立即购买", + "event_name": "", + "num_visitor": "12", + "num_visits": "54", + "visitor_avg_hits": "4.50" + }, + { + "id_event": 844, + "event_key": "取消收藏", + "event_name": "", + "num_visitor": "8", + "num_visits": "32", + "visitor_avg_hits": "4.00" + }, + { + "id_event": 161, + "event_key": "pay_success", + "event_name": "支付成功", + "num_visitor": "1", + "num_visits": "11", + "visitor_avg_hits": "11.00" + }, + { + "id_event": 94522, + "event_key": "ipa", + "event_name": "", + "num_visitor": "1", + "num_visits": "2", + "visitor_avg_hits": "2.00" + }, + { + "id_event": 281238, + "event_key": "iapstatus", + "event_name": "", + "num_visitor": "1", + "num_visits": "2", + "visitor_avg_hits": "2.00" + } + ] +} \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/pageContent.json b/alpha/admin/mock/uni-stat/pageContent.json new file mode 100644 index 0000000..f67abb0 --- /dev/null +++ b/alpha/admin/mock/uni-stat/pageContent.json @@ -0,0 +1,508 @@ +{ + "base_url": "", + "last_page": 4, + "current_page": 1, + "total": 199, + "item": [ + { + "id_page": 81556056, + "url": "pages/forum/detail/detail?id=39355&type=2", + "name": "uni-app提供开箱即用的SSR支持", + "num_visitor": "54", + "num_visits": "60", + "visit_avg_time": "00:00:21", + "visitor_avg_time": "00:00:23", + "num_share": "0" + }, + { + "id_page": 82631518, + "url": "pages/forum/detail/detail?id=133960&type=1", + "name": "前端老手,寻找远程工作机会,外包项目合作,个人随缘接单", + "num_visitor": "36", + "num_visits": "38", + "visit_avg_time": "00:00:23", + "visitor_avg_time": "00:00:25", + "num_share": "0" + }, + { + "id_page": 1241, + "url": "pages/forum/detail/detail?id=35050&type=2", + "name": "【收费ui ¥200】uni-app前端UI框架 graceUI 持续更新(29个基础组件 14 个界面库 表单验证模块 ),大幅度提高您的开发速度!实测 真实项目30个页面 2天完成布局", + "num_visitor": "19", + "num_visits": "34", + "visit_avg_time": "00:00:09", + "visitor_avg_time": "00:00:16", + "num_share": "0" + }, + { + "id_page": 65803226, + "url": "pages/forum/detail/detail?id=100790&type=1", + "name": "请问uniapp怎么获取手机内的文件", + "num_visitor": "14", + "num_visits": "14", + "visit_avg_time": "00:00:13", + "visitor_avg_time": "00:00:13", + "num_share": "0" + }, + { + "id_page": 68899690, + "url": "pages/forum/detail/detail?id=37834&type=2", + "name": " uni-app 项目小程序端支持 vue3 介绍", + "num_visitor": "13", + "num_visits": "13", + "visit_avg_time": "00:00:26", + "visitor_avg_time": "00:00:26", + "num_share": "0" + }, + { + "id_page": 83432568, + "url": "pages/forum/detail/detail?id=135769&type=1", + "name": "【报Bug】字节跳动小程序使用page-meta设置背景,开发工具有报错,uni.setBackgroundColor is not a function", + "num_visitor": "9", + "num_visits": "11", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:07", + "num_share": "0" + }, + { + "id_page": 82778852, + "url": "pages/forum/detail/detail?id=134332&type=1", + "name": "uniapp打包后的通知授权推送", + "num_visitor": "11", + "num_visits": "11", + "visit_avg_time": "00:00:08", + "visitor_avg_time": "00:00:08", + "num_share": "0" + }, + { + "id_page": 83039358, + "url": "pages/forum/detail/detail?id=134922&type=1", + "name": "google play 上架应用因为Dcloud SDK被暂停", + "num_visitor": "9", + "num_visits": "10", + "visit_avg_time": "00:00:09", + "visitor_avg_time": "00:00:10", + "num_share": "0" + }, + { + "id_page": 83419662, + "url": "pages/forum/detail/detail?id=135744&type=1", + "name": "一键登录开通应用催审", + "num_visitor": "10", + "num_visits": "10", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:03", + "num_share": "0" + }, + { + "id_page": 62476061, + "url": "pages/forum/detail/detail?id=35915&type=2", + "name": "iOS平台:用Native.js来写 如何判断系统功能权限是否开启", + "num_visitor": "6", + "num_visits": "10", + "visit_avg_time": "00:00:15", + "visitor_avg_time": "00:00:25", + "num_share": "0" + }, + { + "id_page": 74506803, + "url": "pages/forum/detail/detail?id=36027&type=2", + "name": "终于搞定了UniApp开发的微信小程序的支付,分享下有关微信支付踩的坑", + "num_visitor": "9", + "num_visits": "9", + "visit_avg_time": "00:00:30", + "visitor_avg_time": "00:00:30", + "num_share": "0" + }, + { + "id_page": 62529047, + "url": "pages/forum/detail/detail?id=85976&type=1", + "name": "uni app 打包成 Android 后无法请求服务器", + "num_visitor": "9", + "num_visits": "9", + "visit_avg_time": "00:00:34", + "visitor_avg_time": "00:00:34", + "num_share": "0" + }, + { + "id_page": 83415318, + "url": "pages/forum/detail/detail?id=135730&type=1", + "name": "uniapp-安卓实现自动拍照", + "num_visitor": "8", + "num_visits": "8", + "visit_avg_time": "00:00:07", + "visitor_avg_time": "00:00:07", + "num_share": "0" + }, + { + "id_page": 83418841, + "url": "pages/forum/detail/detail?id=135739&type=1", + "name": "", + "num_visitor": "6", + "num_visits": "7", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:04", + "num_share": "0" + }, + { + "id_page": 66951069, + "url": "pages/forum/detail/detail?id=102581&type=1", + "name": "uniapp 打包成手机h5 js缓存问题怎么解决,只能清手机缓存吗", + "num_visitor": "6", + "num_visits": "7", + "visit_avg_time": "00:00:10", + "visitor_avg_time": "00:00:11", + "num_share": "0" + }, + { + "id_page": 83408388, + "url": "pages/forum/detail/detail?id=135713&type=1", + "name": "使用VideoPlayer播放视频,视频有宽度自动收缩", + "num_visitor": "7", + "num_visits": "7", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:02", + "num_share": "0" + }, + { + "id_page": 83442697, + "url": "pages/forum/detail/detail?id=135783&type=1", + "name": "有没有不用二维数组的版本", + "num_visitor": "7", + "num_visits": "7", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:02", + "num_share": "0" + }, + { + "id_page": 63688602, + "url": "pages/forum/detail/detail?id=37228&type=2", + "name": "5 App和uni-app在App开发上的对比", + "num_visitor": "7", + "num_visits": "7", + "visit_avg_time": "00:00:11", + "visitor_avg_time": "00:00:11", + "num_share": "0" + }, + { + "id_page": 83415397, + "url": "pages/forum/detail/detail?id=39503&type=2", + "name": "uniapp MIUI全局自由窗口适配,uniapp悬浮小窗和分屏适配", + "num_visitor": "2", + "num_visits": "7", + "visit_avg_time": "00:00:17", + "visitor_avg_time": "00:00:59", + "num_share": "0" + }, + { + "id_page": 62347163, + "url": "pages/forum/detail/detail?id=80913&type=1", + "name": "uni-app flex布局,position:absolute有问题", + "num_visitor": "7", + "num_visits": "7", + "visit_avg_time": "00:00:28", + "visitor_avg_time": "00:00:28", + "num_share": "0" + }, + { + "id_page": 75994881, + "url": "pages/forum/detail/detail?id=122399&type=1", + "name": "【报Bug】uni.chooseVideo() 方法选中视频文件 加载时长问题", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:08", + "num_share": "0" + }, + { + "id_page": 83422277, + "url": "pages/forum/detail/detail?id=135749&type=1", + "name": "【报Bug】plus.video.LivePusher控件推流出现变形,直播源是压扁的", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:09", + "visitor_avg_time": "00:00:10", + "num_share": "0" + }, + { + "id_page": 83340805, + "url": "pages/forum/detail/detail?id=135644&type=1", + "name": "uniapp中的input、text area、editor聚焦后无法唤起输入法", + "num_visitor": "3", + "num_visits": "6", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:03", + "num_share": "0" + }, + { + "id_page": 82122616, + "url": "pages/forum/detail/detail?id=39390&type=2", + "name": "公告:阿里云服务空间云存储容量上限调整周知", + "num_visitor": "6", + "num_visits": "6", + "visit_avg_time": "00:00:27", + "visitor_avg_time": "00:00:27", + "num_share": "0" + }, + { + "id_page": 83434138, + "url": "pages/forum/detail/detail?id=135773&type=1", + "name": "海报 二维码", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:02", + "num_share": "0" + }, + { + "id_page": 79225826, + "url": "pages/forum/detail/detail?id=127577&type=1", + "name": "【报Bug】uniapp安卓热更新偶尔出现第一次重启样式错乱,第二次重启正常。", + "num_visitor": "6", + "num_visits": "6", + "visit_avg_time": "00:00:07", + "visitor_avg_time": "00:00:07", + "num_share": "0" + }, + { + "id_page": 83416762, + "url": "pages/forum/detail/detail?id=135731&type=1", + "name": "【报Bug】uni.chooseVideo方法 拍摄视频 超过一分钟之后返回的路径不对", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:04", + "num_share": "0" + }, + { + "id_page": 83113722, + "url": "pages/forum/detail/detail?id=135136&type=1", + "name": "【报Bug】ios nvue 组件中使用富文本rich-text,设置font-size,更新数据后崩溃", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:06", + "num_share": "0" + }, + { + "id_page": 83437008, + "url": "pages/forum/detail/detail?id=135779&type=1", + "name": "详情", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:03", + "num_share": "0" + }, + { + "id_page": 1427, + "url": "pages/forum/detail/detail?id=41&type=2", + "name": "iOS离线打包", + "num_visitor": "5", + "num_visits": "6", + "visit_avg_time": "00:00:14", + "visitor_avg_time": "00:00:17", + "num_share": "0" + }, + { + "id_page": 63162055, + "url": "pages/forum/detail/detail?id=37140&type=2", + "name": "解决uni-app的pages.json的模块化及模块热重载的问题", + "num_visitor": "4", + "num_visits": "5", + "visit_avg_time": "00:00:07", + "visitor_avg_time": "00:00:09", + "num_share": "0" + }, + { + "id_page": 83405330, + "url": "pages/forum/detail/detail?id=135711&type=1", + "name": "【报Bug】将网站套壳打包,wap2app,创建的app会随机出现无响应的情况", + "num_visitor": "5", + "num_visits": "5", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:01", + "num_share": "0" + }, + { + "id_page": 83444463, + "url": "pages/forum/detail/detail?id=135784&type=1", + "name": "#插件讨论# 【 区块链货币数字钱包APP uni-app模板 - 8***@qq.com 】 怎么加你", + "num_visitor": "3", + "num_visits": "5", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:10", + "num_share": "0" + }, + { + "id_page": 83447956, + "url": "pages/forum/detail/detail?id=106275&type=1", + "name": "外包uni-app项目里的APP两端的“APP原生插件配置”谷歌地图开发", + "num_visitor": "4", + "num_visits": "5", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:07", + "num_share": "0" + }, + { + "id_page": 83445502, + "url": "pages/forum/detail/detail?id=135786&type=1", + "name": "【报Bug】savefile 保存doc文件时提示文件没有发现", + "num_visitor": "4", + "num_visits": "5", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:05", + "num_share": "0" + }, + { + "id_page": 83424862, + "url": "pages/forum/detail/detail?id=135755&type=1", + "name": "web-view嵌套的h5页面怎么实现video全屏横屏播放", + "num_visitor": "4", + "num_visits": "5", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:03", + "num_share": "0" + }, + { + "id_page": 83397776, + "url": "pages/forum/detail/detail?id=135707&type=1", + "name": "插件上传,一直都是提示名称错误", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:05", + "num_share": "0" + }, + { + "id_page": 82995242, + "url": "pages/forum/detail/detail?id=134753&type=1", + "name": "【报Bug】华为应用市场 收集个人信息因 ‘好的’ ‘我知道了’ 字眼 违规", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:02", + "num_share": "0" + }, + { + "id_page": 68918405, + "url": "pages/forum/detail/detail?id=102915&type=1", + "name": "uniapp 如何重写音量键动作呢?", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:10", + "visitor_avg_time": "00:00:10", + "num_share": "0" + }, + { + "id_page": 83430380, + "url": "pages/forum/detail/detail?id=135768&type=1", + "name": "在官网下载的App离线SDK,配置了appid、包名、签名、appkey,打包运行后一直停留在HBuilder的界面,没有错误提示,请问如何解决?", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:04", + "num_share": "0" + }, + { + "id_page": 83424008, + "url": "pages/forum/detail/detail?id=135752&type=1", + "name": "uni.navigateTo和uni.redirectTo跳转", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:04", + "num_share": "0" + }, + { + "id_page": 83423019, + "url": "pages/forum/detail/detail?id=135736&type=1", + "name": "使用video组件 模拟器上能正常播放,真机上无法播放", + "num_visitor": "3", + "num_visits": "4", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:02", + "num_share": "0" + }, + { + "id_page": 83396003, + "url": "pages/forum/detail/detail?id=135705&type=1", + "name": "【报Bug】HBuilderX3.3.0 引出的“系统定位”模块 问题", + "num_visitor": "3", + "num_visits": "4", + "visit_avg_time": "00:00:39", + "visitor_avg_time": "00:00:52", + "num_share": "0" + }, + { + "id_page": 885, + "url": "pages/forum/detail/detail?id=63012&type=1", + "name": "用HTML5 新增的蓝牙Bluetooth模块的demo测试,安卓手机可以搜索到附近的蓝牙设备,但是苹果手机搜索不到附近的蓝牙设备,用的ios都是11.1版本以上的,请问一下这是什么原因呢?", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:08", + "visitor_avg_time": "00:00:08", + "num_share": "0" + }, + { + "id_page": 9977925, + "url": "pages/forum/detail/detail?id=35907&type=2", + "name": "DCloud appid 用途/作用/使用说明", + "num_visitor": "3", + "num_visits": "4", + "visit_avg_time": "00:00:13", + "visitor_avg_time": "00:00:17", + "num_share": "0" + }, + { + "id_page": 83351021, + "url": "pages/forum/detail/detail?id=135657&type=1", + "name": "【报Bug】 使用了Hbuilder 3.2.13之后的版本 进行usb设备的拔插后(如键盘等输入设备) 页面v-if会失效以及很多视图无法及时更新。", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:04", + "num_share": "0" + }, + { + "id_page": 63151975, + "url": "pages/forum/detail/detail?id=81272&type=1", + "name": "uni.chooseImage方法使用从相册选择上传就好使 拍照的上传就失败 文件都能获取到", + "num_visitor": "3", + "num_visits": "4", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:06", + "num_share": "0" + }, + { + "id_page": 74766262, + "url": "pages/forum/detail/detail?id=119804&type=1", + "name": "求助!scroll-view 自定义下拉刷新多次触发问题,上滑都会多次触发", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:10", + "visitor_avg_time": "00:00:10", + "num_share": "0" + }, + { + "id_page": 83441117, + "url": "pages/forum/detail/detail?id=135781&type=1", + "name": "【报Bug】onLaunch时 plus.screen.lockOrientation('portrait-primary') 屏幕锁定无效", + "num_visitor": "3", + "num_visits": "4", + "visit_avg_time": "00:00:09", + "visitor_avg_time": "00:00:12", + "num_share": "0" + }, + { + "id_page": 83417459, + "url": "pages/forum/detail/detail?id=135738&type=1", + "name": "使用unicloud,车辆运行轨迹数据库应该如何设计", + "num_visitor": "4", + "num_visits": "4", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:03", + "num_share": "0" + } + ] +} \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/pageEnt.json b/alpha/admin/mock/uni-stat/pageEnt.json new file mode 100644 index 0000000..37ebf6d --- /dev/null +++ b/alpha/admin/mock/uni-stat/pageEnt.json @@ -0,0 +1,337 @@ +{ + "last_page": 6, + "current_page": 1, + "total": 170, + "item": [ + { + "id_page": 8, + "url": "pages/tabBar/forum/forum", + "name": "社区", + "num_visitor": "868", + "num_visits": "3,203", + "visit_avg_time": "00:01:27", + "visitor_avg_time": "00:05:23", + "entry_num_visits": "1,231", + "bounce_rate": "2.52%" + }, + { + "id_page": 9, + "url": "pages/forum/detail/detail", + "name": "社区详情", + "num_visitor": "293", + "num_visits": "1,005", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:01", + "entry_num_visits": "70", + "bounce_rate": "18.57%" + }, + { + "id_page": 11, + "url": "pages/tabBar/case/case", + "name": "实例", + "num_visitor": "550", + "num_visits": "6,957", + "visit_avg_time": "00:00:22", + "visitor_avg_time": "00:04:47", + "entry_num_visits": "65", + "bounce_rate": "23.08%" + }, + { + "id_page": 126, + "url": "pages/forum/login/login", + "name": "登录", + "num_visitor": "156", + "num_visits": "375", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "25", + "bounce_rate": "0.00%" + }, + { + "id_page": 10, + "url": "pages/tabBar/center/center", + "name": "个人中心", + "num_visitor": "365", + "num_visits": "1,046", + "visit_avg_time": "00:01:53", + "visitor_avg_time": "00:05:24", + "entry_num_visits": "18", + "bounce_rate": "50.00%" + }, + { + "id_page": 169, + "url": "pages/forum/search/index", + "name": "[object Object]", + "num_visitor": "84", + "num_visits": "266", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "15", + "bounce_rate": "40.00%" + }, + { + "id_page": 74, + "url": "pages/template/list2detail-list/list2detail-list", + "name": "列表到详情示例", + "num_visitor": "53", + "num_visits": "129", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "13", + "bounce_rate": "0.00%" + }, + { + "id_page": 33, + "url": "pages/component/scroll-view/scroll-view", + "name": "scroll-view", + "num_visitor": "62", + "num_visits": "86", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "10", + "bounce_rate": "40.00%" + }, + { + "id_page": 141, + "url": "pages/API/scan-code/scan-code", + "name": "扫码", + "num_visitor": "38", + "num_visits": "90", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "9", + "bounce_rate": "11.11%" + }, + { + "id_page": 25, + "url": "pages/component/view/view", + "name": "view", + "num_visitor": "98", + "num_visits": "126", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "9", + "bounce_rate": "0.00%" + }, + { + "id_page": 60, + "url": "pages/template/ucharts/ucharts", + "name": "uCharts 图表", + "num_visitor": "65", + "num_visits": "88", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "9", + "bounce_rate": "22.22%" + }, + { + "id_page": 78, + "url": "pages/component/button/button", + "name": "button", + "num_visitor": "73", + "num_visits": "124", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "9", + "bounce_rate": "11.11%" + }, + { + "id_page": 123, + "url": "pages/template/nav-dot/nav-dot", + "name": "[object Object]", + "num_visitor": "34", + "num_visits": "65", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "8", + "bounce_rate": "37.50%" + }, + { + "id_page": 144, + "url": "pages/template/scheme/scheme", + "name": "打开外部应用", + "num_visitor": "55", + "num_visits": "115", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "7", + "bounce_rate": "28.57%" + }, + { + "id_page": 2835009, + "url": "pages/component/ad/index", + "name": "", + "num_visitor": "76", + "num_visits": "215", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "7", + "bounce_rate": "0.00%" + }, + { + "id_page": 313, + "url": "platforms/app-plus/push/push", + "name": "推送", + "num_visitor": "38", + "num_visits": "110", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:01", + "entry_num_visits": "7", + "bounce_rate": "0.00%" + }, + { + "id_page": 34, + "url": "pages/component/swiper/swiper", + "name": "swiper", + "num_visitor": "43", + "num_visits": "59", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "6", + "bounce_rate": "66.67%" + }, + { + "id_page": 40, + "url": "pages/about/about", + "name": "关于", + "num_visitor": "47", + "num_visits": "68", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "5", + "bounce_rate": "0.00%" + }, + { + "id_page": 315, + "url": "pages/template/vant-button/vant-button", + "name": "微信自定义组件示例", + "num_visitor": "37", + "num_visits": "44", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "5", + "bounce_rate": "0.00%" + }, + { + "id_page": 339, + "url": "pages/component/web-view-local/web-view-local", + "name": "button", + "num_visitor": "33", + "num_visits": "47", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:01", + "entry_num_visits": "5", + "bounce_rate": "20.00%" + }, + { + "id_page": 99, + "url": "pages/template/nav-button/nav-button", + "name": "导航栏带自定义按钮", + "num_visitor": "69", + "num_visits": "133", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "5", + "bounce_rate": "0.00%" + }, + { + "id_page": 32, + "url": "pages/component/picker/picker", + "name": "picker", + "num_visitor": "38", + "num_visits": "52", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:06", + "entry_num_visits": "5", + "bounce_rate": "40.00%" + }, + { + "id_page": 30, + "url": "pages/component/web-view/web-view", + "name": "web-view", + "num_visitor": "60", + "num_visits": "125", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "25.00%" + }, + { + "id_page": 110, + "url": "pages/component/textarea/textarea", + "name": "textarea", + "num_visitor": "31", + "num_visits": "34", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "0.00%" + }, + { + "id_page": 342, + "url": "pages/template/nav-image/nav-image", + "name": "[object Object]", + "num_visitor": "37", + "num_visits": "51", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "0.00%" + }, + { + "id_page": 16, + "url": "pages/tabBar/component/component", + "name": "组件", + "num_visitor": "4", + "num_visits": "11", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:07", + "entry_num_visits": "4", + "bounce_rate": "0.00%" + }, + { + "id_page": 44, + "url": "pages/API/request/request", + "name": "网络请求", + "num_visitor": "22", + "num_visits": "29", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "50.00%" + }, + { + "id_page": 128, + "url": "pages/API/share/share", + "name": "分享", + "num_visitor": "24", + "num_visits": "77", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "75.00%" + }, + { + "id_page": 26, + "url": "pages/API/set-navigation-bar-title/set-navigation-bar-title", + "name": "设置界面标题", + "num_visitor": "63", + "num_visits": "85", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "0.00%" + }, + { + "id_page": 35, + "url": "pages/component/movable-view/movable-view", + "name": "movable-view", + "num_visitor": "30", + "num_visits": "40", + "visit_avg_time": "00:00:00", + "visitor_avg_time": "00:00:00", + "entry_num_visits": "4", + "bounce_rate": "50.00%" + } + ] +} \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/pageRes.json b/alpha/admin/mock/uni-stat/pageRes.json new file mode 100644 index 0000000..e5a205f --- /dev/null +++ b/alpha/admin/mock/uni-stat/pageRes.json @@ -0,0 +1,397 @@ + { + "last_page": 6, + "current_page": 1, + "total": 170, + "item": [ + { + "id_page": 11, + "url": "pages/tabBar/case/case", + "name": "实例", + "num_visitor": "550", + "num_visits": "6,957", + "visit_avg_time": "00:00:38", + "visitor_avg_time": "00:08:05", + "exit_num_visits": "485", + "exit_rate": "6.97%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 8, + "url": "pages/tabBar/forum/forum", + "name": "社区", + "num_visitor": "868", + "num_visits": "3,203", + "visit_avg_time": "00:01:47", + "visitor_avg_time": "00:06:37", + "exit_num_visits": "519", + "exit_rate": "16.20%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 10, + "url": "pages/tabBar/center/center", + "name": "个人中心", + "num_visitor": "365", + "num_visits": "1,046", + "visit_avg_time": "00:02:18", + "visitor_avg_time": "00:06:37", + "exit_num_visits": "93", + "exit_rate": "8.89%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 9, + "url": "pages/forum/detail/detail", + "name": "社区详情", + "num_visitor": "293", + "num_visits": "1,005", + "visit_avg_time": "00:00:15", + "visitor_avg_time": "00:00:53", + "exit_num_visits": "122", + "exit_rate": "12.14%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 126, + "url": "pages/forum/login/login", + "name": "登录", + "num_visitor": "156", + "num_visits": "375", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:14", + "exit_num_visits": "27", + "exit_rate": "7.20%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 169, + "url": "pages/forum/search/index", + "name": "[object Object]", + "num_visitor": "84", + "num_visits": "266", + "visit_avg_time": "00:00:11", + "visitor_avg_time": "00:00:35", + "exit_num_visits": "34", + "exit_rate": "12.78%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 310, + "url": "pages/API/subnvue/subnvue", + "name": "SubNvue", + "num_visitor": "50", + "num_visits": "241", + "visit_avg_time": "00:00:12", + "visitor_avg_time": "00:00:58", + "exit_num_visits": "6", + "exit_rate": "2.49%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 2835009, + "url": "pages/component/ad/index", + "name": "", + "num_visitor": "76", + "num_visits": "215", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:04", + "exit_num_visits": "9", + "exit_rate": "4.19%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 21, + "url": "pages/template/tabbar/tabbar", + "name": "可拖动顶部选项卡", + "num_visitor": "66", + "num_visits": "143", + "visit_avg_time": "00:00:30", + "visitor_avg_time": "00:01:06", + "exit_num_visits": "5", + "exit_rate": "3.50%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 99, + "url": "pages/template/nav-button/nav-button", + "name": "导航栏带自定义按钮", + "num_visitor": "69", + "num_visits": "133", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:09", + "exit_num_visits": "5", + "exit_rate": "3.76%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 74, + "url": "pages/template/list2detail-list/list2detail-list", + "name": "列表到详情示例", + "num_visitor": "53", + "num_visits": "129", + "visit_avg_time": "00:00:07", + "visitor_avg_time": "00:00:19", + "exit_num_visits": "3", + "exit_rate": "2.33%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 25, + "url": "pages/component/view/view", + "name": "view", + "num_visitor": "98", + "num_visits": "126", + "visit_avg_time": "00:00:10", + "visitor_avg_time": "00:00:13", + "exit_num_visits": "3", + "exit_rate": "2.38%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 27, + "url": "pages/component/navigator/navigator", + "name": "navigator", + "num_visitor": "67", + "num_visits": "125", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:02", + "exit_num_visits": "2", + "exit_rate": "1.60%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 30, + "url": "pages/component/web-view/web-view", + "name": "web-view", + "num_visitor": "60", + "num_visits": "125", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:08", + "exit_num_visits": "6", + "exit_rate": "4.80%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 78, + "url": "pages/component/button/button", + "name": "button", + "num_visitor": "73", + "num_visits": "124", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:11", + "exit_num_visits": "10", + "exit_rate": "8.06%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 144, + "url": "pages/template/scheme/scheme", + "name": "打开外部应用", + "num_visitor": "55", + "num_visits": "115", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:13", + "exit_num_visits": "16", + "exit_rate": "13.91%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 313, + "url": "platforms/app-plus/push/push", + "name": "推送", + "num_visitor": "38", + "num_visits": "110", + "visit_avg_time": "00:00:05", + "visitor_avg_time": "00:00:15", + "exit_num_visits": "4", + "exit_rate": "3.64%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 129, + "url": "pages/API/login/login", + "name": "授权登录", + "num_visitor": "44", + "num_visits": "109", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:08", + "exit_num_visits": "5", + "exit_rate": "4.59%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 135, + "url": "pages/API/request-payment/request-payment", + "name": "发起支付", + "num_visitor": "43", + "num_visits": "101", + "visit_avg_time": "00:00:04", + "visitor_avg_time": "00:00:10", + "exit_num_visits": "5", + "exit_rate": "4.95%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 141, + "url": "pages/API/scan-code/scan-code", + "name": "扫码", + "num_visitor": "38", + "num_visits": "90", + "visit_avg_time": "00:00:20", + "visitor_avg_time": "00:00:48", + "exit_num_visits": "13", + "exit_rate": "14.44%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 42, + "url": "pages/API/navigator/navigator", + "name": "页面跳转", + "num_visitor": "27", + "num_visits": "89", + "visit_avg_time": "00:00:02", + "visitor_avg_time": "00:00:07", + "exit_num_visits": "1", + "exit_rate": "1.12%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 57, + "url": "pages/extUI/list/list", + "name": "List 列表", + "num_visitor": "36", + "num_visits": "88", + "visit_avg_time": "00:03:21", + "visitor_avg_time": "00:08:11", + "exit_num_visits": "8", + "exit_rate": "9.09%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 60, + "url": "pages/template/ucharts/ucharts", + "name": "uCharts 图表", + "num_visitor": "65", + "num_visits": "88", + "visit_avg_time": "00:00:19", + "visitor_avg_time": "00:00:26", + "exit_num_visits": "12", + "exit_rate": "13.64%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 33, + "url": "pages/component/scroll-view/scroll-view", + "name": "scroll-view", + "num_visitor": "62", + "num_visits": "86", + "visit_avg_time": "00:00:11", + "visitor_avg_time": "00:00:16", + "exit_num_visits": "11", + "exit_rate": "12.79%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 26, + "url": "pages/API/set-navigation-bar-title/set-navigation-bar-title", + "name": "设置界面标题", + "num_visitor": "63", + "num_visits": "85", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:08", + "exit_num_visits": "1", + "exit_rate": "1.18%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 3084839, + "url": "pages/template/swiper-list-nvue/swiper-list-nvue", + "name": "", + "num_visitor": "48", + "num_visits": "80", + "visit_avg_time": "00:01:11", + "visitor_avg_time": "00:01:58", + "exit_num_visits": "6", + "exit_rate": "7.50%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 128, + "url": "pages/API/share/share", + "name": "分享", + "num_visitor": "24", + "num_visits": "77", + "visit_avg_time": "00:00:06", + "visitor_avg_time": "00:00:22", + "exit_num_visits": "8", + "exit_rate": "10.39%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 360577, + "url": "pages/template/component-communication/component-communication", + "name": "组件通讯", + "num_visitor": "52", + "num_visits": "71", + "visit_avg_time": "00:00:03", + "visitor_avg_time": "00:00:04", + "exit_num_visits": "1", + "exit_rate": "1.41%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 361612, + "url": "pages/API/navigator/new-page/new-vue-page-1", + "name": "新VUE页面1", + "num_visitor": "18", + "num_visits": "71", + "visit_avg_time": "00:00:01", + "visitor_avg_time": "00:00:06", + "exit_num_visits": "0", + "exit_rate": "0.00%", + "num_share": "0", + "hasChildren": true + }, + { + "id_page": 314, + "url": "platforms/app-plus/feedback/feedback", + "name": "问题反馈", + "num_visitor": "39", + "num_visits": "69", + "visit_avg_time": "00:00:10", + "visitor_avg_time": "00:00:18", + "exit_num_visits": "7", + "exit_rate": "10.14%", + "num_share": "0", + "hasChildren": true + } + ] + } \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/pageRule.json b/alpha/admin/mock/uni-stat/pageRule.json new file mode 100644 index 0000000..3361cd5 --- /dev/null +++ b/alpha/admin/mock/uni-stat/pageRule.json @@ -0,0 +1,132 @@ +{ + "last_page": 16, + "current_page": 1, + "total": 315, + "item": [ + { + "id_page": 8, + "url": "pages/tabBar/forum/forum", + "name": "社区", + "rules": [ + "id", + "type" + ] + }, + { + "id_page": 9, + "url": "pages/forum/detail/detail", + "name": "社区详情", + "rules": [ + "id,type" + ] + }, + { + "id_page": 10, + "url": "pages/tabBar/center/center", + "name": "个人中心", + "rules": null + }, + { + "id_page": 11, + "url": "pages/tabBar/case/case", + "name": "实例", + "rules": null + }, + { + "id_page": 16, + "url": "pages/tabBar/component/component", + "name": "组件", + "rules": null + }, + { + "id_page": 17, + "url": "pages/tabBar/API/API", + "name": "API", + "rules": null + }, + { + "id_page": 18, + "url": "pages/tabBar/extUI/extUI", + "name": "扩展组件", + "rules": null + }, + { + "id_page": 19, + "url": "pages/tabBar/template/template", + "name": "模版", + "rules": null + }, + { + "id_page": 20, + "url": "pages/template/mpvue-picker/mpvue-picker", + "name": "多列选择picker", + "rules": null + }, + { + "id_page": 21, + "url": "pages/template/tabbar/tabbar", + "name": "可拖动顶部选项卡", + "rules": null + }, + { + "id_page": 22, + "url": "pages/template/scrollmsg/scrollmsg", + "name": "滚动公告", + "rules": null + }, + { + "id_page": 23, + "url": "pages/template/datachecker/datachecker", + "name": "表单校验", + "rules": null + }, + { + "id_page": 24, + "url": "pages/extUI/swipe-action/swipe-action", + "name": "SwipeAction 滑动操作", + "rules": null + }, + { + "id_page": 25, + "url": "pages/component/view/view", + "name": "view", + "rules": null + }, + { + "id_page": 26, + "url": "pages/API/set-navigation-bar-title/set-navigation-bar-title", + "name": "设置界面标题", + "rules": null + }, + { + "id_page": 27, + "url": "pages/component/navigator/navigator", + "name": "navigator", + "rules": null + }, + { + "id_page": 28, + "url": "pages/component/navigator/redirect/redirect", + "name": "redirectPage", + "rules": null + }, + { + "id_page": 29, + "url": "pages/component/map/map", + "name": "map", + "rules": null + }, + { + "id_page": 30, + "url": "pages/component/web-view/web-view", + "name": "web-view", + "rules": null + }, + { + "id_page": 31, + "url": "pages/component/form/form", + "name": "form", + "rules": null + } + ] +} \ No newline at end of file diff --git a/alpha/admin/mock/uni-stat/userActivity.json b/alpha/admin/mock/uni-stat/userActivity.json new file mode 100644 index 0000000..6baf91f --- /dev/null +++ b/alpha/admin/mock/uni-stat/userActivity.json @@ -0,0 +1,73 @@ +{ + "categories": [ + "2021-11-08", + "2021-11-09", + "2021-11-10", + "2021-11-11", + "2021-11-12", + "2021-11-13", + "2021-11-14", + "2021-11-15", + "2021-11-16", + "2021-11-17", + "2021-11-18", + "2021-11-19", + "2021-11-20", + "2021-11-21", + "2021-11-22", + "2021-11-23", + "2021-11-24", + "2021-11-25", + "2021-11-26", + "2021-11-27", + "2021-11-28", + "2021-11-29", + "2021-11-30", + "2021-12-01", + "2021-12-02", + "2021-12-03", + "2021-12-04", + "2021-12-05", + "2021-12-06", + "2021-12-07", + "2021-12-08" + ], + "series": [ + { + "name": "日活", + "data": [ + 1520, + 1523, + 1462, + 1445, + 1433, + 972, + 768, + 1421, + 1581, + 1613, + 1549, + 1517, + 989, + 839, + 1579, + 1539, + 1574, + 1518, + 1584, + 1043, + 853, + 1498, + 1553, + 1170, + 909, + 866, + 620, + 566, + 884, + 905, + 643 + ] + } + ] +} \ No newline at end of file diff --git a/alpha/admin/package.json b/alpha/admin/package.json new file mode 100644 index 0000000..f6788b9 --- /dev/null +++ b/alpha/admin/package.json @@ -0,0 +1,93 @@ +{ + "name": "uni-admin 基础框架(原名 uniCloud admin)", + "id": "uni-template-admin", + "displayName": "uni-admin 基础框架", + "version": "2.3.6", + "description": "基于uni-app & uniCloud的后台管理项目模板(管理后台开发必备神器)", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": "https://github.com/dcloudio/uni-admin.git", + "keywords": [ + "admin", + "uniCloud", + "管理后台", + "云后台", + "uni-admin" + ], + "engines": { + "HBuilderX": "^3.6.0" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "https://github.com/dcloudio/uni-admin/issues" + }, + "homepage": "https://github.com/dcloudio/uni-admin#readme", + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "unicloud-template-project" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "n", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/pages.json b/alpha/admin/pages.json new file mode 100644 index 0000000..959f884 --- /dev/null +++ b/alpha/admin/pages.json @@ -0,0 +1,491 @@ +{ + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/index/index" + }, + { + "path": "uni_modules/uni-id-pages/pages/login/login-withpwd", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "登录" + } + }, + { + "path": "pages/error/404", + "style": { + "navigationBarTitleText": "Not Found" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd", + "style": { + "navigationBarTitleText": "修改密码" + } + }, + { + "path": "uni_modules/uni-upgrade-center/pages/version/list", + "style": { + "navigationBarTitleText": "版本列表" + } + }, + { + "path": "uni_modules/uni-upgrade-center/pages/version/add", + "style": { + "navigationBarTitleText": "新版发布" + } + }, + { + "path": "uni_modules/uni-upgrade-center/pages/version/detail", + "style": { + "navigationBarTitleText": "版本信息查看" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate", + "style": { + "navigationBarTitleText": "注销账号" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/userinfo/userinfo", + "style": { + "navigationBarTitleText": "个人资料" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile", + "style": { + "navigationBarTitleText": "绑定手机号码" + } + }, { + "path": "uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage", + "style": { + "navigationBarTitleText": "" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/login/login-smscode", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "手机验证码登录" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/login/login-withoutpwd", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "免密登录页" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/register/register", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "注册" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/register/register-admin", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "创建超级管理员" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/register/register-by-email", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "邮箱验证码注册" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/retrieve/retrieve", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "重置密码" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email", + "style": { + "topWindow": false, + "leftWindow": false, + "navigationBarTitleText": "通过邮箱重置密码" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/common/webview/webview", + "style": { + "topWindow": false, + "leftWindow": false, + "enablePullDownRefresh": false, + "navigationBarTitleText": "" + } + }, + { + "path": "uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd", + "style": { + "enablePullDownRefresh": false, + "navigationBarTitleText": "设置密码" + } + } + ], + "subPackages": [{ + "root": "pages/system", + "pages": [{ + "path": "menu/list", + "style": { + "navigationBarTitleText": "菜单管理" + } + }, + { + "path": "menu/add", + "style": { + "navigationBarTitleText": "新增菜单", + "navigationStyle": "default" + } + }, + { + "path": "menu/edit", + "style": { + "navigationBarTitleText": "修改菜单", + "navigationStyle": "default" + } + }, + { + "path": "permission/list", + "style": { + "navigationBarTitleText": "权限管理" + } + }, + { + "path": "permission/add", + "style": { + "navigationBarTitleText": "新增权限", + "navigationStyle": "default" + } + }, + { + "path": "permission/edit", + "style": { + "navigationBarTitleText": "修改权限", + "navigationStyle": "default" + } + }, + { + "path": "role/add", + "style": { + "navigationBarTitleText": "新增角色", + "navigationStyle": "default" + } + }, + { + "path": "role/edit", + "style": { + "navigationBarTitleText": "修改角色", + "navigationStyle": "default" + } + }, + { + "path": "role/list", + "style": { + "navigationBarTitleText": "角色管理" + } + }, + { + "path": "user/add", + "style": { + "navigationBarTitleText": "新增用户", + "navigationStyle": "default" + } + }, + { + "path": "user/edit", + "style": { + "navigationBarTitleText": "修改用户", + "navigationStyle": "default" + } + }, + { + "path": "user/list", + "style": { + "navigationBarTitleText": "用户管理" + } + }, + { + "path": "app/add", + "style": { + "navigationBarTitleText": "新增应用", + "navigationStyle": "default" + } + }, + { + "path": "app/list", + "style": { + "navigationBarTitleText": "应用管理" + } + }, + { + "path": "app/uni-portal/uni-portal", + "style": { + "navigationBarTitleText": "发布页管理", + "navigationStyle": "default" + } + }, + { + "path": "tag/add", + "style": { + "navigationBarTitleText": "新增标签" + } + }, + { + "path": "tag/edit", + "style": { + "navigationBarTitleText": "修改标签" + } + }, + { + "path": "tag/list", + "style": { + "navigationBarTitleText": "标签管理" + } + }, + { + "path": "safety/list", + "style": { + "navigationBarTitleText": "用户日志" + } + } + ] + }, + { + "root": "pages/demo", + "pages": [{ + "path": "icons/icons", + "style": { + "navigationBarTitleText": "图标" + } + }, + { + "path": "table/table", + "style": { + "navigationBarTitleText": "表格" + } + } + ] + }, + { + "root": "pages/uni-stat", + "pages": [{ + "path": "page-res/page-res", + "style": { + "navigationBarTitleText": "受访页", + "enablePullDownRefresh": false + } + }, + { + "path": "page-ent/page-ent", + "style": { + "navigationBarTitleText": "入口页", + "enablePullDownRefresh": false + } + }, + { + "path": "scene/scene", + "style": { + "navigationBarTitleText": "场景值(小程序)", + "enablePullDownRefresh": false + } + }, + { + "path": "channel/channel", + "style": { + "navigationBarTitleText": "渠道(app)", + "enablePullDownRefresh": false + } + }, + // #ifndef MP + { + "path": "error/js/js", + "style": { + "navigationBarTitleText": "js报错统计", + "enablePullDownRefresh": false + } + }, + // #endif + { + "path": "error/js/detail", + "style": { + "navigationBarTitleText": "错误信息", + "navigationStyle": "default", + "enablePullDownRefresh": false + } + }, + { + "path": "error/app/app", + "style": { + "navigationBarTitleText": "app原生报错统计", + "enablePullDownRefresh": false + } + }, + { + "path": "event/event", + "style": { + "navigationBarTitleText": "事件和转化", + "enablePullDownRefresh": false + } + }, + { + "path": "device/overview/overview", + "style": { + "navigationBarTitleText": "今日概况", + "enablePullDownRefresh": false + } + }, + { + "path": "device/activity/activity", + "style": { + "navigationBarTitleText": "活跃度", + "enablePullDownRefresh": false + } + }, + { + "path": "device/trend/trend", + "style": { + "navigationBarTitleText": "趋势分析", + "enablePullDownRefresh": false + } + }, + { + "path": "device/retention/retention", + "style": { + "navigationBarTitleText": "留存", + "enablePullDownRefresh": false + } + }, + { + "path": "device/comparison/comparison", + "style": { + "navigationBarTitleText": "平台对比", + "enablePullDownRefresh": false + } + }, + { + "path": "device/stickiness/stickiness", + "style": { + "navigationBarTitleText": "粘性", + "enablePullDownRefresh": false + } + }, + { + "path": "user/overview/overview", + "style": { + "navigationBarTitleText": "今日概况", + "enablePullDownRefresh": false + } + }, + { + "path": "user/activity/activity", + "style": { + "navigationBarTitleText": "活跃度", + "enablePullDownRefresh": false + } + }, + { + "path": "user/trend/trend", + "style": { + "navigationBarTitleText": "趋势分析", + "enablePullDownRefresh": false + } + }, + { + "path": "user/retention/retention", + "style": { + "navigationBarTitleText": "留存", + "enablePullDownRefresh": false + } + }, + { + "path": "user/comparison/comparison", + "style": { + "navigationBarTitleText": "平台对比", + "enablePullDownRefresh": false + } + }, + { + "path": "user/stickiness/stickiness", + "style": { + "navigationBarTitleText": "粘性", + "enablePullDownRefresh": false + } + }, + { + "path": "pay-order/overview/overview", + "style": { + "navigationBarTitleText": "订单概况", + "enablePullDownRefresh": false + } + }, + { + "path": "pay-order/list/list", + "style": { + "navigationBarTitleText": "订单明细", + "enablePullDownRefresh": false + } + }, + { + "path": "pay-order/funnel/funnel", + "style": { + "navigationBarTitleText": "漏斗分析", + "enablePullDownRefresh": false + } + }, + { + "path": "pay-order/ranking/ranking", + "style": { + "navigationBarTitleText": "用户价值排行", + "enablePullDownRefresh": false + } + } + ] + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "管理系统", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8", + "h5": { + "titleNView": false + } + }, + "topWindow": { + "path": "windows/topWindow", + "style": { + "height": "60px" + }, + "matchMedia": { + "minWidth": 0 + } + }, + "leftWindow": { + "path": "windows/leftWindow", + "style": { + "width": "240px" + } + }, + "uniIdRouter": { + "loginPage": "uni_modules/uni-id-pages/pages/login/login-withpwd", + "needLogin": [ + "^((?!uni-id-pages\/pages\/login|register|retrieve).)*$" + ], + "resToLogin": true + } +} diff --git a/alpha/admin/pages/demo/icons/icons.vue b/alpha/admin/pages/demo/icons/icons.vue new file mode 100644 index 0000000..fa8f083 --- /dev/null +++ b/alpha/admin/pages/demo/icons/icons.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/alpha/admin/pages/demo/icons/uni-icons.js b/alpha/admin/pages/demo/icons/uni-icons.js new file mode 100644 index 0000000..fa2cba9 --- /dev/null +++ b/alpha/admin/pages/demo/icons/uni-icons.js @@ -0,0 +1,132 @@ +export default [ + 'pulldown', + 'refreshempty', + 'back', + 'forward', + 'more', + 'more-filled', + 'scan', + 'qq', + 'weibo', + 'weixin', + 'pengyouquan', + 'loop', + 'refresh', + 'refresh-filled', + 'arrowthindown', + 'arrowthinleft', + 'arrowthinright', + 'arrowthinup', + 'undo-filled', + 'undo', + 'redo', + 'redo-filled', + 'bars', + 'chatboxes', + 'camera', + 'chatboxes-filled', + 'camera-filled', + 'cart-filled', + 'cart', + 'checkbox-filled', + 'checkbox', + 'arrowleft', + 'arrowdown', + 'arrowright', + 'smallcircle-filled', + 'arrowup', + 'circle', + 'eye-filled', + 'eye-slash-filled', + 'eye-slash', + 'eye', + 'flag-filled', + 'flag', + 'gear-filled', + 'reload', + 'gear', + 'hand-thumbsdown-filled', + 'hand-thumbsdown', + 'hand-thumbsup-filled', + 'heart-filled', + 'hand-thumbsup', + 'heart', + 'home', + 'info', + 'home-filled', + 'info-filled', + 'circle-filled', + 'chat-filled', + 'chat', + 'mail-open-filled', + 'email-filled', + 'mail-open', + 'email', + 'checkmarkempty', + 'list', + 'locked-filled', + 'locked', + 'map-filled', + 'map-pin', + 'map-pin-ellipse', + 'map', + 'minus-filled', + 'mic-filled', + 'minus', + 'micoff', + 'mic', + 'clear', + 'smallcircle', + 'close', + 'closeempty', + 'paperclip', + 'paperplane', + 'paperplane-filled', + 'person-filled', + 'contact-filled', + 'person', + 'contact', + 'images-filled', + 'phone', + 'images', + 'image', + 'image-filled', + 'location-filled', + 'location', + 'plus-filled', + 'plus', + 'plusempty', + 'help-filled', + 'help', + 'navigate-filled', + 'navigate', + 'mic-slash-filled', + 'search', + 'settings', + 'sound', + 'sound-filled', + 'spinner-cycle', + 'download-filled', + 'personadd-filled', + 'videocam-filled', + 'personadd', + 'upload', + 'upload-filled', + 'starhalf', + 'star-filled', + 'star', + 'trash', + 'phone-filled', + 'compose', + 'videocam', + 'trash-filled', + 'download', + 'chatbubble-filled', + 'chatbubble', + 'cloud-download', + 'cloud-upload-filled', + 'cloud-upload', + 'cloud-download-filled', + 'headphones', + 'shop' +] diff --git a/alpha/admin/pages/demo/table/table.vue b/alpha/admin/pages/demo/table/table.vue new file mode 100644 index 0000000..26394fe --- /dev/null +++ b/alpha/admin/pages/demo/table/table.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/alpha/admin/pages/demo/table/tableData.js b/alpha/admin/pages/demo/table/tableData.js new file mode 100644 index 0000000..14ac826 --- /dev/null +++ b/alpha/admin/pages/demo/table/tableData.js @@ -0,0 +1,193 @@ +export default [{ + "date": "2020-09-01", + "name": "Dcloud1", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-02", + "name": "Dcloud2", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-03", + "name": "Dcloud3", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-04", + "name": "Dcloud4", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-05", + "name": "Dcloud5", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-06", + "name": "Dcloud6", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-07", + "name": "Dcloud7", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-08", + "name": "Dcloud8", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-09", + "name": "Dcloud9", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-10", + "name": "Dcloud10", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-11", + "name": "Dcloud11", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-12", + "name": "Dcloud12", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-13", + "name": "Dcloud13", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-14", + "name": "Dcloud14", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-15", + "name": "Dcloud15", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-16", + "name": "Dcloud16", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-01", + "name": "Dcloud17", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-02", + "name": "Dcloud18", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-03", + "name": "Dcloud19", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-04", + "name": "Dcloud20", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-05", + "name": "Dcloud21", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-06", + "name": "Dcloud22", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-07", + "name": "Dcloud23", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-08", + "name": "Dcloud24", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-09", + "name": "Dcloud25", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-10", + "name": "Dcloud26", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-11", + "name": "Dcloud27", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-12", + "name": "Dcloud28", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-13", + "name": "Dcloud29", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-14", + "name": "Dcloud30", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-15", + "name": "Dcloud31", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-16", + "name": "Dcloud32", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-01", + "name": "Dcloud33", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-02", + "name": "Dcloud34", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-03", + "name": "Dcloud35", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-04", + "name": "Dcloud36", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-05", + "name": "Dcloud37", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-06", + "name": "Dcloud38", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-07", + "name": "Dcloud39", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-08", + "name": "Dcloud40", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-09", + "name": "Dcloud41", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-10", + "name": "Dcloud42", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-11", + "name": "Dcloud43", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-12", + "name": "Dcloud44", + "address": "上海市普陀区金沙江路 1516 弄" +}, { + "date": "2020-09-13", + "name": "Dcloud45", + "address": "上海市普陀区金沙江路 1518 弄" +}, { + "date": "2020-09-14", + "name": "Dcloud46", + "address": "上海市普陀区金沙江路 1517 弄" +}, { + "date": "2020-09-15", + "name": "Dcloud47", + "address": "上海市普陀区金沙江路 1519 弄" +}, { + "date": "2020-09-16", + "name": "Dcloud48", + "address": "上海市普陀区金沙江路 1516 弄" +}] diff --git a/alpha/admin/pages/error/404.vue b/alpha/admin/pages/error/404.vue new file mode 100644 index 0000000..19cba9d --- /dev/null +++ b/alpha/admin/pages/error/404.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/alpha/admin/pages/index/fieldsMap.js b/alpha/admin/pages/index/fieldsMap.js new file mode 100644 index 0000000..e1d1bbb --- /dev/null +++ b/alpha/admin/pages/index/fieldsMap.js @@ -0,0 +1,82 @@ +const deviceFeildsMap = [{ + value: '今天', + contrast: '昨天' +}, { + field: 'appid', + title: 'APPID', + tooltip: '', +}, { + field: 'name', + title: '应用名', + tooltip: '', +}, { + field: 'total_devices', + title: '总设备数', + tooltip: '从添加统计到当前选择时间的总设备数(去重)', + value: 0, + contrast: 0, +}, { + field: 'new_device_count', + title: '新增设备', + tooltip: '首次访问应用的设备数(以设备为判断标准,去重)', + value: 0, + contrast: 0 +}, { + field: 'active_device_count', + title: '活跃设备', + tooltip: '访问过应用内任意页面的总设备数(去重)', + value: 0, + contrast: 0 +}, +// { +// field: 'page_visit_count', +// title: '访问次数', +// tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', +// value: 0, +// contrast: 0 +// } +] + +const userFeildsMap = [{ + value: '今天', + contrast: '昨天' +}, { + field: 'appid', + title: 'APPID', + tooltip: '', +}, { + field: 'name', + title: '应用名', + tooltip: '', +}, { + field: 'total_users', + title: '总用户数', + tooltip: '从添加统计到当前选择时间的总用户数(去重)', + value: 0, + contrast: 0, +}, { + field: 'new_user_count', + title: '新增用户', + tooltip: '首次访问应用的用户数(以用户为判断标准,去重)', + value: 0, + contrast: 0 +}, { + field: 'active_user_count', + title: '活跃用户', + tooltip: '访问过应用内任意页面的总用户数(去重)', + value: 0, + contrast: 0 +}, +// { +// field: 'page_visit_count', +// title: '访问次数', +// tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', +// value: 0, +// co\rast: 0 +// } +] + +export { + deviceFeildsMap, + userFeildsMap +} diff --git a/alpha/admin/pages/index/index.vue b/alpha/admin/pages/index/index.vue new file mode 100644 index 0000000..84445ed --- /dev/null +++ b/alpha/admin/pages/index/index.vue @@ -0,0 +1,361 @@ + + + + + diff --git a/alpha/admin/pages/system/app/add.vue b/alpha/admin/pages/system/app/add.vue new file mode 100644 index 0000000..f9aaeff --- /dev/null +++ b/alpha/admin/pages/system/app/add.vue @@ -0,0 +1,490 @@ + + + + + diff --git a/alpha/admin/pages/system/app/list.vue b/alpha/admin/pages/system/app/list.vue new file mode 100644 index 0000000..53a2e60 --- /dev/null +++ b/alpha/admin/pages/system/app/list.vue @@ -0,0 +1,292 @@ + + + + diff --git a/alpha/admin/pages/system/app/mixin/publish_add_detail_mixin.js b/alpha/admin/pages/system/app/mixin/publish_add_detail_mixin.js new file mode 100644 index 0000000..1969447 --- /dev/null +++ b/alpha/admin/pages/system/app/mixin/publish_add_detail_mixin.js @@ -0,0 +1,273 @@ +import { + validator, + mpPlatform +} from '@/js_sdk/validator/opendb-app-list.js'; + +const formatFilePickerValue = (url) => (url ? { + "name": "", + "extname": "", + "url": url, +} : {}) + +function getValidator(fields) { + let result = {} + for (let key in validator) { + if (fields.includes(key)) { + result[key] = validator[key] + } + } + return result +} + +const schemes = ["mimarket", "samsungapps", "appmarket", "oppomarket", "vivomarket"] +const schemeBrand = ["xiaomi", "samsung", "huawei", "oppo", "vivo"] + +export default { + data() { + let formData = { + "appid": "", + "name": "", + "icon_url": "", + "introduction": "", + "alias": "", + "description": "", + "screenshot": [], + "store_list": [], + "app_android": {}, + "app_ios": {}, + "mp_weixin": {}, + "mp_alipay": {}, + "mp_baidu": {}, + "mp_toutiao": {}, + "mp_qq": {}, + "mp_lark": {}, + "mp_kuaishou": {}, + "mp_dingtalk": {}, + "mp_jd": {}, + "h5": {}, + "quickapp": {} + } + const data = { + formData, + rules: Object.freeze(getValidator(Object.keys(formData))), + mpPlatform: Object.freeze(mpPlatform), + screenshotList: [], + middleware_img: {}, + middleware_checkbox: {}, + appPackageInfo: {}, + appPlatformKeys: Object.freeze(['app_ios', 'app_android']), + appPlatformValues: Object.freeze({ + app_android: 'Android', + app_ios: 'iOS' + }), + keepItems: Object.freeze([]), + isEdit: false, + deletedStore: [] + } + const mpKeys = Object.keys(mpPlatform); + data.mpPlatformKeys = Object.freeze(mpKeys); + [].concat(mpKeys, ['icon_url', 'quickapp']).forEach(key => data.middleware_img[key] = {}); + data.platFormKeys = Object.freeze([].concat(mpKeys, data.appPlatformKeys)) + data.platFormKeys.forEach(key => data.middleware_checkbox[key] = false) + return data + }, + methods: { + requestCloudFunction(functionName, params = {}) { + return this.$request(functionName, params, { + functionName: 'uni-upgrade-center' + }) + }, + hasValue(value) { + if (typeof value !== 'object') return !!value + if (value instanceof Array) return !!value.length + return !!(value && Object.keys(value).length) + }, + initFormData(obj) { + if (!obj || !Object.keys(obj).length) return; + // TODO delete + for (let key in obj) { + const value = obj[key] + switch (key) { + case 'icon_url': + this.middleware_img[key] = formatFilePickerValue(value) + break; + case 'screenshot': + this.screenshotList = value.map(item => formatFilePickerValue(item)) + break; + default: + if ((key.indexOf('mp') !== -1 || key.indexOf('app') !== -1) && this.hasValue(value)) { + this.setPlatformChcekbox(key, true) + if (value.qrcode_url) + this.middleware_img[key] = formatFilePickerValue(value.qrcode_url) + } + break; + } + this.setFormData(key, value) + } + }, + setFormData(key, value) { + const keys = key.indexOf('.') !== -1 ? key.split('.') : [key]; + const lens = keys.length - 1 + let tempObj = this.formData + keys.forEach((key, index) => { + const obj = tempObj[key] + if (typeof obj === 'object' && index < lens) { + tempObj = obj + } else { + tempObj[key] = value + } + }) + }, + getFormData(key) { + const keys = key.indexOf('.') !== -1 ? key.split('.') : [key]; + const lens = keys.length - 1 + let tempObj = this.formData + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + tempObj = tempObj[key] + if (tempObj == null) { + return false + } + } + return tempObj + }, + formatFormData() { + this.setFormData('screenshot', this.screenshotList.map(item => item.fileID || item.url)) + + for (let i = 0; i < this.formData.store_list.length; i++) { + const item = this.formData.store_list[i] + + if (item.scheme.trim().length === 0) { + this.formData.store_list.splice(i, 1) + i-- + continue; + } + + const index = schemes.indexOf((item.scheme.match(/(.*):\/\//) || [])[1]) + if (index !== -1) { + if (item.id !== schemeBrand[index]) { + this.deletedStore.push(item.id) + } + item.id = schemeBrand[index] + } + item.priority = parseFloat(item.priority) + } + + this.keepItems = this.platFormKeys + .filter(key => + this.getPlatformChcekbox(key) && + (this.formData[key].url || this.formData[key].qrcode_url) + ) + .concat(['icon_url', 'screenshot', 'create_date', 'store_list']) + + if (this.formData.h5 && this.formData.h5.url) + this.keepItems.push('h5'); + }, + // 根据 appid 自动填充 + autoFill() { + const appid = this.getFormData('appid') + if (!appid) { + return + } + + uni.showLoading({ + mask: true + }) + + this.requestCloudFunction('getAppInfo', { + appid + }) + .then(res => { + if (res.success) { + this.setFormData('description', res.description) + this.setFormData('name', res.name) + return + } + }).catch(e => { + console.error(e) + }).finally(() => { + uni.hideLoading() + }) + }, + autoFillApp() { + const appid = this.getFormData('appid') + if (!appid) { + return + } + + this.appPlatformKeys.forEach(key => { + this.fetchAppInfo(appid, this.appPlatformValues[key]).then(res => { + if (res && res.success) { + this.setPlatformChcekbox(key, true) + this.setFormData(key, { + name: res.name, + url: res.url + }) + return; + } + }) + }) + }, + fetchAppInfo(appid, platform) { + uni.showLoading({ + mask: true + }) + return this.requestCloudFunction('getAppVersionInfo', { + appid, + platform + }).then(res => { + return res + }).catch(e => { + console.error(e) + }).finally(() => { + uni.hideLoading() + }) + }, + iconUrlSuccess(res, key) { + uni.showToast({ + icon: 'success', + title: '上传成功', + duration: 500 + }) + this.setFormData(key, res.tempFilePaths[0]) + }, + async iconUrlDelete(res, key) { + let deleteRes = await this.requestCloudFunction('deleteFile', { + fileList: [res.tempFile.fileID || res.tempFile.url] + }) + deleteRes.fileList ? + deleteRes = deleteRes.fileList[0] : + deleteRes = deleteRes[0]; + if (deleteRes.success || deleteRes.code === "SUCCESS") { + uni.showToast({ + icon: 'success', + title: '删除成功', + duration: 800 + }) + if (!key) return; + this.setFormData(key, '') + this.$refs.form.clearValidate(key) + } + }, + getPlatformChcekbox(mp_name) { + return this.middleware_checkbox[mp_name] + }, + setPlatformChcekbox(mp_name, value = false) { + this.middleware_checkbox[mp_name] = value + }, + selectFile() { + if (this.hasPackage) { + uni.showToast({ + icon: 'none', + title: '只可上传一个文件,请删除已上传后重试', + duration: 1000 + }); + } + } + }, + computed: { + hasPackage() { + return this.appPackageInfo && !!Object.keys(this.appPackageInfo).length + }, + } +} diff --git a/alpha/admin/pages/system/app/uni-portal/uni-portal.vue b/alpha/admin/pages/system/app/uni-portal/uni-portal.vue new file mode 100644 index 0000000..5da96fe --- /dev/null +++ b/alpha/admin/pages/system/app/uni-portal/uni-portal.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/alpha/admin/pages/system/menu/add.vue b/alpha/admin/pages/system/menu/add.vue new file mode 100644 index 0000000..738d619 --- /dev/null +++ b/alpha/admin/pages/system/menu/add.vue @@ -0,0 +1,164 @@ + + + + diff --git a/alpha/admin/pages/system/menu/edit.vue b/alpha/admin/pages/system/menu/edit.vue new file mode 100644 index 0000000..b21f416 --- /dev/null +++ b/alpha/admin/pages/system/menu/edit.vue @@ -0,0 +1,188 @@ + + + + diff --git a/alpha/admin/pages/system/menu/list.vue b/alpha/admin/pages/system/menu/list.vue new file mode 100644 index 0000000..409b6a6 --- /dev/null +++ b/alpha/admin/pages/system/menu/list.vue @@ -0,0 +1,487 @@ + + + + diff --git a/alpha/admin/pages/system/menu/originalMenuList.json b/alpha/admin/pages/system/menu/originalMenuList.json new file mode 100644 index 0000000..1182e25 --- /dev/null +++ b/alpha/admin/pages/system/menu/originalMenuList.json @@ -0,0 +1,416 @@ +[{ + "menu_id": "index", + "name": "首页", + "icon": "uni-icons-home", + "url": "/", + "sort": 100, + "parent_id": "", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_management", + "name": "系统管理", + "icon": "admin-icons-fl-xitong", + "url": "", + "sort": 1000, + "parent_id": "", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_user", + "name": "用户管理", + "icon": "admin-icons-manager-user", + "url": "/pages/system/user/list", + "sort": 1010, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469398 + }, { + "menu_id": "system_role", + "name": "角色管理", + "icon": "admin-icons-manager-role", + "url": "/pages/system/role/list", + "sort": 1020, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469397 + }, { + "menu_id": "system_permission", + "name": "权限管理", + "icon": "admin-icons-manager-permission", + "url": "/pages/system/permission/list", + "sort": 1030, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_menu", + "name": "菜单管理", + "icon": "admin-icons-manager-menu", + "url": "/pages/system/menu/list", + "sort": 1040, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_app", + "name": "应用管理", + "icon": "admin-icons-manager-app", + "url": "/pages/system/app/list", + "sort": 1035, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469399 + }, { + "menu_id": "system_update", + "name": "App升级中心", + "icon": "uni-icons-cloud-upload", + "url": "/uni_modules/uni-upgrade-center/pages/version/list", + "sort": 1036, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1656491532434 + }, { + "menu_id": "system_tag", + "name": "标签管理", + "icon": "admin-icons-manager-tag", + "url": "/pages/system/tag/list", + "sort": 1037, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662479389 + }, { + "permission": [], + "enable": true, + "menu_id": "safety_statistics", + "name": "安全审计", + "icon": "admin-icons-safety", + "url": "", + "sort": 3100, + "parent_id": "", + "create_date": 1638356430871 + }, { + "permission": [], + "enable": true, + "menu_id": "safety_statistics_user_log", + "name": "用户日志", + "icon": "", + "url": "/pages/system/safety/list", + "sort": 3101, + "parent_id": "safety_statistics", + "create_date": 1638356430871 + }, { + "permission": [], + "enable": true, + "menu_id": "uni-stat", + "name": "uni 统计", + "icon": "admin-icons-tongji", + "url": "", + "sort": 2100, + "parent_id": "", + "create_date": 1638356430871 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device", + "name": "设备统计", + "icon": "admin-icons-shebeitongji", + "url": "", + "sort": 2120, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/device/overview/overview", + "sort": 2121, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-activity", + "name": "活跃度", + "icon": "", + "url": "/pages/uni-stat/device/activity/activity", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-trend", + "name": "趋势分析", + "icon": "", + "url": "/pages/uni-stat/device/trend/trend", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-retention", + "name": "留存", + "icon": "", + "url": "/pages/uni-stat/device/retention/retention", + "sort": 2124, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-comparison", + "name": "平台对比", + "icon": "", + "url": "/pages/uni-stat/device/comparison/comparison", + "sort": 2125, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-stickiness", + "name": "粘性", + "icon": "", + "url": "/pages/uni-stat/device/stickiness/stickiness", + "sort": 2126, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user", + "name": "注册用户统计", + "icon": "admin-icons-yonghutongji", + "url": "", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/user/overview/overview", + "sort": 2121, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-activity", + "name": "活跃度", + "icon": "", + "url": "/pages/uni-stat/user/activity/activity", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "icon": "", + "menu_id": "uni-stat-user-trend", + "name": "趋势分析", + "url": "/pages/uni-stat/user/trend/trend", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-retention", + "name": "留存", + "icon": "", + "url": "/pages/uni-stat/user/retention/retention", + "sort": 2124, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-comparison", + "name": "平台对比", + "icon": "", + "url": "/pages/uni-stat/user/comparison/comparison", + "sort": 2125, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-stickiness", + "name": "粘性", + "icon": "", + "url": "/pages/uni-stat/user/stickiness/stickiness", + "sort": 2126, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-analysis", + "name": "页面统计", + "icon": "admin-icons-page-ent", + "url": "", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-page-analysis", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-res", + "name": "受访页", + "icon": "", + "url": "/pages/uni-stat/page-res/page-res", + "sort": 2131, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-page-analysis", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-ent", + "name": "入口页", + "icon": "", + "url": "/pages/uni-stat/page-ent/page-ent", + "sort": 2132, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel", + "name": "渠道/场景值分析", + "icon": "admin-icons-qudaofenxi", + "url": "", + "sort": 2150, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-senceChannel", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel-scene", + "name": "场景值(小程序)", + "icon": "", + "url": "/pages/uni-stat/scene/scene", + "sort": 2151, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-senceChannel", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel-channel", + "name": "渠道(app)", + "icon": "", + "url": "/pages/uni-stat/channel/channel", + "sort": 2152, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-event-event", + "name": "自定义事件", + "icon": "admin-icons-shijianfenxi", + "url": "/pages/uni-stat/event/event", + "sort": 2160, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error", + "name": "错误统计", + "icon": "admin-icons-cuowutongji", + "url": "", + "sort": 2170, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-error", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error-js", + "name": "js报错", + "icon": "", + "url": "/pages/uni-stat/error/js/js", + "sort": 2171, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-error", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error-app", + "name": "app崩溃", + "icon": "", + "url": "/pages/uni-stat/error/app/app", + "sort": 2172, + "create_date": 1638356902516 + }, + { + "menu_id": "uni-stat-pay", + "name": "支付统计", + "icon": "uni-icons-circle", + "url": "", + "sort": 2122, + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "create_date": 1667386977981 + }, { + "menu_id": "uni-stat-pay-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/pay-order/overview/overview", + "sort": 21221, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1667387038602 + }, + { + "menu_id": "uni-stat-pay-funnel", + "name": "转换漏斗分析", + "icon": "", + "url": "/pages/uni-stat/pay-order/funnel/funnel", + "sort": 21222, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1668430092890 + }, + { + "menu_id": "uni-stat-pay-ranking", + "name": "价值用户排行", + "icon": "", + "url": "/pages/uni-stat/pay-order/ranking/ranking", + "sort": 21223, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1668430128302 + }, + { + "menu_id": "uni-stat-pay-order-list", + "name": "订单明细", + "icon": "", + "url": "/pages/uni-stat/pay-order/list/list", + "sort": 21224, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1667387078947 + } +] diff --git a/alpha/admin/pages/system/permission/add.vue b/alpha/admin/pages/system/permission/add.vue new file mode 100644 index 0000000..047cf89 --- /dev/null +++ b/alpha/admin/pages/system/permission/add.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/alpha/admin/pages/system/permission/list.vue b/alpha/admin/pages/system/permission/list.vue new file mode 100644 index 0000000..b472eea --- /dev/null +++ b/alpha/admin/pages/system/permission/list.vue @@ -0,0 +1,234 @@ + + + + + diff --git a/alpha/admin/pages/system/role/add.vue b/alpha/admin/pages/system/role/add.vue new file mode 100644 index 0000000..110a9a6 --- /dev/null +++ b/alpha/admin/pages/system/role/add.vue @@ -0,0 +1,102 @@ + + + + diff --git a/alpha/admin/pages/system/role/edit.vue b/alpha/admin/pages/system/role/edit.vue new file mode 100644 index 0000000..2bff056 --- /dev/null +++ b/alpha/admin/pages/system/role/edit.vue @@ -0,0 +1,132 @@ + + + + diff --git a/alpha/admin/pages/system/role/list.vue b/alpha/admin/pages/system/role/list.vue new file mode 100644 index 0000000..17d40a9 --- /dev/null +++ b/alpha/admin/pages/system/role/list.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/alpha/admin/pages/system/safety/list.vue b/alpha/admin/pages/system/safety/list.vue new file mode 100644 index 0000000..2e1efaf --- /dev/null +++ b/alpha/admin/pages/system/safety/list.vue @@ -0,0 +1,132 @@ + + + + diff --git a/alpha/admin/pages/system/tag/add.vue b/alpha/admin/pages/system/tag/add.vue new file mode 100644 index 0000000..0d34519 --- /dev/null +++ b/alpha/admin/pages/system/tag/add.vue @@ -0,0 +1,100 @@ + + + + diff --git a/alpha/admin/pages/system/tag/edit.vue b/alpha/admin/pages/system/tag/edit.vue new file mode 100644 index 0000000..20bfd72 --- /dev/null +++ b/alpha/admin/pages/system/tag/edit.vue @@ -0,0 +1,129 @@ + + + + diff --git a/alpha/admin/pages/system/tag/list.vue b/alpha/admin/pages/system/tag/list.vue new file mode 100644 index 0000000..a6ff831 --- /dev/null +++ b/alpha/admin/pages/system/tag/list.vue @@ -0,0 +1,241 @@ + + + diff --git a/alpha/admin/pages/system/user/add.vue b/alpha/admin/pages/system/user/add.vue new file mode 100644 index 0000000..28b2140 --- /dev/null +++ b/alpha/admin/pages/system/user/add.vue @@ -0,0 +1,193 @@ + + + + diff --git a/alpha/admin/pages/system/user/edit.vue b/alpha/admin/pages/system/user/edit.vue new file mode 100644 index 0000000..836afd4 --- /dev/null +++ b/alpha/admin/pages/system/user/edit.vue @@ -0,0 +1,338 @@ + + + + + diff --git a/alpha/admin/pages/system/user/list.vue b/alpha/admin/pages/system/user/list.vue new file mode 100644 index 0000000..c55f0a6 --- /dev/null +++ b/alpha/admin/pages/system/user/list.vue @@ -0,0 +1,462 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/channel/channel.vue b/alpha/admin/pages/uni-stat/channel/channel.vue new file mode 100644 index 0000000..ad14458 --- /dev/null +++ b/alpha/admin/pages/uni-stat/channel/channel.vue @@ -0,0 +1,476 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/channel/fieldsMap.js b/alpha/admin/pages/uni-stat/channel/fieldsMap.js new file mode 100644 index 0000000..efd0840 --- /dev/null +++ b/alpha/admin/pages/uni-stat/channel/fieldsMap.js @@ -0,0 +1,74 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和无谓的重复,固在此抽出来统一配置和处理(计算、格式化等) + * title 显示所使用名称 + * field 字段名 + * computed 计算表达式配置(需要 mapfield 函数支持) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '渠道值', + field: 'channel_code', + tooltip: '', + formatter: '', +}, { + title: '渠道名称', + field: 'channel_name', + tooltip: '', + formatter: '', +}, { + title: '新增设备', + field: 'new_device_count', + tooltip: '首次访问应用的设备数(以设备为判断标准,去重)', + value: 0 +}, { + title: '活跃设备', + field: 'active_device_count', + tooltip: '访问过应用内任意页面的总设备数(去重)', + value: 0 +}, { + title: '访问次数', + field: 'page_visit_count', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '启动次数', + field: 'app_launch_count', + tooltip: '设备从打开应用到主动关闭应用或超时退出计为一次启动', + value: 0 +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0 +}, { + title: '设备平均停留时长 ', + field: 'avg_device_time', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/活跃设备', + value: 0 +}, { + title: '跳出率', + field: 'bounceRate', + computed: 'bounce_times/app_launch_count', + formatter: '%', + tooltip: '只浏览一个页面便离开应用的次数占总启动次数的百分比', + value: 0, + contrast: 0, + fix: 2 +}, { + title: '总设备数', + field: 'total_devices', + tooltip: '从添加统计到当前选择时间的总设备数(去重)', + value: 0, +}] diff --git a/alpha/admin/pages/uni-stat/device/activity/activity.vue b/alpha/admin/pages/uni-stat/device/activity/activity.vue new file mode 100644 index 0000000..d3bf196 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/activity/activity.vue @@ -0,0 +1,442 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/device/activity/fieldsMap.js b/alpha/admin/pages/uni-stat/device/activity/fieldsMap.js new file mode 100644 index 0000000..98b0c57 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/activity/fieldsMap.js @@ -0,0 +1,48 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和无谓的重复,固在此抽出来统一配置和处理(计算、格式化等) + * title 显示所使用名称 + * field 字段名 + * computed 计算表达式配置(需要 mapfield 函数支持) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + + +export default [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '-', +}, { + title: '日活', + field: 'active_device_count', + tooltip: '选中日期当天的访问用户数', +}, { + title: '周活', + field: 'week_active_device_count', + tooltip: '选中日期所在自然周(包括选中日期在内)的访问用户数', +}, { + title: '日活/周活', + field: 'active_device_count/week_active_device_count', + computed: 'active_device_count/week_active_device_count', + tooltip: '选中日期的访问用户数占周访问用户数的百分比', + formatter: '%', +}, { + title: '月活', + field: 'month_active_device_count', + tooltip: '选中日期所在自然月(包括选中日期在内)的访问用户数', +}, { + title: '日活/月活', + field: 'active_device_count/month_active_device_count', + computed: 'active_device_count/month_active_device_count', + tooltip: '选中日期的访问用户数占月访问用户数的百分比', + formatter: '%', +}] diff --git a/alpha/admin/pages/uni-stat/device/comparison/comparison.vue b/alpha/admin/pages/uni-stat/device/comparison/comparison.vue new file mode 100644 index 0000000..3124c08 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/comparison/comparison.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/device/overview/fieldsMap.js b/alpha/admin/pages/uni-stat/device/overview/fieldsMap.js new file mode 100644 index 0000000..43569c1 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/overview/fieldsMap.js @@ -0,0 +1,122 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +const fieldsMap = [{ + value: '今天', + contrast: '昨天' +}, { + title: '新增设备', + field: 'new_device_count', + tooltip: '首次访问应用的设备数(以设备为判断标准,去重)', + value: 0, + contrast: 0 +}, { + title: '活跃设备', + field: 'active_device_count', + tooltip: '访问过应用内任意页面的总设备数,今日数据为每小时活跃设备累加(未虑重),昨日数据为全天活跃设备虑重后结果', + value: 0, + contrast: 0 +}, { + title: '访问次数', + field: 'page_visit_count', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0, + contrast: 0 +}, { + title: '启动次数', + field: 'app_launch_count', + tooltip: '设备从打开应用到主动关闭应用或超时退出计为一次启动', + value: 0, + contrast: 0 +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0, + contrast: 0, + stat: 'avg' +}, { + title: '设备平均停留时长 ', + field: 'avg_device_time', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/活跃设备', + value: 0, + contrast: 0, + stat: 'avg' +}, { + title: '跳出率', + field: 'bounceRate', + computed: 'bounce_times/app_launch_count', + formatter: '%', + tooltip: '只浏览一个页面便离开应用的次数占总启动次数的百分比', + value: 0, + contrast: 0, + fix: 2 +}, { + title: '总设备数', + field: 'total_devices', + tooltip: '从添加统计到当前选择时间的总设备数(去重)', + value: 0, + contrast: 0 +}] + +const resFieldsMap = [{ + title: '受访页', + field: 'path', + tooltip: '设备进入应用访问的所有页面,例如设备从页面1进入应用,跳转到页面2,1,2均为受访页', + formatter: '' +}, { + title: '访问次数', + field: 'visit_times', + tooltip: '访问该页面的总次数', + value: 0 + +}, { + title: '占比', + field: 'rate', + computed: 'visit_times/total_app_access', + tooltip: '页面的访问次数占所有页面访问次数的比例', + formatter: '%', +}] + +const entFieldsMap = [{ + title: '入口页', + field: 'path', + tooltip: '设备进入应用访问的第一个页面,例如设备从页面1进入应用,跳转到页面2,1为入口页,而2不是', + formatter: '' +}, { + title: '入口页次数', + field: 'entry_count', + tooltip: '访问该入口页的总次数', + value: 0 +}, { + title: '占比', + field: 'rate', + computed: 'entry_count/total_app_access', + tooltip: '页面的入口页次数占所有页面访问次数的比例', + formatter: '%' +}] + +export { + fieldsMap, + resFieldsMap, + entFieldsMap +} diff --git a/alpha/admin/pages/uni-stat/device/overview/overview.vue b/alpha/admin/pages/uni-stat/device/overview/overview.vue new file mode 100644 index 0000000..766c2d9 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/overview/overview.vue @@ -0,0 +1,564 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/device/retention/fieldsMap.js b/alpha/admin/pages/uni-stat/device/retention/fieldsMap.js new file mode 100644 index 0000000..e0a7d39 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/retention/fieldsMap.js @@ -0,0 +1,57 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +function fieldsFactory(maps = [{ + title: '新增设备', + field: 'new_device_count', + stat: 0 +}]) { + let fieldsMap = [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '-', + stat: -1 + }] + + if (maps) { + fieldsMap.push(...maps) + } + + const values = [1, 2, 3, 4, 5, 6, 7, 14, 30] + const fields = values.map(val => { + return { + title: `${val}天后`, + field: `d_${val}`, + computed: `d_${val}/${maps[0].field}`, + formatter: '%', + tooltip: '' + } + }) + + fieldsMap = fieldsMap.concat(fields) + + return fieldsMap + + +} + +export default fieldsFactory diff --git a/alpha/admin/pages/uni-stat/device/retention/retention.vue b/alpha/admin/pages/uni-stat/device/retention/retention.vue new file mode 100644 index 0000000..3021fcf --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/retention/retention.vue @@ -0,0 +1,442 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/device/stickiness/fieldsMap.js b/alpha/admin/pages/uni-stat/device/stickiness/fieldsMap.js new file mode 100644 index 0000000..29c7deb --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/stickiness/fieldsMap.js @@ -0,0 +1,48 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '名称', + field: 'name', + tooltip: '', + formatter: '', +}, { + title: '访问人数', + field: 'visit_devices', + tooltip: '访问人数(活跃用户数):访问过应用内任意页面的总用户数(去重)', + value: 0 +}, { + title: '访问人数占比', + field: 'visit_devices/total_visit_devices', + computed: 'visit_devices/total_visit_devices', + formatter: '%', +}, { + title: '访问次数', + field: 'visit_times', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '访问次数占比', + field: 'visit_times/total_visit_times', + computed: 'visit_times/total_visit_times', + formatter: '%', + tooltip: '', +}] diff --git a/alpha/admin/pages/uni-stat/device/stickiness/stickiness.vue b/alpha/admin/pages/uni-stat/device/stickiness/stickiness.vue new file mode 100644 index 0000000..6c52b07 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/stickiness/stickiness.vue @@ -0,0 +1,423 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/device/trend/fieldsMap.js b/alpha/admin/pages/uni-stat/device/trend/fieldsMap.js new file mode 100644 index 0000000..0281945 --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/trend/fieldsMap.js @@ -0,0 +1,79 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<=1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '', + stat: -1 +}, { + title: '新增设备', + field: 'new_device_count', + tooltip: '首次访问应用的设备数(以设备为判断标准,去重)', + value: 0 +}, { + title: '活跃设备', + field: 'active_device_count', + tooltip: '访问过应用内任意页面的总设备数(去重)', + value: 0 +}, { + title: '访问次数', + field: 'page_visit_count', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '启动次数', + field: 'app_launch_count', + tooltip: '设备从打开应用到主动关闭应用或超时退出计为一次启动', + value: 0 +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0, + stat: 'avg' +}, { + title: '设备平均停留时长 ', + field: 'avg_device_time', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/活跃设备', + value: 0, + stat: 'avg' +}, { + title: '跳出率', + field: 'bounceRate', + computed: 'bounce_times/app_launch_count', + formatter: '%', + tooltip: '只浏览一个页面便离开应用的次数占总启动次数的百分比', + value: 0, + contrast: 0, + fix: 2 +}, { + field: 'bounce_times', + disable: true +}, { + title: '总设备数', + field: 'total_devices', + tooltip: '从添加统计到当前选择时间的总设备数(去重)', + value: 0, +}] diff --git a/alpha/admin/pages/uni-stat/device/trend/trend.vue b/alpha/admin/pages/uni-stat/device/trend/trend.vue new file mode 100644 index 0000000..6e3b48f --- /dev/null +++ b/alpha/admin/pages/uni-stat/device/trend/trend.vue @@ -0,0 +1,425 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/error/app/app.vue b/alpha/admin/pages/uni-stat/error/app/app.vue new file mode 100644 index 0000000..ea01ccb --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/app/app.vue @@ -0,0 +1,577 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/error/app/fieldsMap.js b/alpha/admin/pages/uni-stat/error/app/fieldsMap.js new file mode 100644 index 0000000..4169364 --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/app/fieldsMap.js @@ -0,0 +1,210 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * filter 对字段过滤的类型 (暂未应用) + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +const fieldsMap = [{ + title: '报错时间', + field: 'create_time', + tooltip: '', + formatter: '', + filter: "timestamp" +}, { + title: '错误信息', + field: 'error_msg', + formatter: '', + filter: "search" +}, { + title: '原生应用包名', + field: 'package_name', + formatter: '', + filter: "search" +}, { + title: '用户端上报的应用版本号', + field: 'version', + formatter: '', + tooltip: 'manifest.json中的versionName的值', + filter: "search" +}, { + title: '平台', + field: 'platform', + formatter: '', + tooltip: '用户端上报的平台code', + filter: "search" +}, { + title: '渠道', + field: 'channel', + formatter: '', + tooltip: '用户端上报的渠道code场景值', + filter: "search" +}, { + title: '基础库版本号', + field: 'sdk_version', + formatter: '', + tooltip: '', + filter: "search" +}, { + title: '设备标识', + field: 'device_id', + formatter: '', + tooltip: '客户端携带的设备标识', + filter: "search" +}, { + title: '设备网络型号', + field: 'device_net', + formatter: '', + tooltip: '设备网络型号wifi\/3G\/4G\/', + filter: "search" +}, { + title: '系统版本', + field: 'device_os', + formatter: '', + tooltip: 'iOS平台为系统版本号,如15.1;Android平台为API等级,如30', + filter: "search" +}, { + title: '系统版本名称', + field: 'device_os_version', + formatter: '', + tooltip: 'iOS平台与os字段一致;Android平台为版本名称,如5.1.1', + filter: "search" +}, { + title: '设备供应商', + field: 'device_vendor', + formatter: '', + tooltip: '', + filter: "search" +}, { + title: '设备型号', + field: 'device_model', + formatter: '', + tooltip: '', + filter: "search" +}, { + title: '是否root', + field: 'device_is_root', + formatter: '', + tooltip: '1表示root;0表示未root', + filter: "range" +}, { + title: '系统名称', + field: 'device_os_name', + formatter: '', + tooltip: '用于区别Android和鸿蒙,仅Android支持', + filter: "search" +}, { + title: '设备电池电量', + field: 'device_batt_level', + formatter: '', + tooltip: '取值范围0-100,仅Android支持', + filter: "range" +}, { + title: '电池温度', + field: 'device_batt_temp', + formatter: '', + tooltip: '仅Android支持', + filter: "search" +}, { + title: '系统已使用内存', + field: 'device_memory_use_size', + formatter: '', + tooltip: '单位为Byte,仅Android支持', + filter: "range" +}, { + title: '系统总内存', + field: 'device_memory_total_size', + formatter: '', + tooltip: '单位为Byte,仅Android支持', + filter: "range" +}, { + title: '系统磁盘已使用大小', + field: 'device_disk_use_size', + formatter: '', + tooltip: '单位为Byte,仅Android支持', + filter: "range" +}, { + title: '系统磁盘总大小', + field: 'device_disk_total_size', + formatter: '', + tooltip: '单位为Byte,仅Android支持', + filter: "range" +}, { + title: '设备支持的CPU架构', + field: 'device_abis', + formatter: '', + tooltip: '多个使用,分割,如arm64-v8a,armeabi-v7a,armeabi,仅Android支持', + filter: "search" +}, { + title: '运行的app个数', + field: 'app_count', + formatter: '', + tooltip: '包括运行的uni小程序数目,独立App时值为1', + filter: "range" +}, { + title: 'APP使用的内存量', + field: 'app_use_memory_size', + formatter: '', + tooltip: '单位为Byte', + filter: "range" +}, { + title: '运行应用的个数', + field: 'app_count', + formatter: '', + filter: "range" +}, { + title: '打开 Webview 的个数', + field: 'app_webview_count', + formatter: '', + filter: "range" +}, { + title: 'APP使用时长', + field: 'app_use_duration', + formatter: '', + tooltip: '单位为s', + filter: "range" +}, { + title: '是否前台运行', + field: 'app_run_fore', + formatter: '', + tooltip: '1表示前台运行,0表示后台运行', + filter: "search" +}, { + title: '原生应用版本名称', + field: 'package_version', + formatter: '', + tooltip: 'Android的apk版本名称;iOS的ipa版本名称', + filter: "search" +}, +// { +// title: 'APP使用的内存量', +// field: 'app_use_memory_size', +// formatter: '', +// tooltip: '单位为Byte', +// filter: "search" +// }, +{ + title: '页面url', + field: 'page_url', + formatter: '', + filter: "search" +}] + +export { + fieldsMap +} diff --git a/alpha/admin/pages/uni-stat/error/js/detail.vue b/alpha/admin/pages/uni-stat/error/js/detail.vue new file mode 100644 index 0000000..9ed9e65 --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/js/detail.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/error/js/fieldsMap.js b/alpha/admin/pages/uni-stat/error/js/fieldsMap.js new file mode 100644 index 0000000..c015d5a --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/js/fieldsMap.js @@ -0,0 +1,69 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +const fieldsMap = [{ + title: '最近发生时间', + field: 'last_time', + tooltip: '', + formatter: '', +}, { + title: '错误次数', + field: 'count', + tooltip: '相同错误在某时间段内发生的次数', +}, { + title: '错误占比', + computed: 'count/total_count', + field: 'count/total_count', + formatter: '%', + tooltip: '某个错误发生的次数/总错误数', +}, { + title: '平台', + field: 'platform', + formatter: '', +}, { + title: '平台版本号', + field: 'version', + tooltip: '原生平台为客户端 SDK 版本号;小程序平台为微信、支付宝、百度等应用的版本号', + formatter: '', +}, { + title: '错误信息', + field: 'msg', + formatter: '', +}] + +const popupFieldsMap = [{ + title: '创建时间', + field: 'create_time', + formatter: '', +}, { + title: '客户端操作系统', + field: 'os', + formatter: '', +}, { + title: '客户端 user-agent 信息', + field: 'ua', + formatter: '', +}] + +export { + fieldsMap, + popupFieldsMap, +} diff --git a/alpha/admin/pages/uni-stat/error/js/js.vue b/alpha/admin/pages/uni-stat/error/js/js.vue new file mode 100644 index 0000000..4b746e0 --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/js/js.vue @@ -0,0 +1,1020 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/error/js/uploadTask.vue b/alpha/admin/pages/uni-stat/error/js/uploadTask.vue new file mode 100644 index 0000000..46061d0 --- /dev/null +++ b/alpha/admin/pages/uni-stat/error/js/uploadTask.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/event/event.vue b/alpha/admin/pages/uni-stat/event/event.vue new file mode 100644 index 0000000..148bcf3 --- /dev/null +++ b/alpha/admin/pages/uni-stat/event/event.vue @@ -0,0 +1,271 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/event/fieldsMap.js b/alpha/admin/pages/uni-stat/event/fieldsMap.js new file mode 100644 index 0000000..2412a60 --- /dev/null +++ b/alpha/admin/pages/uni-stat/event/fieldsMap.js @@ -0,0 +1,43 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '创建时间', + field: 'create_time', + tooltip: '', + formatter: '' +}, { + title: '事件ID', + field: 'event_key', + stat: -1 +}, { + title: '事件参数', + field: 'param', + tooltip: '', +}, { + title: '平台', + field: 'platform', + tooltip: '', +}, { + title: '设备标识', + field: 'device_id', + tooltip: '' +}] diff --git a/alpha/admin/pages/uni-stat/page-ent/fieldsMap.js b/alpha/admin/pages/uni-stat/page-ent/fieldsMap.js new file mode 100644 index 0000000..e0e885c --- /dev/null +++ b/alpha/admin/pages/uni-stat/page-ent/fieldsMap.js @@ -0,0 +1,64 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '入口页', + field: 'path', + tooltip: '设备进入应用访问的第一个页面,例如设备从页面1进入应用,跳转到页面2,1为入口页,而2不是', +}, { + title: '页面名称', + field: 'title', +}, { + title: '访问次数', + field: 'visit_times', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '入口页次数', + field: 'entry_count', + tooltip: '作为访问会话第一个访问页面(即着陆页)的次数', + value: 0 +}, { + title: '跳出率', + field: 'bounce_rate', + formatter: '%%', + tooltip: '只浏览一个页面便离开应用的次数占总启动次数的百分比', + value: 0, + stat: 'avg' +}, { + title: '访问总时长', + field: 'duration', + disabled: true, +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + computed: 'duration/visit_times', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0 +}, { + title: '设备平均停留时长 ', + field: 'avg_user_time', + computed: 'duration/visit_devices', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/访问设备数', + value: 0 +}, ] diff --git a/alpha/admin/pages/uni-stat/page-ent/page-ent.vue b/alpha/admin/pages/uni-stat/page-ent/page-ent.vue new file mode 100644 index 0000000..99af00f --- /dev/null +++ b/alpha/admin/pages/uni-stat/page-ent/page-ent.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/page-res/fieldsMap.js b/alpha/admin/pages/uni-stat/page-res/fieldsMap.js new file mode 100644 index 0000000..9b217c4 --- /dev/null +++ b/alpha/admin/pages/uni-stat/page-res/fieldsMap.js @@ -0,0 +1,73 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '受访页', + field: 'path', + tooltip: '设备进入应用访问的所有页面,例如设备从页面1进入应用,跳转到页面2,1,2均为受访页', + stat: -1 +}, { + title: '页面名称', + field: 'title', + stat: -1 +}, +{ + title: '访问次数', + field: 'visit_times', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问;', + value: 0 +}, { + title: '退出页次数', + field: 'exit_times', + tooltip: '作为访问会话最后一个访问页面(即离开页)的次数', + value: 0 +}, { + title: '退出率', + field: 'exitRate', + computed: 'exit_times/visit_times', + formatter: '%', + tooltip: '在此页面,选择离开应用占此页面访问次数的比例', + // value: 0, + stat: -1 +}, { + title: '访问总时长', + field: 'duration', + disabled: true, +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + computed: 'duration/visit_times', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0 +}, { + title: '设备平均停留时长', + field: 'avg_user_time', + computed: 'duration/visit_devices', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/访问设备数', + value: 0 +}, { + title: '分享次数', + field: 'share_count', + tooltip: '页面被分享成功的次数', + value: 0 +}] diff --git a/alpha/admin/pages/uni-stat/page-res/page-res.vue b/alpha/admin/pages/uni-stat/page-res/page-res.vue new file mode 100644 index 0000000..9a5d7cd --- /dev/null +++ b/alpha/admin/pages/uni-stat/page-res/page-res.vue @@ -0,0 +1,364 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/components/test.vue b/alpha/admin/pages/uni-stat/pay-order/components/test.vue new file mode 100644 index 0000000..0a33844 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/components/test.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/funnel/components/funnelChart.vue b/alpha/admin/pages/uni-stat/pay-order/funnel/components/funnelChart.vue new file mode 100644 index 0000000..fde1a8d --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/funnel/components/funnelChart.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/funnel/components/trendChart.vue b/alpha/admin/pages/uni-stat/pay-order/funnel/components/trendChart.vue new file mode 100644 index 0000000..5953658 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/funnel/components/trendChart.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/funnel/fieldsMap.js b/alpha/admin/pages/uni-stat/pay-order/funnel/fieldsMap.js new file mode 100644 index 0000000..fec7214 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/funnel/fieldsMap.js @@ -0,0 +1,30 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ +const fieldsMap = [ + { title: '活跃设备数', field: 'activity_device_count', tooltip: '统计时间内,访问设备数,一台设备多次访问被计为一台(包含未登录的用户)。', formatter: ',', value: 0, contrast: 0, stat: 'sum' }, + { title: '活跃用户数', field: 'activity_user_count', tooltip: '活跃用户数:统计时间内,访问人数,一人多次访问被计为一人(只统计已登录的用户)。', formatter: ',', value: 0, contrast: 0, stat: 'sum' }, + { title: '支付用户数', field: 'pay_user_count', tooltip: '统计时间内,成功支付的人数(不剔除退款订单)(只统计已登录的用户)。', formatter: ',', value: 0, contrast: 0, stat: 'sum' }, +] + + +export { + fieldsMap, +} diff --git a/alpha/admin/pages/uni-stat/pay-order/funnel/funnel.vue b/alpha/admin/pages/uni-stat/pay-order/funnel/funnel.vue new file mode 100644 index 0000000..170d074 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/funnel/funnel.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/list/list.vue b/alpha/admin/pages/uni-stat/pay-order/list/list.vue new file mode 100644 index 0000000..82e324e --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/list/list.vue @@ -0,0 +1,514 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelToday.vue b/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelToday.vue new file mode 100644 index 0000000..f922e28 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelToday.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelTotal.vue b/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelTotal.vue new file mode 100644 index 0000000..cc2e4ff --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/overview/components/statPanelTotal.vue @@ -0,0 +1,317 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/overview/components/trendChart.vue b/alpha/admin/pages/uni-stat/pay-order/overview/components/trendChart.vue new file mode 100644 index 0000000..f923501 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/overview/components/trendChart.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/overview/fieldsMap.js b/alpha/admin/pages/uni-stat/pay-order/overview/fieldsMap.js new file mode 100644 index 0000000..c08ba62 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/overview/fieldsMap.js @@ -0,0 +1,77 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * multiple 显示的倍数,只对number类型生效,如原值为100,multiple=0.01 则显示成1 + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +const fieldsGroupMap = [ + { + title: '订单金额', group: "total_amount", + list:[ + { title: '下单金额', field: 'create_total_amount', tooltip: '下单:统计时间内,下单金额(包含未支付订单和退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, + { title: '收款金额', field: 'pay_total_amount', tooltip: '收款:统计时间内,成功支付的订单金额(包含退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, + { title: '退款金额', field: 'refund_total_amount', tooltip: '退款:统计时间内,发生退款的金额。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, multiple:0.01 }, + ] + }, + { + title: '订单数量', group: "order_count", + list:[ + { title: '下单数量', field: 'create_order_count', tooltip: '下单:统计时间内,成功下单的订单笔数(包含未支付订单和退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '收款数量', field: 'pay_order_count', tooltip: '收款:统计时间内,成功支付的订单数(包含退款订单)。', formatter: '', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '退款数量', field: 'refund_order_count', tooltip: '退款:统计时间内,发生退款的订单数。', formatter: '', value: "-", contrast: 0, stat: 'sum', fix:0 }, + ] + }, + { + title: '用户数量', group: "user_count", + list:[ + { title: '下单用户数', field: 'create_user_count', tooltip: '下单:统计时间内,成功下单的客户数(包含未支付订单和退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '收款用户数', field: 'pay_user_count', tooltip: '收款:统计时间内,成功支付的用户数(包含退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '退款用户数', field: 'refund_user_count', tooltip: '退款:统计时间内,发生退款的用户数。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0 }, + ] + }, + { + title: '设备数量', group: "device_count", + list:[ + { title: '下单设备数', field: 'create_device_count', tooltip: '下单:统计时间内,成功下单的设备数(包含未支付订单和退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '收款设备数', field: 'pay_device_count', tooltip: '收款:统计时间内,成功支付的设备数(包含退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '退款设备数', field: 'refund_device_count', tooltip: '退款:统计时间内,发生退款的设备数。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:0 }, + ] + }, +]; + +let fieldsMap = []; + +fieldsGroupMap.map((item1, index1) => { + item1.list.map((item2, index2) => { + fieldsMap.push(item2); + }); +}); + + +const statPanelTodayFieldsMap = [ + { title: '下单金额(GMV)', field: 'create_total_amount', tooltip: '统计时间内,下单金额(包含未支付订单和退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, + { title: '收款金额(GPV)', field: 'pay_total_amount', tooltip: '统计时间内,成功支付的订单金额(包含退款订单)。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, + //{ title: '支付订单数量', field: 'pay_order_count', tooltip: '统计时间内,成功支付的订单数(包含退款订单)。', formatter: '', value: "-", contrast: 0, stat: 'sum', fix:0, trendChart: true }, + { title: '退款金额', field: 'refund_total_amount', tooltip: '统计时间内,发生退款的金额。', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, + { title: '实收金额', field: 'actual_total_amount', tooltip: '实收金额=收款金额-退款金额', formatter: ',', value: "-", contrast: 0, stat: 'sum', fix:2, trendChart: true, multiple:0.01 }, +]; + +export { + fieldsMap, + fieldsGroupMap, + statPanelTodayFieldsMap +} diff --git a/alpha/admin/pages/uni-stat/pay-order/overview/overview.vue b/alpha/admin/pages/uni-stat/pay-order/overview/overview.vue new file mode 100644 index 0000000..89c2b46 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/overview/overview.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/pay-order/ranking/ranking.vue b/alpha/admin/pages/uni-stat/pay-order/ranking/ranking.vue new file mode 100644 index 0000000..04a9055 --- /dev/null +++ b/alpha/admin/pages/uni-stat/pay-order/ranking/ranking.vue @@ -0,0 +1,348 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/scene/fieldsMap.js b/alpha/admin/pages/uni-stat/scene/fieldsMap.js new file mode 100644 index 0000000..6197e6d --- /dev/null +++ b/alpha/admin/pages/uni-stat/scene/fieldsMap.js @@ -0,0 +1,84 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * disabled 是否用于展示,默认为 true + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '场景值', + field: 'channel_code', + tooltip: '', + formatter: '', +}, { + title: '场景名称', + field: 'channel_name', + tooltip: '', + formatter: '', +}, { + title: '新增设备', + field: 'new_device_count', + tooltip: '首次访问应用的设备数(以设备为判断标准,去重)', + value: 0 +}, { + title: '活跃设备', + field: 'active_device_count', + tooltip: '访问过应用内任意页面的总设备数(去重)', + value: 0 +}, { + title: '访问次数', + field: 'page_visit_count', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '启动次数', + field: 'app_launch_count', + tooltip: '设备从打开应用到主动关闭应用或超时退出计为一次启动', + value: 0 +}, { + title: '次均停留时长', + field: 'avg_device_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0, + stat: 'avg' +}, { + title: '设备平均停留时长 ', + field: 'avg_device_time', + formatter: ':', + tooltip: '平均每个设备停留在应用内的总时长,即应用停留总时长/活跃设备', + value: 0, + stat: 'avg' +}, { + title: '跳出率', + field: 'bounceRate', + computed: 'bounce_times/app_launch_count', + formatter: '%', + tooltip: '只浏览一个页面便离开应用的次数占总启动次数的百分比', + value: 0, + contrast: 0, + fix: 2 +}, { + field: 'bounce_times', + disable: true +}, { + title: '总设备数', + field: 'total_devices', + tooltip: '从添加统计到当前选择时间的总设备数(去重)', + value: 0, +}] diff --git a/alpha/admin/pages/uni-stat/scene/scene.vue b/alpha/admin/pages/uni-stat/scene/scene.vue new file mode 100644 index 0000000..fb3cdf0 --- /dev/null +++ b/alpha/admin/pages/uni-stat/scene/scene.vue @@ -0,0 +1,382 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/activity/activity.vue b/alpha/admin/pages/uni-stat/user/activity/activity.vue new file mode 100644 index 0000000..4438652 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/activity/activity.vue @@ -0,0 +1,447 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/activity/fieldsMap.js b/alpha/admin/pages/uni-stat/user/activity/fieldsMap.js new file mode 100644 index 0000000..2f40d61 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/activity/fieldsMap.js @@ -0,0 +1,50 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ +export default [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '-', +}, { + title: '日活', + field: 'active_user_count', + tooltip: '选中日期当天的访问用户数', +}, { + title: '周活', + field: 'week_active_user_count', + tooltip: '选中日期所在自然周(包括选中日期在内)的访问用户数', +}, { + title: '日活/周活', + field: 'active_user_count/week_active_user_count', + computed: 'active_user_count/week_active_user_count', + tooltip: '选中日期的访问用户数占周访问用户数的百分比', + formatter: '%', +}, { + title: '月活', + field: 'month_active_user_count', + tooltip: '选中日期所在自然月(包括选中日期在内)的访问用户数', +}, { + title: '日活/月活', + field: 'active_user_count/month_active_user_count', + computed: 'active_user_count/month_active_user_count', + tooltip: '选中日期的访问用户数占月访问用户数的百分比', + formatter: '%', +}] diff --git a/alpha/admin/pages/uni-stat/user/comparison/comparison.vue b/alpha/admin/pages/uni-stat/user/comparison/comparison.vue new file mode 100644 index 0000000..03cfe06 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/comparison/comparison.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/overview/fieldsMap.js b/alpha/admin/pages/uni-stat/user/overview/fieldsMap.js new file mode 100644 index 0000000..c6f6727 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/overview/fieldsMap.js @@ -0,0 +1,102 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ +const fieldsMap = [{ + value: '今天', + contrast: '昨天', + // stat: -1 +}, { + title: '新增用户', + field: 'new_user_count', + tooltip: '首次访问应用的用户数(以用户为判断标准,去重)', + value: 0, + contrast: 0 +}, { + title: '活跃用户', + field: 'active_user_count', + tooltip: '访问过应用内任意页面的总用户数,今日数据为每小时活跃用户累加(未虑重),昨日数据为全天活跃用户虑重后结果。', + value: 0, + contrast: 0 +}, { + title: '次均停留时长', + field: 'avg_user_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0, + contrast: 0, + stat: 'avg' +}, { + title: '人均停留时长 ', + field: 'avg_user_time', + formatter: ':', + tooltip: '平均每个用户停留在应用内的总时长,即应用停留总时长/活跃用户', + value: 0, + contrast: 0, + stat: 'avg' +}, { + title: '总用户数', + field: 'total_users', + tooltip: '从添加统计到当前选择时间的总用户数(去重)', + value: 0, + contrast: 0 +}] + +const resFieldsMap = [{ + title: '受访页', + field: 'path', + tooltip: '用户进入应用访问的所有页面,例如用户从页面1进入应用,跳转到页面2,1,2均为受访页', + formatter: '' +}, { + title: '访问次数', + field: 'visit_times', + tooltip: '访问该页面的总次数', + value: 0 + +}, { + title: '占比', + field: 'rate', + computed: 'visit_times/total_app_access', + tooltip: '某个页面的访问次数占所有页面访问次数的比例', + formatter: '%', +}] + +const entFieldsMap = [{ + title: '入口页', + field: 'path', + tooltip: '用户进入应用访问的第一个页面,例如用户从页面1进入应用,跳转到页面2,1为入口页,而2不是', + formatter: '' +}, { + title: '访问次数', + field: 'entry_count', + tooltip: '访问该页面的总次数', + value: 0 +}, { + title: '占比', + field: 'rate', + computed: 'entry_count/total_app_access', + tooltip: '某个页面的访问次数占所有页面访问次数的比例', + formatter: '%' +}] + +export { + fieldsMap, + resFieldsMap, + entFieldsMap +} diff --git a/alpha/admin/pages/uni-stat/user/overview/overview.vue b/alpha/admin/pages/uni-stat/user/overview/overview.vue new file mode 100644 index 0000000..d375257 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/overview/overview.vue @@ -0,0 +1,417 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/retention/fieldsMap.js b/alpha/admin/pages/uni-stat/user/retention/fieldsMap.js new file mode 100644 index 0000000..588dae3 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/retention/fieldsMap.js @@ -0,0 +1,56 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ +function fieldsFactory(maps = [{ + title: '新增用户', + field: 'new_user_count', + stat: 0 +}]) { + let fieldsMap = [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '-', + stat: -1 + }] + + if (maps) { + fieldsMap.push(...maps) + } + + const values = [1, 2, 3, 4, 5, 6, 7, 14, 30] + const fields = values.map(val => { + return { + title: `${val}天后`, + field: `d_${val}`, + computed: `d_${val}/${maps[0].field}`, + formatter: '%', + tooltip: '' + } + }) + + fieldsMap = fieldsMap.concat(fields) + + return fieldsMap + + +} + +export default fieldsFactory diff --git a/alpha/admin/pages/uni-stat/user/retention/retention.vue b/alpha/admin/pages/uni-stat/user/retention/retention.vue new file mode 100644 index 0000000..d783a21 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/retention/retention.vue @@ -0,0 +1,439 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/stickiness/fieldsMap.js b/alpha/admin/pages/uni-stat/user/stickiness/fieldsMap.js new file mode 100644 index 0000000..c893f70 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/stickiness/fieldsMap.js @@ -0,0 +1,48 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ + +export default [{ + title: '名称', + field: 'name', + tooltip: '', + formatter: '', +}, { + title: '访问人数', + field: 'visit_users', + tooltip: '访问人数(活跃用户数):访问过应用内任意页面的总用户数(去重)', + value: 0 +}, { + title: '访问人数占比', + field: 'visit_users/total_visit_users', + computed: 'visit_users/total_visit_users', + formatter: '%', +}, { + title: '访问次数', + field: 'visit_times', + tooltip: '访问过应用内任意页面总次数,多个页面之间跳转、同一页面的重复访问计为多次访问', + value: 0 +}, { + title: '访问次数占比', + field: 'visit_times/total_visit_times', + computed: 'visit_times/total_visit_times', + formatter: '%', + tooltip: '', +}] diff --git a/alpha/admin/pages/uni-stat/user/stickiness/stickiness.vue b/alpha/admin/pages/uni-stat/user/stickiness/stickiness.vue new file mode 100644 index 0000000..d77eb8c --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/stickiness/stickiness.vue @@ -0,0 +1,419 @@ + + + + + diff --git a/alpha/admin/pages/uni-stat/user/trend/fieldsMap.js b/alpha/admin/pages/uni-stat/user/trend/fieldsMap.js new file mode 100644 index 0000000..6a9db46 --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/trend/fieldsMap.js @@ -0,0 +1,56 @@ +/** + * 页面上的数据都来自数据库,且多处 ui 消费,页面直接使用字段会造成耦合和冗余,固在此抽出来统一配置(clientdb 查询方法、概念文字提示等)和处理(对值再计算、格式化等) + * title 显示所使用名称 + * field 数据库字段名 + * computed 计算表达式配置,只支持除法计算(需要 mapfield 函数支持,也可自行扩展) + * tooltip 对字段解释的提示文字 + * formatter 数字格式化的配置,省缺为 ',' + * '' 空字符串 则表示不格式化 + * ',' 数字格式,例:1000 格式为 1,000 + * '%' 百分比格式 例:0.1 格式为 10% + * ':' 时分秒格式 例:90 格式为 00:01:30 + * '-' 日期格式 例:1655196831390(值需为时间戳) 格式为 2022-06-14 + * stat 对字段做 groupField 时需使用的数据库计算方法,省缺为 'sum' + * 'sum' 表示对字段做求和运算 + * 'avg' 表示对字段做平均运算 + * '-1' 表示不对字段做运算 + * fix 数字保留几位小数,>1 默认不保留小数,<1 默认保留两位小数 + * value 默认值 (仅用于 uni-stat-panel 组件) todo: 可移除 + * contrast 对比值 (仅用于 uni-stat-panel 组件) todo: 可移除 + */ +export default [{ + title: '日期', + field: 'start_time', + tooltip: '', + formatter: '', + stat: -1 +}, { + title: '新增用户', + field: 'new_user_count', + tooltip: '首次访问应用的用户数(以设备为判断标准,去重)', + value: 0 +}, { + title: '活跃用户', + field: 'active_user_count', + tooltip: '访问过应用内任意页面的总用户数(去重)', + value: 0 +}, { + title: '次均停留时长', + field: 'avg_user_session_time', + formatter: ':', + tooltip: '平均每次打开应用停留在应用内的总时长,即应用停留总时长/启动次数', + value: 0, + stat: 'avg' +}, { + title: '人均停留时长 ', + field: 'avg_user_time', + formatter: ':', + tooltip: '平均每个用户停留在应用内的总时长,即应用停留总时长/活跃用户', + value: 0, + stat: 'avg' +}, { + title: '总用户数', + field: 'total_users', + tooltip: '从添加统计到当前选择时间的总用户数(去重)', + value: 0, +}] diff --git a/alpha/admin/pages/uni-stat/user/trend/trend.vue b/alpha/admin/pages/uni-stat/user/trend/trend.vue new file mode 100644 index 0000000..16804ff --- /dev/null +++ b/alpha/admin/pages/uni-stat/user/trend/trend.vue @@ -0,0 +1,426 @@ + + + + + diff --git a/alpha/admin/postcss.config.js b/alpha/admin/postcss.config.js new file mode 100644 index 0000000..6c53a17 --- /dev/null +++ b/alpha/admin/postcss.config.js @@ -0,0 +1,44 @@ +if (process.env.VITE_ROOT_DIR) { // vite + const { + uniPostcssPlugin, + parseRpx2UnitOnce, + } = require('@dcloudio/uni-cli-shared') + module.exports = { + plugins: [ + uniPostcssPlugin( + Object.assign({ + page: process.env.UNI_PLATFORM === 'h5' ? 'uni-page-body' : 'body' + }, + parseRpx2UnitOnce(process.env.UNI_INPUT_DIR) + ) + ), + require('autoprefixer')(), + ], + } +} else { + + const path = require('path') + module.exports = { + parser: 'postcss-comment', + plugins: { + 'postcss-import': { + resolve(id, basedir, importOptions) { + if (id.startsWith('~@/')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3)) + } else if (id.startsWith('@/')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2)) + } else if (id.startsWith('/') && !id.startsWith('//')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1)) + } + return id + } + }, + 'autoprefixer': { + overrideBrowserslist: ["> 1%", "last 2 versions", "not dead"], + remove: process.env.UNI_PLATFORM !== 'h5', + ignoreUnknownVersions: true + }, + '@dcloudio/vue-cli-plugin-uni/packages/postcss': {} + } + } +} diff --git a/alpha/admin/static/admin-icons.ttf b/alpha/admin/static/admin-icons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8b74e537286cc1f3fce505e09322454a79ef9731 GIT binary patch literal 18340 zcmd^nd3+n?o%cL5(u_vZj5HdJPV2TLOSUXqk|jHKY$tZ&B;-CzID(Vdu|pDv93=^t zIg-KxEfo5)W$8(1OIr#b%0k-(maC<73%hOUu|4Q^DI&0JOLw@UYc>>1{h`%w;Qcnd zU$$fK`2M7O*)E1*zsoSz`*!U)I{DZ4y>~Ce*nZA1y{}G9jPFb&A6tXE|A0`PLWb=* z%U>Y{_tTx@y$H2y5Vra9;R^%^h^UNFEJ5FOi81CoH4XAhiZm@K~vjO{c-ut;_|4rKZ zr`plHKb4Pua5Dd8866+%Ix`Q<*YY#^jyB3U`TxUtq8j!NkjyY0W)t>3a}UVBAeZh& z2c9@ZwjMVi~1+(->Ns>l;7O-=JcEU-@NtIz^NNfefrdcZ*6+Vc^XjC?31gD zMxTD8&$ect{mnivs$XXGc@z4)=l|X(X8iy1k6``gXCt%K_*}-&&(7v&k}*G1%pT*j zkJ-oU|8GAG<6#nvz<9B%gprsi_FH7ajGxIdai$$d8w12=m@H1B!X%kiCdG6zGC;e? z1ehS>Vj@g|sWRP6iSYq1+HhJ5lV&tV1tzwDQn{Hju&j&8Gd)ZVAWm`T|Mx$GMzJTG z+kjnp12{kfPJ?+PW(J%KQwI*vfD>ZsD5n8u#ngdEWGyn>ide96^9M6y$02xdj^Q3{2gL=vg zfEK3SW(G<->$E)rAc(2w%>Y

cDpzDBjnxei{H@Ouf$xfHbDwZw9~|Qy(w`ppU69 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/static/logo.png b/alpha/admin/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..710f9246e7f27c03d72858b39e9ab57d1fa36b5c GIT binary patch literal 22521 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/store/constants.js b/alpha/admin/store/constants.js new file mode 100644 index 0000000..7f08993 --- /dev/null +++ b/alpha/admin/store/constants.js @@ -0,0 +1,5 @@ +/** uni-admin 缓存键名 */ +export const uniAdminCacheKey = { + theme: "uni-admin-theme", // 主题 + +} diff --git a/alpha/admin/store/index.js b/alpha/admin/store/index.js new file mode 100644 index 0000000..eb9a0ec --- /dev/null +++ b/alpha/admin/store/index.js @@ -0,0 +1,41 @@ +import app from './modules/app.js' +import error from './modules/error.js' +import user from './modules/user.js' + +// const modulesFiles = require.context('./modules', true, /\.js$/) +// const modules = modulesFiles.keys().reduce((modules, modulePath) => { +// const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') +// const value = modulesFiles(modulePath) +// modules[moduleName] = value.default +// return modules +// }, {}) + +// #ifndef VUE3 +import Vue from 'vue' +import Vuex from 'vuex' +Vue.use(Vuex) +const store = new Vuex.Store({ + modules: { + app, + error, + user + } +}) +// #endif + +// #ifdef VUE3 +import { + createStore +} from 'vuex' +// todo ssr +const store = createStore({ + modules: { + app, + error, + user + } +}) +// #endif + + +export default store diff --git a/alpha/admin/store/modules/app.js b/alpha/admin/store/modules/app.js new file mode 100644 index 0000000..b7101d8 --- /dev/null +++ b/alpha/admin/store/modules/app.js @@ -0,0 +1,67 @@ +import { + uniAdminCacheKey +} from '../constants.js' + +// #ifndef VUE3 +const statConfig = require('uni-stat-config').default || require('uni-stat-config'); +// #endif + +export default { + namespaced: true, + state: { + inited: false, + navMenu: [], + routes: [], + theme: uni.getStorageSync(uniAdminCacheKey.theme) || 'default', + // #ifndef VUE3 + appName: process.env.VUE_APP_NAME || '', + appid: statConfig && statConfig.appid || '', + // #endif + // #ifdef VUE3 + appName: process.env.UNI_APP_NAME || '', + appid: process.env.UNI_APP_ID || '' + // #endif + }, + mutations: { + SET_APP_NAME: (state, appName) => { + state.appName = appName + }, + SET_NAV_MENU: (state, navMenu) => { + state.inited = true + state.navMenu = navMenu + }, + SET_ROUTES: (state, routes) => { + state.routes = routes + }, + SET_THEME: (state, theme) => { + // #ifdef H5 + document + .getElementsByTagName('body')[0] + .setAttribute('data-theme', theme) + // #endif + uni.setStorageSync(uniAdminCacheKey.theme, theme) + state.theme = theme + } + }, + actions: { + init({ + commit, + dispatch + }) { + // 初始化获取用户信息 + dispatch('user/getUserInfo', null, { + root: true + }) + }, + setAppName({ + commit + }, appName) { + commit('SET_APP_NAME', appName) + }, + setRoutes({ + commit + }, routes) { + commit('SET_ROUTES', routes) + } + } +} diff --git a/alpha/admin/store/modules/error.js b/alpha/admin/store/modules/error.js new file mode 100644 index 0000000..dded325 --- /dev/null +++ b/alpha/admin/store/modules/error.js @@ -0,0 +1,33 @@ +export default { + namespaced: true, + state: { + logs: [] + }, + mutations: { + ADD_ERROR_LOG: (state, log) => { + state.logs.unshift(log) + }, + CLEAR_ERROR_LOG: (state) => { + state.logs.splice(0) + } + }, + actions: { + add({ + commit + }, log) { + if (!log.route) { + const pages = getCurrentPages() + if (pages.length) { + log.route = pages[pages.length - 1].route + } + } + log.route = '/' + (log.route || '') + commit('ADD_ERROR_LOG', log) + }, + clear({ + commit + }) { + commit('CLEAR_ERROR_LOG') + } + } +} diff --git a/alpha/admin/store/modules/user.js b/alpha/admin/store/modules/user.js new file mode 100644 index 0000000..3c546ac --- /dev/null +++ b/alpha/admin/store/modules/user.js @@ -0,0 +1,23 @@ +import * as uniIdPagesStore from '@/uni_modules/uni-id-pages/common/store' +export default { + namespaced: true, + state: {}, + mutations: {}, + actions: { + getUserInfo ({commit}) { + const db = uniCloud.database() + return db + .collection('uni-id-users') + .where('_id==$cloudEnv_uid') + .field('username,nickname,mobile,email,role,permission') + .get() + .then(({result}) => { + const [userInfo] = result.data + + uniIdPagesStore.mutations.setUserInfo(userInfo, true) + + return Promise.resolve(userInfo) + }) + } + } +} diff --git a/alpha/admin/template.h5.html b/alpha/admin/template.h5.html new file mode 100644 index 0000000..ba3e44b --- /dev/null +++ b/alpha/admin/template.h5.html @@ -0,0 +1,27 @@ + + + + + + + <%= htmlWebpackPlugin.options.title %> + + + + + + + +

+ + + + \ No newline at end of file diff --git a/alpha/admin/uni.scss b/alpha/admin/uni.scss new file mode 100644 index 0000000..4c7bc24 --- /dev/null +++ b/alpha/admin/uni.scss @@ -0,0 +1,102 @@ +/** + * 这里是uni-app内置的常用样式变量 + * + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App + * + */ + +/** + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 + * + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 + */ + +/* 颜色变量 */ + +@import '@/uni_modules/uni-scss/variables.scss'; + +/* 行为相关颜色 */ +$uni-color-primary: #2979ff; +$uni-color-success: #18bc37; +$uni-color-warning: #f3a73f; +$uni-color-error: #e43d33; + +$themes: ( + default: ( + primary-color: $uni-color-primary, + success-color: $uni-color-success, + warn-color: $uni-color-error, + warning-color: $uni-color-warning, + error-color: $uni-color-error + ), + green: ( + primary-color: #42b983, + success-color: $uni-color-success, + warn-color: $uni-color-error, + warning-color: $uni-color-warning, + error-color: $uni-color-error + ) +); +/* 兼容 uni-ui 相关颜色 */ +$uni-primary: $uni-color-primary; +$uni-success: $uni-color-success; +$uni-warning: $uni-color-warning; +$uni-error: $uni-color-error; + +/* 文字基本颜色 */ +$uni-text-color: #333; // 基本色 +$uni-text-color-inverse: #fff; // 反色 +$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; +/* 背景颜色 */ +$uni-bg-color: #ffffff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1; // 点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色 +/* 边框颜色 */ +$uni-border-color: #c8c7cc; +$uni-table-border-color: #e6ebf5; + +/* 尺寸变量 */ +/* 文字尺寸 */ +$uni-font-size-sm: 12px; +$uni-font-size-base: 14px; +$uni-font-size-lg: 16px; +/* 图片尺寸 */ +$uni-img-size-sm: 20px; +$uni-img-size-base: 26px; +$uni-img-size-lg: 40px; +/* Border Radius */ +$uni-border-radius-sm: 3px; +$uni-border-radius-base: 5px; +$uni-border-radius-lg: 10px; +$uni-border-radius-circle: 50%; +/* 水平间距 */ +$uni-spacing-row-sm: 10px; +$uni-spacing-row-base: 15px; +$uni-spacing-row-lg: 20px; +/* 垂直间距 */ +$uni-spacing-col-sm: 5px; +$uni-spacing-col-base: 10px; +$uni-spacing-col-lg: 15px; +/* 透明度 */ +$uni-opacity-disabled: 0.3; +// 组件禁用态的透明度 +/* 文章场景相关 */ +$uni-color-title: #2c405a; // 文章标题颜色 +$uni-font-size-title: 20px; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle: 18px; +$uni-color-paragraph: #3f536e; // 文章段落颜色 +$uni-font-size-paragraph: 14px; +$menu-bg-color: #fff; // 一级菜单背景色 +$sub-menu-bg-color: darken($menu-bg-color, 8%); // 二级以下菜单背景色 +$menu-bg-color-hover: darken($menu-bg-color, 15%); +// 菜单 hover 背景颜色 +$menu-text-color: #333; // 菜单前景色 +$menu-text-color-actived: #409eff; // 菜单激活前景色 +$left-window-bg-color: $menu-bg-color; // 左侧窗口背景色 +$top-window-bg-color: #fff; // 顶部窗口背景色 +$top-window-text-color: #999; // 顶部窗口前景色 diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/index.js new file mode 100644 index 0000000..7b505d4 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/index.js @@ -0,0 +1,23 @@ +const { + createApi +} = require('./shared/index') + +let reportDataReceiver, dataStatCron +module.exports = { + //uni统计数据上报数据接收器初始化 + initReceiver: (options = {}) => { + if(!reportDataReceiver) { + reportDataReceiver = require('./stat/receiver') + } + options.clientType = options.clientType || __ctx__.PLATFORM + return createApi(reportDataReceiver, options) + }, + //uni统计数据统计模块初始化 + initStat: (options = {}) => { + if(!dataStatCron) { + dataStatCron = require('./stat/stat') + } + options.clientType = options.clientType || __ctx__.PLATFORM + return createApi(dataStatCron, options) + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/package.json new file mode 100644 index 0000000..c9df117 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/package.json @@ -0,0 +1,15 @@ +{ + "name": "uni-stat", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "uni-config-center": "file:../../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/create-api.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/create-api.js new file mode 100644 index 0000000..ea438f6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/create-api.js @@ -0,0 +1,82 @@ +const { + isFn, + isPlainObject +} = require('./utils') + +/** + * 实例参数处理,注意:不进行递归处理 + * @param {Object} params 初始参数 + * @param {Object} rule 规则集 + * @returns {Object} 处理后的参数 + */ +function parseParams (params = {}, rule) { + if (!rule || !params) { + return params + } + const internalKeys = ['_pre', '_purify', '_post'] + // 转换之前的处理 + if (rule._pre) { + params = rule._pre(params) + } + // 净化参数 + let purify = { shouldDelete: new Set([]) } + if (rule._purify) { + const _purify = rule._purify + for (const purifyKey in _purify) { + _purify[purifyKey] = new Set(_purify[purifyKey]) + } + purify = Object.assign(purify, _purify) + } + if (isPlainObject(rule)) { + for (const key in rule) { + const parser = rule[key] + if (isFn(parser) && internalKeys.indexOf(key) === -1) { + params[key] = parser(params) + } else if (typeof parser === 'string' && internalKeys.indexOf(key) === -1) { + // 直接转换属性名称的删除旧属性名 + params[key] = params[parser] + purify.shouldDelete.add(parser) + } + } + } else if (isFn(rule)) { + params = rule(params) + } + + if (purify.shouldDelete) { + for (const item of purify.shouldDelete) { + delete params[item] + } + } + + // 转换之后的处理 + if (rule._post) { + params = rule._post(params) + } + + return params +} + +/** + * 返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文 + * @param {class} ApiClass 实例类 + * @param {Object} options 参数 + * @returns {Object} 实例类对象 + */ +module.exports = function createApi (ApiClass, options) { + const apiInstance = new ApiClass(options) + return new Proxy(apiInstance, { + get: function (obj, prop) { + if (typeof obj[prop] === 'function' && prop.indexOf('_') !== 0 && obj._protocols && obj._protocols[prop]) { + const protocol = obj._protocols[prop] + return async function (params) { + params = parseParams(params, protocol.args) + let result = await obj[prop](params) + result = parseParams(result, protocol.returnValue) + return result + } + } else { + return obj[prop] + } + } + }) +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/error.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/error.js new file mode 100644 index 0000000..2955d22 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/error.js @@ -0,0 +1,19 @@ +/** + * @class UniCloudError 错误处理模块 + */ +module.exports = class UniCloudError extends Error { + constructor (options) { + super(options.message) + this.errMsg = options.message || '' + Object.defineProperties(this, { + message: { + get () { + return `errCode: ${options.code || ''} | errMsg: ` + this.errMsg + }, + set (msg) { + this.errMsg = msg + } + } + }) + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/index.js new file mode 100644 index 0000000..12951c8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/index.js @@ -0,0 +1,6 @@ +module.exports = { + UniCloudError: require('./error'), + createApi: require('./create-api'), + ... require('./utils') +} + diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/utils.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/utils.js new file mode 100644 index 0000000..2852343 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/shared/utils.js @@ -0,0 +1,197 @@ +const _toString = Object.prototype.toString +const hasOwnProperty = Object.prototype.hasOwnProperty + +/** + * 检查对象是否包含某个属性 + * @param {Object} obj 对象 + * @param {String} key 属性键值 + */ +function hasOwn(obj, key) { + return hasOwnProperty.call(obj, key) +} + +/** + * 参数是否为JavaScript的简单对象 + * @param {Object} obj + * @returns {Boolean} true|false + */ +function isPlainObject(obj) { + return _toString.call(obj) === '[object Object]' +} + +/** + * 是否为函数 + * @param {String} fn 函数名 + */ +function isFn(fn) { + return typeof fn === 'function' +} + +/** + * 深度克隆对象 + * @param {Object} obj + */ +function deepClone(obj) { + return JSON.parse(JSON.stringify(obj)) +} + + +/** + * 解析客户端上报的参数 + * @param {String} primitiveParams 原始参数 + * @param {Object} context 附带的上下文 + */ +function parseUrlParams(primitiveParams, context) { + if (!primitiveParams) { + return primitiveParams + } + + let params = {} + if(typeof primitiveParams === 'string') { + params = primitiveParams.split('&').reduce((res, cur) => { + const arr = cur.split('=') + return Object.assign({ + [arr[0]]: arr[1] + }, res) + }, {}) + } else { + //转换参数类型--兼容性 + for(let key in primitiveParams) { + if(typeof primitiveParams[key] === 'number') { + params[key] = primitiveParams[key] + '' + } else { + params[key] = primitiveParams[key] + } + } + } + + //原以下数据要从客户端上报,现调整为如果以下参数客户端未上报,则通过请求附带的context参数中获取 + const convertParams = { + //appid + ak: 'appId', + //当前登录用户编号 + uid: 'uid', + //设备编号 + did: 'deviceId', + //uni-app 运行平台,与条件编译平台相同。 + up: 'uniPlatform', + //操作系统名称 + p: 'osName', + //因为p参数可能会被前端覆盖掉,所以这里单独拿出来一个osName + on: 'osName', + //客户端ip + ip: 'clientIP', + //客户端的UA + ua: 'userAgent', + //当前服务空间编号 + spid: 'spaceId', + //当前服务空间提供商 + sppd: 'provider', + //应用版本号 + v: 'appVersion', + //rom 名称 + rn: 'romName', + //rom 版本 + rv: 'romVersion', + //操作系统版本 + sv: 'osVersion', + //操作系统语言 + lang: 'osLanguage', + //操作系统主题 + ot: 'osTheme', + //设备类型 + dtp: 'deviceType', + //设备品牌 + brand: 'deviceBrand', + //设备型号 + md: 'deviceModel', + //设备像素比 + pr: 'devicePixelRatio', + //可使用窗口宽度 + ww: 'windowWidth', + //可使用窗口高度 + wh: 'windowHeight', + //屏幕宽度 + sw: 'screenWidth', + //屏幕高度 + sh: 'screenHeight', + } + context = context ? context : {} + for (let key in convertParams) { + if (!params[key] && context[convertParams[key]]) { + params[key] = context[convertParams[key]] + } + } + + return params +} + +/** + * 解析url + * @param {String} url + */ +function parseUrl(url) { + if (typeof url !== "string" || !url) { + return false + } + const urlInfo = url.split('?') + + baseurl = urlInfo[0] + if (baseurl !== '/' && baseurl.indexOf('/') === 0) { + baseurl = baseurl.substr(1) + } + + return { + path: baseurl, + query: urlInfo[1] ? decodeURI(urlInfo[1]) : '' + } +} + +//加载配置中心-uni-config-center +let createConfig +try { + createConfig = require('uni-config-center') +} catch (e) {} + +/** + * 获取配置文件信息 + * @param {String} file 配置文件名称 + * @param {String} key 配置参数键值 + */ +function getConfig(file, key) { + if (!file) { + return false + } + + const uniConfig = createConfig && createConfig({ + pluginId: 'uni-stat' + }) + + if (!uniConfig || !uniConfig.hasFile(file + '.json')) { + console.error('Not found the config file') + return false + } + + const config = uniConfig.requireFile(file) + + return key ? config[key] : config +} + +/** + * 休眠 + * @param {Object} ms 休眠时间(毫秒) + */ +function sleep(ms) { + return new Promise(resolve => setTimeout(() => resolve(), ms)) +} + +module.exports = { + hasOwn, + isPlainObject, + isFn, + deepClone, + parseUrlParams, + parseUrl, + getConfig, + sleep +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/date.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/date.js new file mode 100644 index 0000000..00417a1 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/date.js @@ -0,0 +1,371 @@ +/** + * @class DateTime + * @description 日期处理模块 + */ +module.exports = class DateTime { + constructor() { + //默认日期展示格式 + this.defaultDateFormat = 'Y-m-d H:i:s' + //默认时区 + this.defaultTimezone = 8 + this.setTimeZone(this.defaultTimezone) + } + + /** + * 设置时区 + * @param {Number} timezone 时区 + */ + setTimeZone(timezone) { + if (timezone) { + this.timezone = parseInt(timezone) + } + return this + } + + /** + * 获取 Date对象 + * @param {Date|Time} time + */ + getDateObj(time) { + return time ? new Date(time) : new Date() + } + + /** + * 获取毫秒/秒级时间戳 + * @param {DateTime} datetime 日期 例:'2022-04-21 00:00:00' + * @param {Boolean} showSenconds 是否显示为秒级时间戳 + */ + getTime(datetime, showSenconds) { + let time = this.getDateObj(datetime).getTime() + if (showSenconds) { + time = Math.trunc(time / 1000) + } + return time + } + + /** + * 获取日期 + * @param {String} dateFormat 日期格式 + * @param {Time} time 时间戳 + */ + getDate(dateFormat, time) { + return this.dateFormat(dateFormat, time) + } + + + /** + * 获取日期在不同时区下的时间戳 + * @param {Date|Time}} time 日期或时间戳 + * @param {Object} timezone 时区 + */ + getTimeByTimeZone(time, timezone) { + this.setTimeZone(timezone) + const thisDate = time ? new Date(time) : new Date() + const localTime = thisDate.getTime() + const offset = thisDate.getTimezoneOffset() + const utc = offset * 60000 + localTime + return utc + (3600000 * this.timezone) + } + + /** + * 获取时间信息 + * @param {Time} time 时间戳 + * @param {Boolean} full 是否完整展示, 为true时小于10的位会自动补0 + */ + getTimeInfo(time, full = true) { + time = this.getTimeByTimeZone(time) + const date = this.getDateObj(time) + const retData = { + nYear: date.getFullYear(), + nMonth: date.getMonth() + 1, + nWeek: date.getDay() || 7, + nDay: date.getDate(), + nHour: date.getHours(), + nMinutes: date.getMinutes(), + nSeconds: date.getSeconds() + } + + if (full) { + for (const k in retData) { + if (retData[k] < 10) { + retData[k] = '0' + retData[k] + } + } + } + return retData + } + + /** + * 时间格式转换 + * @param {String} format 展示格式如:Y-m-d H:i:s + * @param {Time} time 时间戳 + */ + dateFormat(format, time) { + const timeInfo = this.getTimeInfo(time) + format = format || this.defaultDateFormat + let date = format + if (format.indexOf('Y') > -1) { + date = date.replace(/Y/, timeInfo.nYear) + } + if (format.indexOf('m') > -1) { + date = date.replace(/m/, timeInfo.nMonth) + } + if (format.indexOf('d') > -1) { + date = date.replace(/d/, timeInfo.nDay) + } + if (format.indexOf('H') > -1) { + date = date.replace(/H/, timeInfo.nHour) + } + if (format.indexOf('i') > -1) { + date = date.replace(/i/, timeInfo.nMinutes) + } + if (format.indexOf('s') > -1) { + date = date.replace(/s/, timeInfo.nSeconds) + } + return date + } + + /** + * 获取utc格式时间 + * @param {Date|Time} datetime 日期或时间戳 + */ + getUTC(datetime) { + return this.getDateObj(datetime).toUTCString() + } + + /** + * 获取ISO 格式时间 + * @param {Date|Time} datetime 日期或时间戳 + */ + getISO(datetime) { + return this.getDateObj(datetime).toISOString() + } + + /** + * 获取两时间相差天数 + * @param {Time} time1 时间戳 + * @param {Time} time2 时间戳 + */ + getDiffDays(time1, time2) { + if (!time1) { + return false + } + time2 = time2 ? time2 : this.getTime() + + let diffTime = time2 - time1 + if (diffTime < 0) { + diffTime = Math.abs(diffTime) + } + + return Math.ceil(diffTime / 86400000) + } + + /** + * 字符串转时间戳 + * @param {Object} str 字符串类型的时间戳 + */ + strToTime(str) { + if (Array.from(str).length === 10) { + str += '000' + } + return this.getTime(parseInt(str)) + } + + /** + * 根据设置的天数获取指定日期N天后(前)的时间戳 + * @param {Number} days 天数 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeBySetDays(days, time, getAll = false) { + const date = this.getDateObj(time) + date.setDate(date.getDate() + days) + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate('Y-m-d 00:00:00', startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + /** + * 根据设置的小时数获取指定日期N小时后(前)的时间戳 + * @param {Number} hours 小时数 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定时间初始时间戳(该小时00:00的时间戳) + */ + getTimeBySetHours(hours, time, getAll = false) { + const date = this.getDateObj(time) + date.setHours(date.getHours() + hours) + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate('Y-m-d H:00:00', startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + /** + * 根据设置的周数获取指定日期N周后(前)的时间戳 + * @param {Number} weeks 周数 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeBySetWeek(weeks, time, getAll = false) { + const date = this.getDateObj(time) + const dateInfo = this.getTimeInfo(time) + const day = dateInfo.nWeek + const offsetDays = 1 - day + weeks = weeks * 7 + offsetDays + date.setDate(date.getDate() + weeks) + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate('Y-m-d 00:00:00', startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + /** + * 根据设置的月数获取指定日期N月后(前)的时间戳 + * @param {Number} monthes 月数 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeBySetMonth(monthes, time, getAll = false) { + const date = this.getDateObj(time) + date.setMonth(date.getMonth() + monthes) + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate('Y-m-01 00:00:00', startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + /** + * 根据设置的季度数获取指定日期N个季度后(前)的时间戳 + * @param {Number} quarter 季度 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeBySetQuarter(quarter, time, getAll = false) { + const date = this.getDateObj(time) + const dateInfo = this.getTimeInfo(time) + date.setMonth(date.getMonth() + quarter * 3) + const month = date.getMonth() + 1; + let quarterN; + let mm; + if ([1,2,3].indexOf(month) > -1) { + // 第1季度 + mm = "01"; + } else if ([4,5,6].indexOf(month) > -1) { + // 第2季度 + mm = "04"; + } else if ([7,8,9].indexOf(month) > -1) { + // 第3季度 + mm = "07"; + } else if ([10,11,12].indexOf(month) > -1) { + // 第4季度 + mm = "10"; + } + let yyyy = date.getFullYear(); + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate(`${yyyy}-${mm}-01 00:00:00`, startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + /** + * 根据设置的年数获取指定日期N年后(前)的时间戳 + * @param {Number} year 月数 + * @param {Date|Time} time 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeBySetYear(year, time, getAll = false) { + const date = this.getDateObj(time) + date.setFullYear(date.getFullYear() + year) + let startTime = date.getTime() + if (!getAll) { + const realdate = this.getDate('Y-01-01 00:00:00', startTime) + startTime = this.getTimeByDateAndTimezone(realdate) + } + return startTime + } + + + /** + * 根据时区获取指定时间的偏移时间 + * @param {Date|Time} 指定的日期或时间戳 + * @param {Number} timezone 时区 + */ + getTimeByDateAndTimezone(date, timezone) { + if (!timezone) { + timezone = this.timezone + } + const thisDate = this.getDateObj(date) + const thisTime = thisDate.getTime() + const offset = thisDate.getTimezoneOffset() + const offsetTime = offset * 60000 + timezone * 3600000 + return thisTime - offsetTime + } + + /** + * 根据指定的时间类型获取时间范围 + * @param {String} type 时间类型 hour:小时 day:天 week:周 month:月 + * @param {Number} offset 时间的偏移量 + * @param {Date|Time} thistime 指定的日期或时间戳 + * @param {Boolean} getAll 是否获取完整时间戳,为 false 时返回指定日期初始时间戳(当天00:00:00的时间戳) + */ + getTimeDimensionByType(type, offset = 0, thistime, getAll = false) { + let startTime = 0 + let endTime = 0 + switch (type) { + case 'hour': { + startTime = this.getTimeBySetHours(offset, thistime, getAll) + endTime = getAll ? startTime : startTime + 3599999 + break + } + case 'day': { + startTime = this.getTimeBySetDays(offset, thistime, getAll) + endTime = getAll ? startTime : startTime + 86399999 + break + } + case 'week': { + startTime = this.getTimeBySetWeek(offset, thistime, getAll) + endTime = getAll ? startTime + 86400000 * 6 : startTime + 86400000 * 6 + 86399999 + break + } + case 'month': { + startTime = this.getTimeBySetMonth(offset, thistime, getAll) + const date = this.getDateObj(this.getDate('Y-m-d H:i:s', startTime)) + const nextMonthFirstDayTime = new Date(date.getFullYear(), date.getMonth() + 1, 1).getTime() + endTime = getAll ? nextMonthFirstDayTime - 86400000 : this.getTimeByDateAndTimezone( + nextMonthFirstDayTime) - 1 + break + } + case 'quarter': { + startTime = this.getTimeBySetQuarter(offset, thistime, getAll) + const date = this.getDateObj(this.getDate('Y-m-d H:i:s', startTime)) + const nextMonthFirstDayTime = new Date(date.getFullYear(), date.getMonth() + 3, 1).getTime() + endTime = getAll ? nextMonthFirstDayTime - 86400000 : this.getTimeByDateAndTimezone( + nextMonthFirstDayTime) - 1 + break + } + case 'year': { + startTime = this.getTimeBySetYear(offset, thistime, getAll) + const date = this.getDateObj(this.getDate('Y-m-d H:i:s', startTime)) + const nextFirstDayTime = new Date(date.getFullYear() + 1, 0, 1).getTime() + endTime = getAll ? nextFirstDayTime - 86400000 : this.getTimeByDateAndTimezone( + nextFirstDayTime) - 1 + break + } + } + return { + startTime, + endTime + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/index.js new file mode 100644 index 0000000..4ccab05 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/index.js @@ -0,0 +1,4 @@ +module.exports = { + DateTime: require('./date'), + UniCrypto: require('./uni-crypto') +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/uni-crypto.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/uni-crypto.js new file mode 100644 index 0000000..d5cdc8d --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/lib/uni-crypto.js @@ -0,0 +1,98 @@ +/** + * @class UniCrypto 数据加密服务 + * @function init 初始化函数 + * @function showConfig 返回配置信息函数 + * @function getCrypto 返回原始crypto对象函数 + * @function aesEncode AES加密函数 + * @function aesDecode AES解密函数 + * @function md5 MD5加密函数 + */ +const crypto = require('crypto') +module.exports = class UniCrypto { + constructor(config) { + this.init(config) + } + + /** + * 配置初始化函数 + * @param {Object} config + */ + init(config) { + this.config = { + //AES加密默认参数 + AES: { + mod: 'aes-128-cbc', + pasword: 'UniStat!010', + iv: 'UniStativ', + charset: 'utf8', + encodeReturnType: 'base64' + }, + //MD5加密默认参数 + MD5: { + encodeReturnType: 'hex' + }, + ...config || {} + } + return this + } + + /** + * 返回配置信息函数 + */ + showConfig() { + return this.config + } + + /** + * 返回原始crypto对象函数 + */ + getCrypto() { + return crypto + } + + /** + * AES加密函数 + * @param {String} data 加密数据明文 + * @param {String} encodeReturnType 返回加密数据类型,如:base64 + * @param {String} key 密钥 + * @param {String} iv 偏移量 + * @param {String} mod 模式 + * @param {String} charset 编码 + */ + aesEncode(data, encodeReturnType, key, iv, mod, charset) { + const cipher = crypto.createCipheriv(mod || this.config.AES.mod, key || this.config.AES.pasword, iv || + this.config.AES.iv) + let crypted = cipher.update(data, charset || this.config.AES.charset, 'binary') + crypted += cipher.final('binary') + crypted = Buffer.from(crypted, 'binary').toString(encodeReturnType || this.config.AES.encodeReturnType) + return crypted + } + + /** + * AES解密函数 + * @param {Object} crypted 加密数据密文 + * @param {Object} encodeReturnType 返回加密数据类型,如:base64 + * @param {Object} key 密钥 + * @param {Object} iv 偏移量 + * @param {Object} mod 模式 + * @param {Object} charset 编码 + */ + aesDecode(crypted, encodeReturnType, key, iv, mod, charset) { + crypted = Buffer.from(crypted, encodeReturnType || this.config.AES.encodeReturnType).toString('binary') + const decipher = crypto.createDecipheriv(mod || this.config.AES.mod, key || this.config.AES.pasword, + iv || this.config.AES.iv) + let decoded = decipher.update(crypted, 'binary', charset || this.config.AES.charset) + decoded += decipher.final(charset || this.config.AES.charset) + return decoded + } + + /** + * @param {Object} str 加密字符串 + * @param {Object} encodeReturnType encodeReturnType 返回加密数据类型,如:hex(转为16进制) + */ + md5(str, encodeReturnType) { + const md5Mod = crypto.createHash('md5') + md5Mod.update(str) + return md5Mod.digest(encodeReturnType || this.config.MD5.encodeReturnType) + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeDevices.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeDevices.js new file mode 100644 index 0000000..dd61a45 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeDevices.js @@ -0,0 +1,528 @@ +/** + * @class ActiveDevices 活跃设备模型 - 每日跑批合并,仅添加本周/本月首次访问的设备。 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const SessionLog = require('./sessionLog') +const { + DateTime, + UniCrypto +} = require('../lib') +module.exports = class ActiveDevices extends BaseMod { + constructor() { + super() + this.tableName = 'active-devices' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + * @desc 活跃设备统计 - 为周统计/月统计提供周活/月活数据 + * @param {date|time} date + * @param {bool} reset + */ + async stat(date, reset) { + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType('day', -1, date) + this.startTime = dateDimension.startTime + // 查看当前时间段数据是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }).get() + if (checkRes.data.length > 0) { + console.log('data have exists') + return { + code: 1003, + msg: 'Devices data in this time have already existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }) + console.log('Delete old data result:', JSON.stringify(delRes)) + } + + const sessionLog = new SessionLog() + const statRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + is_first_visit: 1, + create_time: 1, + device_id: 1 + }, + match: { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + device_id: '$device_id' + }, + is_new: { + $max: '$is_first_visit' + }, + create_time: { + $min: '$create_time' + } + }, + sort: { + create_time: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + // if (this.debug) { + // console.log('statRes', JSON.stringify(statRes)) + // } + if (statRes.data.length > 0) { + const uniCrypto = new UniCrypto() + // 同应用、平台、渠道、版本的数据合并 + const statData = []; + let statKey; + let data + + const statOldRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + is_first_visit: 1, + create_time: 1, + old_device_id: 1 + }, + match: { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + }, + old_device_id: {$exists: true} + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + old_device_id: '$old_device_id' + }, + create_time: { + $min: '$create_time' + } + }, + sort: { + create_time: 1 + }, + getAll: true + }) + if (this.debug) { + console.log('statOldRes', JSON.stringify(statOldRes)) + } + for (const sti in statRes.data) { + data = statRes.data[sti] + statKey = uniCrypto.md5(data._id.appid + data._id.platform + data._id.version + data._id + .channel) + if (!statData[statKey]) { + statData[statKey] = { + appid: data._id.appid, + platform: data._id.platform, + version: data._id.version, + channel: data._id.channel, + device_ids: [], + old_device_ids: [], + info: [], + old_info: [] + } + statData[statKey].device_ids.push(data._id.device_id) + statData[statKey].info[data._id.device_id] = { + is_new: data.is_new, + create_time: data.create_time + } + } else { + statData[statKey].device_ids.push(data._id.device_id) + statData[statKey].info[data._id.device_id] = { + is_new: data.is_new, + create_time: data.create_time + } + } + } + if(statOldRes.data.length) { + const oldDeviceIds = [] + for(const osti in statOldRes.data) { + if(!statOldRes.data[osti]._id.old_device_id) { + continue + } + oldDeviceIds.push(statOldRes.data[osti]._id.old_device_id) + } + if(oldDeviceIds.length) { + const statOldDidRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + is_first_visit: 1, + create_time: 1, + device_id: 1 + }, + match: { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + }, + device_id: {$in: oldDeviceIds} + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + old_device_id: '$device_id' + }, + create_time: { + $min: '$create_time' + } + }, + sort: { + create_time: 1 + }, + getAll: true + }) + + if(statOldDidRes.data.length){ + for(const osti in statOldDidRes.data) { + data = statOldDidRes.data[osti] + statKey = uniCrypto.md5(data._id.appid + data._id.platform + data._id.version + data._id + .channel) + if(!data._id.old_device_id) { + continue + } + + if (!statData[statKey]) { + statData[statKey] = { + appid: data._id.appid, + platform: data._id.platform, + version: data._id.version, + channel: data._id.channel, + device_ids: [], + old_device_ids: [], + old_info: [] + } + statData[statKey].old_device_ids.push(data._id.old_device_id) + } else { + statData[statKey].old_device_ids.push(data._id.old_device_id) + } + if(!statData[statKey].old_info[data._id.old_device_id]) { + statData[statKey].old_info[data._id.old_device_id] = { + create_time: data.create_time + } + } + } + } + } + } + this.fillData = [] + for (const sk in statData) { + await this.getFillData(statData[sk]) + } + + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + /** + * 获取填充数据 + * @param {Object} data + */ + async getFillData(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data.platform]) { + platformInfo = this.platforms[data.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data.appid + '_' + platformInfo._id + '_' + data.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data.appid, platformInfo._id, data.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data.appid + '_' + data.platform + '_' + data.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data.appid, data.platform, data.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + const datetime = new DateTime() + const dateDimension = datetime.getTimeDimensionByType('week', 0, this.startTime) + const dateMonthDimension = datetime.getTimeDimensionByType('month', 0, this.startTime) + + if(data.device_ids) { + // 取出本周已经存储的device_id + const weekHaveDeviceList = [] + const haveWeekList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + device_id: { + $in: data.device_ids + }, + dimension: 'week', + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }, { + device_id: 1 + }) + if (haveWeekList.data.length > 0) { + for (const hui in haveWeekList.data) { + weekHaveDeviceList.push(haveWeekList.data[hui].device_id) + } + } + if (this.debug) { + console.log('weekHaveDeviceList', JSON.stringify(weekHaveDeviceList)) + } + + // 取出本月已经存储的device_id + const monthHaveDeviceList = [] + const haveMonthList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + device_id: { + $in: data.device_ids + }, + dimension: 'month', + create_time: { + $gte: dateMonthDimension.startTime, + $lte: dateMonthDimension.endTime + } + }, { + device_id: 1 + }) + if (haveMonthList.data.length > 0) { + for (const hui in haveMonthList.data) { + monthHaveDeviceList.push(haveMonthList.data[hui].device_id) + } + } + if (this.debug) { + console.log('monthHaveDeviceList', JSON.stringify(monthHaveDeviceList)) + } + //数据填充 + for (const ui in data.device_ids) { + //周活跃数据填充 + if (!weekHaveDeviceList.includes(data.device_ids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + is_new: data.info[data.device_ids[ui]].is_new, + device_id: data.device_ids[ui], + dimension: 'week', + create_time: data.info[data.device_ids[ui]].create_time + }) + } + //月活跃数据填充 + if (!monthHaveDeviceList.includes(data.device_ids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + is_new: data.info[data.device_ids[ui]].is_new, + device_id: data.device_ids[ui], + dimension: 'month', + create_time: data.info[data.device_ids[ui]].create_time + }) + } + } + } + + if(data.old_device_ids) { + // 取出本周已经存储的old_device_id + const weekHaveOldDeviceList = [] + const haveOldWeekList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + device_id: { + $in: data.old_device_ids + }, + dimension: 'week-old', + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }, { + device_id: 1 + }) + if (haveOldWeekList.data.length > 0) { + for (const hui in haveOldWeekList.data) { + weekHaveOldDeviceList.push(haveOldWeekList.data[hui].device_id) + } + } + if (this.debug) { + console.log('weekHaveOldDeviceList', JSON.stringify(weekHaveOldDeviceList)) + } + + // 取出本月已经存储的old_device_id + const monthHaveOldDeviceList = [] + const haveOldMonthList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + device_id: { + $in: data.old_device_ids + }, + dimension: 'month-old', + create_time: { + $gte: dateMonthDimension.startTime, + $lte: dateMonthDimension.endTime + } + }, { + device_id: 1 + }) + if (haveOldMonthList.data.length > 0) { + for (const hui in haveOldMonthList.data) { + monthHaveOldDeviceList.push(haveOldMonthList.data[hui].device_id) + } + } + if (this.debug) { + console.log('monthHaveOldDeviceList', JSON.stringify(monthHaveOldDeviceList)) + } + //数据填充 + for (const ui in data.old_device_ids) { + //周活跃数据填充 + if (!weekHaveOldDeviceList.includes(data.old_device_ids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + is_new: 0, + device_id: data.old_device_ids[ui], + dimension: 'week-old', + create_time: data.old_info[data.old_device_ids[ui]].create_time + }) + } + //月活跃数据填充 + if (!monthHaveOldDeviceList.includes(data.old_device_ids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + is_new: 0, + device_id: data.old_device_ids[ui], + dimension: 'month-old', + create_time: data.old_info[data.old_device_ids[ui]].create_time + }) + } + } + } + + return true + } + + /** + * 日志清理,此处日志为临时数据并不需要自定义清理,默认为固定值即可 + */ + async clean() { + // 清除周数据,周留存统计最高需要10周数据,多余的为无用数据 + const weeks = 10 + console.log('Clean device\'s weekly logs - week:', weeks) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + dimension: 'week', + create_time: { + $lt: dateTime.getTimeBySetWeek(0 - weeks) + } + }) + + if (!res.code) { + console.log('Clean device\'s weekly logs - res:', res) + } + + // 清除月数据,月留存统计最高需要10个月数据,多余的为无用数据 + const monthes = 10 + console.log('Clean device\'s monthly logs - month:', monthes) + const monthRes = await this.delete(this.tableName, { + dimension: 'month', + create_time: { + $lt: dateTime.getTimeBySetMonth(0 - monthes) + } + }) + if (!monthRes.code) { + console.log('Clean device\'s monthly logs - res:', res) + } + return monthRes + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeUsers.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeUsers.js new file mode 100644 index 0000000..bd15f75 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/activeUsers.js @@ -0,0 +1,314 @@ +/** + * @class ActiveUsers 活跃用户模型 - 每日跑批合并,仅添加本周/本月首次访问的用户。 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const UserSessionLog = require('./userSessionLog') +const { + DateTime, + UniCrypto +} = require('../lib') +module.exports = class ActiveUsers extends BaseMod { + constructor() { + super() + this.tableName = 'active-users' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + async stat(date, reset) { + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType('day', -1, date) + this.startTime = dateDimension.startTime + // 查看当前时间段数据是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }).get() + if (checkRes.data.length > 0) { + console.log('data have exists') + return { + code: 1003, + msg: 'Users data in this time have already existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }) + console.log('Delete old data result:', JSON.stringify(delRes)) + } + + const userSessionLog = new UserSessionLog() + const statRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + create_time: 1, + uid: 1 + }, + match: { + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + uid: '$uid' + }, + create_time: { + $min: '$create_time' + } + }, + sort: { + create_time: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + // if (this.debug) { + // console.log('statRes', JSON.stringify(statRes)) + // } + if (statRes.data.length > 0) { + const uniCrypto = new UniCrypto() + // 同应用、平台、渠道、版本的数据合并 + const statData = []; + let statKey; + let data + + for (const sti in statRes.data) { + data = statRes.data[sti] + statKey = uniCrypto.md5(data._id.appid + data._id.platform + data._id.version + data._id + .channel) + if (!statData[statKey]) { + statData[statKey] = { + appid: data._id.appid, + platform: data._id.platform, + version: data._id.version, + channel: data._id.channel, + uids: [], + info: [] + } + statData[statKey].uids.push(data._id.uid) + statData[statKey].info[data._id.uid] = { + create_time: data.create_time + } + } else { + statData[statKey].uids.push(data._id.uid) + statData[statKey].info[data._id.uid] = { + create_time: data.create_time + } + } + } + + this.fillData = [] + for (const sk in statData) { + await this.getFillData(statData[sk]) + } + + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + async getFillData(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data.platform]) { + platformInfo = this.platforms[data.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data.appid + '_' + platformInfo._id + '_' + data.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data.appid, platformInfo._id, data.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data.appid + '_' + data.platform + '_' + data.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data.appid, data.platform, data.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 是否在本周内已存在 + const datetime = new DateTime() + const dateDimension = datetime.getTimeDimensionByType('week', 0, this.startTime) + + // 取出本周已经存储的uid + const weekHaveUserList = [] + const haveWeekList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + uid: { + $in: data.uids + }, + dimension: 'week', + create_time: { + $gte: dateDimension.startTime, + $lte: dateDimension.endTime + } + }, { + uid: 1 + }) + + if (this.debug) { + console.log('haveWeekList', JSON.stringify(haveWeekList)) + } + + if (haveWeekList.data.length > 0) { + for (const hui in haveWeekList.data) { + weekHaveUserList.push(haveWeekList.data[hui].uid) + } + } + + // 取出本月已经存储的uid + const dateMonthDimension = datetime.getTimeDimensionByType('month', 0, this.startTime) + const monthHaveUserList = [] + const haveMonthList = await this.selectAll(this.tableName, { + appid: data.appid, + version_id: versionInfo._id, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + uid: { + $in: data.uids + }, + dimension: 'month', + create_time: { + $gte: dateMonthDimension.startTime, + $lte: dateMonthDimension.endTime + } + }, { + uid: 1 + }) + + if (this.debug) { + console.log('haveMonthList', JSON.stringify(haveMonthList)) + } + + if (haveMonthList.data.length > 0) { + for (const hui in haveMonthList.data) { + monthHaveUserList.push(haveMonthList.data[hui].uid) + } + } + + for (const ui in data.uids) { + if (!weekHaveUserList.includes(data.uids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + uid: data.uids[ui], + dimension: 'week', + create_time: data.info[data.uids[ui]].create_time + }) + } + + if (!monthHaveUserList.includes(data.uids[ui])) { + this.fillData.push({ + appid: data.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + uid: data.uids[ui], + dimension: 'month', + create_time: data.info[data.uids[ui]].create_time + }) + } + } + + return true + } + + /** + * 日志清理,此处日志为临时数据并不需要自定义清理,默认为固定值即可 + */ + async clean() { + // 清除周数据,周留存统计最高需要10周数据,多余的为无用数据 + const weeks = 10 + console.log('Clean user\'s weekly logs - week:', weeks) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + dimension: 'week', + create_time: { + $lt: dateTime.getTimeBySetWeek(0 - weeks) + } + }) + + if (!res.code) { + console.log('Clean user\'s weekly logs - res:', res) + } + + // 清除月数据,月留存统计最高需要10个月数据,多余的为无用数据 + const monthes = 10 + console.log('Clean user\'s monthly logs - month:', monthes) + const monthRes = await this.delete(this.tableName, { + dimension: 'month', + create_time: { + $lt: dateTime.getTimeBySetMonth(0 - monthes) + } + }) + if (!monthRes.code) { + console.log('Clean user\'s monthly logs - res:', res) + } + return monthRes + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/appCrashLogs.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/appCrashLogs.js new file mode 100644 index 0000000..fc64df5 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/appCrashLogs.js @@ -0,0 +1,37 @@ +/** + * @class AppCrashLogs 原生应用崩溃日志模型 + * @function clean 原生应用崩溃日志清理函数 + */ +const BaseMod = require('./base') +const { + DateTime, + UniCrypto +} = require('../lib') +module.exports = class AppCrashLogs extends BaseMod { + constructor() { + super() + this.tableName = 'app-crash-logs' + } + + /** + * 原生应用崩溃日志清理函数 + * @param {Number} days 保留天数 + */ + async clean(days = 7) { + days = Math.max(parseInt(days), 1) + console.log('clean app crash logs - day:', days) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean app crash log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/base.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/base.js new file mode 100644 index 0000000..2914df2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/base.js @@ -0,0 +1,485 @@ +/** + * @class BaseMod 数据模型基类,提供基础服务支持 + */ +const { + getConfig +} = require('../../shared') +//基类 +module.exports = class BaseMod { + constructor() { + //配置信息 + this.config = getConfig('config') + //开启/关闭debug + this.debug = this.config.debug + //主键 + this.primaryKey = '_id' + //单次查询最多返回 500 条数据(阿里云500,腾讯云1000,这里取最小值) + this.selectMaxLimit = 500 + //数据表前缀 + this.tablePrefix = 'uni-stat' + //数据表连接符 + this.tableConnectors = '-' + //数据表名 + this.tableName = '' + //参数 + this.params = {} + //数据库连接 + this._dbConnection() + //redis连接 + this._redisConnection() + } + + /** + * 建立uniCloud数据库连接 + */ + _dbConnection() { + if (!this.db) { + try { + this.db = uniCloud.database() + this.dbCmd = this.db.command + this.dbAggregate = this.dbCmd.aggregate + } catch (e) { + console.error('database connection failed: ' + e) + throw new Error('database connection failed: ' + e) + } + } + } + + /** + * 建立uniCloud redis连接 + */ + _redisConnection() { + if (this.config.redis && !this.redis) { + try { + this.redis = uniCloud.redis() + } catch (e) { + console.log('redis server connection failed: ' + e) + } + } + } + + /** + * 获取uni统计配置项 + * @param {String} key + */ + getConfig(key) { + return this.config[key] + } + + /** + * 获取带前缀的数据表名称 + * @param {String} tab 表名 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + getTableName(tab, useDBPre = true) { + tab = tab || this.tableName + const table = (useDBPre && this.tablePrefix && tab.indexOf(this.tablePrefix) !== 0) ? this.tablePrefix + this + .tableConnectors + tab : tab + return table + } + + /** + * 获取数据集 + * @param {String} tab表名 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + getCollection(tab, useDBPre = true) { + return this.db.collection(this.getTableName(tab, useDBPre)) + } + + /** + * 获取reids缓存 + * @param {String} key reids缓存键值 + */ + async getCache(key) { + if (!this.redis || !key) { + return false + } + let cacheResult = await this.redis.get(key) + + if (this.debug) { + console.log('get cache result by key:' + key, cacheResult) + } + + if (cacheResult) { + try { + cacheResult = JSON.parse(cacheResult) + } catch (e) { + if (this.debug) { + console.log('json parse error: ' + e) + } + } + } + return cacheResult + } + + /** + * 设置redis缓存 + * @param {String} key 键值 + * @param {String} val 值 + * @param {Number} expireTime 过期时间 + */ + async setCache(key, val, expireTime) { + if (!this.redis || !key) { + return false + } + + if (val instanceof Object) { + val = JSON.stringify(val) + } + + if (this.debug) { + console.log('set cache result by key:' + key, val) + } + + return await this.redis.set(key, val, 'EX', expireTime || this.config.cachetime) + } + + /** + * 清除redis缓存 + * @param {String} key 键值 + */ + async clearCache(key) { + if (!this.redis || !key) { + return false + } + + if (this.debug) { + console.log('delete cache by key:' + key) + } + + return await this.redis.del(key) + } + + /** + * 通过数据表主键(_id)获取数据 + * @param {String} tab 表名 + * @param {String} id 主键值 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async getById(tab, id, useDBPre = true) { + const condition = {} + condition[this.primaryKey] = id + const info = await this.getCollection(tab, useDBPre).where(condition).get() + return (info && info.data.length > 0) ? info.data[0] : [] + } + + /** + * 插入数据到数据表 + * @param {String} tab 表名 + * @param {Object} params 字段参数 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async insert(tab, params, useDBPre = true) { + params = params || this.params + return await this.getCollection(tab, useDBPre).add(params) + } + + /** + * 修改数据表数据 + * @param {String} tab 表名 + * @param {Object} params 字段参数 + * @param {Object} condition 条件 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async update(tab, params, condition, useDBPre = true) { + params = params || this.params + return await this.getCollection(tab).where(condition).update(params) + } + + /** + * 删除数据表数据 + * @param {String} tab 表名 + * @param {Object} condition 条件 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async delete(tab, condition, useDBPre = true) { + if (!condition) { + return false + } + return await this.getCollection(tab, useDBPre).where(condition).remove() + } + + /** + * 批量插入 - 云服务空间对单条mongo语句执行时间有限制,所以批量插入需限制每次执行条数 + * @param {String} tab 表名 + * @param {Object} data 数据集合 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async batchInsert(tab, data, useDBPre = true) { + let batchInsertNum = this.getConfig('batchInsertNum') || 3000 + batchInsertNum = Math.min(batchInsertNum, 5000) + const insertNum = Math.ceil(data.length / batchInsertNum) + let start; + let end; + let fillData; + let insertRes; + const res = { + code: 0, + msg: 'success', + data: { + inserted: 0 + } + } + for (let p = 0; p < insertNum; p++) { + start = p * batchInsertNum + end = Math.min(start + batchInsertNum, data.length) + fillData = [] + for (let i = start; i < end; i++) { + fillData.push(data[i]) + } + if (fillData.length > 0) { + insertRes = await this.insert(tab, fillData, useDBPre) + if (insertRes && insertRes.inserted) { + res.data.inserted += insertRes.inserted + } + } + } + return res + } + + /** + * 批量删除 - 云服务空间对单条mongo语句执行时间有限制,所以批量删除需限制每次执行条数 + * @param {String} tab 表名 + * @param {Object} condition 条件 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async batchDelete(tab, condition, useDBPre = true) { + const batchDeletetNum = 5000; + let deleteIds; + let delRes; + let thisCondition + const res = { + code: 0, + msg: 'success', + data: { + deleted: 0 + } + } + let run = true + while (run) { + const dataRes = await this.getCollection(tab).where(condition).limit(batchDeletetNum).get() + if (dataRes && dataRes.data.length > 0) { + deleteIds = [] + for (let i = 0; i < dataRes.data.length; i++) { + deleteIds.push(dataRes.data[i][this.primaryKey]) + } + if (deleteIds.length > 0) { + thisCondition = {} + thisCondition[this.primaryKey] = { + $in: deleteIds + } + delRes = await this.delete(tab, thisCondition, useDBPre) + if (delRes && delRes.deleted) { + res.data.deleted += delRes.deleted + } + } + } else { + run = false + } + } + return res + } + + /** + * 基础查询 + * @param {String} tab 表名 + * @param {Object} params 查询参数 where:where条件,field:返回字段,skip:跳过的文档数,limit:返回的记录数,orderBy:排序,count:返回查询结果的数量 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async select(tab, params, useDBPre = true) { + const { + where, + field, + skip, + limit, + orderBy, + count + } = params + + const query = this.getCollection(tab, useDBPre) + + //拼接where条件 + if (where) { + if (where.length > 0) { + where.forEach(key => { + query.where(where[key]) + }) + } else { + query.where(where) + } + } + + //排序 + if (orderBy) { + Object.keys(orderBy).forEach(key => { + query.orderBy(key, orderBy[key]) + }) + } + + //指定跳过的文档数 + if (skip) { + query.skip(skip) + } + + //指定返回的记录数 + if (limit) { + query.limit(limit) + } + + //指定返回字段 + if (field) { + query.field(field) + } + + //指定返回查询结果数量 + if (count) { + return await query.count() + } + + //返回查询结果数据 + return await query.get() + } + + /** + * 查询并返回全部数据 + * @param {String} tab 表名 + * @param {Object} condition 条件 + * @param {Object} field 指定查询返回字段 + * @param {Boolean} useDBPre 是否使用数据表前缀 + */ + async selectAll(tab, condition, field = {}, useDBPre = true) { + const countRes = await this.getCollection(tab, useDBPre).where(condition).count() + if (countRes && countRes.total > 0) { + const pageCount = Math.ceil(countRes.total / this.selectMaxLimit) + let res, returnData + for (let p = 0; p < pageCount; p++) { + res = await this.getCollection(tab, useDBPre).where(condition).orderBy(this.primaryKey, 'asc').skip(p * + this.selectMaxLimit).limit(this.selectMaxLimit).field(field).get() + if (!returnData) { + returnData = res + } else { + returnData.affectedDocs += res.affectedDocs + for (const i in res.data) { + returnData.data.push(res.data[i]) + } + } + } + return returnData + } + return { + affectedDocs: 0, + data: [] + } + } + + /** + * 聚合查询 + * @param {String} tab 表名 + * @param {Object} params 聚合参数 + */ + async aggregate(tab, params) { + let { + project, + match, + lookup, + group, + skip, + limit, + sort, + getAll, + useDBPre, + addFields + } = params + //useDBPre 是否使用数据表前缀 + useDBPre = (useDBPre !== null && useDBPre !== undefined) ? useDBPre : true + const query = this.getCollection(tab, useDBPre).aggregate() + + //设置返回字段 + if (project) { + query.project(project) + } + + //设置匹配条件 + if (match) { + query.match(match) + } + + //数据表关联 + if (lookup) { + query.lookup(lookup) + } + + //分组 + if (group) { + if (group.length > 0) { + for (const gi in group) { + query.group(group[gi]) + } + } else { + query.group(group) + } + } + + //添加字段 + if (addFields) { + query.addFields(addFields) + } + + //排序 + if (sort) { + query.sort(sort) + } + + //分页 + if (skip) { + query.skip(skip) + } + if (limit) { + query.limit(limit) + } else if (!getAll) { + query.limit(this.selectMaxLimit) + } + + //如果未指定全部返回则直接返回查询结果 + if (!getAll) { + return await query.end() + } + + //若指定了全部返回则分页查询全部结果后再返回 + const resCount = await query.group({ + _id: {}, + aggregate_count: { + $sum: 1 + } + }).end() + + if (resCount && resCount.data.length > 0 && resCount.data[0].aggregate_count > 0) { + //分页查询 + const total = resCount.data[0].aggregate_count + const pageCount = Math.ceil(total / this.selectMaxLimit) + let res, returnData + params.limit = this.selectMaxLimit + params.getAll = false + //结果合并 + for (let p = 0; p < pageCount; p++) { + params.skip = p * params.limit + res = await this.aggregate(tab, params) + if (!returnData) { + returnData = res + } else { + returnData.affectedDocs += res.affectedDocs + for (const i in res.data) { + returnData.data.push(res.data[i]) + } + } + } + return returnData + } else { + return { + affectedDocs: 0, + data: [] + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/channel.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/channel.js new file mode 100644 index 0000000..45c0ab0 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/channel.js @@ -0,0 +1,107 @@ +/** + * @class Channel 渠道模型 + */ +const BaseMod = require('./base') +const Scenes = require('./scenes') +const { + DateTime +} = require('../lib') +module.exports = class Channel extends BaseMod { + constructor() { + super() + this.tableName = 'app-channels' + this.scenes = new Scenes() + } + + /** + * 获取渠道信息 + * @param {String} appid + * @param {String} platformId 平台编号 + * @param {String} channel 渠道代码 + */ + async getChannel(appid, platformId, channel) { + const cacheKey = 'uni-stat-channel-' + appid + '-' + platformId + '-' + channel + let channelData = await this.getCache(cacheKey) + if (!channelData) { + const channelInfo = await this.getCollection(this.tableName).where({ + appid: appid, + platform_id: platformId, + channel_code: channel + }).limit(1).get() + channelData = [] + if (channelInfo.data.length > 0) { + channelData = channelInfo.data[0] + if (channelData.channel_name === '') { + const scenesName = await this.scenes.getScenesNameByPlatformId(platformId, channel) + if (scenesName) { + await this.update(this.tableName, { + channel_name: scenesName, + update_time: new DateTime().getTime() + }, { + _id: channelData._id + }) + } + } + await this.setCache(cacheKey, channelData) + } + } + return channelData + } + + /** + * 获取渠道信息没有则进行创建 + * @param {String} appid + * @param {String} platformId + * @param {String} channel + */ + async getChannelAndCreate(appid, platformId, channel) { + if (!appid || !platformId) { + return [] + } + + const channelInfo = await this.getChannel(appid, platformId, channel) + if (channelInfo.length === 0) { + const thisTime = new DateTime().getTime() + const insertParam = { + appid: appid, + platform_id: platformId, + channel_code: channel, + channel_name: await this.scenes.getScenesNameByPlatformId(platformId, channel), + create_time: thisTime, + update_time: thisTime + } + const res = await this.insert(this.tableName, insertParam) + if (res && res.id) { + return Object.assign(insertParam, { + _id: res.id + }) + } + } + return channelInfo + } + + /** + * 获取渠道_id + * @param {String} appid + * @param {String} platformId + * @param {String} channel + */ + async getChannelId(appid, platformId, channel) { + const channelInfo = await this.getChannel(appid, platformId, channel) + return channelInfo.length > 0 ? channelInfo._id : '' + } + + /** + * 获取渠道码或者场景值 + * @param {Object} params 上报参数 + */ + getChannelCode(params) { + //小程序未上报渠道则使用场景值 + if (params.ch) { + return params.ch + } else if (params.sc && params.ut.indexOf('mp-') === 0) { + return params.sc + } + return this.scenes.defualtCode + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/device.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/device.js new file mode 100644 index 0000000..1784c00 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/device.js @@ -0,0 +1,184 @@ +/** + * @class Device 设备模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const { + DateTime +} = require('../lib') +module.exports = class Device extends BaseMod { + constructor() { + super() + this.tableName = 'opendb-device' + this.tablePrefix = false + this.cacheKeyPre = 'uni-stat-device-' + } + + /** + * 通过设备编号获取设备信息 + * @param {Object} deviceId 设备编号 + */ + async getDeviceById(deviceId) { + const cacheKey = this.cacheKeyPre + deviceId + let deviceData = await this.getCache(cacheKey) + if (!deviceData) { + const deviceRes = await this.getCollection().where({ + device_id: deviceId + }).get() + deviceData = [] + if (deviceRes.data.length > 0) { + deviceData = deviceRes.data[0] + await this.setCache(cacheKey, deviceData) + } + } + return deviceData + } + + /** + * 设置设备信息 + * @param {Object} params 上报参数 + */ + async setDevice(params) { + // 设备信息 + if (!params.did) { + return { + code: 200, + msg: 'Parameter "did" not found' + } + } + const deviceData = await this.getDeviceById(params.did) + //不存在则添加 + if(deviceData.length === 0) { + return await this.addDevice(params) + } else { + return await this.updateDevice(params, deviceData) + } + } + + /** + * 添加设备信息 + * @param {Object} params 上报参数 + */ + async addDevice(params) { + const dateTime = new DateTime() + const platform = new Platform() + const fillParams = { + device_id: params.did, + appid: params.ak, + vendor: params.brand ? params.brand : '', + push_clientid: params.cid ? params.cid : '', + imei: params.imei ? params.imei : '', + oaid: params.oaid ? params.oaid : '', + idfa: params.idfa ? params.idfa : '', + imsi: params.imsi ? params.imsi : '', + model: params.md ? params.md : '', + uni_platform: params.up ? params.up : '', + os_name: params.on ? params.on : platform.getOsName(params.p), + os_version: params.sv ? params.sv : '', + os_language: params.lang ? params.lang : '', + os_theme: params.ot ? params.ot : '', + pixel_ratio: params.pr ? params.pr : '', + network_model: params.net ? params.net : '', + window_width: params.ww ? params.ww : '', + window_height: params.wh ? params.wh : '', + screen_width: params.sw ? params.sw : '', + screen_height: params.sh ? params.sh : '', + rom_name: params.rn ? params.rn : '', + rom_version: params.rv ? params.rv : '', + location_ip: params.ip ? params.ip : '', + location_latitude: params.lat ? parseFloat(params.lat) : 0, + location_longitude: params.lng ? parseFloat(params.lng) : 0, + location_country: params.cn ? params.cn : '', + location_province: params.pn ? params.pn : '', + location_city: params.ct ? params.ct : '', + create_date: dateTime.getTime(), + last_update_date: dateTime.getTime() + } + const res = await this.insert(this.tableName, fillParams) + if (res && res.id) { + return { + code: 0, + msg: 'success', + } + } else { + return { + code: 500, + msg: 'Device data filled error' + } + } + } + + /** + * 修改设备信息 + * @param {Object} params + * @param {Object} deviceData + */ + async updateDevice(params, deviceData) { + //最新的参数 + const dateTime = new DateTime() + const platform = new Platform() + console.log('device params', params) + const newDeviceParams = { + appid: params.ak, + push_clientid: params.cid ? params.cid : '', + imei: params.imei ? params.imei : '', + oaid: params.oaid ? params.oaid : '', + idfa: params.idfa ? params.idfa : '', + imsi: params.imsi ? params.imsi : '', + uni_platform: params.up ? params.up : '', + os_name: params.on ? params.on : platform.getOsName(params.p), + os_version: params.sv ? params.sv : '', + os_language: params.lang ? params.lang : '', + pixel_ratio: params.pr ? params.pr : '', + network_model: params.net ? params.net : '', + window_width: params.ww ? params.ww : '', + window_height: params.wh ? params.wh : '', + screen_width: params.sw ? params.sw : '', + screen_height: params.sh ? params.sh : '', + rom_name: params.rn ? params.rn : '', + rom_version: params.rv ? params.rv : '', + location_ip: params.ip ? params.ip : '', + location_latitude: params.lat ? parseFloat(params.lat) : '', + location_longitude: params.lng ? parseFloat(params.lng) : '', + location_country: params.cn ? params.cn : '', + location_province: params.pn ? params.pn : '', + location_city: params.ct ? params.ct : '', + } + + //检查是否有需要更新的数据 + const updateData = {} + for(let key in newDeviceParams) { + if(newDeviceParams[key] && newDeviceParams[key] !== deviceData[key]) { + updateData[key] = newDeviceParams[key] + } + } + + if(Object.keys(updateData).length) { + if(this.debug) { + console.log('Device need to update', updateData) + } + //数据更新 + updateData.last_update_date = dateTime.getTime() + await this.update(this.tableName, updateData, {device_id: params.did}) + } else { + if(this.debug) { + console.log('Device not need update', newDeviceParams) + } + } + + return { + code: 0, + msg: 'success' + } + } + + async bindPush(params) { + if (!params.cid) { + return { + code: 200, + msg: 'Parameter "cid" not found' + } + } + return await this.setDevice(params) + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorLog.js new file mode 100644 index 0000000..05e6c98 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorLog.js @@ -0,0 +1,141 @@ +/** + * @class ErrorLog 错误日志模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const { + DateTime, + UniCrypto +} = require('../lib') +module.exports = class ErrorLog extends BaseMod { + constructor() { + super() + this.tableName = 'error-logs' + } + + /** + * 错误日志数据填充 + * @param {Object} reportParams 上报参数 + */ + async fill(reportParams) { + let params, errorHash, errorCount, cacheKey; + const fillParams = [] + const platform = new Platform() + const dateTime = new DateTime() + const uniCrypto = new UniCrypto() + const channel = new Channel() + const { + needCheck, + checkTime + } = this.getConfig('errorCheck') + const errorCheckTime = Math.max(checkTime, 1) + let spaceId + let spaceProvider + for (const rk in reportParams) { + params = reportParams[rk] + errorHash = uniCrypto.md5(params.em) + cacheKey = 'error-count-' + errorHash + // 校验在指定时间段内是否已存在相同的错误项 + if (needCheck) { + errorCount = await this.getCache(cacheKey) + if (!errorCount) { + errorCount = await this.getCollection(this.tableName).where({ + error_hash: errorHash, + create_time: { + $gte: dateTime.getTime() - errorCheckTime * 60000 + } + }).count() + if (errorCount && errorCount.total > 0) { + await this.setCache(cacheKey, errorCount, errorCheckTime * 60) + } + } + + if (errorCount && errorCount.total > 0) { + if (this.debug) { + console.log('This error have already existsed: ' + params.em) + } + continue + } + } + + //获取云端信息 + spaceId = null + spaceProvider = null + if (params.spi) { + //云函数调用参数 + spaceId = params.spi.spaceId + spaceProvider = params.spi.provider + } else { + //云对象调用参数 + if (params.spid) { + spaceId = params.spid + } + if (params.sppd) { + spaceProvider = params.sppd + } + } + + // 填充数据 + fillParams.push({ + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + device_id: params.did, + uid: params.uid ? params.uid : '', + os: params.on ? params.on : platform.getOsName(params.p), + ua: params.ua ? params.ua : '', + page_url: params.url ? params.url : '', + space_id: spaceId ? spaceId : '', + space_provider: spaceProvider ? spaceProvider : '', + platform_version: params.mpv ? params.mpv : '', + error_msg: params.em ? params.em : '', + error_hash: errorHash, + create_time: dateTime.getTime() + }) + } + + if (fillParams.length === 0) { + return { + code: 200, + msg: 'Invild param' + } + } + + const res = await this.insert(this.tableName, fillParams) + if (res && res.inserted) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'Filled error' + } + } + } + + /** + * 错误日志清理 + * @param {Number} days 日志保留天数 + */ + async clean(days) { + days = Math.max(parseInt(days), 1) + console.log('clean error logs - day:', days) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean error log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorResult.js new file mode 100644 index 0000000..5cd1ff6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/errorResult.js @@ -0,0 +1,459 @@ +/** + * @class ErrorResult 错误结果统计模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const ErrorLog = require('./errorLog') +const AppCrashLogs = require('./appCrashLogs') +const SessionLog = require('./sessionLog') +const { + DateTime +} = require('../lib') +module.exports = class ErrorResult extends BaseMod { + constructor() { + super() + this.tableName = 'error-result' + this.platforms = [] + this.channels = [] + this.versions = [] + this.errors = [] + } + + /** + * 错误结果统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async stat(type, date, reset) { + //前端js错误统计 + const resJs = await this.statJs(type, date, reset) + //原生应用崩溃错误统计 + const resCrash = await this.statCrash(type, date, reset) + + return { + code: 0, + msg: 'success', + data: { + resJs, + resCrash + } + } + } + + /** + * 前端js错误结果统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async statJs(type, date, reset) { + const allowedType = ['day'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + this.fillType = type + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + + if (this.debug) { + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + type: 'js', + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.log('error log have existed') + return { + code: 1003, + msg: 'This log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + type: 'js', + start_time: this.startTime, + end_time: this.endTime + }) + console.log('delete old data result:', JSON.stringify(delRes)) + } + + // 数据获取 + this.errorLog = new ErrorLog() + const statRes = await this.aggregate(this.errorLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + error_hash: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + error_hash: '$error_hash' + }, + error_count: { + $sum: 1 + } + }, + sort: { + error_count: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + if (statRes.data.length > 0) { + this.fillData = [] + for (const i in statRes.data) { + await this.fillJs(statRes.data[i]) + } + + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + /** + * 前端js错误统计结果数据填充 + * @param {Object} data 数据集合 + */ + async fillJs(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + //暂存下数据,减少读库 + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 错误信息 + let errorInfo = null + if (this.errors && this.errors[data._id.error_hash]) { + errorInfo = this.errors[data._id.error_hash] + } else { + const cacheKey = 'uni-stat-errors-' + data._id.error_hash + errorInfo = await this.getCache(cacheKey) + if (!errorInfo) { + errorInfo = await this.getCollection(this.errorLog.tableName).where({ + error_hash: data._id.error_hash + }).limit(1).get() + if (!errorInfo || errorInfo.data.length === 0) { + errorInfo.error_msg = '' + } else { + errorInfo = errorInfo.data[0] + await this.setCache(cacheKey, errorInfo) + } + } + this.errors[data._id.error_hash] = errorInfo + } + + // 最近一次报错时间 + const matchCondition = data._id + Object.assign(matchCondition, { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }) + const lastErrorLog = await this.getCollection(this.errorLog.tableName).where(matchCondition).orderBy( + 'create_time', 'desc').limit(1).get() + let lastErrorTime = '' + if (lastErrorLog && lastErrorLog.data.length > 0) { + lastErrorTime = lastErrorLog.data[0].create_time + } + + //数据填充 + const datetime = new DateTime() + const insertParams = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + type: 'js', + hash: data._id.error_hash, + msg: errorInfo.error_msg, + count: data.error_count, + last_time: lastErrorTime, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + this.fillData.push(insertParams) + + return insertParams + } + + + /** + * 原生应用错误结果统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async statCrash(type, date, reset) { + const allowedType = ['day'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + this.fillType = type + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + + if (this.debug) { + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + type: 'crash', + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.log('error log have existed') + return { + code: 1003, + msg: 'This log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + type: 'crash', + start_time: this.startTime, + end_time: this.endTime + }) + console.log('delete old data result:', JSON.stringify(delRes)) + } + + // 数据获取 + this.crashLogs = new AppCrashLogs() + const statRes = await this.aggregate(this.crashLogs.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel' + }, + error_count: { + $sum: 1 + } + }, + sort: { + error_count: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + if (statRes.data.length > 0) { + this.fillData = [] + for (const i in statRes.data) { + await this.fillCrash(statRes.data[i]) + } + + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + async fillCrash(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + //暂存下数据,减少读库 + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + data._id.channel = data._id.channel ? data._id.channel : '1001' + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + //app启动次数 + const sessionLog = new SessionLog() + const sessionTimesRes = await this.getCollection(sessionLog.tableName).where({ + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }).count() + + let sessionTimes = 0 + if(sessionTimesRes && sessionTimesRes.total > 0) { + sessionTimes = sessionTimesRes.total + } else { + console.log('Not found session logs') + return false + } + + + //数据填充 + const datetime = new DateTime() + const insertParams = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + type: 'crash', + count: data.error_count, + app_launch_count: sessionTimes, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + this.fillData.push(insertParams) + + return insertParams + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/event.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/event.js new file mode 100644 index 0000000..82e104c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/event.js @@ -0,0 +1,72 @@ +/** + * @class StatEvent 事件统计模型 + */ +const BaseMod = require('./base') +const { + DateTime +} = require('../lib') +module.exports = class StatEvent extends BaseMod { + constructor() { + super() + this.tableName = 'events' + this.defaultEvent = this.getConfig('event') || { + login: '登录', + register: '注册', + click: '点击', + share: '分享', + pay_success: '支付成功', + pay_fail: '支付失败' + } + } + + /** + * 获取事件信息 + * @param {String} appid: DCloud appid + * @param {String} eventKey 事件键值 + */ + async getEvent(appid, eventKey) { + const cacheKey = 'uni-stat-event-' + appid + '-' + eventKey + let eventData = await this.getCache(cacheKey) + if (!eventData) { + const eventInfo = await this.getCollection(this.tableName).where({ + appid: appid, + event_key: eventKey + }).get() + eventData = [] + if (eventInfo.data.length > 0) { + eventData = eventInfo.data[0] + await this.setCache(cacheKey, eventData) + } + } + return eventData + } + + + /** + * 获取事件信息不存在则创建 + * @param {String} appid: DCloud appid + * @param {String} eventKey 事件键值 + */ + async getEventAndCreate(appid, eventKey) { + const eventInfo = await this.getEvent(appid, eventKey) + if (eventInfo.length === 0) { + const thisTime = new DateTime().getTime() + const insertParam = { + appid: appid, + event_key: eventKey, + event_name: this.defaultEvent[eventKey] ? this.defaultEvent[eventKey] : '', + create_time: thisTime, + update_time: thisTime + } + const res = await this.insert(this.tableName, insertParam) + + if (res && res.id) { + return Object.assign(insertParam, { + _id: res.id + }) + } + } + + return eventInfo + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventLog.js new file mode 100644 index 0000000..61172cb --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventLog.js @@ -0,0 +1,156 @@ +/** + * @class EventLog 事件日志模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const StatEvent = require('./event') +const SessionLog = require('./sessionLog') +const ShareLog = require('./shareLog') +const { + DateTime +} = require('../lib') +module.exports = class EventLog extends BaseMod { + constructor() { + super() + this.tableName = 'event-logs' + this.sessionLogInfo = [] + } + + /** + * 事件日志填充 + * @param {Object} reportParams 上报参数 + */ + async fill(reportParams) { + let params; + let sessionKey, sessionLogKey; + let sessionLogInfo; + const sessionData = [] + const fillParams = [] + const shareParams = [] + const sessionLog = new SessionLog() + const event = new StatEvent() + const platform = new Platform() + const dateTime = new DateTime() + const channel = new Channel() + for (const rk in reportParams) { + params = reportParams[rk] + + //暂存下会话数据,减少读库 + sessionKey = params.ak + params.did + params.p + if (!this.sessionLogInfo[sessionKey]) { + // 会话日志 + sessionLogInfo = await sessionLog.getSession(params) + if (sessionLogInfo.code) { + return sessionLogInfo + } + if (this.debug) { + console.log('sessionLogInfo', JSON.stringify(sessionLogInfo)) + } + this.sessionLogInfo[sessionKey] = sessionLogInfo + } else { + sessionLogInfo = this.sessionLogInfo[sessionKey] + } + + // 会话数据 + sessionLogKey = sessionLogInfo.data.sessionLogId.toString() + if (!sessionData[sessionLogKey]) { + sessionData[sessionLogKey] = { + eventCount: sessionLogInfo.data.eventCount + 1, + addEventCount: 1, + uid: sessionLogInfo.data.uid, + createTime: sessionLogInfo.data.createTime + } + } else { + sessionData[sessionLogKey].eventCount++ + sessionData[sessionLogKey].addEventCount++ + } + + // 事件 + const eventInfo = await event.getEventAndCreate(params.ak, params.e_n) + + // 填充数据 + fillParams.push({ + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + device_id: params.did, + uid: params.uid ? params.uid : '', + session_id: sessionLogInfo.data.sessionLogId, + page_id: sessionLogInfo.data.pageId, + event_key: eventInfo.event_key, + param: params.e_v ? params.e_v : '', + // 版本 + sdk_version: params.mpsdk ? params.mpsdk : '', + platform_version: params.mpv ? params.mpv : '', + // 设备相关 + device_os_name: params.on ? params.on : platform.getOsName(params.p), + device_os_version: params.sv ? params.sv : '', + device_vendor: params.brand ? params.brand : '', + device_model: params.md ? params.md : '', + device_language: params.lang ? params.lang : '', + device_pixel_ratio: params.pr ? params.pr : '', + device_window_width: params.ww ? params.ww : '', + device_window_height: params.wh ? params.wh : '', + device_screen_width: params.sw ? params.sw : '', + device_screen_height: params.sh ? params.sh : '', + create_time: dateTime.getTime() + }) + // 分享数据 + if (eventInfo.event_key === 'share') { + shareParams.push(params) + } + } + + if (fillParams.length === 0) { + return { + code: 200, + msg: 'Invild param' + } + } + + if (shareParams.length > 0) { + const shareLog = new ShareLog() + await shareLog.fill(shareParams, this.sessionLogInfo) + } + + const res = await this.insert(this.tableName, fillParams) + if (res && res.inserted) { + for (const sid in sessionData) { + await sessionLog.updateSession(sid, sessionData[sid]) + } + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'Filled error' + } + } + } + + /** + * 事件日志清理 + * @param {Number} days 保留天数 + */ + async clean(days) { + days = Math.max(parseInt(days), 1) + console.log('clean event logs - day:', days) + + const dateTime = new DateTime() + //删除过期数据 + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean event log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventResult.js new file mode 100644 index 0000000..89e69a9 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/eventResult.js @@ -0,0 +1,268 @@ +/** + * @class EventResult 事件结果统计 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const EventLog = require('./eventLog') +const { + DateTime +} = require('../lib') +module.exports = class EventResult extends BaseMod { + constructor() { + super() + this.tableName = 'event-result' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + * 事件数据统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async stat(type, date, reset) { + const allowedType = ['day'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + this.fillType = type + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + if (this.debug) { + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.log('event log have existed') + return { + code: 1003, + msg: 'This log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + start_time: this.startTime, + end_time: this.endTime + }) + console.log('delete old data result:', JSON.stringify(delRes)) + } + + // 数据获取 + this.eventLog = new EventLog() + const statRes = await this.aggregate(this.eventLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + event_key: 1, + device_id: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + event_key: '$event_key' + }, + event_count: { + $sum: 1 + } + }, + sort: { + event_count: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + if (statRes.data.length > 0) { + this.fillData = [] + for (const i in statRes.data) { + await this.fill(statRes.data[i]) + } + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + /** + * 事件统计数据填充 + * @param {Object} data 数据集合 + */ + async fill(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + //暂存下数据,减少读库 + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + const matchCondition = data._id + Object.assign(matchCondition, { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }) + if (this.debug) { + console.log('matchCondition', JSON.stringify(matchCondition)) + } + + // 触发事件设备数统计 + const statEventDeviceRes = await this.aggregate(this.eventLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + event_key: 1, + device_id: 1, + create_time: 1 + }, + match: matchCondition, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + let eventDeviceCount = 0 + if (statEventDeviceRes.data.length > 0) { + eventDeviceCount = statEventDeviceRes.data[0].total_devices + } + + // 触发事件用户数统计 + const statEventUserRes = await this.aggregate(this.eventLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + event_key: 1, + uid: 1, + create_time: 1 + }, + match: { + ...matchCondition, + uid: { + $ne: '' + } + }, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + let eventUserCount = 0 + if (statEventUserRes.data.length > 0) { + eventUserCount = statEventUserRes.data[0].total_users + } + + const datetime = new DateTime() + const insertParams = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + event_key: data._id.event_key, + event_count: data.event_count, + device_count: eventDeviceCount, + user_count: eventUserCount, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + this.fillData.push(insertParams) + return insertParams + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/index.js new file mode 100644 index 0000000..4980049 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/index.js @@ -0,0 +1,23 @@ +/** + * 基础对外模型 + */ +module.exports = { + BaseMod: require('./base'), + SessionLog: require('./sessionLog'), + UserSessionLog: require('./userSessionLog'), + PageLog: require('./pageLog'), + EventLog: require('./eventLog'), + ShareLog: require('./shareLog'), + ErrorLog: require('./errorLog'), + AppCrashLogs: require('./appCrashLogs'), + StatResult: require('./statResult'), + ActiveUsers: require('./activeUsers'), + ActiveDevices: require('./activeDevices'), + PageResult: require('./pageResult'), + EventResult: require('./eventResult'), + ErrorResult: require('./errorResult'), + Loyalty: require('./loyalty'), + RunErrors: require('./runErrors'), + uniPay: require('./uni-pay'), + Setting: require('./setting'), +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/loyalty.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/loyalty.js new file mode 100644 index 0000000..273c04b --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/loyalty.js @@ -0,0 +1,491 @@ +/** + * 设备/用户忠诚度(粘性)统计模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const SessionLog = require('./sessionLog') +const UserSessionLog = require('./userSessionLog') +const { + DateTime +} = require('../lib') +module.exports = class Loyalty extends BaseMod { + constructor() { + super() + this.tableName = 'loyalty-result' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + * 设备/用户忠诚度(粘性)统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async stat(type, date, reset) { + const allowedType = ['day'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + + this.fillType = type + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + + if (this.debug) { + console.log('this time', dateTime.getTime()) + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.log('loyalty log have existed') + return { + code: 1003, + msg: 'This log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + start_time: this.startTime, + end_time: this.endTime + }) + console.log('delete old data result:', JSON.stringify(delRes)) + } + + // 数据获取 + this.sessionLog = new SessionLog() + const statRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_count: 1, + duration: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel' + }, + page_count_sum: { + $sum: '$page_count' + }, + duration_sum: { + $sum: '$duration' + } + }, + sort: { + page_count_sum: 1, + duration_sum: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + if (statRes.data.length > 0) { + this.fillData = [] + for (const i in statRes.data) { + await this.fill(statRes.data[i]) + } + + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + /** + * 设备/用户忠诚度(粘性)数据填充 + * @param {Object} data 数据集合 + */ + async fill(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 访问深度-用户数统计和访问次数 + const pageMark = [1, 2, 3, 4, [5, 10], [10]] + + const matchCondition = Object.assign(data._id, { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }) + + const visitDepthData = { + visit_devices: {}, + visit_users: {}, + visit_times: {} + } + + const userSessionLog = new UserSessionLog() + //根据各访问页面数区间统计 + for (const pi in pageMark) { + let pageMarkCondition = { + page_count: pageMark[pi] + } + + if (Array.isArray(pageMark[pi])) { + if (pageMark[pi].length === 2) { + pageMarkCondition = { + page_count: { + $gte: pageMark[pi][0], + $lte: pageMark[pi][1] + } + } + } else { + pageMarkCondition = { + page_count: { + $gt: pageMark[pi][0] + } + } + } + } + + // 访问次数(会话次数)统计 + const searchCondition = { + ...matchCondition, + ...pageMarkCondition + } + const vistRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_count: 1, + create_time: 1 + }, + match: searchCondition, + group: { + _id: {}, + total_visits: { + $sum: 1 + } + } + }) + + if (this.debug) { + console.log('vistResCondtion', JSON.stringify(searchCondition)) + console.log('vistRes', JSON.stringify(vistRes)) + } + let vistCount = 0 + if (vistRes.data.length > 0) { + vistCount = vistRes.data[0].total_visits + } + + // 设备数统计 + const deviceRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_count: 1, + create_time: 1, + device_id: 1 + }, + match: searchCondition, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('searchCondition', JSON.stringify(searchCondition)) + console.log('deviceRes', JSON.stringify(deviceRes)) + } + + let deviceCount = 0 + if (deviceRes.data.length > 0) { + deviceCount = deviceRes.data[0].total_devices + } + + // 用户数统计 + const userRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_count: 1, + create_time: 1, + uid: 1 + }, + match: searchCondition, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('userResCondtion', JSON.stringify(searchCondition)) + console.log('userRes', JSON.stringify(userRes)) + } + + let userCount = 0 + if (userRes.data.length > 0) { + userCount = userRes.data[0].total_users + } + + const pageKey = 'p_' + (Array.isArray(pageMark[pi]) ? pageMark[pi][0] : pageMark[pi]) + visitDepthData.visit_devices[pageKey] = deviceCount + visitDepthData.visit_users[pageKey] = userCount + visitDepthData.visit_times[pageKey] = vistCount + } + + // 访问时长-用户数统计和访问次数 + const durationMark = [ + [0, 2], + [3, 5], + [6, 10], + [11, 20], + [21, 30], + [31, 50], + [51, 100], + [100] + ] + const durationData = { + visit_devices: {}, + visit_users: {}, + visit_times: {} + } + //根据各访问时长区间统计 + for (const di in durationMark) { + let durationMarkCondition = { + duration: durationMark[di] + } + + if (Array.isArray(durationMark[di])) { + if (durationMark[di].length === 2) { + durationMarkCondition = { + duration: { + $gte: durationMark[di][0], + $lte: durationMark[di][1] + } + } + } else { + durationMarkCondition = { + duration: { + $gt: durationMark[di][0] + } + } + } + } + + // 访问次数(会话次数)统计 + const searchCondition = { + ...matchCondition, + ...durationMarkCondition + } + if (this.debug) { + console.log('searchCondition', JSON.stringify(searchCondition)) + } + const vistRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + duration: 1, + create_time: 1 + }, + match: searchCondition, + group: { + _id: {}, + total_visits: { + $sum: 1 + } + } + }) + + if (this.debug) { + console.log('vistRes', JSON.stringify(vistRes)) + } + let vistCount = 0 + if (vistRes.data.length > 0) { + vistCount = vistRes.data[0].total_visits + } + + // 设备数统计 + const deviceRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + duration: 1, + create_time: 1 + }, + match: searchCondition, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('userRes', JSON.stringify(deviceRes)) + } + + let deviceCount = 0 + if (deviceRes.data.length > 0) { + deviceCount = deviceRes.data[0].total_devices + } + + // 用户数统计 + const userRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + duration: 1, + create_time: 1 + }, + match: searchCondition, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('userRes', JSON.stringify(userRes)) + } + + let userCount = 0 + if (userRes.data.length > 0) { + userCount = userRes.data[0].total_users + } + + const pageKey = 's_' + (Array.isArray(durationMark[di]) ? durationMark[di][0] : durationMark[di]) + durationData.visit_devices[pageKey] = deviceCount + durationData.visit_users[pageKey] = userCount + durationData.visit_times[pageKey] = vistCount + } + + // 数据填充 + const datetime = new DateTime() + const insertParams = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + visit_depth_data: visitDepthData, + duration_data: durationData, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + this.fillData.push(insertParams) + return insertParams + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/page.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/page.js new file mode 100644 index 0000000..260fdc1 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/page.js @@ -0,0 +1,83 @@ +/** + * @class Page 页面模型 + */ +const BaseMod = require('./base') +const { + parseUrl +} = require('../../shared') +const { + DateTime +} = require('../lib') +module.exports = class Page extends BaseMod { + constructor() { + super() + this.tableName = 'pages' + } + + /** + * 获取页面信息 + * @param {String} appid + * @param {String} url 页面地址 + */ + async getPage(appid, url) { + const cacheKey = 'uni-stat-page-' + appid + '-' + url + let pageData = await this.getCache(cacheKey) + if (!pageData) { + const pageInfo = await this.getCollection(this.tableName).where({ + appid: appid, + path: url + }).limit(1).get() + pageData = [] + if (pageInfo.data.length > 0) { + pageData = pageInfo.data[0] + await this.setCache(cacheKey, pageData) + } + } + return pageData + } + + /** + * 获取页面信息不存在则创建 + * @param {String} appid + * @param {String} url 页面地址 + * @param {Object} title 页面标题 + */ + async getPageAndCreate(appid, url, title) { + //获取url信息 + const urlInfo = parseUrl(url) + if (!urlInfo) { + return false + } + const baseurl = urlInfo.path + const pageInfo = await this.getPage(appid, baseurl) + //页面不存在则创建 + if (pageInfo.length === 0) { + const thisTime = new DateTime().getTime() + const insertParam = { + appid: appid, + path: baseurl, + title: title, + page_params: [], + create_time: thisTime, + update_time: thisTime + } + const res = await this.insert(this.tableName, insertParam) + + if (res && res.id) { + return Object.assign(insertParam, { + _id: res.id + }) + } + } else if (!pageInfo.title && title) { + const cacheKey = 'uni-stat-page-' + appid + '-' + baseurl + await this.clearCache(cacheKey) + await this.update(this.tableName, { + title: title + }, { + _id: pageInfo._id + }) + } + + return pageInfo + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageLog.js new file mode 100644 index 0000000..6cc03d6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageLog.js @@ -0,0 +1,186 @@ +/** + * @class PageLog 页面日志模型 + */ +const BaseMod = require('./base') +const Page = require('./page') +const Platform = require('./platform') +const Channel = require('./channel') +const SessionLog = require('./sessionLog') +const { + DateTime +} = require('../lib') +const { + parseUrl +} = require('../../shared') +module.exports = class PageLog extends BaseMod { + constructor() { + super() + this.tableName = 'page-logs' + this.sessionLogInfo = [] + } + + /** + * 页面日志数据填充 + * @param {Object} reportParams 上报参数 + */ + async fill(reportParams) { + let params; + let sessionKey + let sessionLogKey + let sessionLogInfo + let pageKey + let pageInfo + let referPageInfo + const sessionData = [] + const pageData = [] + const fillParams = [] + const sessionLog = new SessionLog() + const page = new Page() + const platform = new Platform() + const dateTime = new DateTime() + const channel = new Channel() + for (const pk in reportParams) { + params = reportParams[pk] + if (['3', '4'].includes(params.lt) && !params.url && params.urlref) { + params.url = params.urlref + } + + // 页面信息 + pageKey = params.ak + params.url + if (pageData[pageKey]) { + pageInfo = pageData[pageKey] + } else { + pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj) + if (!pageInfo || pageInfo.length === 0) { + console.log('Not found this page by param:', JSON.stringify(params)) + continue + } + pageData[pageKey] = pageInfo + } + + // 会话日志,暂存下会话数据,减少读库 + sessionKey = params.ak + params.did + params.p + if (!this.sessionLogInfo[sessionKey]) { + sessionLogInfo = await sessionLog.getSession(params) + if (sessionLogInfo.code) { + return sessionLogInfo + } + if (this.debug) { + console.log('sessionLogInfo', JSON.stringify(sessionLogInfo)) + } + this.sessionLogInfo[sessionKey] = sessionLogInfo + } else { + sessionLogInfo = this.sessionLogInfo[sessionKey] + } + + // 会话数据 + sessionLogKey = sessionLogInfo.data.sessionLogId.toString() + if (!sessionData[sessionLogKey]) { + //临时存储减少查询次数 + sessionData[sessionLogKey] = { + pageCount: sessionLogInfo.data.pageCount + 1, + addPageCount: 1, + createTime: sessionLogInfo.data.createTime, + pageId: pageInfo._id, + uid: sessionLogInfo.data.uid + } + + if (this.debug) { + console.log('add sessionData - ' + sessionLogKey, sessionData) + } + + } else { + sessionData[sessionLogKey].pageCount += 1 + sessionData[sessionLogKey].addPageCount += 1 + sessionData[sessionLogKey].pageId = pageInfo._id + + if (this.debug) { + console.log('update sessionData - ' + sessionLogKey, sessionData) + } + } + + // 上级页面信息 + pageKey = params.ak + params.urlref + if (pageData[pageKey]) { + referPageInfo = pageData[pageKey] + } else { + referPageInfo = await page.getPageAndCreate(params.ak, params.urlref, params.ttpj) + if (!referPageInfo || referPageInfo.length === 0) { + referPageInfo = {_id:''} + } + pageData[pageKey] = referPageInfo + } + + //当前页面url信息 + const urlInfo = parseUrl(params.url) + + // 填充数据 + fillParams.push({ + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + device_id: params.did, + uid: params.uid ? params.uid : '', + session_id: sessionLogInfo.data.sessionLogId, + page_id: pageInfo._id, + query_string: urlInfo.query, + //上级页面相关 + previous_page_id: referPageInfo._id, + previous_page_duration: params.urlref_ts ? parseInt(params.urlref_ts) : 0, + previous_page_is_entry: referPageInfo._id === sessionLogInfo.data.entryPageId ? 1 : 0, + create_time: dateTime.getTime() + }) + } + + if (fillParams.length === 0) { + console.log('No page params') + return { + code: 200, + msg: 'Invild param' + } + } + + //日志数据入库 + const res = await this.insert(this.tableName, fillParams) + if (res && res.inserted) { + // 更新会话数据 + const nowTime = dateTime.getTime() + for (const sid in sessionData) { + await sessionLog.updateSession(sid, sessionData[sid]) + } + + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'Filled error' + } + } + } + + /** + * 页面日志清理 + * @param {Number} days 页面日志保留天数 + */ + async clean(days) { + days = Math.max(parseInt(days), 1) + console.log('clean page logs - day:', days) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean page log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageResult.js new file mode 100644 index 0000000..d002ed3 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/pageResult.js @@ -0,0 +1,522 @@ +/** + * @class PageResult 页面结果统计模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const SessionLog = require('./sessionLog') +const PageLog = require('./pageLog') +const ShareLog = require('./shareLog') +const { + DateTime +} = require('../lib') +module.exports = class PageResult extends BaseMod { + constructor() { + super() + this.tableName = 'page-result' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + * 数据统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async stat(type, date, reset) { + //允许的类型 + const allowedType = ['day'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + this.fillType = type + //获取当前统计的时间范围 + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + if (this.debug) { + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复执行 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.error('This page stat log have exists') + return { + code: 1003, + msg: 'This page stat log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + start_time: this.startTime, + end_time: this.endTime + }) + console.log('Delete old data result:', JSON.stringify(delRes)) + } + + // 数据获取 + this.pageLog = new PageLog() + const statRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_id: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + page_id: '$page_id' + }, + visit_times: { + $sum: 1 + } + }, + sort: { + visit_times: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('Page statRes', JSON.stringify(statRes)) + } + if (statRes.data.length > 0) { + this.fillData = [] + //获取填充数据 + for (const i in statRes.data) { + await this.fill(statRes.data[i]) + } + + //数据批量入库 + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + } + return res + } + + /** + * 页面统计数据填充 + * @param {Object} data 统计数据 + */ + async fill(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + //暂存下数据,减少读库 + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + const matchCondition = data._id + Object.assign(matchCondition, { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }) + if (this.debug) { + console.log('matchCondition', JSON.stringify(matchCondition)) + } + + // 当前页面访问设备数 + const statPageDeviceRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + page_id: 1, + create_time: 1 + }, + match: matchCondition, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + let pageVisitDevices = 0 + if (statPageDeviceRes.data.length > 0) { + pageVisitDevices = statPageDeviceRes.data[0].total_devices + } + + // 当前页面访问人数 + const statPageUserRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + page_id: 1, + create_time: 1 + }, + match: { + ...matchCondition, + uid: { + $ne: '' + } + }, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + let pageVisitUsers = 0 + if (statPageUserRes.data.length > 0) { + pageVisitUsers = statPageUserRes.data[0].total_users + } + + // 退出次数 + const sessionLog = new SessionLog() + let existTimes = 0 + const existRes = await this.getCollection(sessionLog.tableName).where({ + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + exit_page_id: data._id.page_id, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }).count() + if (existRes && existRes.total > 0) { + existTimes = existRes.total + } + + // 访问时长 + const statPageDurationRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + previous_page_id: 1, + previous_page_duration: 1, + create_time: 1 + }, + match: { + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + previous_page_id: data._id.page_id, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: {}, + total_duration: { + $sum: '$previous_page_duration' + } + } + }) + + let totalDuration = 0 + if (statPageDurationRes.data.length > 0) { + totalDuration = statPageDurationRes.data[0].total_duration + } + + // 分享次数 + const shareLog = new ShareLog() + const statShareRes = await this.aggregate(shareLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + page_id: 1, + create_time: 1 + }, + match: { + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + page_id: data._id.page_id, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: {}, + share_count: { + $sum: 1 + } + } + }) + + let shareCount = 0 + if (statShareRes.data.length > 0) { + shareCount = statShareRes.data[0].share_count + } + + // 作为入口页的总次数和总访问时长 + const statPageEntryCountRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + previous_page_id: 1, + previous_page_duration: 1, + previous_page_is_entry: 1, + create_time: 1 + }, + match: { + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + previous_page_id: data._id.page_id, + previous_page_is_entry: 1, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: {}, + entry_count: { + $sum: 1 + }, + entry_duration: { + $sum: '$previous_page_duration' + } + } + }) + + let entryCount = 0 + let entryDuration = 0 + if (statPageEntryCountRes.data.length > 0) { + entryCount = statPageEntryCountRes.data[0].entry_count + entryDuration = statPageEntryCountRes.data[0].entry_duration + } + + // 作为入口页的总设备数 + const statPageEntryDevicesRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + previous_page_id: 1, + previous_page_is_entry: 1, + create_time: 1 + }, + match: { + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + previous_page_id: data._id.page_id, + previous_page_is_entry: 1, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + entry_devices: { + $sum: 1 + } + }] + }) + + let entryDevices = 0 + if (statPageEntryDevicesRes.data.length > 0) { + entryDevices = statPageEntryDevicesRes.data[0].entry_devices + } + + // 作为入口页的总人数 + const statPageEntryUsersRes = await this.aggregate(this.pageLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + previous_page_id: 1, + previous_page_is_entry: 1, + create_time: 1 + }, + match: { + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + previous_page_id: data._id.page_id, + previous_page_is_entry: 1, + uid: { + $ne: '' + }, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + entry_users: { + $sum: 1 + } + }] + }) + + let entryUsers = 0 + if (statPageEntryUsersRes.data.length > 0) { + entryUsers = statPageEntryUsersRes.data[0].entry_users + } + + // 跳出率 + let bounceTimes = 0 + const bounceRes = await this.getCollection(sessionLog.tableName).where({ + appid: data._id.appid, + version: data._id.version, + platform: data._id.platform, + channel: data._id.channel, + entry_page_id: data._id.page_id, + page_count: 1, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }).count() + if (bounceRes && bounceRes.total > 0) { + bounceTimes = bounceRes.total + } + let bounceRate = 0 + if (bounceTimes > 0 && data.visit_times > 0) { + bounceRate = bounceTimes * 100 / data.visit_times + bounceRate = parseFloat(bounceRate.toFixed(2)) + } + + // 数据填充 + const datetime = new DateTime() + const insertParams = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + page_id: data._id.page_id, + visit_times: data.visit_times, + visit_devices: pageVisitDevices, + visit_users: pageVisitUsers, + exit_times: existTimes, + duration: totalDuration > 0 ? totalDuration : 1, + share_count: shareCount, + entry_users: entryUsers, + entry_devices: entryDevices, + entry_count: entryCount, + entry_duration: entryDuration, + bounce_rate: bounceRate, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + this.fillData.push(insertParams) + return insertParams + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/platform.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/platform.js new file mode 100644 index 0000000..5a5bcfd --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/platform.js @@ -0,0 +1,160 @@ +/** + * @class Platform 应用平台模型 + */ +const BaseMod = require('./base') +const { + DateTime +} = require('../lib') +module.exports = class Platform extends BaseMod { + constructor() { + super() + this.tableName = 'app-platforms' + } + + /** + * 获取平台信息 + * @param {String} platform 平台代码 + * @param {String} os 系统 + */ + async getPlatform(platform, os) { + const cacheKey = 'uni-stat-platform-' + platform + '-' + os + let platformData = await this.getCache(cacheKey) + if (!platformData) { + const platformCode = this.getPlatformCode(platform, os) + const platformInfo = await this.getCollection(this.tableName).where({ + code: platformCode + }).limit(1).get() + platformData = [] + if (platformInfo.data.length > 0) { + platformData = platformInfo.data[0] + await this.setCache(cacheKey, platformData) + } + } + return platformData + } + + /** + * 获取平台信息没有则创建 + * @param {String} platform 平台代码 + * @param {String} os 系统 + */ + async getPlatformAndCreate(platform, os) { + if (!platform) { + return false + } + const platformInfo = await this.getPlatform(platform, os) + + if (platformInfo.length === 0) { + const platformCode = this.getPlatformCode(platform, os) + const insertParam = { + code: platformCode, + name: platformCode, + create_time: new DateTime().getTime() + } + const res = await this.insert(this.tableName, insertParam) + if (res && res.id) { + return Object.assign(insertParam, { + _id: res.id + }) + } + } + return platformInfo + } + + /** + * 获取平台代码 + * @param {String} platform 平台代码 + * @param {String} os 系统 + */ + getPlatformCode(platform, os) { + let platformCode = platform + + //兼容客户端上报参数 + switch(platform) { + //h5|web + case 'h5': + platformCode = 'web' + break + //微信小程序 + case 'wx': + platformCode = 'mp-weixin' + break + //百度小程序 + case 'bd': + platformCode = 'mp-baidu' + break + //支付宝小程序 + case 'ali': + platformCode = 'mp-alipay' + break + //字节跳动小程序 + case 'tt': + platformCode = 'mp-toutiao' + break + //qq小程序 + case 'qq': + platformCode = 'mp-qq' + break + //快应用联盟 + case 'qn': + platformCode = 'quickapp-webview-union' + break + //快应用(webview) + case 'qw': + platformCode = 'quickapp-webview' + break + //快应用华为 + case 'qi': + platformCode = 'quickapp-webview-huawei' + break + //360小程序 + case '360': + platformCode = 'mp-360' + break + //京东小程序 + case 'jd': + platformCode = 'mp-jd' + break + //钉钉小程序 + case 'dt': + platformCode = 'mp-dingtalk' + break + //快手小程序 + case 'ks': + platformCode = 'mp-kuaishou' + break + //飞书小程序 + case 'lark': + platformCode = 'mp-lark' + break + //原生应用 + case 'n': + case 'app-plus': + case 'app': + os = this.getOsName(os) + if (os === 'ios') { + platformCode = 'ios' + } else { + platformCode = 'android' + } + break + } + return platformCode + } + + /** + * 获取系统名称 + * @param {Object} os系统标识 + */ + getOsName(os) { + if(!os) { + return '' + } + //兼容老版上报参数 + const osSetting = { + i: 'ios', + a: 'android' + } + return osSetting[os] ? osSetting[os] : os + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/runErrors.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/runErrors.js new file mode 100644 index 0000000..be09242 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/runErrors.js @@ -0,0 +1,20 @@ +/** + * @class RunErrors 运行错误日志 + */ +const BaseMod = require('./base') +module.exports = class RunErrors extends BaseMod { + constructor() { + super() + this.tableName = 'run-errors' + } + + /** + * 创建日志 + * @param {Object} params 参数 + */ + async create(params) { + if (!params) return + const res = await this.insert(this.tableName, params) + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/scenes.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/scenes.js new file mode 100644 index 0000000..af04b3c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/scenes.js @@ -0,0 +1,80 @@ +/** + * @class Scenes 场景值模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +module.exports = class Scenes extends BaseMod { + constructor() { + super() + this.tableName = 'mp-scenes' + this.defualtCode = '1001' + } + + /** + * 获取场景值 + * @param {String} platform 平台代码 + * @param {String} code 场景值代码 + */ + async getScenes(platform, code) { + const cacheKey = 'uni-stat-scenes-' + platform + '-' + code + let scenesData = await this.getCache(cacheKey) + if (!scenesData) { + const scenesInfo = await this.getCollection(this.tableName).where({ + platform: platform, + scene_code: code + }).limit(1).get() + scenesData = [] + if (scenesInfo.data.length > 0) { + scenesData = scenesInfo.data[0] + await this.setCache(cacheKey, scenesData) + } + } + return scenesData + } + + /** + * 通过平台编号获取场景值 + * @param {String} platformId 平台编号 + * @param {String} code 场景值代码 + */ + async getScenesByPlatformId(platformId, code) { + const platform = new Platform() + let platformInfo = await this.getCollection(platform.tableName).where({ + _id: platformId + }).limit(1).get() + let scenesData + if (platformInfo.data.length > 0) { + platformInfo = platformInfo.data[0] + scenesData = await this.getScenes(platformInfo.code, code) + } else { + scenesData = [] + } + return scenesData + } + + /** + * 获取场景值名称 + * @param {String} platform 平台代码 + * @param {String} code 场景值代码 + */ + async getScenesName(platform, code) { + const scenesData = await this.getScenes(platform, code) + if (scenesData.length === 0) { + return '' + } + return scenesData.scene_name + } + + /** + * 通过平台编号获取场景值名称 + * @param {String} platformId 平台编号 + * @param {String} code 场景值代码 + */ + async getScenesNameByPlatformId(platformId, code) { + const scenesData = await this.getScenesByPlatformId(platformId, code) + if (scenesData.length === 0) { + return code === this.defualtCode ? '默认' : '' + } + return scenesData.scene_name + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/sessionLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/sessionLog.js new file mode 100644 index 0000000..34f3c85 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/sessionLog.js @@ -0,0 +1,343 @@ +/** + * @class SessionLog 基础会话日志模型 + */ +const BaseMod = require('./base') +const Page = require('./page') +const Platform = require('./platform') +const Channel = require('./channel') +const UserSessionLog = require('./userSessionLog') +const Device = require('./device') +const { + DateTime +} = require('../lib') +module.exports = class SessionLog extends BaseMod { + constructor() { + super() + this.tableName = 'session-logs' + } + + + /** + * 会话日志批量填充 + * @param {Object} reportParams 上报参数 + */ + async batchFill(reportParams) { + let params, pageInfo, nowTime, firstVistTime, lastVistTime; + const fillParams = [] + + const page = new Page() + const platform = new Platform() + const dateTime = new DateTime() + const channel = new Channel() + const device = new Device() + let res + for (const pk in reportParams) { + params = reportParams[pk] + res = await this.fill(params) + if (res.code) { + console.error(res.msg) + } else { + //添加设备信息 + await device.setDevice(params) + } + } + return res + } + + /** + * 会话日志填充 + * @param {Object} params 上报参数 + */ + async fill(params) { + // 应用信息 + if (!params.ak) { + return { + code: 200, + msg: 'Parameter "ak" not found' + } + } + + // 平台信息 + if (!params.ut) { + return { + code: 200, + msg: 'Parameter "ut" not found' + } + } + + // 设备信息 + if (!params.did) { + return { + code: 200, + msg: 'Parameter "did" not found' + } + } + + // 页面信息 + const page = new Page() + const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj) + if (!pageInfo || pageInfo.length === 0) { + return { + code: 300, + msg: 'Not found this entry page' + } + } + if (this.debug) { + console.log('pageInfo', JSON.stringify(pageInfo)) + } + const platform = new Platform() + const dateTime = new DateTime() + const channel = new Channel() + const nowTime = dateTime.getTime() + const firstVistTime = params.fvts ? dateTime.strToTime(params.fvts) : nowTime + const lastVistTime = (params.lvts && params.lvts !== '0') ? dateTime.strToTime(params.lvts) : 0 + + const fillParams = { + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + type: params.cst ? parseInt(params.cst) : 0, + // 访问设备 + device_id: params.did, + //是否为首次访问,判断标准:最后一次访问时间为0 + is_first_visit: (params.lt === '1' && !lastVistTime) ? 1 : 0, + first_visit_time: firstVistTime, + last_visit_time: nowTime, + visit_count: params.tvc ? parseInt(params.tvc) : 1, + // 用户相关 + last_visit_user_id: params.uid ? params.uid : '', + // 页面相关 + entry_page_id: pageInfo._id, + exit_page_id: pageInfo._id, + page_count: 0, + event_count: 0, + duration: 1, + // 版本 + sdk_version: params.mpsdk ? params.mpsdk : '', + platform_version: params.mpv ? params.mpv : '', + // 设备相关 + device_os_name: params.on ? params.on : platform.getOsName(params.p), + device_os_version: params.sv ? params.sv : '', + device_vendor: params.brand ? params.brand : '', + device_model: params.md ? params.md : '', + device_language: params.lang ? params.lang : '', + device_pixel_ratio: params.pr ? params.pr : '', + device_window_width: params.ww ? params.ww : '', + device_window_height: params.wh ? params.wh : '', + device_screen_width: params.sw ? params.sw : '', + device_screen_height: params.sh ? params.sh : '', + // 地区相关 + location_ip: params.ip ? params.ip : '', + location_latitude: params.lat ? parseFloat(params.lat) : -1, + location_longitude: params.lng ? parseFloat(params.lng) : -1, + location_country: params.cn ? params.cn : '', + location_province: params.pn ? params.pn : '', + location_city: params.ct ? params.ct : '', + is_finish: 0, + create_time: nowTime + } + + if(this.isHaveOldDeviceId(params)) { + fillParams.old_device_id = params.odid + } + + const res = await this.insert(this.tableName, fillParams) + + if (res && res.id) { + + //填充用户的会话日志 + if (params.uid) { + await new UserSessionLog().fill({ + ...params, + page_id: pageInfo._id, + sid: res.id + }) + } + + return { + code: 0, + msg: 'success', + data: { + pageId: pageInfo._id, + sessionLogId: res.id, + entryPageId: fillParams.entry_page_id, + eventCount: fillParams.event_count, + startTime: fillParams.first_visit_time, + createTime: fillParams.create_time, + pageCount: fillParams.page_count, + uid: fillParams.last_visit_user_id + } + } + } else { + return { + code: 500, + msg: 'Session log filled error' + } + } + } + + /** + * 判断是否包含老版本sdk生成的device_id, 此功能用于处理前端sdk升级后 device_id 发生变化导致日活、留存数据不准确的问题 + * @param {Object} params + */ + isHaveOldDeviceId(params) { + if(params.odid && params.odid !== params.did && params.odid !== 'YluY92BA6nJ6NfixI77sFQ%3D%3D&ie=1') { + console.log('params.odid', params.odid) + return true + } + return false + } + + + /** + * 获取会话 + * @param {Object} params 上报参数 + */ + async getSession(params) { + // 页面信息 + const page = new Page() + const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj) + if (!pageInfo || pageInfo.length === 0) { + return { + code: 300, + msg: 'Not found this entry page' + } + } + + const platformObj = new Platform() + const platform = platformObj.getPlatformCode(params.ut, params.p) + // 查询日志 + const sessionLogInfo = await this.getCollection(this.tableName).where({ + appid: params.ak, + platform: platform, + device_id: params.did, + is_finish: 0 + }).orderBy('create_time', 'desc').limit(1).get() + + if (sessionLogInfo.data.length > 0) { + const userSessionLog = new UserSessionLog() + const sessionLogInfoData = sessionLogInfo.data[0] + // 最后一次访问时间距现在超过半小时算上次会话已结束并生成一次新的会话 + let sessionExpireTime = this.getConfig('sessionExpireTime') + sessionExpireTime = sessionExpireTime ? sessionExpireTime : 1800 + const sessionTime = new DateTime().getTime() - sessionLogInfoData.last_visit_time + if (sessionTime >= sessionExpireTime * 1000) { + if (this.debug) { + console.log('session log time expired', sessionTime) + } + await this.update(this.tableName, { + is_finish: 1 + }, { + appid: params.ak, + platform: platform, + device_id: params.did, + is_finish: 0 + }) + //关闭用户会话 + await userSessionLog.closeUserSession() + + return await this.fill(params) + } else { + //如果当前会话切换了用户则生成新的用户会话 + if (params.uid != sessionLogInfoData.last_visit_user_id) { + await userSessionLog.checkUserSession({ + ...params, + page_id: pageInfo._id, + sid: sessionLogInfoData._id, + last_visit_user_id: sessionLogInfoData.last_visit_user_id + }) + + await this.update(this.tableName, { + last_visit_user_id: params.uid ? params.uid : '' + }, { + _id: sessionLogInfoData._id + }) + } + + return { + code: 0, + msg: 'success', + data: { + pageId: pageInfo._id, + sessionLogId: sessionLogInfoData._id, + entryPageId: sessionLogInfoData.entry_page_id, + eventCount: sessionLogInfoData.event_count, + startTime: sessionLogInfoData.first_visit_time, + createTime: sessionLogInfoData.create_time, + pageCount: sessionLogInfoData.page_count, + uid: sessionLogInfoData.last_visit_user_id + } + } + } + } else { + return await this.fill(params) + } + } + + /** + * 更新会话信息 + * @param {String} sid 会话编号 + * @param {Object} data 更新数据 + */ + async updateSession(sid, data) { + const nowTime = new DateTime().getTime() + const accessTime = nowTime - data.createTime + const accessSenconds = accessTime > 1000 ? parseInt(accessTime / 1000) : 1 + + const updateData = { + last_visit_time: nowTime, + duration: accessSenconds, + } + //访问页面数量 + if (data.addPageCount) { + updateData.page_count = data.pageCount + } + //最终访问的页面编号 + if (data.pageId) { + updateData.exit_page_id = data.pageId + } + //产生事件次数 + if (data.eventCount) { + updateData.event_count = data.eventCount + } + + if (this.debug) { + console.log('update session log by sid-' + sid, updateData) + } + + //更新会话 + await this.update(this.tableName, updateData, { + _id: sid + }) + + //更新用户会话 + if (data.uid) { + data.nowTime = nowTime + await new UserSessionLog().updateUserSession(sid, data) + } + + return true + } + + /** + * 清理日志数据 + * @param {Number} days 保留天数, 留存统计需要计算30天后留存率,因此至少应保留31天的日志数据 + */ + async clean(days) { + days = Math.max(parseInt(days), 1) + console.log('clean session logs - day:', days) + + const dateTime = new DateTime() + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean session log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/setting.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/setting.js new file mode 100644 index 0000000..c0ebc94 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/setting.js @@ -0,0 +1,44 @@ +/** + * @class Version 应用版本模型 + */ +const BaseMod = require('./base') +const { + DateTime +} = require('../lib') +module.exports = class Setting extends BaseMod { + constructor() { + super() + this.tableName = 'opendb-tempdata' + this.tablePrefix = false + this.settingKey = "uni-stat-setting" + } + + /** + * 获取统计云端配置 + */ + async getSetting() { + const res = await this.getCollection(this.tableName).doc(this.settingKey).get(); + if (res.data && res.data[0] && res.data[0].value) { + return res.data[0].value; + } else { + return { + mode: "open", + day: 7 + }; + } + } + /** + * 检测N天内是否有设备访问记录,如果有,则返回true,否则返回false + */ + async checkAutoRun(obj = {}) { + let { + day = 7 + } = obj; + const _ = this.dbCmd; + let nowTime = Date.now(); + const res = await this.getCollection("uni-stat-session-logs").where({ + create_time: _.gte(nowTime - 1000 * 3600 * 24 * day) + }).count(); + return res.total > 0 ? true : false; + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/shareLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/shareLog.js new file mode 100644 index 0000000..5f42138 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/shareLog.js @@ -0,0 +1,104 @@ +/** + * @class ShareLog 分享日志模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const SessionLog = require('./sessionLog') +const { + DateTime +} = require('../lib') +module.exports = class ShareLog extends BaseMod { + constructor() { + super() + this.tableName = 'share-logs' + } + + /** + * 分析日志填充 + * @param {Object} reportParams 上报参数 + * @param {Object} sessionLogData 会话日志数据,此参数传递可减少数据库查询 + */ + async fill(reportParams, sessionLogData) { + let params, sessionLogInfo, sessionKey; + const fillParams = [] + const sessionLog = new SessionLog() + const platform = new Platform() + const dateTime = new DateTime() + const channel = new Channel() + for (const rk in reportParams) { + params = reportParams[rk] + + //暂存下会话数据,减少读库 + sessionKey = params.ak + params.did + params.p + if (!sessionLogData[sessionKey]) { + // 会话日志 + sessionLogInfo = await sessionLog.getSession(params) + if (sessionLogInfo.code) { + return sessionLogInfo + } + if (this.debug) { + console.log('sessionLogInfo', JSON.stringify(sessionLogInfo)) + } + sessionLogData[sessionKey] = sessionLogInfo + } else { + sessionLogInfo = sessionLogData[sessionKey] + } + + // 填充数据 + fillParams.push({ + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + device_id: params.did, + uid: params.uid ? params.uid : '', + session_id: sessionLogInfo.data.sessionLogId, + page_id: sessionLogInfo.data.pageId, + create_time: dateTime.getTime() + }) + } + + if (fillParams.length === 0) { + return { + code: 200, + msg: 'Invild param' + } + } + + const res = await this.insert(this.tableName, fillParams) + if (res && res.inserted) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'Filled error' + } + } + } + + /** + * 分享日志清理 + * @param {Number} days 保留天数 + */ + async clean(days) { + days = Math.max(parseInt(days), 1) + console.log('clean share logs - day:', days) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean share log:', res) + } + return res + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/statResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/statResult.js new file mode 100644 index 0000000..aac8dbf --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/statResult.js @@ -0,0 +1,2151 @@ +/** + * @class StatResult 基础数据结果统计模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const Version = require('./version') +const SessionLog = require('./sessionLog') +const UserSessionLog = require('./userSessionLog') +const ErrorLog = require('./errorLog') +const ActiveDevices = require('./activeDevices') +const ActiveUsers = require('./activeUsers') +const UniIDUsers = require('./uniIDUsers') +const { + DateTime +} = require('../lib') +module.exports = class StatResult extends BaseMod { + constructor() { + super() + this.tableName = 'result' + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + * 基础数据统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async stat(type, date, reset) { + const allowedType = ['hour', 'day', 'week', 'month'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + + if (this.debug) { + console.log('result --type:' + type + ', date:' + date + ', reset:' + reset) + } + + this.fillType = type + const dateTime = new DateTime() + const dateDimension = dateTime.getTimeDimensionByType(type, -1, date) + this.startTime = dateDimension.startTime + this.endTime = dateDimension.endTime + if (this.debug) { + console.log('dimension time', this.startTime + '--' + this.endTime) + } + + // 查看当前时间段日志是否已存在,防止重复生成 + if (!reset) { + const checkRes = await this.getCollection(this.tableName).where({ + dimension: this.fillType, + start_time: this.startTime, + end_time: this.endTime + }).get() + if (checkRes.data.length > 0) { + console.log('log have existed') + return { + code: 1003, + msg: 'This log have existed' + } + } + } else { + const delRes = await this.delete(this.tableName, { + start_time: this.startTime, + end_time: this.endTime + }) + console.log('delete old data result:', JSON.stringify(delRes)) + } + + // 周月数据单独统计 + if (['week', 'month'].includes(this.fillType)) { + return await this.statWeekOrMonth() + } + + // 数据获取 + this.sessionLog = new SessionLog() + const statRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + is_first_visit: 1, + page_count: 1, + duration: 1, + create_time: 1 + }, + match: { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel' + }, + new_device_count: { + $sum: '$is_first_visit' + }, + page_view_count: { + $sum: '$page_count' + }, + total_duration: { + $sum: '$duration' + }, + session_times: { + $sum: 1 + } + }, + sort: { + new_device_count: 1, + page_view_count: 1, + session_times: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + + this.fillData = [] + this.composes = [] + if (statRes.data.length > 0) { + for (const i in statRes.data) { + await this.fill(statRes.data[i]) + } + } + //补充数据 + await this.replenishStat() + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + return res + } + + /** + * 按周/月统计 + */ + async statWeekOrMonth() { + const statRes = await this.aggregate(this.tableName, { + project: { + appid: 1, + version_id: 1, + platform_id: 1, + channel_id: 1, + new_device_count: 1, + new_user_count: 1, + page_visit_count: 1, + user_visit_times: 1, + app_launch_count: 1, + error_count: 1, + bounce_times: 1, + duration: 1, + user_duration: 1, + dimension: 1, + start_time: 1 + }, + match: { + dimension: 'day', + start_time: { + $gte: this.startTime, + $lte: this.endTime + } + }, + group: { + _id: { + appid: '$appid', + version_id: '$version_id', + platform_id: '$platform_id', + channel_id: '$channel_id' + }, + new_device_count: { + $sum: '$new_device_count' + }, + new_user_count: { + $sum: '$new_user_count' + }, + error_count: { + $sum: '$error_count' + }, + page_count: { + $sum: '$page_visit_count' + }, + total_duration: { + $sum: '$duration' + }, + total_user_duration: { + $sum: '$user_duration' + }, + total_user_session_times: { + $sum: '$user_session_times' + }, + session_times: { + $sum: '$app_launch_count' + }, + total_bounce_times: { + $sum: '$bounce_times' + } + }, + sort: { + new_device_count: 1, + error_count: 1, + page_count: 1 + }, + getAll: true + }) + + let res = { + code: 0, + msg: 'success' + } + if (this.debug) { + console.log('statRes', JSON.stringify(statRes)) + } + + this.activeDevices = new ActiveDevices() + this.activeUsers = new ActiveUsers() + this.fillData = [] + this.composes = [] + if (statRes.data.length > 0) { + for (const i in statRes.data) { + await this.getWeekOrMonthData(statRes.data[i]) + } + } + //补充数据 + await this.replenishStat() + if (this.fillData.length > 0) { + res = await this.batchInsert(this.tableName, this.fillData) + } + return res + } + + /** + * 获取周/月维度的填充数据 + * @param {Object} data 统计数据 + */ + async getWeekOrMonthData(data) { + + const matchCondition = { + ...data._id, + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + } + + // 查询活跃设备数 + const statVisitDeviceRes = await this.getCollection(this.activeDevices.tableName).where({ + ...matchCondition, + dimension: this.fillType + }).count() + + let activeDeviceCount = 0 + if (statVisitDeviceRes && statVisitDeviceRes.total > 0) { + activeDeviceCount = statVisitDeviceRes.total + } + + // 设备次均停留时长 + let avgSessionTime = 0 + if (data.total_duration > 0 && data.session_times > 0) { + avgSessionTime = Math.round(data.total_duration / data.session_times) + } + + // 设均停留时长 + let avgDeviceTime = 0 + if (data.total_duration > 0 && activeDeviceCount > 0) { + avgDeviceTime = Math.round(data.total_duration / activeDeviceCount) + } + + // 跳出率 + let bounceRate = 0 + if (data.total_bounce_times > 0 && data.session_times > 0) { + bounceRate = data.total_bounce_times * 100 / data.session_times + bounceRate = parseFloat(bounceRate.toFixed(2)) + } + + // 累计设备数 + let totalDevices = data.new_device_count + const totalDeviceRes = await this.getCollection(this.tableName).where({ + ...matchCondition, + dimension: this.fillType, + start_time: { + $lt: this.startTime + } + }).orderBy('start_time', 'desc').limit(1).get() + if (totalDeviceRes && totalDeviceRes.data.length > 0) { + totalDevices += totalDeviceRes.data[0].total_devices + } + + //活跃用户数 + const statVisitUserRes = await this.getCollection(this.activeUsers.tableName).where({ + ...matchCondition, + dimension: this.fillType + }).count() + let activeUserCount = 0 + if (statVisitUserRes && statVisitUserRes.total > 0) { + activeUserCount = statVisitUserRes.total + } + + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform_id]) { + platformInfo = this.platforms[data._id.platform_id] + } else { + const platform = new Platform() + platformInfo = await this.getById(platform.tableName, data._id.platform_id) + if (!platformInfo || platformInfo.length === 0) { + platformInfo.code = '' + } + this.platforms[data._id.platform_id] = platformInfo + } + + // 渠道信息 + let channelInfo = null + if (this.channels && this.channels[data._id.channel_id]) { + channelInfo = this.channels[data._id.channel_id] + } else { + const channel = new Channel() + channelInfo = await this.getById(channel.tableName, data._id.channel_id) + if (!channelInfo || channelInfo.length === 0) { + channelInfo.channel_code = '' + } + this.channels[data._id.channel_id] = channelInfo + } + + // 版本信息 + let versionInfo = null + if (this.versions && this.versions[data._id.version_id]) { + versionInfo = this.versions[data._id.version_id] + } else { + const version = new Version() + versionInfo = await this.getById(version.tableName, data._id.version_id, false) + if (!versionInfo || versionInfo.length === 0) { + versionInfo.version = '' + } + this.versions[data._id.version_id] = versionInfo + } + + //总用户数 + const uniIDUsers = new UniIDUsers() + let totalUserCount = await uniIDUsers.getUserCount(data._id.appid, platformInfo.code, channelInfo.channel_code, versionInfo.version, { + $lte: this.endTime + }) + + //人均停留时长 + let avgUserTime = 0 + if (data.total_user_duration > 0 && activeUserCount > 0) { + avgUserTime = Math.round(data.total_user_duration / activeUserCount) + } + + //用户次均访问时长 + let avgUserSessionTime = 0 + if (data.total_user_duration > 0 && data.total_user_session_times > 0) { + avgUserSessionTime = Math.round(data.total_user_duration / data.total_user_session_times) + } + + //安卓平台活跃设备数需要减去sdk更新后device_id发生变更的设备数 + if(platformInfo.code === 'android') { + try{ + const statVisitOldDeviceRes = await this.getCollection(this.activeDevices.tableName).where({ + ...data._id, + create_time: { + $gte: this.startTime, + $lte: this.endTime + }, + dimension: this.fillType + '-old' + }).count() + if (statVisitOldDeviceRes && statVisitOldDeviceRes.total > 0) { + // 活跃设备留存数 + activeDeviceCount -= statVisitOldDeviceRes.total + //平均设备停留时长 + avgDeviceTime = Math.round(data.total_duration / activeDeviceCount) + } + } catch (e) { + console.log('server error: ' + e) + } + } + + const insertParam = { + appid: data._id.appid, + platform_id: data._id.platform_id, + channel_id: data._id.channel_id, + version_id: data._id.version_id, + //总设备数 + total_devices: totalDevices, + //本时间段新增设备数 + new_device_count: data.new_device_count, + //登录用户会话次数 + user_session_times: data.total_user_session_times, + //活跃设备数 + active_device_count: activeDeviceCount, + //总用户数 + total_users: totalUserCount, + //新增用户数 + new_user_count: data.new_user_count, + //活跃用户数 + active_user_count: activeUserCount, + //应用启动次数 = 设备会话次数 + app_launch_count: data.session_times, + //页面访问次数 + page_visit_count: data.page_view_count, + //错误次数 + error_count: data.error_count, + //会话总访问时长 + duration: data.total_duration, + //用户会话总访问时长 + user_duration: data.total_user_duration, + avg_device_session_time: avgSessionTime, + avg_user_session_time: avgUserSessionTime, + avg_device_time: avgDeviceTime, + avg_user_time: avgUserTime, + bounce_times: data.total_bounce_times, + bounce_rate: bounceRate, + retention: {}, + dimension: this.fillType, + stat_date: new DateTime().getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + this.fillData.push(insertParam) + this.composes.push(data._id.appid + '_' + data._id.platform_id + '_' + data._id.channel_id + '_' + data + ._id.version_id) + + return insertParam + } + + /** + * 基础填充数据-目前只有小时和天维度的数据 + * @param {Object} data 统计数据 + */ + async fill(data) { + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[data._id.platform]) { + //暂存下数据,减少读库 + platformInfo = this.platforms[data._id.platform] + } else { + const platform = new Platform() + platformInfo = await platform.getPlatformAndCreate(data._id.platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[data._id.platform] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + + // 渠道信息 + let channelInfo = null + const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey] + } else { + const channel = new Channel() + channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + + // 版本信息 + let versionInfo = null + const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const version = new Version() + versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 访问设备数统计 + const matchCondition = data._id + Object.assign(matchCondition, { + create_time: { + $gte: this.startTime, + $lte: this.endTime + } + }) + const statVisitDeviceRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + create_time: 1 + }, + match: matchCondition, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + let activeDeviceCount = 0 + if (statVisitDeviceRes.data.length > 0) { + activeDeviceCount = statVisitDeviceRes.data[0].total_devices + } + + //安卓平台活跃设备数需要减去sdk更新后device_id发生变更的设备数 + if(platformInfo.code === 'android') { + const oldDeviceRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + old_device_id: 1, + create_time: 1 + }, + match: matchCondition, + group: { + _id: { + device_id: '$old_device_id' + }, + create_time: { + $min: '$create_time' + }, + sessionCount: { + $sum: 1 + } + }, + sort: { + create_time: 1, + sessionCount: 1 + }, + getAll: true + }) + + if(oldDeviceRes.data.length) { + const thisOldDeviceIds = [] + for (const tau in oldDeviceRes.data) { + if(oldDeviceRes.data[tau]._id.device_id) { + thisOldDeviceIds.push(oldDeviceRes.data[tau]._id.device_id) + } + } + const statVisitOldDeviceRes = await this.aggregate(this.sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + create_time: 1 + }, + match: { + ...matchCondition, + device_id: { + $in: thisOldDeviceIds + } + }, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('statVisitOldDeviceRes', JSON.stringify(statVisitOldDeviceRes)) + } + if (statVisitOldDeviceRes && statVisitOldDeviceRes.data.length > 0) { + // 活跃设备留存数 + activeDeviceCount -= statVisitOldDeviceRes.data[0].total_devices + } + } + } + + // 错误数量统计 + const errorLog = new ErrorLog() + const statErrorRes = await this.getCollection(errorLog.tableName).where(matchCondition).count() + let errorCount = 0 + if (statErrorRes && statErrorRes.total > 0) { + errorCount = statErrorRes.total + } + + // 设备的次均停留时长,设备访问总时长/设备会话次数 + let avgSessionTime = 0 + if (data.total_duration > 0 && data.session_times > 0) { + avgSessionTime = Math.round(data.total_duration / data.session_times) + } + + // 设均停留时长 + let avgDeviceTime = 0 + if (data.total_duration > 0 && activeDeviceCount > 0) { + avgDeviceTime = Math.round(data.total_duration / activeDeviceCount) + } + + // 跳出率 + let bounceTimes = 0 + const bounceRes = await this.getCollection(this.sessionLog.tableName).where({ + ...matchCondition, + page_count: 1 + }).count() + if (bounceRes && bounceRes.total > 0) { + bounceTimes = bounceRes.total + } + let bounceRate = 0 + if (bounceTimes > 0 && data.session_times > 0) { + bounceRate = bounceTimes * 100 / data.session_times + bounceRate = parseFloat(bounceRate.toFixed(2)) + } + + // 应用启动次数 = 会话次数 + const launchCount = data.session_times + + // 累计设备数 + let totalDevices = data.new_device_count + const totalDeviceRes = await this.getCollection(this.tableName).where({ + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + dimension: this.fillType, + start_time: { + $lt: this.startTime + } + }).orderBy('start_time', 'desc').limit(1).get() + + if (totalDeviceRes && totalDeviceRes.data.length > 0) { + totalDevices += totalDeviceRes.data[0].total_devices + } + + //活跃用户数 + const userSessionLog = new UserSessionLog() + let activeUserCount = 0 + const activeUserCountRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + create_time: 1 + }, + match: matchCondition, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + if (activeUserCountRes && activeUserCountRes.data.length > 0) { + activeUserCount = activeUserCountRes.data[0].total_users + } + + //新增用户数 + const uniIDUsers = new UniIDUsers() + let newUserCount = await uniIDUsers.getUserCount(matchCondition.appid, matchCondition.platform, + matchCondition.channel, matchCondition.version, { + $gte: this.startTime, + $lte: this.endTime + }) + + //总用户数 + let totalUserCount = await uniIDUsers.getUserCount(matchCondition.appid, matchCondition.platform, + matchCondition.channel, matchCondition.version, { + $lte: this.endTime + }) + + + //用户停留总时长及总会话次数 + let totalUserDuration = 0 + let totalUserSessionTimes = 0 + const totalUserDurationRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + duration: 1, + create_time: 1 + }, + match: matchCondition, + group: [{ + _id: {}, + total_duration: { + $sum: "$duration" + }, + total_session_times: { + $sum: 1 + } + }] + }) + if (totalUserDurationRes && totalUserDurationRes.data.length > 0) { + totalUserDuration = totalUserDurationRes.data[0].total_duration + totalUserSessionTimes = totalUserDurationRes.data[0].total_session_times + } + + //人均停留时长 + let avgUserTime = 0 + //用户次均访问时长 + let avgUserSessionTime = 0 + if (totalUserDuration > 0 && activeUserCount > 0) { + avgUserTime = Math.round(totalUserDuration / activeUserCount) + avgUserSessionTime = Math.round(totalUserDuration / totalUserSessionTimes) + } + + //设置填充数据 + const datetime = new DateTime() + const insertParam = { + appid: data._id.appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + total_devices: totalDevices, + new_device_count: data.new_device_count, + active_device_count: activeDeviceCount, + total_users: totalUserCount, + new_user_count: newUserCount, + active_user_count: activeUserCount, + user_session_times: totalUserSessionTimes, + app_launch_count: launchCount, + page_visit_count: data.page_view_count, + error_count: errorCount, + duration: data.total_duration, + user_duration: totalUserDuration, + avg_device_session_time: avgSessionTime, + avg_user_session_time: avgUserSessionTime, + avg_device_time: avgDeviceTime, + avg_user_time: avgUserTime, + bounce_times: bounceTimes, + bounce_rate: bounceRate, + retention: {}, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + } + + //数据填充 + this.fillData.push(insertParam) + this.composes.push(data._id.appid + '_' + platformInfo._id + '_' + channelInfo._id + '_' + versionInfo + ._id) + return insertParam + } + + /** + * 基础统计数据补充,防止累计数据丢失 + */ + async replenishStat() { + if (this.debug) { + console.log('composes data', this.composes) + } + + const datetime = new DateTime() + // const { + // startTime + // } = datetime.getTimeDimensionByType(this.fillType, -1, this.startTime) + + //上一次统计时间 + let preStatRes = await this.getCollection(this.tableName).where({ + start_time: {$lt: this.startTime}, + dimension: this.fillType + }).orderBy('start_time', 'desc').limit(1).get() + let preStartTime = 0 + if(preStatRes && preStatRes.data.length > 0) { + preStartTime = preStatRes.data[0].start_time + } + + if (this.debug) { + console.log('replenishStat-preStartTime', preStartTime) + } + + if(!preStartTime) { + return false + } + + // 上一阶段数据 + const preStatData = await this.selectAll(this.tableName, { + start_time: preStartTime, + dimension: this.fillType + }, { + appid: 1, + platform_id: 1, + channel_id: 1, + version_id: 1, + total_devices: 1, + total_users: 1 + }) + + if (!preStatData || preStatData.data.length === 0) { + return false + } + + if (this.debug) { + console.log('preStatData', JSON.stringify(preStatData)) + } + + let preKey + const preKeyArr = [] + for (const pi in preStatData.data) { + preKey = preStatData.data[pi].appid + '_' + preStatData.data[pi].platform_id + '_' + preStatData + .data[pi].channel_id + '_' + preStatData.data[pi].version_id + if (!this.composes.includes(preKey) && !preKeyArr.includes(preKey)) { + preKeyArr.push(preKey) + if (this.debug) { + console.log('preKey -add', preKey) + } + this.fillData.push({ + appid: preStatData.data[pi].appid, + platform_id: preStatData.data[pi].platform_id, + channel_id: preStatData.data[pi].channel_id, + version_id: preStatData.data[pi].version_id, + total_devices: preStatData.data[pi].total_devices, + new_device_count: 0, + active_device_count: 0, + total_users: preStatData.data[pi].total_users, + new_user_count: 0, + active_user_count: 0, + user_session_times: 0, + app_launch_count: 0, + page_visit_count: 0, + error_count: 0, + duration: 0, + user_duration: 0, + avg_device_session_time: 0, + avg_user_session_time: 0, + avg_device_time: 0, + avg_user_time: 0, + bounce_times: 0, + bounce_rate: 0, + retention: {}, + dimension: this.fillType, + stat_date: datetime.getDate('Ymd', this.startTime), + start_time: this.startTime, + end_time: this.endTime + }) + } else if (this.debug) { + console.log('preKey -have', preKey) + } + } + + return true + } + + /** + * 留存数据统计 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {String} mod 统计模块 device:设备,user:用户 + */ + async retentionStat(type, date, mod = 'device') { + date = date ? date : new DateTime().getTimeBySetDays(-1, date) + const allowedType = ['day', 'week', 'month'] + if (!allowedType.includes(type)) { + return { + code: 1002, + msg: 'This type is not allowed' + } + } + let days = [] + switch (type) { + case 'week': + case 'month': + days = [1, 2, 3, 4, 5, 6, 7, 8, 9] + break + default: + days = [1, 2, 3, 4, 5, 6, 7, 14, 30] + break + } + + let res = { + code: 0, + msg: 'success' + } + + for (const day in days) { + //留存统计数据库查询较为复杂,因此这里拆分为多个维度 + if (mod && mod === 'user') { + //用户留存统计 + if (type === 'day') { + res = await this.userRetentionFillDayly(type, days[day], date) + } else { + res = await this.userRetentionFillWeekOrMonth(type, days[day], date) + } + } else { + //设备留存统计 + if (type === 'day') { + res = await this.deviceRetentionFillDayly(type, days[day], date) + } else { + res = await this.deviceRetentionFillWeekOrMonth(type, days[day], date) + } + } + } + return res + } + + /** + * 设备日留存统计数据填充 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async deviceRetentionFillDayly(type, day, date) { + if (type !== 'day') { + return { + code: 301, + msg: 'Type error:' + type + } + } + const dateTime = new DateTime() + const { + startTime, + endTime + } = dateTime.getTimeDimensionByType(type, 0 - day, date) + + if (!startTime || !endTime) { + return { + code: 1001, + msg: 'The statistic time get failed' + } + } + + // 截止时间范围 + const lastTimeInfo = dateTime.getTimeDimensionByType(type, 0, date) + + // 获取当时批次的统计日志 + const resultLogRes = await this.selectAll(this.tableName, { + dimension: type, + start_time: startTime, + end_time: endTime + }) + // const resultLogRes = await this.getCollection(this.tableName).where({ + // dimension: type, + // start_time: startTime, + // end_time: endTime + // }).get() + + if (this.debug) { + console.log('resultLogRes', JSON.stringify(resultLogRes)) + } + + if (!resultLogRes || resultLogRes.data.length === 0) { + if (this.debug) { + console.log('Not found this log --' + type + ':' + day + ', start:' + startTime + ',endTime:' + + endTime) + } + return { + code: 1000, + msg: 'Not found this log' + } + } + + const sessionLog = new SessionLog() + const platform = new Platform() + const channel = new Channel() + const version = new Version() + let res = null + for (const resultIndex in resultLogRes.data) { + const resultLog = resultLogRes.data[resultIndex] + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[resultLog.platform_id]) { + platformInfo = this.platforms[resultLog.platform_id] + } else { + platformInfo = await this.getById(platform.tableName, resultLog.platform_id) + if (!platformInfo || platformInfo.length === 0) { + platformInfo.code = '' + } + this.platforms[resultLog.platform_id] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + // 渠道信息 + let channelInfo = null + if (this.channels && this.channels[resultLog.channel_id]) { + channelInfo = this.channels[resultLog.channel_id] + } else { + channelInfo = await this.getById(channel.tableName, resultLog.channel_id) + if (!channelInfo || channelInfo.length === 0) { + channelInfo.channel_code = '' + } + this.channels[resultLog.channel_id] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + // 版本信息 + let versionInfo = null + if (this.versions && this.versions[resultLog.version_id]) { + versionInfo = this.versions[resultLog.version_id] + } else { + versionInfo = await this.getById(version.tableName, resultLog.version_id, false) + if (!versionInfo || versionInfo.length === 0) { + versionInfo.version = '' + } + this.versions[resultLog.version_id] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 获取该批次的活跃设备数 + const activeDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + create_time: { + $gte: startTime, + $lte: endTime + } + }, + group: { + _id: { + device_id: '$device_id' + }, + create_time: { + $min: '$create_time' + }, + sessionCount: { + $sum: 1 + } + }, + sort: { + create_time: 1, + sessionCount: 1 + }, + getAll: true + }) + + if (this.debug) { + console.log('activeDeviceRes', JSON.stringify(activeDeviceRes)) + } + let activeDeviceRate = 0 + let activeDevices = 0 + if (activeDeviceRes && activeDeviceRes.data.length > 0) { + const thisDayActiveDevices = activeDeviceRes.data.length + const thisDayActiveDeviceIds = [] + for (const tau in activeDeviceRes.data) { + thisDayActiveDeviceIds.push(activeDeviceRes.data[tau]._id.device_id) + } + if (this.debug) { + console.log('thisDayActiveDeviceIds', JSON.stringify(thisDayActiveDeviceIds)) + } + + // 留存活跃设备查询 + const retentionActiveDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + device_id: { + $in: thisDayActiveDeviceIds + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('retentionActiveDeviceRes', JSON.stringify(retentionActiveDeviceRes)) + } + if (retentionActiveDeviceRes && retentionActiveDeviceRes.data.length > 0) { + // 活跃设备留存数 + activeDevices = retentionActiveDeviceRes.data[0].total_devices + // 活跃设备留存率 + activeDeviceRate = parseFloat((activeDevices * 100 / thisDayActiveDevices).toFixed(2)) + } + + //安卓平台留存需要增加sdk更新后device_id发生变更的设备数 + if(platformInfo.code === 'android') { + const retentionActiveOldDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + old_device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + old_device_id: { + $in: thisDayActiveDeviceIds + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + device_id: '$old_device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('retentionActiveOldDeviceRes', JSON.stringify(retentionActiveOldDeviceRes)) + } + if (retentionActiveOldDeviceRes && retentionActiveOldDeviceRes.data.length > 0) { + // 活跃设备留存数 + activeDevices += retentionActiveOldDeviceRes.data[0].total_devices + // 活跃设备留存率 + activeDeviceRate = parseFloat((activeDevices * 100 / thisDayActiveDevices).toFixed(2)) + } + } + } + + // 获取该批次新增设备数 + const newDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + is_first_visit: 1, + device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + is_first_visit: 1, + create_time: { + $gte: startTime, + $lte: endTime + } + }, + group: { + _id: { + device_id: '$device_id' + }, + create_time: { + $min: '$create_time' + }, + sessionCount: { + $sum: 1 + } + }, + sort: { + create_time: 1, + sessionCount: 1 + }, + getAll: true + }) + + let newDeviceRate = 0 + let newDevices = 0 + if (newDeviceRes && newDeviceRes.data.length > 0) { + const thisDayNewDevices = newDeviceRes.data.length + const thisDayNewDeviceIds = [] + for (const tau in newDeviceRes.data) { + thisDayNewDeviceIds.push(newDeviceRes.data[tau]._id.device_id) + } + + if (this.debug) { + console.log('thisDayNewDeviceIds', JSON.stringify(thisDayNewDeviceIds)) + } + + // 留存的设备查询 + const retentionNewDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + device_id: { + $in: thisDayNewDeviceIds + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + device_id: '$device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (retentionNewDeviceRes && retentionNewDeviceRes.data.length > 0) { + // 新增设备留存数 + newDevices = retentionNewDeviceRes.data[0].total_devices + // 新增设备留存率 + newDeviceRate = parseFloat((newDevices * 100 / thisDayNewDevices).toFixed(2)) + } + + //安卓平台留存需要增加sdk更新后device_id发生变更的设备数 + if(platformInfo.code === 'android') { + const retentionNewOldDeviceRes = await this.aggregate(sessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + old_device_id: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + old_device_id: { + $in: thisDayNewDeviceIds + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + device_id: '$old_device_id' + } + }, { + _id: {}, + total_devices: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('retentionNewOldDeviceRes', JSON.stringify(retentionNewOldDeviceRes)) + } + + if (retentionNewOldDeviceRes && retentionNewOldDeviceRes.data.length > 0) { + // 新增设备留存数 + newDevices += retentionNewOldDeviceRes.data[0].total_devices + // 新增设备留存率 + newDeviceRate = parseFloat((newDevices * 100 / thisDayNewDevices).toFixed(2)) + } + } + } + + // 数据更新 + const retentionData = resultLog.retention + const dataKey = type.substr(0, 1) + '_' + day + if (!retentionData.active_device) { + retentionData.active_device = {} + } + retentionData.active_device[dataKey] = { + device_count: activeDevices, + device_rate: activeDeviceRate + } + if (!retentionData.new_device) { + retentionData.new_device = {} + } + retentionData.new_device[dataKey] = { + device_count: newDevices, + device_rate: newDeviceRate + } + + if (this.debug) { + console.log('retentionData', JSON.stringify(retentionData)) + } + + res = await this.update(this.tableName, { + retention: retentionData + }, { + _id: resultLog._id + }) + } + + if (res && res.updated) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'retention data update failed' + } + } + } + + /** + * 设备周/月留存数据填充 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async deviceRetentionFillWeekOrMonth(type, day, date) { + if (!['week', 'month'].includes(type)) { + return { + code: 301, + msg: 'Type error:' + type + } + } + const dateTime = new DateTime() + const { + startTime, + endTime + } = dateTime.getTimeDimensionByType(type, 0 - day, date) + + if (!startTime || !endTime) { + return { + code: 1001, + msg: 'The statistic time get failed' + } + } + + // 截止时间范围 + const lastTimeInfo = dateTime.getTimeDimensionByType(type, 0, date) + + // 获取当时批次的统计日志 + const resultLogRes = await this.selectAll(this.tableName, { + dimension: type, + start_time: startTime, + end_time: endTime + }) + + if (this.debug) { + console.log('resultLogRes', JSON.stringify(resultLogRes)) + } + + if (!resultLogRes || resultLogRes.data.length === 0) { + if (this.debug) { + console.log('Not found this session log --' + type + ':' + day + ', start:' + startTime + + ',endTime:' + endTime) + } + return { + code: 1000, + msg: 'Not found this session log' + } + } + + const activeDevicesObj = new ActiveDevices() + let res = null; + let activeDeviceRes; + let activeDeviceRate; + let activeDevices; + let newDeviceRate; + let newDevices + for (const resultIndex in resultLogRes.data) { + const resultLog = resultLogRes.data[resultIndex] + // 获取该批次的活跃设备数 + activeDeviceRes = await this.selectAll(activeDevicesObj.tableName, { + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + dimension: type, + create_time: { + $gte: startTime, + $lte: endTime + } + }, { + device_id: 1 + }) + + if (this.debug) { + console.log('activeDeviceRes', JSON.stringify(activeDeviceRes)) + } + + activeDeviceRate = 0 + activeDevices = 0 + if (activeDeviceRes && activeDeviceRes.data.length > 0) { + const thisDayActiveDevices = activeDeviceRes.data.length + const thisDayActiveDeviceIds = [] + for (const tau in activeDeviceRes.data) { + thisDayActiveDeviceIds.push(activeDeviceRes.data[tau].device_id) + } + if (this.debug) { + console.log('thisDayActiveDeviceIds', JSON.stringify(thisDayActiveDeviceIds)) + } + // 留存活跃设备数 + const retentionActiveDeviceRes = await this.getCollection(activeDevicesObj.tableName).where({ + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + device_id: { + $in: thisDayActiveDeviceIds + }, + dimension: type, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }).count() + + if (this.debug) { + console.log('retentionActiveDeviceRes', JSON.stringify(retentionActiveDeviceRes)) + } + if (retentionActiveDeviceRes && retentionActiveDeviceRes.total > 0) { + // 活跃设备留存数 + activeDevices = retentionActiveDeviceRes.total + // 活跃设备留存率 + activeDeviceRate = parseFloat((activeDevices * 100 / thisDayActiveDevices).toFixed(2)) + } + } + + // 获取该批次的新增设备数 + const newDeviceRes = await this.selectAll(activeDevicesObj.tableName, { + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + is_new: 1, + dimension: type, + create_time: { + $gte: startTime, + $lte: endTime + } + }, { + device_id: 1 + }) + + newDeviceRate = 0 + newDevices = 0 + if (newDeviceRes && newDeviceRes.data.length > 0) { + const thisDayNewDevices = newDeviceRes.data.length + const thisDayNewDeviceIds = [] + for (const tau in newDeviceRes.data) { + thisDayNewDeviceIds.push(newDeviceRes.data[tau].device_id) + } + + // 新增设备留存数 + const retentionNewDeviceRes = await this.getCollection(activeDevicesObj.tableName).where({ + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + device_id: { + $in: thisDayNewDeviceIds + }, + dimension: type, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }).count() + + if (retentionNewDeviceRes && retentionNewDeviceRes.total > 0) { + // 新增设备留存数 + newDevices = retentionNewDeviceRes.total + // 新增设备留存率 + newDeviceRate = parseFloat((newDevices * 100 / thisDayNewDevices).toFixed(2)) + } + } + + // 数据更新 + const retentionData = resultLog.retention + const dataKey = type.substr(0, 1) + '_' + day + if (!retentionData.active_device) { + retentionData.active_device = {} + } + retentionData.active_device[dataKey] = { + device_count: activeDevices, + device_rate: activeDeviceRate + } + if (!retentionData.new_device) { + retentionData.new_device = {} + } + retentionData.new_device[dataKey] = { + device_count: newDevices, + device_rate: newDeviceRate + } + + if (this.debug) { + console.log('retentionData', JSON.stringify(retentionData)) + } + + res = await this.update(this.tableName, { + retention: retentionData + }, { + _id: resultLog._id + }) + } + + if (res && res.updated) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'retention data update failed' + } + } + } + + /** + * 用户日留存数据填充 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async userRetentionFillDayly(type, day, date) { + if (type !== 'day') { + return { + code: 301, + msg: 'Type error:' + type + } + } + const dateTime = new DateTime() + const { + startTime, + endTime + } = dateTime.getTimeDimensionByType(type, 0 - day, date) + + if (!startTime || !endTime) { + return { + code: 1001, + msg: 'The statistic time get failed' + } + } + + // 截止时间范围 + const lastTimeInfo = dateTime.getTimeDimensionByType(type, 0, date) + + // 获取当时批次的统计日志 + const resultLogRes = await this.selectAll(this.tableName, { + dimension: type, + start_time: startTime, + end_time: endTime + }) + + if (this.debug) { + console.log('resultLogRes', JSON.stringify(resultLogRes)) + } + + if (!resultLogRes || resultLogRes.data.length === 0) { + if (this.debug) { + console.log('Not found this log --' + type + ':' + day + ', start:' + startTime + ',endTime:' + + endTime) + } + return { + code: 1000, + msg: 'Not found this log' + } + } + + const userSessionLog = new UserSessionLog() + const uniIDUsers = new UniIDUsers() + const platform = new Platform() + const channel = new Channel() + const version = new Version() + let res = null + for (const resultIndex in resultLogRes.data) { + const resultLog = resultLogRes.data[resultIndex] + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[resultLog.platform_id]) { + platformInfo = this.platforms[resultLog.platform_id] + } else { + platformInfo = await this.getById(platform.tableName, resultLog.platform_id) + if (!platformInfo || platformInfo.length === 0) { + platformInfo.code = '' + } + this.platforms[resultLog.platform_id] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + // 渠道信息 + let channelInfo = null + if (this.channels && this.channels[resultLog.channel_id]) { + channelInfo = this.channels[resultLog.channel_id] + } else { + channelInfo = await this.getById(channel.tableName, resultLog.channel_id) + if (!channelInfo || channelInfo.length === 0) { + channelInfo.channel_code = '' + } + this.channels[resultLog.channel_id] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + // 版本信息 + let versionInfo = null + if (this.versions && this.versions[resultLog.version_id]) { + versionInfo = this.versions[resultLog.version_id] + } else { + versionInfo = await this.getById(version.tableName, resultLog.version_id, false) + if (!versionInfo || versionInfo.length === 0) { + versionInfo.version = '' + } + this.versions[resultLog.version_id] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 获取该时间段内的活跃用户 + const activeUserRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + create_time: { + $gte: startTime, + $lte: endTime + } + }, + group: { + _id: { + uid: '$uid' + }, + create_time: { + $min: '$create_time' + }, + sessionCount: { + $sum: 1 + } + }, + sort: { + create_time: 1, + sessionCount: 1 + }, + getAll: true + }) + + if (this.debug) { + console.log('activeUserRes', JSON.stringify(activeUserRes)) + } + + //活跃用户留存率 + let activeUserRate = 0 + //活跃用户留存数 + let activeUsers = 0 + if (activeUserRes && activeUserRes.data.length > 0) { + const thisDayActiveUsers = activeUserRes.data.length + //获取该时间段内的活跃用户编号,这里没用lookup联查是因为数据量较大时lookup效率很低 + const thisDayActiveUids = [] + for (let tau in activeUserRes.data) { + thisDayActiveUids.push(activeUserRes.data[tau]._id.uid) + } + + if (this.debug) { + console.log('thisDayActiveUids', JSON.stringify(thisDayActiveUids)) + } + + // 留存活跃用户数 + const retentionActiveUserRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + uid: { + $in: thisDayActiveUids + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + if (this.debug) { + console.log('retentionActiveUserRes', JSON.stringify(retentionActiveUserRes)) + } + if (retentionActiveUserRes && retentionActiveUserRes.data.length > 0) { + // 活跃用户留存数 + activeUsers = retentionActiveUserRes.data[0].total_users + // 活跃用户留存率 + activeUserRate = parseFloat((activeUsers * 100 / thisDayActiveUsers).toFixed(2)) + } + } + + + + //新增用户编号 + const thisDayNewUids = await uniIDUsers.getUserIds(resultLog.appid, platformInfo.code, channelInfo.channel_code, versionInfo.version, { + $gte: startTime, + $lte: endTime + }) + //新增用户留存率 + let newUserRate = 0 + //新增用户留存数 + let newUsers = 0 + if (thisDayNewUids.length > 0) { + // 现在依然活跃的用户数 + const retentionNewUserRes = await this.aggregate(userSessionLog.tableName, { + project: { + appid: 1, + version: 1, + platform: 1, + channel: 1, + uid: 1, + create_time: 1 + }, + match: { + appid: resultLog.appid, + version: versionInfo.version, + platform: platformInfo.code, + channel: channelInfo.channel_code, + uid: { + $in: thisDayNewUids + }, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }, + group: [{ + _id: { + uid: '$uid' + } + }, { + _id: {}, + total_users: { + $sum: 1 + } + }] + }) + + if (retentionNewUserRes && retentionNewUserRes.data.length > 0) { + // 新增用户留存数 + newUsers = retentionNewUserRes.data[0].total_users + // 新增用户留存率 + newUserRate = parseFloat((newUsers * 100 / thisDayNewUids.length).toFixed(2)) + } + } + + // 数据更新 + const retentionData = resultLog.retention + const dataKey = type.substr(0, 1) + '_' + day + if (!retentionData.active_user) { + retentionData.active_user = {} + } + retentionData.active_user[dataKey] = { + user_count: activeUsers, + user_rate: activeUserRate + } + if (!retentionData.new_user) { + retentionData.new_user = {} + } + retentionData.new_user[dataKey] = { + user_count: newUsers, + user_rate: newUserRate + } + + if (this.debug) { + console.log('retentionData', JSON.stringify(retentionData)) + } + + res = await this.update(this.tableName, { + retention: retentionData + }, { + _id: resultLog._id + }) + } + + if (res && res.updated) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'retention data update failed' + } + } + } + + + /** + * 用户周/月留存数据填充 + * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计 + * @param {Date|Time} date 指定日期或时间戳 + * @param {Boolean} reset 是否重置,为ture时会重置该批次数据 + */ + async userRetentionFillWeekOrMonth(type, day, date) { + if (!['week', 'month'].includes(type)) { + return { + code: 301, + msg: 'Type error:' + type + } + } + const dateTime = new DateTime() + const { + startTime, + endTime + } = dateTime.getTimeDimensionByType(type, 0 - day, date) + + if (!startTime || !endTime) { + return { + code: 1001, + msg: 'The statistic time get failed' + } + } + + // 截止时间范围 + const lastTimeInfo = dateTime.getTimeDimensionByType(type, 0, date) + + // 获取当时批次的统计日志 + const resultLogRes = await this.selectAll(this.tableName, { + dimension: type, + start_time: startTime, + end_time: endTime + }) + + if (this.debug) { + console.log('resultLogRes', JSON.stringify(resultLogRes)) + } + + if (!resultLogRes || resultLogRes.data.length === 0) { + if (this.debug) { + console.log('Not found this session log --' + type + ':' + day + ', start:' + startTime + + ',endTime:' + endTime) + } + return { + code: 1000, + msg: 'Not found this session log' + } + } + + const activeUserObj = new ActiveUsers() + const uniIDUsers = new UniIDUsers() + const platform = new Platform() + const channel = new Channel() + const version = new Version() + let res = null + //活跃用户留存率 + let activeUserRate + //活跃用户留存数 + let activeUsers + //新增用户留存率 + let newUserRate + //新增用户留存数 + let newUsers + for (const resultIndex in resultLogRes.data) { + const resultLog = resultLogRes.data[resultIndex] + + // 平台信息 + let platformInfo = null + if (this.platforms && this.platforms[resultLog.platform_id]) { + platformInfo = this.platforms[resultLog.platform_id] + } else { + platformInfo = await this.getById(platform.tableName, resultLog.platform_id) + if (!platformInfo || platformInfo.length === 0) { + platformInfo.code = '' + } + this.platforms[resultLog.platform_id] = platformInfo + if (this.debug) { + console.log('platformInfo', JSON.stringify(platformInfo)) + } + } + // 渠道信息 + let channelInfo = null + if (this.channels && this.channels[resultLog.channel_id]) { + channelInfo = this.channels[resultLog.channel_id] + } else { + channelInfo = await this.getById(channel.tableName, resultLog.channel_id) + if (!channelInfo || channelInfo.length === 0) { + channelInfo.channel_code = '' + } + this.channels[resultLog.channel_id] = channelInfo + if (this.debug) { + console.log('channelInfo', JSON.stringify(channelInfo)) + } + } + // 版本信息 + let versionInfo = null + if (this.versions && this.versions[resultLog.version_id]) { + versionInfo = this.versions[resultLog.version_id] + } else { + versionInfo = await this.getById(version.tableName, resultLog.version_id, false) + if (!versionInfo || versionInfo.length === 0) { + versionInfo.version = '' + } + this.versions[resultLog.version_id] = versionInfo + if (this.debug) { + console.log('versionInfo', JSON.stringify(versionInfo)) + } + } + + // 获取该批次的活跃用户数 + const activeUserRes = await this.selectAll(activeUserObj.tableName, { + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + dimension: type, + create_time: { + $gte: startTime, + $lte: endTime + } + }, { + uid: 1 + }) + + if (this.debug) { + console.log('activeUserRes', JSON.stringify(activeUserRes)) + } + + activeUserRate = 0 + activeUsers = 0 + if (activeUserRes && activeUserRes.data.length > 0) { + const thisDayactiveUsers = activeUserRes.data.length + const thisDayActiveDeviceIds = [] + for (const tau in activeUserRes.data) { + thisDayActiveDeviceIds.push(activeUserRes.data[tau].uid) + } + if (this.debug) { + console.log('thisDayActiveDeviceIds', JSON.stringify(thisDayActiveDeviceIds)) + } + // 留存活跃用户数 + const retentionactiveUserRes = await this.getCollection(activeUserObj.tableName).where({ + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + uid: { + $in: thisDayActiveDeviceIds + }, + dimension: type, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }).count() + + if (this.debug) { + console.log('retentionactiveUserRes', JSON.stringify(retentionactiveUserRes)) + } + if (retentionactiveUserRes && retentionactiveUserRes.total > 0) { + // 活跃用户留存数 + activeUsers = retentionactiveUserRes.total + // 活跃用户留存率 + activeUserRate = parseFloat((activeUsers * 100 / thisDayactiveUsers).toFixed(2)) + } + } + + + //新增用户编号 + const thisDayNewUids = await uniIDUsers.getUserIds(resultLog.appid, platformInfo.code, channelInfo.channel_code, versionInfo.version, { + $gte: startTime, + $lte: endTime + }) + + // 新增用户留存率 + newUserRate = 0 + // 新增用户留存数 + newUsers = 0 + if(thisDayNewUids && thisDayNewUids.length > 0) { + // 新增用户留存数 + const retentionnewUserRes = await this.getCollection(activeUserObj.tableName).where({ + appid: resultLog.appid, + platform_id: resultLog.platform_id, + channel_id: resultLog.channel_id, + version_id: resultLog.version_id, + uid: { + $in: thisDayNewUids + }, + dimension: type, + create_time: { + $gte: lastTimeInfo.startTime, + $lte: lastTimeInfo.endTime + } + }).count() + + if (retentionnewUserRes && retentionnewUserRes.total > 0) { + // 新增用户留存数 + newUsers = retentionnewUserRes.total + // 新增用户留存率 + newUserRate = parseFloat((newUsers * 100 / thisDayNewUids.length).toFixed(2)) + } + } + + // 数据更新 + const retentionData = resultLog.retention + const dataKey = type.substr(0, 1) + '_' + day + if (!retentionData.active_user) { + retentionData.active_user = {} + } + retentionData.active_user[dataKey] = { + user_count: activeUsers, + user_rate: activeUserRate + } + if (!retentionData.new_user) { + retentionData.new_user = {} + } + retentionData.new_user[dataKey] = { + user_count: newUsers, + user_rate: newUserRate + } + + if (this.debug) { + console.log('retentionData', JSON.stringify(retentionData)) + } + + res = await this.update(this.tableName, { + retention: retentionData + }, { + _id: resultLog._id + }) + } + + if (res && res.updated) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'retention data update failed' + } + } + } + + + /** + * 清理实时统计的日志 + * @param {Number} days 实时统计日志保留天数 + */ + async cleanHourLog(days = 7) { + + console.log('clean hour logs - day:', days) + + const dateTime = new DateTime() + + const res = await this.delete(this.tableName, { + dimension: 'hour', + start_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean hour logs - res:', res) + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/config.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/config.js new file mode 100644 index 0000000..c285788 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/config.js @@ -0,0 +1,12 @@ +/** + * 表名 + */ +const dbName = { + uniIdUsers: 'uni-id-users', // 支付订单明细表 + uniPayOrders: 'uni-pay-orders', // 支付订单明细表 + uniStatPayResult: 'uni-stat-pay-result', // 统计结果存储表 + uniStatSessionLogs: 'uni-stat-session-logs', // 设备会话日志表(主要用于统计访问设备数) + uniStatUserSessionLogs: 'uni-stat-user-session-logs', // 用户会话日志表(主要用于统计访问人数) +}; + +module.exports = dbName; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/index.js new file mode 100644 index 0000000..933a82b --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/index.js @@ -0,0 +1,10 @@ +/** + * 数据库操作 + */ +module.exports = { + uniIdUsers: require('./uniIdUsers'), + uniPayOrders: require('./uniPayOrders'), + uniStatPayResult: require('./uniStatPayResult'), + uniStatSessionLogs: require('./uniStatSessionLogs'), + uniStatUserSessionLogs: require('./uniStatUserSessionLogs'), +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniIdUsers.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniIdUsers.js new file mode 100644 index 0000000..5560be2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniIdUsers.js @@ -0,0 +1,62 @@ +/** + * 数据库操作 + */ +const dbName = require("./config"); + +let db = uniCloud.database(); +let _ = db.command; +let $ = _.aggregate; + +class Dao { + async count(whereJson) { + let dbRes = await db.collection(dbName.uniIdUsers).where(whereJson).count() + return dbRes && dbRes.total ? dbRes.total : 0; + } + + async countNewUserOrder(obj) { + let { + whereJson, + status + } = obj; + let dbRes = await db.collection(dbName.uniIdUsers).aggregate() + .match(whereJson) + .lookup({ + from: dbName.uniPayOrders, + let: { + user_id: '$_id', + }, + pipeline: $.pipeline() + .match(_.expr($.and([ + $.eq(['$user_id', '$$user_id']), + $.in(['$status', status]) + ]))) + .limit(1) + .done(), + as: 'order', + }) + .unwind({ + path: '$order', + }) + .group({ + _id: null, + count: { + $addToSet: '$_id' + }, + }) + .addFields({ + count: { + $size: '$count' + } + }) + .end() + try { + return dbRes.data[0].count; + } catch (err) { + return 0; + } + + } +} + + +module.exports = new Dao(); diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniPayOrders.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniPayOrders.js new file mode 100644 index 0000000..40e3709 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniPayOrders.js @@ -0,0 +1,99 @@ +/** + * 数据库操作 + */ +const BaseMod = require('../../base'); +const dbName = require("./config"); + +class Dao extends BaseMod { + + constructor() { + super() + this.tablePrefix = false; // 不使用表前缀 + } + + async group(data) { + let { + start_time, + end_time, + status: status_str + } = data; + let status; + if (status_str === "已下单") { + + } else if (status_str === "已付款") { + status = { + $gt: 0 + } + } else if (status_str === "已退款") { + status = { + $in: [2, 3] + } + } + const dbRes = await this.aggregate(dbName.uniPayOrders, { + match: { + create_date: { + $gte: start_time, + $lte: end_time + }, + status + }, + group: { + _id: { + appid: '$appid', + version: '$stat_data.app_version', + platform: '$stat_data.platform', + channel: '$stat_data.channel', + }, + status: { + $first: '$status' + }, + // 支付金额 + total_fee: { + $sum: '$total_fee' + }, + // 退款金额 + refund_fee: { + $sum: '$refund_fee' + }, + // 支付笔数 + order_count: { + $sum: 1 + }, + // 支付人数(去重复) + user_count: { + $addToSet: '$user_id' + }, + // 支付设备数(去重复) + device_count: { + $addToSet: '$device_id' + }, + + create_date: { + $min: '$create_date' + } + }, + addFields: { + user_count: { + $size: '$user_count' + }, + device_count: { + $size: '$device_count' + } + }, + // 按创建时间排序 + sort: { + create_date: 1 + }, + getAll: true + }); + + let list = dbRes.data; + list.map((item) => { + item.status_str = status_str; + }); + return list; + } +} + + +module.exports = new Dao(); diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatPayResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatPayResult.js new file mode 100644 index 0000000..5fb8944 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatPayResult.js @@ -0,0 +1,36 @@ +/** + * 数据库操作 + */ +const BaseMod = require('../../base'); +const dbName = require("./config"); + +class Dao extends BaseMod { + + constructor() { + super() + this.tablePrefix = false; // 不使用表前缀 + } + + async list(data) { + let { + whereJson, + } = data; + const dbRes = await this.getCollection(dbName.uniStatPayResult).where(whereJson).get(); + return dbRes.data; + } + + async del(data) { + let { + whereJson + } = data; + const dbRes = await this.delete(dbName.uniStatPayResult, whereJson); + return dbRes.deleted; + } + + async adds(saveList) { + return await this.batchInsert(dbName.uniStatPayResult, saveList); + } +} + + +module.exports = new Dao(); diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatSessionLogs.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatSessionLogs.js new file mode 100644 index 0000000..17511c0 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatSessionLogs.js @@ -0,0 +1,78 @@ +/** + * 数据库操作 + */ +const BaseMod = require('../../base'); +const dbName = require("./config"); + +class Dao extends BaseMod { + + constructor() { + super() + this.tablePrefix = false; // 不使用表前缀 + } + + async group(data) { + let { + whereJson, + } = data; + const dbRes = await this.aggregate(dbName.uniStatSessionLogs, { + match: whereJson, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + }, + // 设备数(去重复) + device_count: { + $addToSet: '$device_id' + }, + + create_time: { + $min: '$create_time' + } + }, + addFields: { + device_count: { + $size: '$device_count' + } + }, + // 按创建时间排序 + sort: { + create_time: 1 + }, + getAll: true + }); + + return dbRes.data; + } + + async groupCount(whereJson) { + const dbRes = await this.aggregate(dbName.uniStatSessionLogs, { + match: whereJson, + group: { + _id: null, + // 设备数(去重复) + count: { + $addToSet: '$device_id' + }, + }, + addFields: { + count: { + $size: '$count' + } + }, + getAll: true + }); + try { + return dbRes.data[0].count; + } catch (err) { + return 0; + } + } + +} + + +module.exports = new Dao(); diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatUserSessionLogs.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatUserSessionLogs.js new file mode 100644 index 0000000..d4792f8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/dao/uniStatUserSessionLogs.js @@ -0,0 +1,78 @@ +/** + * 数据库操作 + */ +const BaseMod = require('../../base'); +const dbName = require("./config"); + +class Dao extends BaseMod { + + constructor() { + super() + this.tablePrefix = false; // 不使用表前缀 + } + + async group(data) { + let { + whereJson + } = data; + const dbRes = await this.aggregate(dbName.uniStatUserSessionLogs, { + match: whereJson, + group: { + _id: { + appid: '$appid', + version: '$version', + platform: '$platform', + channel: '$channel', + }, + // 用户数(去重复) + user_count: { + $addToSet: '$uid' + }, + + create_time: { + $min: '$create_time' + } + }, + addFields: { + user_count: { + $size: '$user_count' + } + }, + // 按创建时间排序 + sort: { + create_time: 1 + }, + getAll: true + }); + + let list = dbRes.data; + return list; + } + + async groupCount(whereJson) { + const dbRes = await this.aggregate(dbName.uniStatUserSessionLogs, { + match: whereJson, + group: { + _id: null, + // 设备数(去重复) + count: { + $addToSet: '$uid' + }, + }, + addFields: { + count: { + $size: '$count' + } + }, + getAll: true + }); + try { + return dbRes.data[0].count; + } catch (err) { + return 0; + } + } +} + + +module.exports = new Dao(); diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/index.js new file mode 100644 index 0000000..c22fea2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/index.js @@ -0,0 +1,6 @@ +/** + * 基础对外模型 + */ +module.exports = { + PayResult: require('./payResult'), +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/payResult.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/payResult.js new file mode 100644 index 0000000..ad864ed --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uni-pay/payResult.js @@ -0,0 +1,500 @@ +/** + * @class ActiveDevices 活跃设备模型 - 每日跑批合并,仅添加本周/本月首次访问的设备。 + */ +const BaseMod = require('../base') +const Platform = require('../platform') +const Channel = require('../channel') +const Version = require('../version') + +const { + DateTime, + UniCrypto +} = require('../../lib') + +const dao = require('./dao') + +let db = uniCloud.database(); +let _ = db.command; +let $ = _.aggregate; + +module.exports = class PayResult extends BaseMod { + constructor() { + super() + this.platforms = [] + this.channels = [] + this.versions = [] + } + + /** + 支付金额:统计时间内,成功支付的订单金额之和(不剔除退款订单)。 + 支付笔数:统计时间内,成功支付的订单数,一个订单对应唯一一个订单号。(不剔除退款订单。) + 支付人数:统计时间内,成功支付的人数(不剔除退款订单)。 + 支付设备数:统计时间内,成功支付的设备数(不剔除退款订单)。 + 下单金额:统计时间内,成功下单的订单金额(不剔除退款订单)。 + 下单笔数:统计时间内,成功下单的订单笔数(不剔除退款订单)。 + 下单人数:统计时间内,成功下单的客户数,一人多次下单记为一人(不剔除退款订单)。 + 下单设备数:统计时间内,成功下单的设备数,一台设备多次访问被计为一台(不剔除退款订单)。 + 访问人数:统计时间内,访问人数,一人多次访问被计为一人(只统计已登录的用户)。 + 访问设备数:统计时间内,访问设备数,一台设备多次访问被计为一台(包含未登录的用户)。 + * @desc 支付统计(按日统计) + * @param {string} type 统计范围 hour:按小时统计,day:按天统计,week:按周统计,month:按月统计 quarter:按季度统计 year:按年统计 + * @param {date|time} date + * @param {bool} reset + */ + async stat(type, date, reset, config = {}) { + if (!date) date = Date.now(); + + // 以下是测试代码----------------------------------------------------------- + //reset = true; + //date = 1667318400000; + // 以上是测试代码----------------------------------------------------------- + let res = await this.run(type, date, reset, config); // 每小时 + if (type === "hour" && config.timely) { + /** + * 如果是小时纬度统计,则还需要再统计(今日实时数据) + * 2022-11-01 01:00:00 统计的是 2022-11-01 的天维度数据(即该天0点-1点数据) + * 2022-11-01 02:00:00 统计的是 2022-11-01 的天维度数据(即该天0点-2点数据) + * 2022-11-01 23:00:00 统计的是 2022-11-01 的天维度数据(即该天0点-23点数据) + * 2022-11-02 00:00:00 统计的是 2022-11-01 的天维度数据(即该天最终数据) + * 2022-11-02 01:00:00 统计的是 2022-11-02 的天维度数据(即该天0点-1点数据) + */ + date -= 1000 * 3600; // 需要减去1小时 + let tasks = []; + tasks.push(this.run("day", date, true, 0)); // 今日 + // 以下数据每6小时刷新一次 + const dateTime = new DateTime(); + const timeInfo = dateTime.getTimeInfo(date); + if ((timeInfo.nHour + 1) % 6 === 0) { + tasks.push(this.run("week", date, true, 0)); // 本周 + tasks.push(this.run("month", date, true, 0)); // 本月 + tasks.push(this.run("quarter", date, true, 0)); // 本季度 + tasks.push(this.run("year", date, true, 0)); // 本年度 + } + await Promise.all(tasks); + } + return res; + } + /** + * @desc 支付统计 + * @param {string} type 统计范围 hour:按小时统计,day:按天统计,week:按周统计,month:按月统计 quarter:按季度统计 year:按年统计 + * @param {date|time} date 哪个时间节点计算(默认已当前时间计算) + * @param {bool} reset 如果统计数据已存在,是否需要重新统计 + */ + async run(type, date, reset, offset = -1) { + let dimension = type; + const dateTime = new DateTime(); + // 获取统计的起始时间和截止时间 + const dateDimension = dateTime.getTimeDimensionByType(dimension, offset, date); + let start_time = dateDimension.startTime; + let end_time = dateDimension.endTime; + + let runStartTime = Date.now(); + let debug = true; + if (debug) { + console.log(`-----------------支付统计开始(${dimension})-----------------`); + console.log('本次统计时间:', dateTime.getDate('Y-m-d H:i:s', start_time), "-", dateTime.getDate('Y-m-d H:i:s', end_time)) + console.log('本次统计参数:', 'type:' + type, 'date:' + date, 'reset:' + reset) + } + this.startTime = start_time; + let pubWhere = { + start_time, + end_time + }; + // 查看当前时间段数据是否已存在,防止重复生成 + + if (!reset) { + let list = await dao.uniStatPayResult.list({ + whereJson: { + ...pubWhere, + dimension + } + }); + if (list.length > 0) { + console.log('data have exists') + if (debug) { + let runEndTime = Date.now(); + console.log(`耗时:${((runEndTime - runStartTime ) / 1000).toFixed(3)} 秒`) + console.log(`-----------------支付统计结束(${dimension})-----------------`); + } + return { + code: 1003, + msg: 'Pay data in this time have already existed' + } + } + } else { + let delRes = await dao.uniStatPayResult.del({ + whereJson: { + ...pubWhere, + dimension + } + }); + console.log('Delete old data result:', JSON.stringify(delRes)) + } + // 支付订单分组(已下单) + let statPayOrdersList1 = await dao.uniPayOrders.group({ + ...pubWhere, + status: "已下单" + }); + // 支付订单分组(且已付款,含退款) + let statPayOrdersList2 = await dao.uniPayOrders.group({ + ...pubWhere, + status: "已付款" + }); + // 支付订单分组(已退款) + let statPayOrdersList3 = await dao.uniPayOrders.group({ + ...pubWhere, + status: "已退款" + }); + let statPayOrdersList = statPayOrdersList1.concat(statPayOrdersList2).concat(statPayOrdersList3) + let res = { + code: 0, + msg: 'success' + } + // 将支付订单分组查询结果组装 + let statDta = {}; + if (statPayOrdersList.length > 0) { + for (let i = 0; i < statPayOrdersList.length; i++) { + let item = statPayOrdersList[i]; + let { + appid, + version, + platform, + channel, + } = item._id; + let { + status_str + } = item; + let key = `${appid}-${version}-${platform}-${channel}`; + if (!statDta[key]) { + statDta[key] = { + appid, + version, + platform, + channel, + status: {} + }; + } + let newItem = JSON.parse(JSON.stringify(item)); + delete newItem._id; + statDta[key].status[status_str] = newItem; + } + } + if (this.debug) console.log('statDta: ', statDta) + + let saveList = []; + for (let key in statDta) { + let item = statDta[key]; + let { + appid, + version, + platform, + channel, + status: statusData, + } = item; + if (!channel) channel = item.scene; + + let fieldData = { + pay_total_amount: 0, + pay_order_count: 0, + pay_user_count: 0, + pay_device_count: 0, + create_total_amount: 0, + create_order_count: 0, + create_user_count: 0, + create_device_count: 0, + refund_total_amount: 0, + refund_order_count: 0, + refund_user_count: 0, + refund_device_count: 0, + }; + + + for (let status in statusData) { + let statusItem = statusData[status]; + if (status === "已下单") { + // 已下单 + fieldData.create_total_amount += statusItem.total_fee; + fieldData.create_order_count += statusItem.order_count; + fieldData.create_user_count += statusItem.user_count; + fieldData.create_device_count += statusItem.device_count; + } else if (status === "已付款") { + // 已付款 + fieldData.pay_total_amount += statusItem.total_fee; + fieldData.pay_order_count += statusItem.order_count; + fieldData.pay_user_count += statusItem.user_count; + fieldData.pay_device_count += statusItem.device_count; + } else if (status === "已退款") { + // 已退款 + fieldData.refund_total_amount += statusItem.total_fee; + fieldData.refund_order_count += statusItem.order_count; + fieldData.refund_user_count += statusItem.user_count; + fieldData.refund_device_count += statusItem.device_count; + } + } + // 平台信息 + let platformInfo = null; + if (this.platforms && this.platforms[platform]) { + // 从缓存中读取数据 + platformInfo = this.platforms[platform] + } else { + const platformObj = new Platform() + platformInfo = await platformObj.getPlatformAndCreate(platform, null) + if (!platformInfo || platformInfo.length === 0) { + platformInfo._id = '' + } + this.platforms[platform] = platformInfo; + } + // 渠道信息 + let channelInfo = null + const channelKey = appid + '_' + platformInfo._id + '_' + channel; + if (this.channels && this.channels[channelKey]) { + channelInfo = this.channels[channelKey]; + } else { + const channelObj = new Channel() + channelInfo = await channelObj.getChannelAndCreate(appid, platformInfo._id, channel) + if (!channelInfo || channelInfo.length === 0) { + channelInfo._id = '' + } + this.channels[channelKey] = channelInfo + } + // 版本信息 + let versionInfo = null + const versionKey = appid + '_' + platform + '_' + version + if (this.versions && this.versions[versionKey]) { + versionInfo = this.versions[versionKey] + } else { + const versionObj = new Version() + versionInfo = await versionObj.getVersionAndCreate(appid, platform, version) + if (!versionInfo || versionInfo.length === 0) { + versionInfo._id = '' + } + this.versions[versionKey] = versionInfo + } + let countWhereJson = { + create_time: _.gte(start_time).lte(end_time), + appid, + version, + platform: _.in(getUniPlatform(platform)), + channel, + }; + // 活跃设备数量 + let activity_device_count = await dao.uniStatSessionLogs.groupCount(countWhereJson); + // 活跃用户数量 + let activity_user_count = await dao.uniStatUserSessionLogs.groupCount(countWhereJson); + + /* + // TODO 此处有问题,暂不使用 + // 新设备数量 + let new_device_count = await dao.uniStatSessionLogs.groupCount({ + ...countWhereJson, + is_first_visit: 1, + }); + // 新注册用户数量 + let new_user_count = await dao.uniIdUsers.count({ + register_date: _.gte(start_time).lte(end_time), + register_env: { + appid, + app_version: version, + uni_platform: _.in(getUniPlatform(platform)), + channel, + } + }); + + + // 新注册用户中下单的人数 + let new_user_create_order_count = await dao.uniIdUsers.countNewUserOrder({ + whereJson: { + register_date: _.gte(start_time).lte(end_time), + register_env: { + appid, + app_version: version, + uni_platform: _.in(getUniPlatform(platform)), + channel, + } + }, + status: [-1, 0] + }); + // 新注册用户中支付成功的人数 + let new_user_pay_order_count = await dao.uniIdUsers.countNewUserOrder({ + whereJson: { + register_date: _.gte(start_time).lte(end_time), + register_env: { + appid, + app_version: version, + uni_platform: _.in(getUniPlatform(platform)), + channel, + } + }, + status: [1, 2, 3] + }); */ + + + saveList.push({ + appid, + platform_id: platformInfo._id, + channel_id: channelInfo._id, + version_id: versionInfo._id, + dimension, + create_date: Date.now(), // 记录下当前时间 + start_time, + end_time, + stat_date: getNowDate(start_time, 8, dimension), + ...fieldData, + activity_user_count, + activity_device_count, + // new_user_count, + // new_device_count, + // new_user_create_order_count, + // new_user_pay_order_count, + }); + } + if (this.debug) console.log('saveList: ', saveList) + //return; + if (saveList.length > 0) { + res = await dao.uniStatPayResult.adds(saveList); + } + if (debug) { + let runEndTime = Date.now(); + console.log(`耗时:${((runEndTime - runStartTime ) / 1000).toFixed(3)} 秒`) + console.log(`本次共添加:${saveList.length } 条记录`) + console.log(`-----------------支付统计结束(${dimension})-----------------`); + } + return res + } + +} + + +function getUniPlatform(platform) { + let list = []; + if (["h5", "web"].indexOf(platform) > -1) { + list = ["h5", "web"]; + } else if (["app-plus", "app"].indexOf(platform) > -1) { + list = ["app-plus", "app"]; + } else { + list = [platform]; + } + return list; +} + +function getNowDate(date = new Date(), targetTimezone = 8, dimension) { + if (typeof date === "string" && !isNaN(date)) date = Number(date); + if (typeof date == "number") { + if (date.toString().length == 10) date *= 1000; + date = new Date(date); + } + const { + year, + month, + day, + hour, + minute, + second + } = getFullTime(date); + // 现在的时间 + let date_str; + if (dimension === "month") { + date_str = timeFormat(date, "yyyy-MM", targetTimezone); + } else if (dimension === "quarter") { + date_str = timeFormat(date, "yyyy-MM", targetTimezone); + } else if (dimension === "year") { + date_str = timeFormat(date, "yyyy", targetTimezone); + } else { + date_str = timeFormat(date, "yyyy-MM-dd", targetTimezone); + } + return { + date_str, + year, + month, + day, + hour, + //minute, + //second, + }; +} + +function getFullTime(date = new Date(), targetTimezone = 8) { + if (!date) { + return ""; + } + if (typeof date === "string" && !isNaN(date)) date = Number(date); + if (typeof date == "number") { + if (date.toString().length == 10) date *= 1000; + date = new Date(date); + } + const dif = date.getTimezoneOffset(); + const timeDif = dif * 60 * 1000 + (targetTimezone * 60 * 60 * 1000); + const east8time = date.getTime() + timeDif; + date = new Date(east8time); + + let YYYY = date.getFullYear() + ''; + let MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1); + let DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()); + let hh = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()); + let mm = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()); + let ss = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds()); + return { + YYYY: Number(YYYY), + MM: Number(MM), + DD: Number(DD), + hh: Number(hh), + mm: Number(mm), + ss: Number(ss), + + year: Number(YYYY), + month: Number(MM), + day: Number(DD), + hour: Number(hh), + minute: Number(mm), + second: Number(ss), + }; +}; + + +/** + * 日期格式化 + */ +function timeFormat(time, fmt = 'yyyy-MM-dd hh:mm:ss', targetTimezone = 8) { + try { + if (!time) { + return ""; + } + if (typeof time === "string" && !isNaN(time)) time = Number(time); + // 其他更多是格式化有如下: + // yyyy-MM-dd hh:mm:ss|yyyy年MM月dd日 hh时MM分等,可自定义组合 + let date; + if (typeof time === "number") { + if (time.toString().length == 10) time *= 1000; + date = new Date(time); + } else { + date = time; + } + + const dif = date.getTimezoneOffset(); + const timeDif = dif * 60 * 1000 + (targetTimezone * 60 * 60 * 1000); + const east8time = date.getTime() + timeDif; + + date = new Date(east8time); + let opt = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "h+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + for (let k in opt) { + if (new RegExp("(" + k + ")").test(fmt)) { + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (opt[k]) : (("00" + opt[k]).substr(("" + opt[k]).length))); + } + } + return fmt; + } catch (err) { + // 若格式错误,则原值显示 + return time; + } +}; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uniIDUsers.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uniIDUsers.js new file mode 100644 index 0000000..6f40dde --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/uniIDUsers.js @@ -0,0 +1,97 @@ +/** + * @class UniIDUsers uni-id 用户模型 + */ +const BaseMod = require('./base') +module.exports = class UniIDUsers extends BaseMod { + + constructor() { + super() + this.tableName = 'uni-id-users' + this.tablePrefix = false + } + + /** + * 获取用户数 + * @param {String} appid DCloud-appid + * @param {String} platform 平台 + * @param {String} channel 渠道 + * @param {String} version 版本 + * @param {Object} registerTime 注册时间范围 例:{$gte:开始日期时间戳, $lte:结束日期时间戳} + * @return {Number} + */ + async getUserCount(appid, platform, channel, version, registerTime) { + if(!appid || !platform) { + return false + } + const condition = this.getCondition(appid, platform, channel, version, registerTime) + let userCount = 0 + const userCountRes = await this.getCollection(this.tableName).where(condition).count() + if(userCountRes && userCountRes.total > 0) { + userCount = userCountRes.total + } + return userCount + } + + /** + * 获取用户编号列表 + * @param {String} appid DCloud-appid + * @param {String} platform 平台 + * @param {String} channel 渠道 + * @param {String} version 版本 + * @param {Object} registerTime 注册时间范围 例:{$gte:开始日期时间戳, $lte:结束日期时间戳} + * @return {Array} + */ + async getUserIds(appid, platform, channel, version, registerTime) { + if(!appid || !platform) { + return false + } + const condition = this.getCondition(appid, platform, channel, version, registerTime) + let uids = [] + const uidsRes = await this.selectAll(this.tableName, condition, { + _id: 1 + }) + + for (const u in uidsRes.data) { + uids.push(uidsRes.data[u]._id) + } + + return uids + } + + /** + * 获取查询条件 + * @param {String} appid DCloud-appid + * @param {String} platform 平台 + * @param {String} channel 渠道 + * @param {String} version 版本 + * @param {Object} registerTime 注册时间范围 例:{$gte:开始日期时间戳, $lte:结束日期时间戳} + */ + getCondition(appid, platform, channel, version, registerTime) { + + let condition = { + 'register_env.appid': appid,//DCloud appid + 'register_env.uni_platform': platform,//平台 + 'register_env.channel': channel ? channel : '1001', //渠道或场景值 + 'register_env.app_version' : version //应用版本区分 + } + + //原生应用平台 + if(['android', 'ios'].includes(platform)) { + condition['register_env.uni_platform'] = 'app'//systemInfo中uniPlatform字段android和ios都用app表示,所以此处查询需要用osName区分一下 + condition['register_env.os_name'] = platform //系统 + } + + //兼容vue2 + if(channel === '1001') { + condition['register_env.channel'] = {$in:['', '1001']} + } + + //注册时间 + if(registerTime) { + condition.register_date = registerTime + } + + return condition + } + +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/userSessionLog.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/userSessionLog.js new file mode 100644 index 0000000..2af4ebd --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/userSessionLog.js @@ -0,0 +1,229 @@ +/** + * @class UserSessionLog 用户会话日志模型 + */ +const BaseMod = require('./base') +const Platform = require('./platform') +const Channel = require('./channel') +const { + DateTime +} = require('../lib') +module.exports = class UserSessionLog extends BaseMod { + constructor() { + super() + this.tableName = 'user-session-logs' + } + + /** + * 用户会话日志数据填充 + * @param {Object} params 上报参数 + */ + async fill(params) { + + if (!params.sid) { + return { + code: 200, + msg: 'Not found session log' + } + } + + if (!params.uid) { + return { + code: 200, + msg: 'Parameter "uid" not found' + } + } + + const dateTime = new DateTime() + const platform = new Platform() + const channel = new Channel() + + //获取当前页面信息 + if (!params.page_id) { + const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj) + if (!pageInfo || pageInfo.length === 0) { + return { + code: 300, + msg: 'Not found this entry page' + } + } + params.page_id = pageInfo._id + } + + const nowTime = dateTime.getTime() + + const fillParams = { + appid: params.ak, + version: params.v ? params.v : '', + platform: platform.getPlatformCode(params.ut, params.p), + channel: channel.getChannelCode(params), + session_id: params.sid, + uid: params.uid, + last_visit_time: nowTime, + entry_page_id: params.page_id, + exit_page_id: params.page_id, + page_count: 0, + event_count: 0, + duration: 1, + is_finish: 0, + create_time: nowTime, + } + + const res = await this.insert(this.tableName, fillParams) + + if (res && res.id) { + return { + code: 0, + msg: 'success' + } + } else { + return { + code: 500, + msg: 'User session log filled error' + } + } + } + + /** + * 检测用户会话是否有变化,并更新 + * @param {Object} params 校验参数 - sid:基础会话编号 uid:用户编号 last_visit_user_id:基础会话中最近一个访问用户的编号 + */ + async checkUserSession(params) { + if (!params.sid) { + return { + code: 200, + msg: 'Not found session log' + } + } + + if (!params.uid) { + //用户已退出会话 + if (params.last_visit_user_id) { + if (this.debug) { + console.log('user "' + params.last_visit_user_id + '" is exit session :', params.sid) + } + await this.closeUserSession(params.sid) + } + } else { + //添加用户日志 + if (!params.last_visit_user_id) { + await this.fill(params) + } + //用户已切换 + else if (params.uid != params.last_visit_user_id) { + if (this.debug) { + console.log('user "' + params.last_visit_user_id + '" change to "' + params.uid + + '" in the session :', params.sid) + } + //关闭原会话生成新用户对话 + await this.closeUserSession(params.sid) + await this.fill(params) + } + } + return { + code: 0, + msg: 'success' + } + } + + + + /** + * 关闭用户会话 + * @param {String} sid 基础会话编号 + */ + async closeUserSession(sid) { + if (this.debug) { + console.log('close user session log by sid:', sid) + } + return await this.update(this.tableName, { + is_finish: 1 + }, { + session_id: sid, + is_finish: 0 + }) + } + + + /** + * 更新会话信息 + * @param {String} sid 基础会话编号 + * @param {Object} data 更新数据 + */ + async updateUserSession(sid, data) { + + const userSession = await this.getCollection(this.tableName).where({ + session_id: sid, + uid: data.uid, + is_finish: 0 + }).orderBy('create_time', 'desc').limit(1).get() + + if (userSession.data.length === 0) { + console.log('Not found the user session', { + session_id: sid, + uid: data.uid, + is_finish: 0 + }) + return { + code: 300, + msg: 'Not found the user session' + } + } + + let nowTime = data.nowTime ? data.nowTime : new DateTime().getTime() + const accessTime = nowTime - userSession.data[0].createTime + const accessSenconds = accessTime > 1000 ? parseInt(accessTime / 1000) : 1 + + const updateData = { + last_visit_time: nowTime, + duration: accessSenconds, + } + + //访问页面数量 + if (data.addPageCount) { + updateData.page_count = userSession.data[0].page_count + data.addPageCount + } + //最终访问的页面编号 + if (data.pageId) { + updateData.exit_page_id = data.pageId + } + //产生事件次数 + if (data.eventCount) { + updateData.event_count = userSession.data[0].event_count + data.addEventCount + } + + if (this.debug) { + console.log('update user session log by sid-' + sid, updateData) + } + + await this.update(this.tableName, updateData, { + _id: userSession.data[0]._id + }) + + return { + code: 0, + msg: 'success' + } + } + + /** + * 清理用户会话日志数据 + * @param {Object} days 保留天数, 留存统计需要计算30天后留存率,因此至少应保留31天的日志数据 + */ + async clean(days = 31) { + days = Math.max(parseInt(days), 1) + console.log('clean user session logs - day:', days) + + const dateTime = new DateTime() + const res = await this.delete(this.tableName, { + create_time: { + $lt: dateTime.getTimeBySetDays(0 - days) + } + }) + + if (!res.code) { + console.log('clean user session log:', res) + } + return res + } + +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/version.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/version.js new file mode 100644 index 0000000..b20236a --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/mod/version.js @@ -0,0 +1,73 @@ +/** + * @class Version 应用版本模型 + */ +const BaseMod = require('./base') +const { + DateTime +} = require('../lib') +module.exports = class Version extends BaseMod { + constructor() { + super() + this.tableName = 'opendb-app-versions' + this.tablePrefix = false + this.cacheKeyPre = 'uni-stat-app-version-' + } + + /** + * 获取版本信息 + * @param {String} appid DCloud-appid + * @param {String} platformId 平台编号 + * @param {String} appVersion 平台版本号 + */ + async getVersion(appid, platform, appVersion) { + const cacheKey = this.cacheKeyPre + appid + '-' + platform + '-' + appVersion + let versionData = await this.getCache(cacheKey) + if (!versionData) { + const versionInfo = await this.getCollection(this.tableName).where({ + appid: appid, + uni_platform: platform, + type: 'native_app', + version: appVersion + }).limit(1).get() + versionData = [] + if (versionInfo.data.length > 0) { + versionData = versionInfo.data[0] + await this.setCache(cacheKey, versionData) + } + } + return versionData + } + + + /** + * 获取版本信息没有则进行创建 + * @param {String} appid DCloud-appid + * @param {String} platform 平台代码 + * @param {String} appVersion 平台版本号 + */ + async getVersionAndCreate(appid, platform, appVersion) { + const versionInfo = await this.getVersion(appid, platform, appVersion) + if (versionInfo.length === 0) { + if (appVersion.length > 0 && !appVersion.includes('}')) { + const thisTime = new DateTime().getTime() + const insertParam = { + appid: appid, + platform: [], + uni_platform: platform, + type: 'native_app', + version: appVersion, + stable_publish: false, + create_env: 'uni-stat', + create_date: thisTime + } + const res = await this.insert(this.tableName, insertParam) + if (res && res.id) { + return Object.assign(insertParam, { + _id: res.id + }) + } + } + } + return versionInfo + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/receiver.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/receiver.js new file mode 100644 index 0000000..61306e2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/receiver.js @@ -0,0 +1,126 @@ +/** + * @class UniStatReportDataReceiver uni统计上报数据接收器 + * @function report 上报数据调度处理函数 + */ +const { + parseUrlParams +} = require('../shared') +const SessionLog = require('./mod/sessionLog') +const PageLog = require('./mod/pageLog') +const EventLog = require('./mod/eventLog') +const ErrorLog = require('./mod/errorLog') +const Device = require('./mod/device') +class UniStatReportDataReceiver { + /** + * @description 上报数据调度处理函数 + * @param {Object} params 基础上报参数 + * @param {Object} context 请求附带的上下文信息 + */ + async report(params, context) { + let res = { + code: 0, + msg: 'success' + } + + if (!params || !params.requests) { + return { + code: 200, + msg: 'Invild params' + } + } + + // JSON参数解析 + const requestParam = JSON.parse(params.requests) + if (!requestParam || requestParam.length === 0) { + return { + code: 200, + msg: 'Invild params' + } + } + + // 日志填充 + const sessionParams = [] + const pageParams = [] + const eventParams = [] + const errorParams = [] + const device = new Device() + for (const ri in requestParam) { + //参数解析 + const urlParams = parseUrlParams(requestParam[ri], context) + if (!urlParams.ak) { + return { + code: 201, + msg: 'Not found appid' + } + } + + if (!urlParams.lt) { + return { + code: 202, + msg: 'Not found this log type' + } + } + + switch (parseInt(urlParams.lt)) { + // 会话日志 + case 1: { + sessionParams.push(urlParams) + break + } + // 页面日志 + case 3: + case 11: { + pageParams.push(urlParams) + break + } + // 事件日志 + case 21: { + eventParams.push(urlParams) + break + } + // 错误日志 + case 31: { + errorParams.push(urlParams) + break + } + //unipush信息绑定 + case 101: { + res = await device.bindPush(urlParams) + break + } + default: { + console.log('Invalid type by param "lt:' + urlParams.lt + '"') + break + } + } + } + + //会话日志填充 + if (sessionParams.length > 0) { + const sessionLog = new SessionLog() + res = await sessionLog.batchFill(sessionParams) + } + + //页面日志填充 + if (pageParams.length > 0) { + const pageLog = new PageLog() + res = await pageLog.fill(pageParams) + } + + //事件日志填充 + if (eventParams.length > 0) { + const eventLog = new EventLog() + res = await eventLog.fill(eventParams) + } + + //错误日志填充 + if (errorParams.length > 0) { + const errorLog = new ErrorLog() + res = await errorLog.fill(errorParams) + } + + return res + } +} + +module.exports = UniStatReportDataReceiver diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/stat.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/stat.js new file mode 100644 index 0000000..93fc433 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/common/uni-stat/stat/stat.js @@ -0,0 +1,388 @@ +/** + * @class UniStatDataStat uni统计-数据统计调度处理模块 + * @function cron 数据统计定时任务处理函数 + * @function stat 数据统计调度处理函数 + * @function cleanLog 日志清理调度处理函数 + */ +const { + DateTime +} = require('./lib') + +const { + sleep +} = require('../shared') + +const { + BaseMod, + SessionLog, + PageLog, + EventLog, + ShareLog, + ErrorLog, + StatResult, + ActiveDevices, + ActiveUsers, + PageResult, + EventResult, + ErrorResult, + Loyalty, + RunErrors, + UserSessionLog, + uniPay, + Setting +} = require('./mod') +class UniStatDataStat { + /** + * 数据统计定时任务处理函数 + * @param {Object} context 服务器请求上下文参数 + */ + async cron(context) { + const baseMod = new BaseMod() + const dateTime = new DateTime() + console.log('Cron start time: ', dateTime.getDate('Y-m-d H:i:s')) + + // const setting = new Setting(); + // let settingValue = await setting.getSetting() + // if (settingValue.mode === "close") { + // // 如果关闭了统计任务,则任务直接结束 + // return { + // code: 0, + // msg: 'Task is close', + // } + // } else if (settingValue.mode === "auto") { + // // 如果开启了节能模式,则判断N天内是否有设备访问记录 + // let runKey = await setting.checkAutoRun(settingValue); + // if (!runKey) { + // return { + // code: 0, + // msg: 'Task is auto close', + // } + // } + // } + + //获取运行参数 + const timeInfo = dateTime.getTimeInfo(null, false) + const cronConfig = baseMod.getConfig('cron') + const cronMin = baseMod.getConfig('cronMin') + const realtimeStat = baseMod.getConfig('realtimeStat') + // 数据跑批 + let res = null + if (cronConfig && cronConfig.length > 0) { + for (var mi in cronConfig) { + const currCronConfig = cronConfig[mi] + const cronType = currCronConfig.type + const cronTime = currCronConfig.time.split(' ') + const cronDimension = currCronConfig.dimension + + //未开启分钟级定时任务,则设置为小时级定时任务 + if (cronTime.length === 4 && !cronMin) { + cronTime.splice(3, 1) + } + + if (baseMod.debug) { + console.log('cronTime', cronTime) + } + //精度为分钟级的定时任务 + if (cronTime.length === 4) { + if (cronTime[0] !== '*') { + //周统计任务 + if (timeInfo.nWeek == cronTime[0] && timeInfo.nHour == cronTime[2] && timeInfo.nMinutes == + cronTime[3]) { + let dimension = cronDimension || 'week'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: cronDimension, + config: currCronConfig + }) + } + } else if (cronTime[1] !== '*') { + //月统计任务(包含季度统计任务和年统计任务) + if (timeInfo.nDay == cronTime[1] && timeInfo.nHour == cronTime[2] && timeInfo.nMinutes == + cronTime[3]) { + let dimension = cronDimension || 'month'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } else if (cronTime[2] !== '*') { + //日统计任务 + if (timeInfo.nHour == cronTime[2] && timeInfo.nMinutes == cronTime[3]) { + let dimension = cronDimension || 'day'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } else if (cronTime[3] !== '*') { + //实时统计任务 + if (timeInfo.nMinutes == cronTime[3] && realtimeStat) { + let dimension = cronDimension || 'hour'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } + } + //精度为小时级的定时任务 + else if (cronTime.length === 3) { + if (cronTime[0] !== '*') { + //周统计任务 + if (timeInfo.nWeek == cronTime[0] && timeInfo.nHour == cronTime[2]) { + let dimension = cronDimension || 'week'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } else if (cronTime[1] !== '*') { + //月统计任务(包含季度统计任务和年统计任务) + if (timeInfo.nDay == cronTime[1] && timeInfo.nHour == cronTime[2]) { + let dimension = cronDimension || 'month'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } else if (cronTime[2] !== '*') { + //日统计任务 + if (timeInfo.nHour == cronTime[2]) { + let dimension = cronDimension || 'day'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } else { + //实时统计任务 + if (realtimeStat) { + let dimension = cronDimension || 'hour'; + console.log(cronType + `--${dimension} run`) + res = await this.stat({ + type: cronType, + dimension: dimension, + config: currCronConfig + }) + } + } + } else { + console.error('Cron configuration error') + } + } + } + console.log('Cron end time: ', dateTime.getDate('Y-m-d H:i:s')) + return { + code: 0, + msg: 'Task have done', + lastCronResult: res + } + } + + /** + * 数据统计调度处理函数 + * @param {Object} params 统计参数 + */ + async stat(params) { + const { + type, + dimension, + date, + reset, + config + } = params + let res = { + code: 0, + msg: 'success' + } + + try { + switch (type) { + // 基础统计 + case 'stat': { + const resultStat = new StatResult() + res = await resultStat.stat(dimension, date, reset) + break + } + // 活跃设备统计归集 + case 'active-device': { + const activeDevices = new ActiveDevices() + res = await activeDevices.stat(date, reset) + break + } + // 活跃用户统计归集 + case 'active-user': { + const activeUsers = new ActiveUsers() + res = await activeUsers.stat(date, reset) + break + } + // 设备留存统计 + case 'retention-device': { + const retentionStat = new StatResult() + res = await retentionStat.retentionStat(dimension, date) + break + } + // 用户留存统计 + case 'retention-user': { + const retentionStat = new StatResult() + res = await retentionStat.retentionStat(dimension, date, 'user') + break + } + // 页面统计 + case 'page': { + const pageStat = new PageResult() + res = await pageStat.stat(dimension, date, reset) + break + } + // 事件统计 + case 'event': { + const eventStat = new EventResult() + res = await eventStat.stat(dimension, date, reset) + break + } + // 错误统计 + case 'error': { + const errorStat = new ErrorResult() + res = await errorStat.stat(dimension, date, reset) + break + } + // 设备忠诚度统计 + case 'loyalty': { + const loyaltyStat = new Loyalty() + res = await loyaltyStat.stat(dimension, date, reset) + break + } + // 日志清理 + case 'clean': { + res = await this.cleanLog() + } + // 支付统计 + case 'pay-result': { + const paymentResult = new uniPay.PayResult() + res = await paymentResult.stat(dimension, date, reset, config) + break + } + } + } catch (e) { + const maxTryTimes = 2 + if (!this.tryTimes) { + this.tryTimes = 1 + } else { + this.tryTimes++ + } + + //报错则重新尝试2次, 解决部分云服务器偶现连接超时问题 + if (this.tryTimes <= maxTryTimes) { + //休眠1秒后重新调用 + await sleep(1000) + params.reset = true + res = await this.stat(params) + } else { + // 2次尝试失败后记录错误 + console.error('server error: ' + e) + const runError = new RunErrors() + runError.create({ + mod: 'stat', + params: params, + error: e, + create_time: new DateTime().getTime() + }) + + res = { + code: 500, + msg: 'server error' + e + } + } + } + return res + } + + /** + * 日志清理调度处理函数 + */ + async cleanLog() { + const baseMod = new BaseMod() + const cleanLog = baseMod.getConfig('cleanLog') + if (!cleanLog || !cleanLog.open) { + return { + code: 100, + msg: 'The log cleanup service has not been turned on' + } + } + + const res = { + code: 0, + msg: 'success', + data: {} + } + + // 会话日志 + if (cleanLog.reserveDays.sessionLog > 0) { + const sessionLog = new SessionLog() + res.data.sessionLog = await sessionLog.clean(cleanLog.reserveDays.sessionLog) + } + + // 用户会话日志 + if (cleanLog.reserveDays.userSessionLog > 0) { + const userSessionLog = new UserSessionLog() + res.data.userSessionLog = await userSessionLog.clean(cleanLog.reserveDays.userSessionLog) + } + + // 页面日志 + if (cleanLog.reserveDays.pageLog > 0) { + const pageLog = new PageLog() + res.data.pageLog = await pageLog.clean(cleanLog.reserveDays.pageLog) + } + + // 事件日志 + if (cleanLog.reserveDays.eventLog > 0) { + const eventLog = new EventLog() + res.data.eventLog = await eventLog.clean(cleanLog.reserveDays.eventLog) + } + + // 分享日志 + if (cleanLog.reserveDays.shareLog > 0) { + const shareLog = new ShareLog() + res.data.shareLog = await shareLog.clean(cleanLog.reserveDays.shareLog) + } + + // 错误日志 + if (cleanLog.reserveDays.errorLog > 0) { + const errorLog = new ErrorLog() + res.data.errorLog = await errorLog.clean(cleanLog.reserveDays.errorLog) + } + + // 活跃设备日志 + const activeDevicesLog = new ActiveDevices() + res.data.activeDevicesLog = await activeDevicesLog.clean() + + // 活跃用户日志 + const activeUsersLog = new ActiveUsers() + res.data.activeUsersLog = await activeUsersLog.clean() + + // 实时统计日志 + const resultHourLog = new StatResult() + res.data.resultHourLog = await resultHourLog.cleanHourLog() + + //原生应用崩溃日志 + const appCrashLogs = new AppCrashLogs() + res.data.appCrashLogs = await appCrashLogs.clean() + + return res + } +} + +module.exports = UniStatDataStat diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js new file mode 100644 index 0000000..1f16dc2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js @@ -0,0 +1,49 @@ +'use strict'; +exports.main = async (event, context) => { + /** + * 根据搜索记录,设定时间间隔来归纳出热搜数据并存储在热搜表中 + */ + const SEARCHHOT = 'opendb-search-hot'; // 热搜数据库名称 + const SEARCHLOG = 'opendb-search-log'; // 搜索记录数据库名称 + const SEARCHLOG_timeZone = 604800000; // 归纳搜索记录时间间隔,毫秒数,默认为最近7天 + const SEARCHHOT_size = 10; // 热搜条数 + + const DB = uniCloud.database(); + const DBCmd = DB.command; + const $ = DB.command.aggregate; + const SEARCHHOT_db = DB.collection(SEARCHHOT); + const SEARCHLOG_db = DB.collection(SEARCHLOG); + const timeEnd = Date.now() - SEARCHLOG_timeZone; + + let { + data: searchHotData + } = await SEARCHLOG_db + .aggregate() + .match({ + create_date: DBCmd.gt(timeEnd) + }) + .group({ + _id: { + 'content': '$content', + }, + count: $.sum(1) + }) + .replaceRoot({ + newRoot: $.mergeObjects(['$_id', '$$ROOT']) + }) + .project({ + _id: false + }) + .sort({ + count: -1 + }) + .end(); + + let now = Date.now(); + searchHotData.map(item => { + item.create_date = now; + return item; + }).slice(0, SEARCHHOT_size); + // searchHotData = searchHotData.sort((a, b) => b.count - a.count).slice(0, SEARCHHOT_size); + return searchHotData.length ? await SEARCHHOT_db.add(searchHotData) : '' +}; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json new file mode 100644 index 0000000..6005add --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json @@ -0,0 +1,14 @@ +{ + "name": "uni-analyse-searchhot", + "version": "1.0.0", + "description": "定时归纳热搜", + "main": "index.js", + "dependencies": {}, + "cloudfunction-config": { + "triggers": [{ + "name": "analyse-searchHot", + "type": "timer", + "config": "0 0 */2 * * * *" + }] + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/index.js new file mode 100644 index 0000000..4a0c31c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/index.js @@ -0,0 +1,188 @@ +const fs = require('fs') +const path = require('path') +const TE = require('./lib/art-template.js'); + +// 标准语法的界定符规则 +TE.defaults.openTag = '{@' +TE.defaults.closeTag = '@}' + +const success = { + success: true +} +const fail = { + success: false +} + +async function translateTCB(_fileList = []) { + if (!_fileList.length) return _fileList + // 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回 + const { + fileList + } = await uniCloud.getTempFileURL({ + fileList: _fileList + }); + return fileList.map((item, index) => item.tempFileURL ? item.tempFileURL : _fileList[index]) +} + +function hasValue(value) { + if (typeof value !== 'object') return !!value + if (value instanceof Array) return !!value.length + return !!(value && Object.keys(value).length) +} + +module.exports = async function(id) { + if (!id) { + return { + ...fail, + code: -1, + errMsg: 'id required' + }; + } + + // 根据sitemap配置加载页面模板,例如列表页,详情页 + let templatePage = fs.readFileSync(path.resolve(__dirname, './template.html'), 'utf8'); + if (!templatePage) { + return { + ...fail, + code: -2, + errMsg: 'page template no found' + }; + } + + const db = uniCloud.database() + let dbPublishList + try { + dbPublishList = db.collection('opendb-app-list') + } catch (e) {} + + if (!dbPublishList) return fail; + + const record = await dbPublishList.where({ + _id: id + }).get({ + getOne: true + }) + + if (record && record.data && record.data.length) { + const appInfo = record.data[0] + + const defaultOptions = { + hasApp: false, + hasMP: false, + hasH5: false, + hasQuickApp: false + } + + defaultOptions.mpNames = { + 'mp_weixin': '微信', + 'mp_alipay': '支付宝', + 'mp_baidu': '百度', + 'mp_toutiao': '字节', + 'mp_qq': 'QQ', + 'mp_dingtalk': '钉钉', + 'mp_kuaishou': '快手', + 'mp_lark': '飞书', + 'mp_jd': '京东' + } + + const imageList = []; + ['app_android'].forEach(key => { + if (!hasValue(appInfo[key])) return + imageList.push({ + key, + urlKey: 'url', + url: appInfo[key].url + }) + }) + Object.keys(defaultOptions.mpNames).concat('quickapp').forEach(key => { + if (!hasValue(appInfo[key])) return + imageList.push({ + key, + urlKey: 'qrcode_url', + url: appInfo[key].qrcode_url + }) + }); + ['icon_url'].forEach(key => { + if (!hasValue(appInfo[key])) return + imageList.push({ + key, + url: appInfo[key] + }) + }) + const filelist = await translateTCB(imageList.map(item => item.url)) + imageList.forEach((item, index) => { + if (item.urlKey) { + appInfo[item.key][item.urlKey] = filelist[index] + } else { + appInfo[item.key] = filelist[index] + } + }) + if (hasValue(appInfo.screenshot)) { + appInfo.screenshot = await translateTCB(appInfo.screenshot) + } + + { + const appInfoKeys = Object.keys(appInfo) + if (appInfoKeys.some(key => { + return key.indexOf('app_') !== -1 && hasValue(appInfo[key]) + })) { + defaultOptions.hasApp = true + } + if (appInfoKeys.some(key => { + return key.indexOf('mp') !== -1 && hasValue(appInfo[key]) + })) { + defaultOptions.hasMP = true + } + if (appInfo.h5 && appInfo.h5.url) { + defaultOptions.hasH5 = true + } + if (appInfo.quickapp && appInfo.quickapp.qrcode_url) { + defaultOptions.hasQuickApp = true + } + + // app + if (defaultOptions.hasApp && appInfo.app_android && appInfo.app_android.url) { + defaultOptions.android_url = appInfo.app_android.url + } else { + defaultOptions.android_url = '' + } + if (defaultOptions.hasApp && appInfo.app_ios && appInfo.app_ios.url) { + defaultOptions.ios_url = appInfo.app_ios.url + } else { + defaultOptions.ios_url = '' + } + + // mp + defaultOptions.mpKeys = Object.keys(appInfo).filter(key => { + return key.indexOf('mp') !== -1 && hasValue(appInfo[key]) + }) + } + + const html = TE.render(templatePage)(Object.assign({}, appInfo, defaultOptions)); + + if (!(defaultOptions.hasApp || defaultOptions.hasH5 || defaultOptions.hasMP || defaultOptions + .hasQuickApp)) { + return { + ...fail, + code: -100, + errMsg: '缺少应用信息,App、小程序、H5、快应用请至少填写一项' + } + } + + return { + ...success, + mpserverlessComposedResponse: true, // 使用阿里云返回集成响应是需要此字段为true + statusCode: 200, + headers: { + 'content-type': 'text/html' + }, + body: html + }; + } + + return { + ...fail, + code: -3, + errMsg: 'no record' + }; +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/lib/art-template.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/lib/art-template.js new file mode 100644 index 0000000..b292990 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/lib/art-template.js @@ -0,0 +1,2 @@ +/*!art-template - Template Engine | http://aui.github.com/artTemplate/*/ +!function(){function a(a){return a.replace(t,"").replace(u,",").replace(v,"").replace(w,"").replace(x,"").split(y)}function b(a){return"'"+a.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"'"}function c(c,d){function e(a){return m+=a.split(/\n/).length-1,k&&(a=a.replace(/\s+/g," ").replace(//g,"")),a&&(a=s[1]+b(a)+s[2]+"\n"),a}function f(b){var c=m;if(j?b=j(b,d):g&&(b=b.replace(/\n/g,function(){return m++,"$line="+m+";"})),0===b.indexOf("=")){var e=l&&!/^=[=#]/.test(b);if(b=b.replace(/^=[=#]?|[\s;]*$/g,""),e){var f=b.replace(/\s*\([^\)]+\)/,"");n[f]||/^(include|print)$/.test(f)||(b="$escape("+b+")")}else b="$string("+b+")";b=s[1]+b+s[2]}return g&&(b="$line="+c+";"+b),r(a(b),function(a){if(a&&!p[a]){var b;b="print"===a?u:"include"===a?v:n[a]?"$utils."+a:o[a]?"$helpers."+a:"$data."+a,w+=a+"="+b+",",p[a]=!0}}),b+"\n"}var g=d.debug,h=d.openTag,i=d.closeTag,j=d.parser,k=d.compress,l=d.escape,m=1,p={$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1},q="".trim,s=q?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],t=q?"$out+=text;return $out;":"$out.push(text);",u="function(){var text=''.concat.apply('',arguments);"+t+"}",v="function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);"+t+"}",w="'use strict';var $utils=this,$helpers=$utils.$helpers,"+(g?"$line=0,":""),x=s[0],y="return new String("+s[3]+");";r(c.split(h),function(a){a=a.split(i);var b=a[0],c=a[1];1===a.length?x+=e(b):(x+=f(b),c&&(x+=e(c)))});var z=w+x+y;g&&(z="try{"+z+"}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:"+b(c)+".split(/\\n/)[$line-1].replace(/^\\s+/,'')};}");try{var A=new Function("$data","$filename",z);return A.prototype=n,A}catch(B){throw B.temp="function anonymous($data,$filename) {"+z+"}",B}}var d=function(a,b){return"string"==typeof b?q(b,{filename:a}):g(a,b)};d.version="3.0.0",d.config=function(a,b){e[a]=b};var e=d.defaults={openTag:"<%",closeTag:"%>",escape:!0,cache:!0,compress:!1,parser:null},f=d.cache={};d.render=function(a,b){return q(a,b)};var g=d.renderFile=function(a,b){var c=d.get(a)||p({filename:a,name:"Render Error",message:"Template not found"});return b?c(b):c};d.get=function(a){var b;if(f[a])b=f[a];else if("object"==typeof document){var c=document.getElementById(a);if(c){var d=(c.value||c.innerHTML).replace(/^\s*|\s*$/g,"");b=q(d,{filename:a})}}return b};var h=function(a,b){return"string"!=typeof a&&(b=typeof a,"number"===b?a+="":a="function"===b?h(a.call(a)):""),a},i={"<":"<",">":">",'"':""","'":"'","&":"&"},j=function(a){return i[a]},k=function(a){return h(a).replace(/&(?![\w#]+;)|[<>"']/g,j)},l=Array.isArray||function(a){return"[object Array]"==={}.toString.call(a)},m=function(a,b){var c,d;if(l(a))for(c=0,d=a.length;d>c;c++)b.call(a,a[c],c,a);else for(c in a)b.call(a,a[c],c)},n=d.utils={$helpers:{},$include:g,$string:h,$escape:k,$each:m};d.helper=function(a,b){o[a]=b};var o=d.helpers=n.$helpers;d.onerror=function(a){var b="Template Error\n\n";for(var c in a)b+="<"+c+">\n"+a[c]+"\n\n";"object"==typeof console&&console.error(b)};var p=function(a){return d.onerror(a),function(){return"{Template Error}"}},q=d.compile=function(a,b){function d(c){try{return new i(c,h)+""}catch(d){return b.debug?p(d)():(b.debug=!0,q(a,b)(c))}}b=b||{};for(var g in e)void 0===b[g]&&(b[g]=e[g]);var h=b.filename;try{var i=c(a,b)}catch(j){return j.filename=h||"anonymous",j.name="Syntax Error",p(j)}return d.prototype=i.prototype,d.toString=function(){return i.toString()},h&&b.cache&&(f[h]=d),d},r=n.$each,s="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",t=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g,u=/[^\w$]+/g,v=new RegExp(["\\b"+s.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),w=/^\d[^,]*|,\d[^,]*/g,x=/^,+|,+$/g,y=/^$|,+/;e.openTag="{{",e.closeTag="}}";var z=function(a,b){var c=b.split(":"),d=c.shift(),e=c.join(":")||"";return e&&(e=", "+e),"$helpers."+d+"("+a+e+")"};e.parser=function(a){a=a.replace(/^\s/,"");var b=a.split(" "),c=b.shift(),e=b.join(" ");switch(c){case"if":a="if("+e+"){";break;case"else":b="if"===b.shift()?" if("+b.join(" ")+")":"",a="}else"+b+"{";break;case"/if":a="}";break;case"each":var f=b[0]||"$data",g=b[1]||"as",h=b[2]||"$value",i=b[3]||"$index",j=h+","+i;"as"!==g&&(f="[]"),a="$each("+f+",function("+j+"){";break;case"/each":a="});";break;case"echo":a="print("+e+");";break;case"print":case"include":a=c+"("+b.join(",")+");";break;default:if(/^\s*\|\s*[\w\$]/.test(e)){var k=!0;0===a.indexOf("#")&&(a=a.substr(1),k=!1);for(var l=0,m=a.split("|"),n=m.length,o=m[l++];n>l;l++)o=z(o,m[l]);a=(k?"=":"=#")+o}else a=d.helpers[c]?"=#"+c+"("+b.join(",")+");":"="+a}return a},"function"==typeof define?define(function(){return d}):"undefined"!=typeof exports?module.exports=d:this.template=d}(); \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/template.html b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/template.html new file mode 100644 index 0000000..22d699d --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/createPublishHtml/template.html @@ -0,0 +1,238 @@ + + + + + + + + + {@name@} + + + +
+ +
+ +
+ +

{@name@}

+

{@introduction@}

+
+ + {@if hasApp || hasMP || hasH5 || hasQuickApp@} +
+
+ {@if hasApp@} + App + {@/if@} + {@if hasMP@} + 小程序 + {@/if@} + {@if hasH5@} + H5 + {@/if@} + {@if hasQuickApp@} + 快应用 + {@/if@} +
+
+ {@if hasApp@} +
+ +

扫码获取

+ 下载安装 + + +

Android平台尚未发布,敬请期待~

+
+ {@/if@} + {@if hasMP@} +
+
+
+ {@each mpKeys@} +
+
+
+ {@mpNames[$value]@} +
+
+ {@/each@} +
+
+ {@each mpKeys@} +
+ + +

长按图片识别小程序

+
+ {@/each@} +
+
+
+ {@/if@} + {@if hasH5@} +
+
+ + {@h5.url@} +
+
+ {@/if@} + {@if hasQuickApp@} +
+ +

快应用

+

扫描二维码或复制名称后可在手机应用市场中搜索快应用

+
+ {@/if@} +
+
+ {@/if@} + + +
+
+ +
+
+
+ +
+ + +
+

{@name@}

+

{@introduction@}

+
+ + {@if hasApp || hasMP || hasH5 || hasQuickApp@} +
+
+ {@if hasApp@} + App + {@/if@} + {@if hasMP@} + 小程序 + {@/if@} + {@if hasH5@} + H5 + {@/if@} + {@if hasQuickApp@} + 快应用 + {@/if@} +
+
+ {@if hasApp@} + + {@/if@} + {@if hasMP@} +
+ {@each mpKeys@} +
+ +
扫二维码识别小程序
+
{@mpNames[$value]@}小程序
+
+ {@/each@} +
+ {@/if@} + {@if hasH5@} +
+
+
+ {@h5.url@} +
+
+ {@/if@} + {@if hasQuickApp@} +
+ +

快应用

+

扫描二维码或复制名称后可在手机应用市场中搜索快应用

+
+ {@/if@} +
+
+ {@/if@} +
+ + {@if description && description.length@} +
+

应用描述

+
{@description@}
+
+ {@/if@} + + {@if screenshot && screenshot.length@} +
+

应用截图

+
+
+
    + {@each screenshot@} +
  • + +
  • + {@/each@} +
+
+ {@/if@} +
+

复制成功

+
+
+ + + + + \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/index.js new file mode 100644 index 0000000..f45fb9c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/index.js @@ -0,0 +1,25 @@ +'use strict'; +const success = { + success: true +} +const fail = { + success: false +} +const createPublishHtml = require('./createPublishHtml') + +exports.main = async (event, context) => { + //event为客户端上传的参数 + console.log('event : ', event) + + let res = {}; + let params = event.data || event.params; + + switch (event.action) { + case 'createPublishHtml': + res = createPublishHtml(params.id) + break; + } + + //返回数据给客户端 + return res +}; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/package.json new file mode 100644 index 0000000..354f947 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-portal/package.json @@ -0,0 +1,7 @@ +{ + "name": "uni-portal", + "dependencies": {}, + "extensions": { + "uni-cloud-jql": {} + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/build-template-data.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/build-template-data.js new file mode 100644 index 0000000..0057d40 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/build-template-data.js @@ -0,0 +1,26 @@ +module.exports = (templateData, user) => { + const data = {} + for (const template of templateData) { + const isDynamic = /\{.*?\}/.test(template.value) + + // 仅支持uni-id-users + if (isDynamic) { + const [collection, field] = template.value.replace(/\{|\}/g, '').split('.') + data[template.field] = collection === 'uni-id-users' ? user[field] || template.value: template.value + } else { + data[template.field] = template.value + } + // switch (template.type) { + // case 'static': + // data[template.field] = template.value + // break + // case 'dynamic': + // data[template.field] = user[template.value] || '' + // break + // default: + // throw new Error(`template type [${template.type}] not supported`) + // } + } + + return data +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/index.obj.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/index.obj.js new file mode 100644 index 0000000..2b7ac1e --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/index.obj.js @@ -0,0 +1,414 @@ +// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj +// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129 +const createConfig = require('uni-config-center') +const buildTemplateData = require('./build-template-data') +const { parserDynamicField } = require('./utils') +const schemaNameAdapter = require('./schema-name-adapter') +const {presetCondition, conditionConvert} = require("./preset-condition") + +const uniSmsCo = uniCloud.importObject('uni-sms-co') +const db = uniCloud.database() +const smsConfig = createConfig({ + pluginId: 'uni-sms-co' +}).config() + +function errCode(code) { + return 'uni-sms-co-' + code +} + +const tableNames = { + template: 'opendb-sms-template', + task: 'opendb-sms-task', + log: 'opendb-sms-log' +} + +module.exports = { + _before: async function () { // 通用预处理器 + if (!smsConfig.smsKey || smsConfig.smsKey.length <= 20 || !smsConfig.smsSecret || smsConfig.smsSecret.length <= 20) { + throw new Error('请先配置smsKey和smsSecret') + } + + this.tableNames = tableNames + + /** + * 优化 schema 的命名规范,需要兼容 uni-admin@2.1.6 以下版本 + * 如果是在uni-admin@2.1.6版本以上创建的项目可以将其注释 + * */ + await schemaNameAdapter.call(this) + }, + _after: function (error, result) { + if (error) { + console.error(error) + if (error instanceof Error) { + return { + errCode: 'error', + errMsg: error.message + } + } + + if (error.errCode) { + return error + } + + throw error + } + + return result + }, + /** + * 创建短信任务 + * @param {{receiver: *[], type: string}} to + * @param {String} to.type=user to.all=true时用来区分发送类型 + * @param {Array} to.receiver 用户ID's / 用户标签ID's + * @param {Object} to.condition 用户筛选条件 + * @param {String} templateId 短信模板ID + * @param {Array} templateData 短信模板数据 + * @param {Object} options + * @param {String} options.taskName 任务名称 + */ + async createSmsTask(to, templateId, templateData, options = {}) { + if (!templateId) { + return { + errCode: errCode('template-id-required'), + errMsg: '缺少templateId' + } + } + + if (!to.condition && (!to.receiver || to.receiver.length <= 0)) { + return { + errCode: errCode('send-users-is-null'), + errMsg: '请选择要发送的用户' + } + } + + const clientInfo = this.getClientInfo() + + const {data: templates} = await db.collection(this.tableNames.template).where({_id: templateId}).get() + if (templates.length <= 0) { + return { + errCode: errCode('template-not-found'), + errMsg: '短信模板不存在' + } + } + const [template] = templates + + // 预设条件 + if (presetCondition[to.condition]) { + to.condition = typeof presetCondition[to.condition] === "function" ? presetCondition[to.condition]() : presetCondition[to.condition] + } + + // 创建短信任务 + const task = await db.collection(this.tableNames.task).add({ + app_id: clientInfo.appId, + name: options.taskName, + template_id: templateId, + template_content: template.content, + vars: templateData, + to, + send_qty: 0, + success_qty: 0, + fail_qty: 0, + create_date: Date.now() + }) + + uniSmsCo.createUserSmsMessage(task.id) + + return new Promise(resolve => setTimeout(() => resolve({ + errCode: 0, + errMsg: '任务创建成功', + taskId: task.id + }), 300)) + }, + async createUserSmsMessage(taskId, execData = {}) { + const parallel = 100 + let beforeId + const { data: tasks } = await db.collection(this.tableNames.task).where({ _id: taskId }).get() + + if (tasks.length <= 0) { + return { + errCode: errCode('task-id-not-found'), + errMsg: '任务ID不存在' + } + } + + const [task] = tasks + let query = { + mobile: db.command.exists(true) + } + + // 指定用户发送 + if (task.to.type === 'user' && task.to.receiver.length > 0 && !task.to.condition) { + let index = 0 + if (execData.beforeId) { + const i = task.to.receiver.findIndex(id => id === execData.beforeId) + index = i !== -1 ? i + 1 : 0 + } + + const receiver = task.to.receiver.slice(index, index + parallel) + query._id = db.command.in(receiver) + beforeId = receiver[receiver.length - 1] + } + + // 指定用户标签 + if (task.to.type === 'userTags') { + query.tags = db.command.in(task.to.receiver) + } + + // 自定义条件 + if (task.to.condition) { + const condition = conditionConvert(task.to.condition, db.command) + + query = { + ...query, + ...condition + } + } + + if ((task.to.condition || task.to.type === "userTags") && execData.beforeId) { + query._id = db.command.gt(execData.beforeId) + } + + // 动态数据仅支持uni-id-users表字段 + const dynamicField = parserDynamicField(task.vars) + const userFields = dynamicField['uni-id-users'] ? dynamicField['uni-id-users'].reduce((res, field) => { + res[field] = true + return res + }, {}): {} + + const { data: users } = await db.collection('uni-id-users') + .where(query) + .field({ + mobile: true, + ...userFields + }) + .limit(parallel) + .orderBy('_id', 'asc') + .get() + + if (users.length <= 0) { + // 更新要发送的短信数量 + const count = await db.collection(this.tableNames.log).where({ task_id: taskId }).count() + await db.collection(this.tableNames.task).where({ _id: taskId }).update({ + send_qty: count.total + }) + + // 开始发送 + uniSmsCo.sendSms(taskId) + + return new Promise(resolve => setTimeout(() => resolve({ + errCode: 0, + errMsg: '创建完成' + }), 500)) + } + + if (!beforeId) { + beforeId = users[users.length - 1]._id + } + + let docs = [] + for (const user of users) { + const varData = await buildTemplateData(task.vars, user) + docs.push({ + uid: user._id, + task_id: taskId, + mobile: user.mobile, + var_data: varData, + status: 0, + create_date: Date.now() + }) + } + + await db.collection(this.tableNames.log).add(docs) + + uniSmsCo.createUserSmsMessage(taskId, { beforeId }) + + return new Promise(resolve => setTimeout(() => resolve(), 500)) + }, + async sendSms(taskId) { + const { data: tasks } = await db.collection(this.tableNames.task).where({ _id: taskId }).get() + if (tasks.length <= 0) { + console.warn(`task [${taskId}] not found`) + return + } + + const [task] = tasks + const isStaticTemplate = !task.vars.length + + let sendData = { + appId: task.app_id, + smsKey: smsConfig.smsKey, + smsSecret: smsConfig.smsSecret, + templateId: task.template_id, + data: {} + } + + const { data: records } = await db.collection(this.tableNames.log) + .where({ task_id: taskId, status: 0 }) + .limit(isStaticTemplate ? 50 : 1) + .field({ mobile: true, var_data: true }) + .get() + + if (records.length <= 0) { + return { + errCode: 0, + errMsg: '发送完成' + } + } + + if (isStaticTemplate) { + sendData.phoneList = records.reduce((res, user) => { + res.push(user.mobile) + return res + }, []) + } else { + const [record] = records + sendData.phone = record.mobile + sendData.data = record.var_data + } + + try { + // await sendSms(sendData) + await uniCloud.sendSms(sendData) + // 修改发送状态为已发送 + await db.collection(this.tableNames.log).where({ + _id: db.command.in(records.map(record => record._id)) + }).update({ + status: 1, + send_date: Date.now() + }) + // 更新任务的短信成功数 + await db.collection(this.tableNames.task).where({ _id: taskId }) + .update({ + success_qty: db.command.inc(records.length) + }) + } catch (e) { + console.error('[sendSms Fail]', e) + // 修改发送状态为发送失败 + await db.collection(this.tableNames.log).where({ + _id: db.command.in(records.map(record => record._id)) + }).update({ + status: 2, + reason: e.errMsg || '未知原因', + send_date: Date.now() + }) + // 更新任务的短信失败数 + await db.collection(this.tableNames.task).where({ _id: taskId }) + .update({ + fail_qty: db.command.inc(records.length) + }) + } + + uniSmsCo.sendSms(taskId) + + return new Promise(resolve => setTimeout(() => resolve(), 500)) + }, + async template() { + const {data: templates = []} = await db.collection(this.tableNames.template).get() + return templates + }, + async task (id) { + const {data: tasks} = await db.collection(this.tableNames.task).where({_id: id}).get() + if (tasks.length <= 0) { + return null + } + + return tasks[0] + }, + async updateTemplates (templates) { + if (templates.length <= 0) { + return { + errCode: errCode('template-is-null'), + errMsg: '缺少模板信息' + } + } + + let group = [] + for (const template of templates) { + group.push( + db.collection(this.tableNames.template).doc(String(template.templateId)).set({ + name: template.templateName, + content: template.templateContent, + type: template.templateType, + sign: template.templateSign + }) + ) + } + + await Promise.all(group) + + return { + errCode: 0, + errMsg: '更新成功' + } + }, + /** + * @param to + * @param templateId + * @param templateData + * @param options {Object} + * @param options.condition 群发条件 + * */ + async preview (to, templateId, templateData, options = {}) { + const count = 1 + let query = { + mobile: db.command.exists(true) + } + + // 指定用户发送 + if (to.type === 'user' && to.receiver.length > 0 && !to.condition) { + // const receiver = to.receiver.slice(0, 10) + query._id = db.command.in(to.receiver) + } + + // 指定用户标签 + if (to.type === 'userTags') { + query.tags = db.command.in(to.receiver) + } + + // 自定义条件 + let condition = to.condition + if (presetCondition[to.condition]) { + condition = typeof presetCondition[to.condition] === "function" ? presetCondition[to.condition]() : presetCondition[to.condition] + } + + if (condition) { + query = { + ...query, + ...conditionConvert(condition, db.command) + } + } + + const {data: users} = await db.collection('uni-id-users').where(query).limit(count).get() + const {total} = await db.collection('uni-id-users').where(query).count() + + if (users.length <= 0) { + return { + errCode: errCode('users-is-null'), + errMsg: '请添加要发送的用户' + } + } + + const {data: templates} = await db.collection(this.tableNames.template).where({_id: templateId}).get() + if (templates.length <= 0) { + return { + errCode: errCode('template-not-found'), + errMsg: '模板不存在' + } + } + const [template] = templates + + let docs = [] + for (const user of users) { + const varData = buildTemplateData(templateData, user) + const content = template.content.replace(/\$\{(.*?)\}/g, ($1, param) => varData[param] || $1) + docs.push(`【${template.sign}】${content}`) + } + + return { + errCode: 0, + errMsg: '', + list: docs, + total + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/package.json new file mode 100644 index 0000000..f989531 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/package.json @@ -0,0 +1,10 @@ +{ + "name": "uni-sms-co", + "dependencies": { + "uni-config-center": "file:../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "extensions": { + "uni-cloud-sms": {}, + "uni-cloud-jql": {} + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/preset-condition.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/preset-condition.js new file mode 100644 index 0000000..40c620f --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/preset-condition.js @@ -0,0 +1,82 @@ +const presetCondition = { + all: {}, + '7-day-offline-users': () => ({ + last_login_date: { + type: 'lt', + value: Date.now() - (7 * 24 * 60 * 60 * 1000) + } + }), + '15-day-offline-users': () => ({ + last_login_date: { + type: 'lt', + value: Date.now() - (15 * 24 * 60 * 60 * 1000) + } + }), + '30-day-offline-users': () => ({ + last_login_date: { + type: 'lt', + value: Date.now() - (30 * 24 * 60 * 60 * 1000) + } + }) +} + +function conditionConvert(condition, command) { + const newCondition = {} + + for (const key in condition) { + const field = condition[key] + + switch (field.type) { + case 'search': + newCondition[key] = new RegExp(field.value) + break + case 'select': + if (field.value.length) { + newCondition[key] = command.or( + field.value.map(value => command.eq(value)) + ) + } + break + case 'range': + if (field.value.length) { + const [gt, lt] = field.value + newCondition[key] = command.and([ + command.gte(gt), + command.lte(lt) + ]) + } + break + case 'date': + if (field.value.length) { + const [startTimestamp, endTimestamp] = field.value + const startDate = new Date(startTimestamp) + const endDate = new Date(endTimestamp) + + newCondition[key] = command.and([ + command.gte(startDate), + command.lte(endDate) + ]) + } + break + case 'timestamp': + if (field.value.length) { + const [startDate, endDate] = field.value + + newCondition[key] = command.and([ + command.gte(startDate), + command.lte(endDate) + ]) + } + break + case 'lt': + newCondition[key] = command.lt(field.value) + break + } + } + + return newCondition +} + + +module.exports.presetCondition = presetCondition +module.exports.conditionConvert = conditionConvert diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/schema-name-adapter.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/schema-name-adapter.js new file mode 100644 index 0000000..cf00293 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/schema-name-adapter.js @@ -0,0 +1,15 @@ +const db = uniCloud.database() + +module.exports = async function () { + try { + const count = await db.collection('batch-sms-template').count() + + if (count.total > 0) { + this.tableNames = { + template: 'batch-sms-template', + task: 'batch-sms-task', + log: 'batch-sms-result' + } + } + } catch (e) {} +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/utils.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/utils.js new file mode 100644 index 0000000..edf34b8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-sms-co/utils.js @@ -0,0 +1,42 @@ +exports.chunk = function (arr, num) { + const list = [] + let current = [] + + for (const item of arr) { + current.push(item); + if (current.length === num) { + list.push(current) + current = [] + } + } + + if (current.length) list.push(current) + + return list +} + +exports.checkIsStaticTemplate = function (data = []) { + let isStatic = data.length <= 0 + + for (const template of data) { + if (template.type === 'static') { + isStatic = true + break + } + } + + return isStatic +} + +exports.parserDynamicField = function (templateData) { + return templateData.reduce((res, template) => { + if (/\{.*?\}/.test(template.value)) { + const [collection, field] = template.value.replace(/\{|\}/g, '').split('.') + if (!res[collection]) { + res[collection] = [] + } + res[collection].push(field) + } + return res + }, {}) +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/index.js new file mode 100644 index 0000000..685c330 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/index.js @@ -0,0 +1,6 @@ +'use strict'; +const uniStat = require('uni-stat') +exports.main = async (event, context) => { + //数据跑批处理函数 + return await uniStat.initStat().cron(context) +}; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/package.json new file mode 100644 index 0000000..b70c322 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-cron/package.json @@ -0,0 +1,27 @@ +{ + "name": "uni-stat-cron", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "uni-stat": "file:../common/uni-stat" + }, + "cloudfunction-config": { + "concurrency": 1, + "memorySize": 512, + "timeout": 600, + "triggers": [ + { + "name": "uni-stat-cron", + "type": "timer", + "config": "17 17 * * * * *" + } + ] + }, + "extensions": {} +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/index.obj.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/index.obj.js new file mode 100644 index 0000000..dac8354 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/index.obj.js @@ -0,0 +1,29 @@ +const uniStat = require('uni-stat') +const uniID = require('uni-id-common') +module.exports = { + report: async function (params = {}) { + //客户端信息 + const clientInfo = this.getClientInfo() + //云服务信息 + const cloudInfo = this.getCloudInfo() + //token信息 + const token = this.getUniIdToken() + //当前登录用户id + let uid + if(token) { + const tokenRes = await uniID.createInstance({ + clientInfo + }).checkToken(token) + + if(tokenRes.uid) { + uid = tokenRes.uid + } + } + //数据上报 + return await uniStat.initReceiver().report(params, { + ...clientInfo, + ...cloudInfo, + uid + }) + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/package.json new file mode 100644 index 0000000..2535f17 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/package.json @@ -0,0 +1,16 @@ +{ + "name": "uni-stat-receiver", + "dependencies": { + "uni-stat": "file:../common/uni-stat", + "uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common" + }, + "cloudfunction-config": { + "concurrency": 1, + "memorySize": 128, + "timeout": 60, + "triggers": [] + }, + "extensions": { + "uni-cloud-jql": {} + } +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/uni-stat-receiver.param.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/uni-stat-receiver.param.js new file mode 100644 index 0000000..b38c3c6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-stat-receiver/uni-stat-receiver.param.js @@ -0,0 +1,2 @@ +// 本文件中的内容将在云对象【运行】时解析为运行参数 +// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/rundebug.html#run-obj-param \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/checkVersion/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/checkVersion/index.js new file mode 100644 index 0000000..e38892c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/checkVersion/index.js @@ -0,0 +1,167 @@ +'use strict'; +module.exports = async (event, context) => { + /** + * 检测升级 使用说明 + * 上传包: + * 1. 根据传参,先检测传参是否完整,appid appVersion wgtVersion 必传 + * 2. 先从数据库取出所有该平台(从上下文读取平台信息,默认 Andriod)的所有线上发行更新 + * 3. 再从所有线上发行更新中取出版本最大的一版。如果可以,尽量先检测wgt的线上发行版更新 + * 4. 使用上步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新,必须同时大于这两项,否则返回暂无更新 + * 5. 如果库中 wgt包 版本大于传参 appVersion,但是不满足 min_uni_version < appVersion,则不会使用wgt更新,会接着判断库中 app包version 是否大于 appVersion + */ + + let { + appid, + appVersion, + wgtVersion, + } = event; + + const platform_Android = 'Android'; + const platform_iOS = 'iOS'; + const package_app = 'native_app'; + const package_wgt = 'wgt'; + const app_version_db_name = 'opendb-app-versions' + + let platform = platform_Android; + + // 云函数URL化请求 + if (event.headers) { + let body; + try { + if (event.httpMethod.toLocaleLowerCase() === 'get') { + body = event.queryStringParameters; + } else { + body = JSON.parse(event.body); + } + } catch (e) { + return { + code: 500, + msg: '请求错误' + }; + } + + appid = body.appid; + appVersion = body.appVersion; + wgtVersion = body.wgtVersion; + + platform = /iPhone|iPad/.test(event.headers) ? platform_iOS : platform_Android; + } else if (context.OS) { + platform = context.OS === 'android' ? + platform_Android : + context.OS === 'ios' ? + platform_iOS : + platform_Android; + } + + if (appid && appVersion && wgtVersion && platform) { + const collection = uniCloud.database().collection(app_version_db_name); + + const record = await collection.where({ + appid, + platform, + stable_publish: true + }) + .orderBy('create_date', 'desc') + .get(); + + if (record && record.data && record.data.length > 0) { + const appVersionInDb = record.data.find(item => item.type === package_app) || {}; + const wgtVersionInDb = record.data.find(item => item.type === package_wgt) || {}; + const hasAppPackage = !!Object.keys(appVersionInDb).length; + const hasWgtPackage = !!Object.keys(wgtVersionInDb).length; + + // 取两个版本中版本号最大的包,版本一样,使用wgt包 + let stablePublishDb = hasAppPackage ? + hasWgtPackage ? + compare(wgtVersionInDb.version, appVersionInDb.version) >= 0 ? + wgtVersionInDb : + appVersionInDb : + appVersionInDb : + wgtVersionInDb; + + const { + version, + min_uni_version + } = stablePublishDb; + + // 库中的version必须满足同时大于appVersion和wgtVersion才行,因为上次更新可能是wgt更新 + const appUpdate = compare(version, appVersion) === 1; // app包可用更新 + const wgtUpdate = compare(version, wgtVersion) === 1; // wgt包可用更新 + + if (Object.keys(stablePublishDb).length && appUpdate && wgtUpdate) { + // 判断是否可用wgt更新 + if (min_uni_version && compare(min_uni_version, appVersion) < 1) { + return { + code: 101, + message: 'wgt更新', + ...stablePublishDb + }; + } else if (hasAppPackage && compare(appVersionInDb.version, appVersion) === 1) { + return { + code: 102, + message: '整包更新', + ...appVersionInDb + }; + } + } + + return { + code: 0, + message: '当前版本已经是最新的,不需要更新' + }; + } + + return { + code: -101, + message: '暂无更新或检查appid是否填写正确' + }; + } + + return { + code: -102, + message: '请检查传参是否填写正确' + }; +}; + +/** + * 对比版本号,如需要,请自行修改判断规则 + * 支持比对 ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之类的 + * @param {Object} v1 + * @param {Object} v2 + * v1 > v2 return 1 + * v1 < v2 return -1 + * v1 == v2 return 0 + */ +function compare(v1 = '0', v2 = '0') { + v1 = String(v1).split('.') + v2 = String(v2).split('.') + const minVersionLens = Math.min(v1.length, v2.length); + + let result = 0; + for (let i = 0; i < minVersionLens; i++) { + const curV1 = Number(v1[i]) + const curV2 = Number(v2[i]) + + if (curV1 > curV2) { + result = 1 + break; + } else if (curV1 < curV2) { + result = -1 + break; + } + } + + if (result === 0 && (v1.length !== v2.length)) { + const v1BiggerThenv2 = v1.length > v2.length; + const maxLensVersion = v1BiggerThenv2 ? v1 : v2; + for (let i = minVersionLens; i < maxLensVersion.length; i++) { + const curVersion = Number(maxLensVersion[i]) + if (curVersion > 0) { + v1BiggerThenv2 ? result = 1 : result = -1 + break; + } + } + } + + return result; +} diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/index.js b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/index.js new file mode 100644 index 0000000..7fbaae8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/index.js @@ -0,0 +1,91 @@ +'use strict'; +const success = { + success: true +} +const fail = { + success: false +} +const checkVersion = require('./checkVersion') + +exports.main = async (event, context) => { + //event为客户端上传的参数 + + const db = uniCloud.database() + const appListDBName = 'opendb-app-list' + const appVersionDBName = 'opendb-app-versions' + let res = {}; + + if (event.headers) { + try { + if (event.httpMethod.toLocaleLowerCase() === 'get') { + event = event.queryStringParameters; + } else { + event = JSON.parse(event.body); + } + } catch (e) { + return { + code: 500, + msg: '请求错误' + }; + } + } + + let params = event.data || event.params; + switch (event.action) { + case 'checkVersion': + res = await checkVersion(event, context) + break; + case 'deleteFile': + res = await uniCloud.deleteFile({ + fileList: params.fileList + }) + break; + case 'setNewAppData': + params.value.create_date = Date.now() + res = await db.collection(appListDBName).doc(params.id).set(params.value) + break; + case 'getAppInfo': + let dbAppList + try { + dbAppList = db.collection(appListDBName) + } catch (e) {} + + if (!dbAppList) return fail; + + const dbAppListRecord = await dbAppList.where({ + appid: params.appid + }).get() + + if (dbAppListRecord && dbAppListRecord.data.length) + return Object.assign({}, success, dbAppListRecord.data[0]) + + //返回数据给客户端 + return fail + break; + case 'getAppVersionInfo': + let dbVersionList + try { + dbVersionList = db.collection(appVersionDBName) + } catch (e) {} + + if (!dbVersionList) return fail; + + const dbVersionListrecord = await dbVersionList.where({ + appid: params.appid, + platform: params.platform, + type: "native_app", + stable_publish: true + }) + .orderBy('create_date', 'desc') + .get(); + + if (dbVersionListrecord && dbVersionListrecord.data && dbVersionListrecord.data.length > 0) + return Object.assign({}, dbVersionListrecord.data[0], success) + + return fail + break; + } + + //返回数据给客户端 + return res +}; diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/package.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/package.json new file mode 100644 index 0000000..ae7bc6c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/package.json @@ -0,0 +1,7 @@ +{ + "name": "uni-app-manager", + "dependencies": {}, + "extensions": { + "uni-cloud-jql": {} + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/uni-app-manager.param.json b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/uni-app-manager.param.json new file mode 100644 index 0000000..e43d322 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/cloudfunctions/uni-upgrade-center/uni-app-manager.param.json @@ -0,0 +1,10 @@ +// 本文件中的json内容将在云函数【运行】时作为参数传给云函数。 + +// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam + +{ + "action": "checkVersion", + "appid": "__UNI__HelloUNIApp", + "appVersion": "1.0.0", + "wgtVersion": "1.0.0" +} diff --git a/alpha/admin/uniCloud-aliyun/database/JQL file Name.jql b/alpha/admin/uniCloud-aliyun/database/JQL file Name.jql new file mode 100644 index 0000000..35d21de --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/JQL file Name.jql @@ -0,0 +1,12 @@ +// 本文件用于,使用JQL语法操作项目关联的uniCloud空间的数据库,方便开发调试和远程数据库管理 +// 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法 +// 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码 +// 如果文档中存在多条JQL语句,只有最后一条语句生效 +// 如果混写了普通js,最后一条语句需是数据库操作语句 +// 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission +// 不支持clientDB的action +// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database.html#limit +// 详细JQL语法,请参考:https://uniapp.dcloud.net.cn/uniCloud/jql.html + +// 下面示例查询uni-id-users表的所有数据 +db.collection('uni-id-users').get(); diff --git a/alpha/admin/uniCloud-aliyun/database/db_init.json b/alpha/admin/uniCloud-aliyun/database/db_init.json new file mode 100644 index 0000000..652864e --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/db_init.json @@ -0,0 +1,549 @@ +// 在本文件中可配置云数据库初始化,数据格式见:https://uniapp.dcloud.io/uniCloud/hellodb?id=db-init + +// 编写完毕后对本文件点右键,可按配置规则创建表和添加数据 + +{ + "uni-id-users": { + "data": [{ + "_id": "_uni_starter_test_user_id", + "username": "uni-starter预置用户名", + "nickname": "测试用户昵称", + "avatar": "https://unicloud.dcloud.net.cn/assets/logo.dca09351.png", + "mobile": "18888888888", + "mobile_confirmed": 1 + }] + }, + "uni-id-roles": { + "data": [{ + "role_id": "admin", + "role_name": "超级管理员", + "permission": [], + "comment": "超级管理员拥有所有权限", + "create_date": 0 + }] + }, + "opendb-banner": { + "data": [{ + "status": true, + "bannerfile": { + "name": "094a9dc0-50c0-11eb-b680-7980c8a877b8.jpg", + "extname": "jpg", + "fileType": "image", + "url": "https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg", + "size": 70880, + "image": { + "width": 500, + "height": 333 + }, + "path": "https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg" + }, + "open_url": "https://www.dcloud.io/", + "title": "测试", + "sort": 1, + "category_id": "", + "description": "" + }, + { + "status": true, + "bannerfile": { + "name": "094a9dc0-50c0-11eb-b680-7980c8a877b8.jpg", + "extname": "jpg", + "fileType": "image", + "url": "https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg", + "size": 70880, + "image": { + "width": 500, + "height": 333 + }, + "path": "https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg" + }, + "open_url": "https://www.dcloud.io/", + "title": "", + "category_id": "", + "description": "" + } + ] + }, + "opendb-news-articles": { + "data": [{ + "title": "阿里小程序IDE官方内嵌uni-app,为开发者提供多端开发服务", + "excerpt": "阿里小程序IDE官方内嵌uni-app,为开发者提供多端开发服务", + "content": "

随着微信、阿里、百度、头条、QQ纷纷推出小程序,开发者的开发维护成本持续上升,负担过重。这点已经成为共识,现在连小程序平台厂商也充分意识到了。

\n

阿里小程序团队,为了减轻开发者的负担,在官方的小程序开发者工具中整合了多端框架。

\n

经过阿里团队仔细评估,uni-app 在产品完成度、跨平台支持度、开发者社区、可持续发展等多方面优势明显,最终选定 uni-app内置于阿里小程序开发工具中,为开发者提供多端开发解决方案。

\n

经过之前1个月的公测,10月10日,阿里小程序正式发布0.70版开发者工具,通过 uni-app 实现多端开发,成为本次版本更新的亮点功能!

\n

如下图,在阿里小程序工具左侧主导航选择 uni-app,创建项目,即可开发。

\n
\n


阿里小程序开发工具更新说明详见:https://docs.alipay.com/mini/ide/0.70-stable

\n

 

\n

集成uni-app,这对于阿里团队而言,并不是一个容易做出的决定。毕竟 uni-app 是一个三方产品,要经过复杂的评审流程。

\n

这一方面突显出阿里团队以开发者需求为本的优秀价值观,另一方面也证明 uni-app的产品确实过硬。

\n

很多开发者都有多端需求,但又没有足够精力去了解、评估 uni-app,而处于观望态度。现在大家可以更放心的使用 uni-app 了,它没有让阿里失望,也不会让你失望。

\n

自从uni-app推出以来,DCloud也取得了高速的发展,目前拥有370万开发者,框架运行在4.6亿手机用户设备上,月活达到1.35亿(仅包括部分接入DCloud统计平台的数据)。并且数据仍在高速增长中,在市场占有率上处于遥遥领先的位置。

\n

本次阿里小程序工具集成 uni-app,会让 uni-app 继续快速爆发,取得更大的成功。

\n

后续DCloud还将深化与阿里的合作,在serverless等领域给开发者提供更多优质服务。

\n

使用多端框架开发各端应用,是多赢的模式。开发者减轻了负担,获得了更多新流量。而小程序平台厂商,也能保证自己平台上的各种应用可以被及时的更新。

\n

DCloud欢迎更多小程序平台厂商,与我们一起合作,为开发者、平台、用户的多赢而努力。

\n

进一步了解uni-app,详见:https://uniapp.dcloud.io

\n

欢迎扫码关注DCloud公众号,转发消息到朋友圈。

", + "avatar": "https://ask.dcloud.net.cn/uploads/article/20191014/56f7dc1bd5f265e824649f7cb4f78d5b.png", + "type": 0, + "user_id": "_uni_starter_test_user_id", + "comment_count": 0, + "like_count": 0, + "comment_status": 0, + "article_status": 1, + "publish_date": 1616092287006, + "last_modify_date": 1616092303031, + "create_date": 1616092287006 + }] + }, + "opendb-admin-menus": { + "data": [{ + "menu_id": "index", + "name": "首页", + "icon": "uni-icons-home", + "url": "/", + "sort": 100, + "parent_id": "", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_management", + "name": "系统管理", + "icon": "admin-icons-fl-xitong", + "url": "", + "sort": 1000, + "parent_id": "", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_user", + "name": "用户管理", + "icon": "admin-icons-manager-user", + "url": "/pages/system/user/list", + "sort": 1010, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469398 + }, { + "menu_id": "system_role", + "name": "角色管理", + "icon": "admin-icons-manager-role", + "url": "/pages/system/role/list", + "sort": 1020, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469397 + }, { + "menu_id": "system_permission", + "name": "权限管理", + "icon": "admin-icons-manager-permission", + "url": "/pages/system/permission/list", + "sort": 1030, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_menu", + "name": "菜单管理", + "icon": "admin-icons-manager-menu", + "url": "/pages/system/menu/list", + "sort": 1040, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469396 + }, { + "menu_id": "system_app", + "name": "应用管理", + "icon": "admin-icons-manager-app", + "url": "/pages/system/app/list", + "sort": 1035, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662469399 + }, { + "menu_id": "system_update", + "name": "App升级中心", + "icon": "uni-icons-cloud-upload", + "url": "/uni_modules/uni-upgrade-center/pages/version/list", + "sort": 1036, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1656491532434 + }, { + "menu_id": "system_tag", + "name": "标签管理", + "icon": "admin-icons-manager-tag", + "url": "/pages/system/tag/list", + "sort": 1037, + "parent_id": "system_management", + "permission": [], + "enable": true, + "create_date": 1602662479389 + }, { + "permission": [], + "enable": true, + "menu_id": "safety_statistics", + "name": "安全审计", + "icon": "admin-icons-safety", + "url": "", + "sort": 3100, + "parent_id": "", + "create_date": 1638356430871 + }, { + "permission": [], + "enable": true, + "menu_id": "safety_statistics_user_log", + "name": "用户日志", + "icon": "", + "url": "/pages/system/safety/list", + "sort": 3101, + "parent_id": "safety_statistics", + "create_date": 1638356430871 + }, { + "permission": [], + "enable": true, + "menu_id": "uni-stat", + "name": "uni 统计", + "icon": "admin-icons-tongji", + "url": "", + "sort": 2100, + "parent_id": "", + "create_date": 1638356430871 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device", + "name": "设备统计", + "icon": "admin-icons-shebeitongji", + "url": "", + "sort": 2120, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/device/overview/overview", + "sort": 2121, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-activity", + "name": "活跃度", + "icon": "", + "url": "/pages/uni-stat/device/activity/activity", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-trend", + "name": "趋势分析", + "icon": "", + "url": "/pages/uni-stat/device/trend/trend", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-retention", + "name": "留存", + "icon": "", + "url": "/pages/uni-stat/device/retention/retention", + "sort": 2124, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-comparison", + "name": "平台对比", + "icon": "", + "url": "/pages/uni-stat/device/comparison/comparison", + "sort": 2125, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-device", + "permission": [], + "enable": true, + "menu_id": "uni-stat-device-stickiness", + "name": "粘性", + "icon": "", + "url": "/pages/uni-stat/device/stickiness/stickiness", + "sort": 2126, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user", + "name": "注册用户统计", + "icon": "admin-icons-yonghutongji", + "url": "", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/user/overview/overview", + "sort": 2121, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-activity", + "name": "活跃度", + "icon": "", + "url": "/pages/uni-stat/user/activity/activity", + "sort": 2122, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "icon": "", + "menu_id": "uni-stat-user-trend", + "name": "趋势分析", + "url": "/pages/uni-stat/user/trend/trend", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-retention", + "name": "留存", + "icon": "", + "url": "/pages/uni-stat/user/retention/retention", + "sort": 2124, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-comparison", + "name": "平台对比", + "icon": "", + "url": "/pages/uni-stat/user/comparison/comparison", + "sort": 2125, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-user", + "permission": [], + "enable": true, + "menu_id": "uni-stat-user-stickiness", + "name": "粘性", + "icon": "", + "url": "/pages/uni-stat/user/stickiness/stickiness", + "sort": 2126, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-analysis", + "name": "页面统计", + "icon": "admin-icons-page-ent", + "url": "", + "sort": 2123, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-page-analysis", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-res", + "name": "受访页", + "icon": "", + "url": "/pages/uni-stat/page-res/page-res", + "sort": 2131, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-page-analysis", + "permission": [], + "enable": true, + "menu_id": "uni-stat-page-ent", + "name": "入口页", + "icon": "", + "url": "/pages/uni-stat/page-ent/page-ent", + "sort": 2132, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel", + "name": "渠道/场景值分析", + "icon": "admin-icons-qudaofenxi", + "url": "", + "sort": 2150, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-senceChannel", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel-scene", + "name": "场景值(小程序)", + "icon": "", + "url": "/pages/uni-stat/scene/scene", + "sort": 2151, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-senceChannel", + "permission": [], + "enable": true, + "menu_id": "uni-stat-senceChannel-channel", + "name": "渠道(app)", + "icon": "", + "url": "/pages/uni-stat/channel/channel", + "sort": 2152, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-event-event", + "name": "自定义事件", + "icon": "admin-icons-shijianfenxi", + "url": "/pages/uni-stat/event/event", + "sort": 2160, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error", + "name": "错误统计", + "icon": "admin-icons-cuowutongji", + "url": "", + "sort": 2170, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-error", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error-js", + "name": "js报错", + "icon": "", + "url": "/pages/uni-stat/error/js/js", + "sort": 2171, + "create_date": 1638356902516 + }, { + "parent_id": "uni-stat-error", + "permission": [], + "enable": true, + "menu_id": "uni-stat-error-app", + "name": "app崩溃", + "icon": "", + "url": "/pages/uni-stat/error/app/app", + "sort": 2172, + "create_date": 1638356902516 + }, + { + "menu_id": "uni-stat-pay", + "name": "支付统计", + "icon": "uni-icons-circle", + "url": "", + "sort": 2122, + "parent_id": "uni-stat", + "permission": [], + "enable": true, + "create_date": 1667386977981 + }, { + "menu_id": "uni-stat-pay-overview", + "name": "概况", + "icon": "", + "url": "/pages/uni-stat/pay-order/overview/overview", + "sort": 21221, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1667387038602 + }, + { + "menu_id": "uni-stat-pay-funnel", + "name": "转换漏斗分析", + "icon": "", + "url": "/pages/uni-stat/pay-order/funnel/funnel", + "sort": 21222, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1668430092890 + }, + { + "menu_id": "uni-stat-pay-ranking", + "name": "价值用户排行", + "icon": "", + "url": "/pages/uni-stat/pay-order/ranking/ranking", + "sort": 21223, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1668430128302 + }, + { + "menu_id": "uni-stat-pay-order-list", + "name": "订单明细", + "icon": "", + "url": "/pages/uni-stat/pay-order/list/list", + "sort": 21224, + "parent_id": "uni-stat-pay", + "permission": [], + "enable": true, + "create_date": 1667387078947 + } + ] + }, + "uni-id-permissions": {}, + "uni-id-log": {}, + "uni-id-tag": {}, + "uni-id-device": {}, + "uni-id-scores": {}, + "opendb-verify-codes": {}, + "opendb-app-list": {}, + "opendb-app-versions": {}, + "opendb-device": {}, + "opendb-department": {}, + "opendb-sms-task": {}, + "opendb-sms-log": {}, + "opendb-sms-template": {}, + "opendb-open-data": {}, + "uni-stat-app-versions": {}, + "uni-stat-active-devices": {}, + "uni-stat-active-users": {}, + "uni-stat-app-channels": {}, + "uni-stat-app-crash-logs": {}, + "uni-stat-app-platforms": {}, + "uni-stat-error-logs": {}, + "uni-stat-error-result": {}, + "uni-stat-error-source-map": {}, + "uni-stat-event-logs": {}, + "uni-stat-event-result": {}, + "uni-stat-events": {}, + "uni-stat-loyalty-result": {}, + "uni-stat-mp-scenes": {}, + "uni-stat-page-logs": {}, + "uni-stat-page-result": {}, + "uni-stat-pages": {}, + "uni-stat-result": {}, + "uni-stat-run-errors": {}, + "uni-stat-session-logs": {}, + "uni-stat-share-logs": {}, + "uni-stat-user-session-logs": {}, + "uni-stat-pay-result": {}, + "uni-pay-orders": {}, + "opendb-tempdata": {}, + "opendb-feedback": {}, + "opendb-news-categories": {}, + "opendb-news-comments": {}, + "opendb-news-favorite": {}, + "opendb-search-hot": {}, + "opendb-search-log": {}, + "opendb-sign-in": {}, + "read-news-log": {} +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-admin-menus.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-admin-menus.schema.json new file mode 100644 index 0000000..3ffcb4c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-admin-menus.schema.json @@ -0,0 +1,59 @@ +{ + "bsonType": "object", + "required": ["name", "menu_id"], + "permission": { + "read": true, + "create": "'CREATE_OPENDB_ADMIN_MENUS' in auth.permission", + "update": "'UPDATE_OPENDB_ADMIN_MENUS' in auth.permission", + "delete": "'DELETE_OPENDB_ADMIN_MENUS' in auth.permission" + }, + "properties": { + "_id": { + "description": "存储文档 ID,系统自动生成" + }, + "menu_id": { + "bsonType": "string", + "description": "菜单项的ID,不可重复", + "trim": "both" + }, + "name": { + "bsonType": "string", + "description": "菜单名称", + "trim": "both" + }, + "icon": { + "bsonType": "string", + "description": "菜单图标", + "trim": "both" + }, + "url": { + "bsonType": "string", + "description": "菜单url", + "trim": "both" + }, + "sort": { + "bsonType": "int", + "description": "菜单序号(越大越靠后)" + }, + "parent_id": { + "bsonType": "string", + "description": "父级菜单Id", + "parentKey": "menu_id" + }, + "permission": { + "bsonType": "array", + "description": "菜单权限列表" + }, + "enable": { + "bsonType": "bool", + "description": "是否启用菜单,true启用、false禁用" + }, + "create_date": { + "bsonType": "timestamp", + "description": "菜单创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-app-list.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-app-list.schema.json new file mode 100644 index 0000000..71c4063 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-app-list.schema.json @@ -0,0 +1,325 @@ +{ + "bsonType": "object", + "required": ["appid", "name"], + "permission": { + "read": "'READ_OPENDB_APP_LIST' in auth.permission", + "create": "'CREATE_OPENDB_APP_LIST' in auth.permission", + "update": "'UPDATE_OPENDB_APP_LIST' in auth.permission", + "delete": "'DELETE_OPENDB_APP_LIST' in auth.permission" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用的AppID", + "label": "AppID", + "componentForEdit": { + "name": "uni-easyinput", + "props": { + ":disabled": true + } + } + }, + "name": { + "bsonType": "string", + "description": "应用名称", + "label": "应用名称", + "componentForEdit": { + "name": "uni-easyinput", + "props": { + ":disabled": true + } + } + }, + "description": { + "bsonType": "string", + "description": "应用描述", + "label": "应用描述", + "componentForEdit": { + "name": "textarea" + }, + "componentForShow": { + "name": "textarea", + "props": { + ":disabled": true + } + } + }, + "creator_uid": { + "description": "创建者的user_id,创建者必然是用户,不随应用转让而改变", + "bsonType": "string" + }, + "owner_type": { + "bsonType": "int", + "description": "应用当前归属者类型,1:个人,2:企业" + }, + "owner_id": { + "bsonType": "string", + "description": "应用当前归属者的id,user_id or enterprise_id" + }, + "managers": { + "bsonType": "array", + "description": "应用管理员ID列表" + }, + "members": { + "bsonType": "array", + "description": "团队成员ID列表" + }, + "icon_url": { + "bsonType": "string", + "trim": "both", + "description": "应用图标链接", + "label": "应用图标" + }, + "introduction": { + "bsonType": "string", + "trim": "both", + "description": "应用简介", + "label": "应用简介", + "componentForEdit": { + "name": "uni-easyinput", + "props": { + "disabled": true + } + } + }, + "screenshot": { + "bsonType": "array", + "description": "应用截图", + "label": "应用截图" + }, + "app_android": { + "bsonType": "object", + "description": "安卓 App 相关信息", + "properties": { + "name": { + "bsonType": "string", + "description": "快应用名称", + "label": "快应用名称" + }, + "url": { + "bsonType": "string", + "description": "安卓可下载安装包地址", + "label": "安卓下载地址" + } + } + }, + "app_ios": { + "bsonType": "object", + "description": "苹果 App 相关信息", + "properties": { + "name": { + "bsonType": "string", + "description": "快应用名称", + "label": "快应用名称" + }, + "url": { + "bsonType": "string", + "description": "AppStore 上架地址", + "label": "AppStore 地址" + } + } + }, + "mp_weixin": { + "bsonType": "object", + "description": "微信小程序相关信息", + "label": "微信小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_alipay": { + "bsonType": "object", + "description": "支付宝小程序相关信息", + "label": "支付宝小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_baidu": { + "bsonType": "object", + "description": "百度小程序相关信息", + "label": "百度小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_toutiao": { + "bsonType": "object", + "description": "头条小程序相关信息", + "label": "头条小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_qq": { + "bsonType": "object", + "description": "QQ小程序相关信息", + "label": "QQ小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_kuaishou": { + "bsonType": "object", + "description": "快手小程序相关信息", + "label": "快手小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_lark": { + "bsonType": "object", + "description": "飞书小程序相关信息", + "label": "飞书小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_jd": { + "bsonType": "object", + "description": "京东小程序相关信息", + "label": "京东小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "mp_dingtalk": { + "bsonType": "object", + "description": "钉钉小程序相关信息", + "label": "钉钉小程序", + "properties": { + "name": { + "bsonType": "string", + "description": "小程序名字" + }, + "qrcode_url": { + "bsonType": "string", + "description": "二维码url" + } + } + }, + "h5": { + "bsonType": "object", + "properties": { + "url": { + "bsonType": "string", + "description": "H5 可访问链接" + } + } + }, + "quickapp": { + "bsonType": "object", + "properties": { + "name": { + "bsonType": "string", + "description": "快应用名称", + "label": "快应用名称" + }, + "qrcode_url": { + "bsonType": "string", + "description": "快应用二维码url" + } + } + }, + "store_list": { + "bsonType": "array", + "description": "发布的应用市场", + "label": "应用市场", + "properties": { + "id": { + "bsonType": "string", + "description": "应用id,自动生成", + "label": "id" + }, + "name": { + "bsonType": "string", + "description": "应用名称", + "label": "应用名称" + }, + "scheme": { + "bsonType": "string", + "description": "应用 scheme", + "label": "应用 scheme" + }, + "enable": { + "bsonType": "bool", + "description": "是否启用" + }, + "priority": { + "bsonType": "int", + "description": "按照从大到小排序", + "label": "优先级" + } + } + }, + "create_date": { + "bsonType": "timestamp", + "label": "创建时间", + "forceDefaultValue": { + "$env": "now" + }, + "componentForEdit": { + "name": "uni-dateformat" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-app-versions.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-app-versions.schema.json new file mode 100644 index 0000000..459ff9c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-app-versions.schema.json @@ -0,0 +1,178 @@ +// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema +{ + "bsonType": "object", + "required": [ + "appid", + "uni_platform", + "version", + "type", + "create_env" + ], + "permission": { + "read": "'READ_OPENDB_APP_VERSIONS' in auth.permission", + "create": "'CREATE_OPENDB_APP_VERSIONS' in auth.permission", + "update": "'UPDATE_OPENDB_APP_VERSIONS' in auth.permission", + "delete": "'DELETE_OPENDB_APP_VERSIONS' in auth.permission" + }, + "properties": { + "_id": { + "description": "记录id,自动生成" + }, + "appid": { + "bsonType": "string", + "trim": "both", + "description": "应用的AppID", + "label": "AppID", + "componentForEdit": { + "name": "uni-easyinput", + "props": { + "disabled": true + } + } + }, + "name": { + "bsonType": "string", + "trim": "both", + "description": "应用名称", + "label": "应用名称", + "componentForEdit": { + "name": "uni-easyinput", + "props": { + "disabled": true + } + } + }, + "title": { + "bsonType": "string", + "description": "更新标题", + "label": "更新标题" + }, + "contents": { + "bsonType": "string", + "description": "更新内容", + "label": "更新内容", + "componentForEdit": { + "name": "textarea" + }, + "componentForShow": { + "name": "textarea", + "props": { + "disabled": true + } + } + }, + "platform": { + "bsonType": "array", + "enum": [ + { + "value": "Android", + "text": "安卓" + }, + { + "value": "iOS", + "text": "苹果" + } + ], + "description": "更新平台,Android || iOS || [Android, iOS]", + "label": "平台" + }, + "type": { + "bsonType": "string", + "enum": [ + { + "value": "native_app", + "text": "原生App安装包" + }, + { + "value": "wgt", + "text": "Wgt资源包" + } + ], + "description": "安装包类型,native_app || wgt", + "label": "安装包类型" + }, + "version": { + "bsonType": "string", + "description": "当前包版本号,必须大于当前线上发行版本号", + "label": "版本号" + }, + "min_uni_version": { + "bsonType": "string", + "description": "原生App最低版本", + "label": "原生App最低版本" + }, + "url": { + "bsonType": "string", + "description": "可下载或跳转的链接", + "label": "链接" + }, + "stable_publish": { + "bsonType": "bool", + "description": "是否上线发行", + "label": "上线发行" + }, + "is_silently": { + "bsonType": "bool", + "description": "是否静默更新", + "label": "静默更新", + "defaultValue": false + }, + "is_mandatory": { + "bsonType": "bool", + "description": "是否强制更新", + "label": "强制更新", + "defaultValue": false + }, + "create_date": { + "bsonType": "timestamp", + "label": "上传时间", + "forceDefaultValue": { + "$env": "now" + }, + "componentForEdit": { + "name": "uni-dateformat" + } + }, + "uni_platform": { + "bsonType": "string", + "description": "uni平台信息,如:mp-weixin/web/ios/android", + "label": "uni 平台" + }, + "create_env": { + "bsonType": "string", + "description": "创建来源,uni-stat:uni统计自动创建,upgrade-center:升级中心管理员创建" + }, + "store_list": { + "bsonType": "array", + "description": "发布的应用市场", + "label": "应用市场", + "properties": { + "id": { + "bsonType": "string", + "description": "应用id,自动生成", + "label": "id" + }, + "name": { + "bsonType": "string", + "description": "应用名称", + "label": "应用名称" + }, + "scheme": { + "bsonType": "string", + "description": "应用 scheme", + "label": "应用 scheme" + }, + "enable": { + "bsonType": "bool", + "description": "是否启用" + }, + "priority": { + "bsonType": "int", + "description": "按照从大到小排序", + "label": "优先级" + } + } + } + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-banner.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-banner.schema.json new file mode 100644 index 0000000..a027517 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-banner.schema.json @@ -0,0 +1,54 @@ +{ + "bsonType": "object", + "required": ["bannerfile"], + "permission": { + "read": true + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "bannerfile": { + "bsonType": "file", + "fileMediaType": "image", + "title": "图片文件", + "description": "图片文件信息,包括文件名、url等" + }, + "open_url": { + "bsonType": "string", + "description": "点击跳转目标地址。如果是web地址则使用内置web-view打开;如果是本地页面则跳转本地页面;如果是schema地址则打开本地的app", + "title": "点击目标地址", + "format": "url", + "pattern": "^(http:\/\/|https:\/\/|\/|.\/|@\/)\\S", + "trim": "both" + }, + "title": { + "bsonType": "string", + "description": "注意标题文字颜色和背景图靠色导致看不清的问题", + "maxLength": 20, + "title": "标题", + "trim": "both" + }, + "sort": { + "bsonType": "int", + "description": "数字越小,排序越前", + "title": "排序" + }, + "category_id": { + "bsonType": "string", + "description": "多个栏目的banner都存在一个表里时可用这个字段区分", + "title": "分类id" + }, + "status": { + "bsonType": "bool", + "defaultValue": true, + "title": "生效状态" + }, + "description": { + "bsonType": "string", + "description": "维护者自用描述", + "title": "备注", + "trim": "both" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-news-articles.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-news-articles.schema.json new file mode 100644 index 0000000..ee4f8cc --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-news-articles.schema.json @@ -0,0 +1,165 @@ +{ + "bsonType": "object", + "required": ["user_id", "title", "content"], + "permission": { + "read": "doc.uid == auth.uid && doc.article_status == 0 || doc.article_status == 1", + "create": "auth.uid != null", + "update": "doc.user_id == auth.uid", + "delete": "doc.user_id == auth.uid" + }, + "properties": { + "_id": { + "description": "存储文档 ID(用户 ID),系统自动生成" + }, + "user_id": { + "bsonType": "string", + "description": "文章作者ID, 参考`uni-id-users` 表", + "foreignKey": "uni-id-users._id", + "defaultValue": { + "$env": "uid" + } + }, + "category_id": { + "bsonType": "string", + "title": "分类", + "description": "分类 id,参考`uni-news-categories`表", + "foreignKey": "opendb-news-categories._id", + "enum": { + "collection": "opendb-news-categories", + "field": "name as text, _id as value" + } + }, + "title": { + "bsonType": "string", + "title": "标题", + "description": "标题", + "label": "标题", + "trim": "both" + }, + "content": { + "bsonType": "string", + "title": "文章内容", + "description": "文章内容", + "label": "文章内容", + "trim": "right" + }, + "excerpt": { + "bsonType": "string", + "title": "文章摘录", + "description": "文章摘录", + "label": "摘要", + "trim": "both" + }, + "article_status": { + "bsonType": "int", + "title": "文章状态", + "description": "文章状态:0 草稿箱 1 已发布", + "defaultValue": 0, + "enum": [{ + "value": 0, + "text": "草稿箱" + }, { + "value": 1, + "text": "已发布" + }] + }, + "view_count": { + "bsonType": "int", + "title": "阅读数量", + "description": "阅读数量", + "permission": { + "write": false + } + }, + "like_count": { + "bsonType": "int", + "description": "喜欢数、点赞数", + "permission": { + "write": false + } + }, + "is_sticky": { + "bsonType": "bool", + "title": "是否置顶", + "description": "是否置顶", + "permission": { + "write": false + } + }, + "is_essence": { + "bsonType": "bool", + "title": "阅读加精", + "description": "阅读加精", + "permission": { + "write": false + } + }, + "comment_status": { + "bsonType": "int", + "title": "开放评论", + "description": "评论状态:0 关闭 1 开放", + "enum": [{ + "value": 0, + "text": "关闭" + }, { + "value": 1, + "text": "开放" + }] + }, + "comment_count": { + "bsonType": "int", + "description": "评论数量", + "permission": { + "write": false + } + }, + "last_comment_user_id": { + "bsonType": "string", + "description": "最后回复用户 id,参考`uni-id-users` 表", + "foreignKey": "uni-id-users._id" + }, + "avatar": { + "bsonType": "string", + "title": "封面大图", + "description": "缩略图地址", + "label": "封面大图", + "trim": "both" + }, + "publish_date": { + "bsonType": "timestamp", + "title": "发表时间", + "description": "发表时间", + "defaultValue": { + "$env": "now" + } + }, + "publish_ip": { + "bsonType": "string", + "title": "发布文章时IP地址", + "description": "发表时 IP 地址", + "forceDefaultValue": { + "$env": "clientIP" + } + }, + "last_modify_date": { + "bsonType": "timestamp", + "title": "最后修改时间", + "description": "最后修改时间", + "defaultValue": { + "$env": "now" + } + }, + "last_modify_ip": { + "bsonType": "string", + "description": "最后修改时 IP 地址", + "forceDefaultValue": { + "$env": "clientIP" + } + }, + "mode": { + "bsonType": "number", + "title": "排版显示模式", + "description": "排版显示模式,如左图右文、上图下文等" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-news-categories.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-news-categories.schema.json new file mode 100644 index 0000000..976c8a8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-news-categories.schema.json @@ -0,0 +1,50 @@ +{ + "bsonType": "object", + "required": ["name"], + "permission": { + "read": true, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "存储文档 ID(文章 ID),系统自动生成" + }, + "name": { + "bsonType": "string", + "description": "类别名称", + "label": "名称", + "trim": "both" + }, + "description": { + "bsonType": "string", + "description": "类别描述", + "label": "描述", + "trim": "both" + }, + "icon": { + "bsonType": "string", + "description": "类别图标地址", + "label": "图标地址", + "pattern": "^(http:\/\/|https:\/\/|\/|.\/|@\/)\\S", + "trim": "both" + }, + "sort": { + "bsonType": "int", + "description": "类别显示顺序", + "label": "排序" + }, + "article_count": { + "bsonType": "int", + "description": "该类别下文章数量" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-news-comments.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-news-comments.schema.json new file mode 100644 index 0000000..1c0b197 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-news-comments.schema.json @@ -0,0 +1,68 @@ +{ + "bsonType": "object", + "required": ["article_id", "user_id", "comment_content", "like_count", "comment_type", "reply_user_id", + "reply_comment_id" + ], + "permission": { + "read": true, + "create": "auth.uid != null && get(`database.opendb-news-article.${doc.article_id}`).comment_status == 1", + "update": "doc.user_id == auth.uid", + "delete": "doc.user_id == auth.uid" + }, + "properties": { + "_id": { + "description": "存储文档 ID(文章 ID),系统自动生成" + }, + "article_id": { + "bsonType": "string", + "description": "文章ID,opendb-news-posts 表中的`_id`字段", + "foreignKey": "opendb-news-articles._id" + }, + "user_id": { + "bsonType": "string", + "description": "评论者ID,参考`uni-id-users` 表", + "forceDefaultValue": { + "$env": "uid" + }, + "foreignKey": "uni-id-users._id" + }, + "comment_content": { + "bsonType": "string", + "description": "评论内容", + "title": "评论内容", + "trim": "right" + }, + "like_count": { + "bsonType": "int", + "description": "评论喜欢数、点赞数" + }, + "comment_type": { + "bsonType": "int", + "description": "回复类型: 0 针对文章的回复 1 针对评论的回复" + }, + "reply_user_id": { + "bsonType": "string", + "description": "被回复的评论用户ID,comment_type为1时有效", + "foreignKey": "uni-id-users._id" + }, + "reply_comment_id": { + "bsonType": "string", + "description": "被回复的评论ID,comment_type为1时有效", + "foreignKey": "opendb-news-comments._id" + }, + "comment_date": { + "bsonType": "timestamp", + "description": "评论发表时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "comment_ip": { + "bsonType": "string", + "description": "评论发表时 IP 地址", + "forceDefaultValue": { + "$env": "clientIP" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-news-favorite.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-news-favorite.schema.json new file mode 100644 index 0000000..a4034f1 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-news-favorite.schema.json @@ -0,0 +1,46 @@ +{ + "bsonType": "object", + "required": ["user_id", "article_id"], + "permission": { + "read": "doc.user_id == auth.uid", + "create": "auth.uid != null", + "update": "doc.user_id == auth.uid", + "delete": "doc.user_id == auth.uid" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "article_id": { + "bsonType": "string", + "description": "文章id,参考opendb-news-articles表", + "foreignKey": "opendb-news-articles._id" + }, + "article_title": { + "bsonType": "string", + "description": "文章标题" + }, + "user_id": { + "bsonType": "string", + "description": "收藏者id,参考uni-id-users表", + "forceDefaultValue": { + "$env": "uid" + }, + "foreignKey": "uni-id-users._id" + }, + "create_date": { + "bsonType": "timestamp", + "description": "收藏时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "update_date": { + "bsonType": "timestamp", + "description": "更新\/修改时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-search-hot.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-search-hot.schema.json new file mode 100644 index 0000000..1230be4 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-search-hot.schema.json @@ -0,0 +1,27 @@ +{ + "bsonType": "object", + "permission": { + "create": false, + "delete": false, + "read": true, + "update": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "content": { + "bsonType": "string", + "description": "搜索内容" + }, + "count": { + "bsonType": "long", + "description": "搜索次数" + }, + "create_date": { + "bsonType": "timestamp", + "description": "统计时间" + } + }, + "required": ["content", "count"] +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-search-log.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-search-log.schema.json new file mode 100644 index 0000000..421ee8c --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-search-log.schema.json @@ -0,0 +1,31 @@ +{ + "bsonType": "object", + "permission": { + "create": true, + "delete": false, + "read": false, + "update": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "content": { + "bsonType": "string", + "description": "搜索内容" + }, + "create_date": { + "bsonType": "timestamp", + "description": "统计时间" + }, + "device_id": { + "bsonType": "string", + "description": "设备id" + }, + "user_id": { + "bsonType": "string", + "description": "收藏者id,参考uni-id-users表" + } + }, + "required": ["content"] +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-sms-log.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-sms-log.schema.json new file mode 100644 index 0000000..ed66233 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-sms-log.schema.json @@ -0,0 +1,63 @@ +{ + "bsonType": "object", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "task_id": { + "bsonType": "string", + "description": "任务ID", + "foreignKey": "batch-sms-task._id" + }, + "uid": { + "bsonType": "string", + "description": "用户ID", + "foreignKey": "uni-id-users._id" + }, + "mobile": { + "bsonType": "int", + "description": "手机号" + }, + "var_data": { + "bsonType": "object", + "description": "变量数据" + }, + "status": { + "bsonType": "int", + "description": "发送状态", + "defaultValue": 0, + "enum": [{ + "text": "未发送", + "value": 0 + }, { + "text": "已发送", + "value": 1 + }, { + "text": "发送失败", + "value": 2 + }] + }, + "reason": { + "bsonType": "string", + "description": "发送失败原因" + }, + "send_date": { + "bsonType": "timestamp", + "description": "发送时间" + }, + "ccreate_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-sms-task.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-sms-task.schema.json new file mode 100644 index 0000000..c2cea06 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-sms-task.schema.json @@ -0,0 +1,81 @@ +{ + "bsonType": "object", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "name": { + "bsonType": "string", + "description": "任务名称", + "trim": "both" + }, + "app_id": { + "bsonType": "string", + "description": "App ID", + "trim": "both" + }, + "template_id": { + "bsonType": "string", + "description": "短信模板ID", + "trim": "both" + }, + "template_content": { + "bsonType": "string", + "description": "短信模板内容", + "trim": "both" + }, + "vars": { + "bsonType": "array", + "description": "短信变量" + }, + "to": { + "bsonType": "object", + "description": "短信接收者信息", + "properties": { + "all": { + "bsonType": "bool", + "description": "全部用户发送;字段废弃,由 condition 替代" + }, + "type": { + "bsonType": "string", + "description": "可选值 user | userTags" + }, + "receiver": { + "bsonType": "array", + "description": "用户ID's / 用户标签ID's;指定id发送" + }, + "condition": { + "bsonType": "object", + "description": "根据条件发送,例如给所有人发送" + } + } + }, + "send_qty": { + "bsonType": "int", + "description": "发送总数" + }, + "success_qty": { + "bsonType": "int", + "description": "成功总数" + }, + "fail_qty": { + "bsonType": "int", + "description": "失败总数" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-sms-template.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-sms-template.schema.json new file mode 100644 index 0000000..e8e571e --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-sms-template.schema.json @@ -0,0 +1,32 @@ +// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema +{ + "bsonType": "object", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "模板ID" + }, + "name": { + "bsonType": "string", + "description": "模板名称" + }, + "content": { + "bsonType": "string", + "description": "模板内容" + }, + "type": { + "bsonType": "int", + "description": "模板类型" + }, + "sign": { + "bsonType": "string", + "description": "模板签名" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/opendb-tempdata.schema.json b/alpha/admin/uniCloud-aliyun/database/opendb-tempdata.schema.json new file mode 100644 index 0000000..1a741f3 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/opendb-tempdata.schema.json @@ -0,0 +1,22 @@ +{ + "bsonType": "object", + "required": ["value", "expired"], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "value": { + "description": "值" + }, + "expired": { + "description": "过期时间", + "bsonType": "timestamp" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/read-news-log.schema.json b/alpha/admin/uniCloud-aliyun/database/read-news-log.schema.json new file mode 100644 index 0000000..1cbd342 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/read-news-log.schema.json @@ -0,0 +1,35 @@ +{ + "bsonType": "object", + "required": ["user_id", "article_id"], + "permission": { + "read": "doc.user_id == auth.uid", + "create": "auth.uid != null", + "update": "doc.user_id == auth.uid" + //"delete": "doc.user_id == auth.uid" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "article_id": { + "bsonType": "string", + "description": "文章id,参考opendb-news-articles表", + "foreignKey": "opendb-news-articles._id" + }, + "user_id": { + "bsonType": "string", + "description": "收藏者id,参考uni-id-users表", + "forceDefaultValue": { + "$env": "uid" + }, + "foreignKey": "uni-id-users._id" + }, + "last_time": { //设计策略是多次看同一个文章只做一次记录,重复看的文章时间更新为当前时间 + "bsonType": "timestamp", + "description": "最后一次看的时间", + "defaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-id-scores.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-id-scores.schema.json new file mode 100644 index 0000000..0e2a7f6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-id-scores.schema.json @@ -0,0 +1,44 @@ +{ + "bsonType": "object", + "required": ["user_id", "score", "balance"], + "permission": { + "read": "doc.user_id == auth.uid", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "user_id": { + "bsonType": "string", + "description": "用户id,参考uni-id-users表" + }, + "score": { + "bsonType": "int", + "description": "本次变化的积分" + }, + "type": { + "bsonType": "int", + "enum": [1, 2], + "description": "积分类型 1:收入 2:支出" + }, + "balance": { + "bsonType": "int", + "description": "变化后的积分余额" + }, + "comment": { + "bsonType": "string", + "description": "备注,说明积分新增、消费的缘由", + "trim": "both" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-id-tag.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-id-tag.schema.json new file mode 100644 index 0000000..1589273 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-id-tag.schema.json @@ -0,0 +1,52 @@ +{ + "bsonType": "object", + "required": ["tagid", "name"], + "permission": { + "read": "'READ_UNI_ID_TAG' in auth.permission", + "create": "'CREATE_UNI_ID_TAG' in auth.permission", + "update": "'UPDATE_UNI_ID_TAG' in auth.permission", + "delete": "'DELETE_UNI_ID_TAG' in auth.permission" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "tagid": { + "bsonType": "string", + "description": "标签tagid", + "label": "标签tagid", + "componentForEdit": { + "name": "uni-easyinput" + } + }, + "name": { + "bsonType": "string", + "description": "标签名称", + "label": "标签名称", + "componentForEdit": { + "name": "uni-easyinput" + } + }, + "description": { + "bsonType": "string", + "description": "标签描述", + "label": "标签描述", + "componentForEdit": { + "name": "textarea" + }, + "componentForShow": { + "name": "textarea" + } + }, + "create_date": { + "bsonType": "timestamp", + "label": "创建时间", + "forceDefaultValue": { + "$env": "now" + }, + "componentForEdit": { + "name": "uni-dateformat" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-pay-orders.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-pay-orders.schema.json new file mode 100644 index 0000000..5c83460 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-pay-orders.schema.json @@ -0,0 +1,247 @@ +{ + "bsonType": "object", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_PAY' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "provider": { + "title": "支付供应商", + "bsonType": "string", + "enum": [{ + "text": "微信支付", + "value": "wxpay" + }, + { + "text": "支付宝", + "value": "alipay" + }, + { + "text": "苹果应用内支付", + "value": "appleiap" + } + ], + "description": "支付供应商 如 wxpay alipay 参考 https://uniapp.dcloud.net.cn/api/plugins/provider.html#" + }, + "provider_pay_type": { + "title": "支付方式", + "bsonType": "string", + "description": "支付供应商的支付类型(插件内部标记支付类型的标识,不需要用户传)", + "trim": "both" + }, + "uni_platform": { + "title": "应用平台", + "bsonType": "string", + "description": "uni客户端平台,如:web、mp-weixin、mp-alipay、app等", + "trim": "both" + }, + "status": { + "title": "订单状态", + "bsonType": "int", + "enum": [{ + "text": "已关闭", + "value": -1 + }, + { + "text": "未支付", + "value": 0 + }, + { + "text": "已支付", + "value": 1 + }, + { + "text": "已部分退款", + "value": 2 + }, + { + "text": "已全额退款", + "value": 3 + } + ], + "description": "订单状态 -1 已关闭 0:未支付 1:已支付 2:已部分退款 3:已全额退款", + "defaultValue": 0 + }, + "type": { + "title": "订单类型", + "bsonType": "string", + "description": "订单类型 goods:订单付款 recharge:余额充值付款 vip:vip充值付款 等等,可自定义", + "trim": "both" + }, + "order_no": { + "title": "业务系统订单号", + "bsonType": "string", + "minLength": 20, + "maxLength": 28, + "description": "业务系统订单号,控制在20-28位(不可以是24位,24位在阿里云空间可能会有问题,可重复,代表1个业务订单会有多次付款的情况)", + "trim": "both" + }, + "out_trade_no": { + "title": "支付插件订单号", + "bsonType": "string", + "description": "支付插件订单号(需控制唯一,不传则由插件自动生成)", + "trim": "both" + }, + "transaction_id": { + "title": "交易单号", + "bsonType": "string", + "description": "交易单号(支付平台订单号,由支付平台控制唯一)", + "trim": "both" + }, + "user_id": { + "title": "用户ID", + "bsonType": "string", + "description": "用户id,参考uni-id-users表", + "foreignKey": "uni-id-users._id" + }, + "nickname": { + "title": "用户昵称", + "bsonType": "string", + "description": "用户昵称冗余", + "trim": "both" + }, + "device_id": { + "bsonType": "string", + "description": "客户端设备ID" + }, + "client_ip": { + "title": "客户端IP", + "bsonType": "string", + "description": "创建支付的客户端ip", + "trim": "both" + }, + "openid": { + "title": "openid", + "bsonType": "string", + "description": "发起支付的用户openid", + "trim": "both" + }, + "description": { + "title": "支付描述", + "bsonType": "string", + "description": "支付描述,如:uniCloud个人版包月套餐", + "trim": "both" + }, + "err_msg": { + "title": "支付失败原因", + "bsonType": "string", + "description": "支付失败原因", + "trim": "both" + }, + "total_fee": { + "title": "订单总金额", + "bsonType": "int", + "description": "订单总金额,单位为分,100等于1元" + }, + "refund_fee": { + "title": "订单总退款金额", + "bsonType": "int", + "description": "订单总退款金额,单位为分,100等于1元" + }, + "refund_count": { + "title": "当前退款笔数", + "bsonType": "int", + "description": "当前退款笔数 (退款单号为 out_trade_no-refund_count)" + }, + "refund_list": { + "title": "退款详情", + "bsonType": "array", + "description": "退款详情" + }, + "provider_appid": { + "title": "开放平台appid", + "bsonType": "string", + "description": "公众号appid,小程序appid,app开放平台appid 等", + "trim": "both" + }, + "appid": { + "title": "DCloud AppId", + "bsonType": "string", + "description": "dcloud_appid", + "trim": "both" + }, + "user_order_success": { + "title": "回调状态", + "bsonType": "bool", + "description": "用户异步通知逻辑是否全部执行完成,且无异常(建议前端通过此参数是否为true来判断是否支付成功)" + }, + "custom": { + "title": "自定义数据", + "bsonType": "object", + "description": "自定义数据(用户自定义数据)" + }, + "original_data": { + "title": "异步通知原始数据", + "bsonType": "object", + "description": "异步回调通知返回的原始数据,微信v2是xml转json后的数据,微信v3和支付宝是原始json" + }, + "create_date": { + "title": "创建时间", + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "pay_date": { + "title": "支付时间", + "bsonType": "timestamp", + "description": "支付时间" + }, + "notify_date": { + "title": "异步通知时间", + "bsonType": "timestamp", + "description": "订单通知支付成功时间" + }, + "cancel_date": { + "title": "取消时间", + "bsonType": "timestamp", + "description": "订单取消时间" + }, + "stat_data": { + "title": "uni统计相关数据", + "bsonType": "object", + "description": "uni统计相关数据", + "properties": { + "platform": { + "bsonType": "string", + "description": "与uni_platform唯一区别是APP区分 android 和 ios" + }, + "app_version": { + "bsonType": "string", + "description": "客户端版本号 (字符串形式)如1.0.0" + }, + "app_version_code": { + "bsonType": "string", + "description": "客户端版本号(数字形式) 如100" + }, + "app_wgt_version": { + "bsonType": "string", + "description": "客户端热更新版本号" + }, + "os": { + "bsonType": "string", + "description": "设备的操作系统 如 android ios" + }, + "ua": { + "bsonType": "string", + "description": "客户端userAgent" + }, + "channel": { + "bsonType": "string", + "description": "客户端渠道" + }, + "scene": { + "bsonType": "string", + "description": "小程序场景值" + } + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-active-devices.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-active-devices.schema.json new file mode 100644 index 0000000..c3e2afe --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-active-devices.schema.json @@ -0,0 +1,67 @@ +// 活跃设备表 +{ + "bsonType": "object", + "description": "给周月维度的设备基础统计和留存统计提供数据,每日跑批合并,仅添加本周/本月首次访问的设备", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "is_new": { + "bsonType": "int", + "description": "是否为新设备", + "defaultValue": 0, + "enum": [{ + "text": "否", + "value": 0 + }, { + "text": "是", + "value": 1 + }] + }, + "dimension": { + "bsonType": "string", + "description": "时间范围 week:周,month:月", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }] + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-active-users.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-active-users.schema.json new file mode 100644 index 0000000..7c3f421 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-active-users.schema.json @@ -0,0 +1,55 @@ +// 活跃用户表 +{ + "bsonType": "object", + "description": "给周月维度的用户基础统计和留存统计提供数据,每日跑批合并,仅添加本周/本月首次访问的用户。", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "uid": { + "bsonType": "string", + "description": "用户编号, 对应uni-id-users._id" + }, + "dimension": { + "bsonType": "string", + "description": "时间范围 week:周,month:月", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }] + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-app-channels.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-channels.schema.json new file mode 100644 index 0000000..3a7c1f8 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-channels.schema.json @@ -0,0 +1,44 @@ +// 应用渠道表 +{ + "bsonType": "object", + "description": "提供渠道和场景值数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_APP_CHANNELS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "统计应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_code": { + "bsonType": "int", + "description": "客户端上报的渠道代码" + }, + "channel_name": { + "bsonType": "string", + "description": "渠道名称,用户可编辑" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + }, + "last_modify_time": { + "bsonType": "timestamp", + "description": "最后修改时间" + } + } +} + diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-app-crash-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-crash-logs.schema.json new file mode 100644 index 0000000..389e2f6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-crash-logs.schema.json @@ -0,0 +1,137 @@ +// 原生应用崩溃日志表 +{ + "bsonType": "object", + "description": "记录原生应用的崩溃日志", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_APP_CRASH_LOGS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "用户端上报的应用ID" + }, + "version": { + "bsonType": "string", + "description": "用户端上报的应用版本号。manifest.json中的version->name的值" + }, + "platform": { + "bsonType": "string", + "description": "用户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "用户端上报的渠道code\/场景值" + }, + "sdk_version": { + "bsonType": "string", + "description": "基础库版本号" + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "device_net": { + "bsonType": "string", + "description": "设备网络型号wifi\/3G\/4G\/" + }, + "device_os": { + "bsonType": "string", + "description": "系统版本:iOS平台为系统版本号,如15.1;Android平台为API等级,如30" + }, + "device_os_version": { + "bsonType": "string", + "description": "系统版本名称:iOS平台与os字段一致;Android平台为版本名称,如5.1.1" + }, + "device_vendor": { + "bsonType": "string", + "description": "设备供应商 " + }, + "device_model": { + "bsonType": "string", + "description": "设备型号" + }, + "device_is_root": { + "bsonType": "int", + "description": "是否root:1表示root;0表示未root" + }, + "device_os_name": { + "bsonType": "string", + "description": "系统名称:用于区别Android和鸿蒙,仅Android支持" + }, + "device_batt_level": { + "bsonType": "int", + "description": "设备电池电量:取值范围0-100,仅Android支持" + }, + "device_batt_temp": { + "bsonType": "string", + "description": "电池温度,仅Android支持" + }, + "device_memory_use_size": { + "bsonType": "int", + "description": "系统已使用内存,单位为Byte,仅Android支持" + }, + "device_memory_total_size": { + "bsonType": "int", + "description": "系统总内存,单位为Byte,仅Android支持" + }, + "device_disk_use_size": { + "bsonType": "int", + "description": "系统磁盘已使用大小,单位为Byte,仅Android支持" + }, + "device_disk_total_size": { + "bsonType": "int", + "description": "系统磁盘总大小,单位为Byte,仅Android支持" + }, + "device_abis": { + "bsonType": "string", + "description": "设备支持的CPU架构:多个使用,分割,如arm64-v8a,armeabi-v7a,armeabi,仅Android支持" + }, + "app_count": { + "bsonType": "int", + "description": "运行的app个数:包括运行的uni小程序数目。独立App时值为1" + }, + "app_use_memory_size": { + "bsonType": "int", + "description": "APP使用的内存量,单位为Byte" + }, + "app_webview_count": { + "bsonType": "int", + "description": "打开Webview窗口的个数" + }, + "app_use_duration": { + "bsonType": "int", + "description": "APP使用时长:单位为s" + }, + "app_run_fore": { + "bsonType": "int", + "description": "是否前台运行:1表示前台运行,0表示后台运行" + }, + "package_name": { + "bsonType": "string", + "description": "原生应用包名" + }, + "package_version": { + "bsonType": "string", + "description": "Android的apk版本名称;iOS的ipa版本名称" + }, + "page_url": { + "bsonType": "string", + "description": "页面url" + }, + "error_msg": { + "bsonType": "string", + "description": "错误信息" + }, + "create_time": { + "bsonType": "timestamp", + "description": "客户端记录到的崩溃时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-app-platforms.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-platforms.schema.json new file mode 100644 index 0000000..6c46b4f --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-platforms.schema.json @@ -0,0 +1,46 @@ +// 应用平台表 +{ + "bsonType": "object", + "description": "提供应用的平台字典", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_APP_PLATFORMS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "code": { + "bsonType": "string", + "description": "平台代码,前端上报" + }, + "name": { + "bsonType": "string", + "description": "平台名称,管理端显示" + }, + "order": { + "bsonType": "int", + "description": "序号,前端页面排序使用", + "defaultValue": 0 + }, + "enable": { + "bsonType": "bool", + "description": "是否启动", + "defaultValue": true, + "enum": [{ + "text": "否", + "value": false + }, { + "text": "是", + "value": true + }] + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-app-versions.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-versions.schema.json new file mode 100644 index 0000000..3c7742f --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-app-versions.schema.json @@ -0,0 +1,38 @@ +{ + "bsonType": "object", + "description": "提供应用的版本号字典", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "统计应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "version": { + "bsonType": "string", + "description": "应用版本" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + }, + "last_modify_time": { + "bsonType": "timestamp", + "description": "最后修改时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-error-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-logs.schema.json new file mode 100644 index 0000000..b117bec --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-logs.schema.json @@ -0,0 +1,102 @@ +// 应用错误日志表 +{ + "bsonType": "object", + "description": "记录上报的应用运行错误日志", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_ERROR_LOGS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "用户端上报的应用ID" + }, + "version": { + "bsonType": "string", + "description": "用户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "description": "用户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "用户端上报的渠道code\/场景值" + }, + "error_type": { + "bsonType": "int", + "description": "错误类型", + "defaultValue": 0, + "enum": [{ + "text": "未知", + "value": 0 + }, { + "text": "表示webview页面js异常(uni-app项目对应vue页面)", + "value": 2 + }, { + "text": "表示uni框架js异常(仅uni-app项目)", + "value": 4 + }, { + "text": "表示控制页js异常(仅uni-app项目)", + "value": 5 + }, { + "text": "表示nvue页面js异常(仅uni-app项目)", + "value": 6 + }] + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "uid": { + "bsonType": "string", + "description": "用户编号, 对应uni-id-users._id" + }, + "os": { + "bsonType": "string", + "description": "客户端操作系统" + }, + "ua": { + "bsonType": "string", + "description": "客户端user-agent信息" + }, + "space_id": { + "bsonType": "string", + "description": "服务空间编号" + }, + "space_provider": { + "bsonType": "string", + "description": "服务空间提供商" + }, + "sdk_version": { + "bsonType": "string", + "description": "小程序基础库版本号" + }, + "platform_version": { + "bsonType": "string", + "description": "微信、支付宝宿主App的版本号" + }, + "error_msg": { + "bsonType": "string", + "description": "错误信息" + }, + "error_hash": { + "bsonType": "string", + "description": "错误hash码" + }, + "page_url": { + "bsonType": "string", + "description": "页面url" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-error-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-result.schema.json new file mode 100644 index 0000000..0bb60c2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-result.schema.json @@ -0,0 +1,96 @@ +// 错误数据统计结果表 +{ + "bsonType": "object", + "description": "存储汇总的错误日志的数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_ERROR_RESULT' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "type": { + "bsonType": "string", + "description": "错误类型", + "enum": [{ + "text": "前端js错误", + "value": "js" + }, { + "text": "原生应用崩溃错误", + "value": "crash" + }] + }, + "hash": { + "bsonType": "string", + "description": "错误hash码" + }, + "msg": { + "bsonType": "string", + "description": "错误信息" + }, + "count": { + "bsonType":"int", + "description":"报错次数" + }, + "app_launch_count": { + "bsonType": "int", + "description": "本时间段App启动或从后台切到前台的次数" + }, + "last_time": { + "bsonType":"timestamp", + "description":"最近一次报错事件" + }, + "dimension": { + "bsonType": "string", + "description": "统计范围 day:按天统计,hour:按小时统计", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + },{ + "text": "天", + "value": "day" + }, { + "text": "小时", + "value": "hour" + }] + }, + "stat_date":{ + "bsonType":"int", + "description":"统计日期,格式yyyymmdd,例:20211201" + }, + "start_time":{ + "bsonType":"timestamp", + "description":"开始时间" + }, + "end_time":{ + "bsonType":"timestamp", + "description":"结束时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.ext.js b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.ext.js new file mode 100644 index 0000000..556f31e --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.ext.js @@ -0,0 +1,29 @@ +module.exports = { + trigger: { + // 监听 - 删除前 + beforeDelete: async function(obj = {}) { + let { + collection, + operation, + where, + field + } = obj; + // 删除表记录前先删除云存储内的文件 + const db = uniCloud.database(); + const _ = db.command; + let getRes = await db.collection("uni-stat-error-source-map").where(where).limit(1000).get(); + let list = getRes.data; + if (list && list.length > 0) { + let fileList = list.map((item, index) => { + return item.file_id; + }); + try { + let deleteFileRes = await uniCloud.deleteFile({ + fileList + }); + // console.log('deleteFileRes: ', deleteFileRes) + } catch (err) {} + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.json new file mode 100644 index 0000000..98b53ef --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-error-source-map.schema.json @@ -0,0 +1,61 @@ +{ + "bsonType": "object", + "description": "存储sourceMap文件资源地址", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_ERROR_RESULT' in auth.permission", + "create": "'READ_UNI_STAT_ERROR_RESULT' in auth.permission", + "update": "'READ_UNI_STAT_ERROR_RESULT' in auth.permission", + "delete": "'READ_UNI_STAT_ERROR_RESULT' in auth.permission" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "uni_platform": { + "title": "应用平台", + "bsonType": "string", + "description": "uni客户端平台,如:web、mp-weixin、mp-alipay、app等", + "trim": "both" + }, + "version": { + "bsonType": "string", + "description": "客户端上报的应用版本号" + }, + "file_id": { + "bsonType": "string", + "description": "fileID" + }, + "url": { + "bsonType": "string", + "description": "文件外网url路径" + }, + "name": { + "bsonType": "string", + "description": "文件名" + }, + "size": { + "bsonType": "int", + "description": "文件大小" + }, + "cloud_path": { + "bsonType": "string", + "description": "云端路径,通过该值识别是否是同一个文件" + }, + "base": { + "bsonType": "string", + "description": "基础路径" + }, + "create_time": { + "bsonType": "timestamp", + "description": "上传时间", + "forceDefaultValue": { + "$env": "now" + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-event-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-event-logs.schema.json new file mode 100644 index 0000000..2e109f0 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-event-logs.schema.json @@ -0,0 +1,116 @@ +// 应用事件日志表 +{ + "bsonType": "object", + "description": "记录上报的事件日志", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_EVENT_LOGS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "客户端上报的应用ID" + }, + "version": { + "bsonType": "string", + "description": "客户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "foreignKey": "uni-stat-app-platforms.code", + "description": "客户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "客户端上报的渠道code\/场景值" + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "uid": { + "bsonType": "string", + "description": "用户编号, 对应uni-id-users._id" + }, + "session_id": { + "bsonType": "string", + "description": "访问会话日志ID,对应uni-stat-session-logs._id", + "foreignKey": "uni-stat-session-logs._id" + }, + "page_id": { + "bsonType": "string", + "description": "页面ID,对应uni-stat-pages._id", + "foreignKey": "uni-stat-pages._id" + }, + "event_key": { + "bsonType": "string", + "description": "客户端上报的key" + }, + "param": { + "bsonType": "string", + "description": "事件参数" + }, + "sdk_version": { + "bsonType": "string", + "description": "基础库版本号" + }, + "platform_version": { + "bsonType": "string", + "description": "平台版本,如微信、支付宝宿主App版本号" + }, + "device_os": { + "bsonType": "int", + "description": "设备系统编号,1:安卓,2:iOS,3:PC" + }, + "device_os_version": { + "bsonType": "string", + "description": "设备系统版本" + }, + "device_net": { + "bsonType": "string", + "description": "设备网络型号wifi\/3G\/4G\/" + }, + "device_vendor": { + "bsonType": "string", + "description": "设备供应商 " + }, + "device_model": { + "bsonType": "string", + "description": "设备型号" + }, + "device_language": { + "bsonType": "string", + "description": "设备语言包" + }, + "device_pixel_ratio": { + "bsonType": "string", + "description": "设备像素比 " + }, + "device_window_width": { + "bsonType": "string", + "description": "设备窗口宽度 " + }, + "device_window_height": { + "bsonType": "string", + "description": "设备窗口高度" + }, + "device_screen_width": { + "bsonType": "string", + "description": "设备屏幕宽度" + }, + "device_screen_height": { + "bsonType": "string", + "description": "设备屏幕高度" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-event-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-event-result.schema.json new file mode 100644 index 0000000..c78dff7 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-event-result.schema.json @@ -0,0 +1,82 @@ +// 事件统计结果表 +{ + "bsonType": "object", + "description": "存储汇总的事件日志的数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_EVENT_RESULT' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "event_key": { + "bsonType": "string", + "description": "事件key,对应uni-stat-events.event_key", + "foreignKey": "uni-stat-events.event_key" + }, + "event_count": { + "bsonType": "int", + "description": "触发次数" + }, + "device_count": { + "bsonType": "int", + "description": "触发该事件的设备数" + }, + "user_count": { + "bsonType": "int", + "description": "触发该事件的用户数" + }, + "dimension": { + "bsonType": "string", + "description": "统计范围 day:按天统计,hour:按小时统计", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }, { + "text": "天", + "value": "day" + }, { + "text": "小时", + "value": "hour" + }] + }, + "stat_date": { + "bsonType": "int", + "description": "统计日期,格式yyyymmdd,例:20211201" + }, + "start_time": { + "bsonType": "timestamp", + "description": "开始时间" + }, + "end_time": { + "bsonType": "timestamp", + "description": "结束时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-events.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-events.schema.json new file mode 100644 index 0000000..f3c0d33 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-events.schema.json @@ -0,0 +1,38 @@ +// 应用事件表 +{ + "bsonType": "object", + "description": "提供应用的事件字典", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_EVENTS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "统计应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "event_key": { + "bsonType": "string", + "description": "事件键值" + }, + "event_name": { + "bsonType": "string", + "description": "事件名称" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + }, + "update_time": { + "bsonType": "timestamp", + "description": "last_modify_time" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-loyalty-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-loyalty-result.schema.json new file mode 100644 index 0000000..37848b3 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-loyalty-result.schema.json @@ -0,0 +1,84 @@ +// 用户忠诚度统计表 +{ + "bsonType": "object", + "description": "存储汇总的设备/用户的粘性数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_LOYALTY_RESULT' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "visit_depth_data": { + "bsonType": "object", + "description": "访问深度数据", + "properties": { + "visit_users": { + "bsonType": "object", + "description": "访问用户数" + }, + "visit_devices": { + "bsonType": "object", + "description": "访问设备数" + }, + "visit_times": { + "bsonType": "object", + "description": "访问次数" + } + } + }, + "duration_data": { + "bsonType": "object", + "description": "访问时长数据", + "properties": { + "visit_users": { + "bsonType": "object", + "description": "访问用户数" + }, + "visit_devices": { + "bsonType": "object", + "description": "访问设备数" + }, + "visit_times": { + "bsonType": "object", + "description": "访问次数" + } + } + }, + "stat_date": { + "bsonType": "int", + "description": "统计日期,格式yyyymmdd,例:20211201" + }, + "start_time": { + "bsonType": "timestamp", + "description": "开始时间" + }, + "end_time": { + "bsonType": "timestamp", + "description": "结束时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-mp-scenes.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-mp-scenes.schema.json new file mode 100644 index 0000000..c126cad --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-mp-scenes.schema.json @@ -0,0 +1,34 @@ +// 小程序场景值对照表 +{ + "bsonType": "object", + "description": "提供应用渠道和小程序场景值的数据字典", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "platform": { + "bsonType": "string", + "description": "应用平台,对应uni-stat-app-platforms.code", + "foreignKey": "uni-stat-app-platforms.code" + }, + "scene_code": { + "bsonType": "string", + "description": "场景代码" + }, + "scene_name": { + "bsonType": "string", + "description": "场景名称" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-page-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-page-logs.schema.json new file mode 100644 index 0000000..616e451 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-page-logs.schema.json @@ -0,0 +1,79 @@ +// 应用页面访问日志表 +{ + "bsonType": "object", + "description": "记录上报的页面访问日志", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_PAGE_LOGS' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "version": { + "bsonType": "string", + "description": "用户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "description": "用户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "用户端上报的渠道code\/场景值" + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "uid": { + "bsonType": "string", + "description": "用户编号, 对应uni-id-users._id" + }, + "session_id": { + "bsonType": "string", + "description": "访问会话日志ID,对应uni-stat-session-logs._id", + "foreignKey": "uni-stat-session-logs._id" + }, + "page_id": { + "bsonType": "string", + "description": "当前页面ID,对应uni-stat-pages._id", + "foreignKey": "uni-stat-pages._id" + }, + "previous_page_id": { + "bsonType": "string", + "description": "上级页面ID,为空表示第一个页面, 对应uni-stat-pages._id" + }, + "previous_page_duration": { + "bsonType": "int", + "description": "上级页面停留时间,单位秒,前端上报" + }, + "previous_page_is_entry": { + "bsonType": "int", + "defaultValue": 0, + "description": " 上级页面是否为入口页, 0否 1是", + "enum": [{ + "text": "否", + "value": 0 + }, { + "text": "是", + "value": 1 + }] + }, + "query_string": { + "bsonType": "string", + "description": "页面参数" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-page-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-page-result.schema.json new file mode 100644 index 0000000..72065c2 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-page-result.schema.json @@ -0,0 +1,114 @@ +// 页面统计结果表 +{ + "bsonType": "object", + "description": "存储汇总的页面访问日志的数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_PAGE_RESULT' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "page_id": { + "bsonType": "string", + "description": "页面表ID,对应页面表ID,对应uni-stat-pages._id", + "foreignKey": "uni-stat-pages._id" + }, + "visit_times": { + "bsonType": "int", + "description": "访问次数" + }, + "visit_devices": { + "bsonType": "int", + "description": "访问设备数" + }, + "exit_times": { + "bsonType": "int", + "description": "退出次数" + }, + "duration": { + "bsonType": "int", + "description": "访问总时长,单位秒" + }, + "share_count": { + "bsonType": "int", + "description": "分享次数" + }, + "entry_devices": { + "bsonType": "int", + "description": "当前页作为入口页的设备数" + }, + "entry_users": { + "bsonType": "int", + "description": "当前页作为入口页的用户数" + }, + "entry_count": { + "bsonType": "int", + "description": "当前页作为入口页的总次数" + }, + "entry_duration": { + "bsonType": "int", + "description": "当前页作为入口时,本页面的总访问时长,单位秒" + }, + "bounce_times": { + "bsonType": "int", + "description": "跳出次数" + }, + "bounce_rate": { + "bsonType": "double", + "description": "跳出率" + }, + "dimension": { + "bsonType": "string", + "description": "统计范围 day:按天统计,hour:按小时统计", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }, { + "text": "天", + "value": "day" + }, { + "text": "小时", + "value": "hour" + }] + }, + "stat_date": { + "bsonType": "int", + "description": "统计日期,格式yyyymmdd,例:20211201" + }, + "start_time": { + "bsonType": "timestamp", + "description": "开始时间" + }, + "end_time": { + "bsonType": "timestamp", + "description": "结束时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-pages.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-pages.schema.json new file mode 100644 index 0000000..5a074c6 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-pages.schema.json @@ -0,0 +1,34 @@ +// 应用页面表 +{ + "bsonType": "object", + "description": "提供应用的页面字典", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_PAGES' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "统计应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "path": { + "bsonType": "string", + "description": "页面路径,如`\/pages\/index\/index`" + }, + "title": { + "bsonType": "string", + "description": "页面标题" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-pay-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-pay-result.schema.json new file mode 100644 index 0000000..e7ef7bd --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-pay-result.schema.json @@ -0,0 +1,169 @@ +{ + "bsonType": "object", + "description": "存储统计汇总的支付数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_PAY' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "pay_total_amount": { + "bsonType": "int", + "description": "支付金额:统计时间内,成功支付的订单金额之和(不剔除退款订单)。单位分。" + }, + "pay_order_count": { + "bsonType": "int", + "description": "支付笔数:统计时间内,成功支付的订单数,一个订单对应唯一一个订单号。(不剔除退款订单。)" + }, + "pay_user_count": { + "bsonType": "int", + "description": "支付人数:统计时间内,成功支付的人数(不剔除退款订单)。" + }, + "pay_device_count": { + "bsonType": "int", + "description": "支付设备数:统计时间内,成功支付的设备数(不剔除退款订单)。" + }, + "create_total_amount": { + "bsonType": "int", + "description": "下单金额:统计时间内,成功下单的订单金额(不剔除退款订单)。单位分。" + }, + "create_order_count": { + "bsonType": "int", + "description": "下单笔数:统计时间内,成功下单的订单笔数(不剔除退款订单)。" + }, + "create_user_count": { + "bsonType": "int", + "description": "下单人数:统计时间内,成功下单的客户数,一人多次下单记为一人(不剔除退款订单)。" + }, + "create_device_count": { + "bsonType": "int", + "description": "下单设备数:统计时间内,成功下单的设备数,一台设备多次访问被计为一台(不剔除退款订单)。" + }, + "refund_total_amount": { + "bsonType": "int", + "description": "成功退款金额:统计时间内,成功退款的金额。以成功退款时间点为准。单位分。" + }, + "refund_order_count": { + "bsonType": "int", + "description": "成功退款订单数:统计时间内,成功退款的订单数。以成功退款时间点为准。" + }, + "refund_user_count": { + "bsonType": "int", + "description": "成功退款人数:统计时间内,成功退款的人数(不剔除退款订单)。" + }, + "refund_device_count": { + "bsonType": "int", + "description": "成功退款设备数:统计时间内,成功退款的设备数(不剔除退款订单)。" + }, + "activity_user_count": { + "bsonType": "int", + "description": "访问人数:统计时间内,访问人数,一人多次访问被计为一人(只统计已登录的用户)。" + }, + "activity_device_count": { + "bsonType": "int", + "description": "访问设备数:统计时间内,访问设备数,一台设备多次访问被计为一台(包含未登录的用户)。" + }, + "new_user_count": { + "bsonType": "int", + "description": "新增注册人数:统计时间内,注册人数。" + }, + "new_device_count": { + "bsonType": "int", + "description": "新增新设备数:统计时间内,新设备数。" + }, + "new_user_create_order_count": { + "bsonType": "int", + "description": "新用户下单人数:统计时间内,新增注册人数中下单的人数。" + }, + "new_user_pay_order_count": { + "bsonType": "int", + "description": "新用户支付人数:统计时间内,新增注册人数中下成功支付的人数。" + }, + "dimension": { + "bsonType": "string", + "description": "统计范围 hour:按小时统计,day:按天统计,week:按周统计,month:按月统计 quarter:按季度统计 year:按年统计", + "enum": [{ + "text": "年", + "value": "year" + }, { + "text": "季度", + "value": "quarter" + }, { + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }, { + "text": "天", + "value": "day" + }, { + "text": "小时", + "value": "hour" + }] + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间" + }, + "start_time": { + "bsonType": "timestamp", + "description": "统计开始时间" + }, + "end_time": { + "bsonType": "timestamp", + "description": "统计结束时间" + }, + "stat_date": { + "bsonType": "object", + "description": "统计日期参数", + "properties": { + "date_str": { + "bsonType": "string", + "description": "如:2021-07-27" + }, + "year": { + "bsonType": "int", + "description": "年" + }, + "month": { + "bsonType": "int", + "description": "月" + }, + "day": { + "bsonType": "int", + "description": "日" + }, + "hour": { + "bsonType": "int", + "description": "时" + } + } + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-result.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-result.schema.json new file mode 100644 index 0000000..53edd17 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-result.schema.json @@ -0,0 +1,156 @@ +// 应用统计结果表 +{ + "bsonType": "object", + "description": "存储统计汇总的会话数据包括不限于设备\/用户的数量、访问量、活跃度(日活、周活、月活)、留存率(日留存、周留存、月留存)、跳出率、访问时长等数据", + "required": [], + "permission": { + "read": "'READ_UNI_STAT_RESULT' in auth.permission", + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "应用ID,对应opendb-app-list.appid", + "foreignKey": "opendb-app-list.appid" + }, + "platform_id": { + "bsonType": "string", + "description": "应用平台ID,对应uni-stat-app-platforms._id", + "foreignKey": "uni-stat-app-platforms._id" + }, + "channel_id": { + "bsonType": "string", + "description": "渠道\/场景值ID,对应uni-stat-app-channels._id", + "foreignKey": "uni-stat-app-channels._id" + }, + "version_id": { + "bsonType": "string", + "description": "应用版本ID,对应opendb-app-versions._id", + "foreignKey": "opendb-app-versions._id" + }, + "total_users": { + "bsonType": "int", + "description": "历史累计总用户数" + }, + "new_user_count": { + "bsonType": "int", + "description": "本时间段新增用户数" + }, + "active_user_count": { + "bsonType": "int", + "description": "本时间段活跃用户数" + }, + "total_devices": { + "bsonType": "int", + "description": "历史累计总设备数" + }, + "new_device_count": { + "bsonType": "int", + "description": "本时间段新增设备数" + }, + "user_session_times": { + "bsonType": "int", + "description": "本时间段用户的会话次数" + }, + "active_device_count": { + "bsonType": "int", + "description": "本时间段活跃设备数" + }, + "app_launch_count": { + "bsonType": "int", + "description": "本时间段App启动或从后台切到前台的次数" + }, + "error_count": { + "bsonType": "int", + "description": "本时间段报错次数" + }, + "duration": { + "bsonType": "int", + "description": "时间段内,所有会话访问总时长,单位秒" + }, + "user_duration": { + "bsonType": "int", + "description": "本次登录用户的会话总时长,单位为秒" + }, + "avg_device_session_time": { + "bsonType": "int", + "description": "设备的次均停留时长,单位秒" + }, + "avg_device_time": { + "bsonType": "int", + "defaultValue": "设均停留时长(平均每台设备的停留时长),单位秒" + }, + "avg_user_session_time": { + "bsonType": "int", + "description": "用户的次均停留时长,单位秒" + }, + "avg_user_time": { + "bsonType": "int", + "defaultValue": "人均停留时长(平均每个登录用户的停留时长),单位秒" + }, + "bounce_times": { + "bsonType": "int", + "description": "跳出次数" + }, + "bounce_rate": { + "bsonType": "double", + "description": "跳出率" + }, + "retention": { + "bsonType": "object", + "description": "留存信息", + "properties": { + "active_user": { + "bsonType": "object", + "description": "活跃用户留存信息" + }, + "new_user": { + "bsonType": "object", + "description": "新增用户留存信息" + }, + "active_device": { + "bsonType": "object", + "description": "活跃设备留存信息" + }, + "new_device": { + "bsonType": "object", + "description": "新增设备留存信息" + } + } + }, + "dimension": { + "bsonType": "string", + "description": "统计范围 day:按天统计,hour:按小时统计", + "enum": [{ + "text": "月", + "value": "month" + }, { + "text": "周", + "value": "week" + }, { + "text": "天", + "value": "day" + }, { + "text": "小时", + "value": "hour" + }] + }, + "stat_date": { + "bsonType": "int", + "description": "统计日期,格式yyyymmdd,例:20211201" + }, + "start_time": { + "bsonType": "timestamp", + "description": "开始时间" + }, + "end_time": { + "bsonType": "timestamp", + "description": "结束时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-run-errors.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-run-errors.schema.json new file mode 100644 index 0000000..8dfecb3 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-run-errors.schema.json @@ -0,0 +1,33 @@ +// 运行错误日志表 +{ + "bsonType": "object", + "description": "记录数据统计时运行出错的日志", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "mod": { + "bsonType": "string", + "description": "运行模块" + }, + "params": { + "bsonType": "object", + "description": "运行参数" + }, + "error": { + "bsonType": "string", + "description": "错误信息" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-session-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-session-logs.schema.json new file mode 100644 index 0000000..352c3f1 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-session-logs.schema.json @@ -0,0 +1,192 @@ +// 应用会话日志表 +{ + "bsonType": "object", + "description": "记录设备访问时产生的会话日志", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "客户端上报的应用ID" + }, + "version": { + "bsonType": "string", + "description": "客户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "description": "客户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "客户端上报的渠道code\/场景值" + }, + "type": { + "bsonType": "string", + "description": "会话类型", + "defaultValue": 1, + "enum": [{ + "text": "正常进入上报", + "value": 1 + }, { + "text": "后台进前台超时上报", + "value": 2 + }, { + "text": "页面停留超时上报", + "value": 3 + }] + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "last_visit_user_id": { + "bsonType": "string", + "description": "本次会话最终访问用户的ID, uni-id-users._id,客户端上报" + }, + "is_first_visit": { + "bsonType": "int", + "description": "是否为首次访问", + "defaultValue": 0, + "enum": [{ + "text": "否", + "value": 0 + }, { + "text": "是", + "value": 1 + }] + }, + "first_visit_time": { + "bsonType": "timestamp", + "description": "用户首次访问时间" + }, + "last_visit_time": { + "bsonType": "timestamp", + "description": "用户最后一次访问时间" + }, + "total_visit_count": { + "bsonType": "int", + "description": "用户累计访问次数,客户端上报" + }, + "entry_page_id": { + "bsonType": "string", + "description": "本次会话入口页面ID, 同uni-stat-pagesd" + }, + "exit_page_id": { + "bsonType": "string", + "description": "本次会话退出页面ID, 同uni-stat-pagesd" + }, + "page_count": { + "bsonType": "int", + "description": "本次会话浏览的页面数" + }, + "event_count": { + "bsonType": "int", + "description": "本次会话产生的事件数" + }, + "duration": { + "bsonType": "int", + "description": "本次会话时长,单位为秒,服务端计算" + }, + "sdk_version": { + "bsonType": "string", + "description": "基础库版本号" + }, + "platform_version": { + "bsonType": "string", + "description": "平台版本,如微信、支付宝宿主App版本号" + }, + "device_os": { + "bsonType": "int", + "description": "设备系统编号,1:安卓,2:iOS,3:PC" + }, + "device_os_version": { + "bsonType": "string", + "description": "设备系统版本" + }, + "device_net": { + "bsonType": "string", + "description": "设备网络型号wifi\/3G\/4G\/" + }, + "device_vendor": { + "bsonType": "string", + "description": "设备供应商 " + }, + "device_model": { + "bsonType": "string", + "description": "设备型号" + }, + "device_language": { + "bsonType": "string", + "description": "设备语言包" + }, + "device_pixel_ratio": { + "bsonType": "string", + "description": "设备像素比 " + }, + "device_window_width": { + "bsonType": "string", + "description": "设备窗口宽度 " + }, + "device_window_height": { + "bsonType": "string", + "description": "设备窗口高度" + }, + "device_screen_width": { + "bsonType": "string", + "description": "设备屏幕宽度" + }, + "device_screen_height": { + "bsonType": "string", + "description": "设备屏幕高度" + }, + "location_ip": { + "bsonType": "string", + "description": "ip" + }, + "location_latitude": { + "bsonType": "double", + "description": "纬度" + }, + "location_longitude": { + "bsonType": "double", + "description": "经度" + }, + "location_country": { + "bsonType": "string", + "description": "国家" + }, + "location_province": { + "bsonType": "string", + "description": "省份" + }, + "location_city": { + "bsonType": "string", + "description": "城市" + }, + "is_finish": { + "bsonType": "int", + "defaultValue": 0, + "description": "本次会话是否结束,0:否,1是", + "enum": [{ + "text": "否", + "value": 0 + }, { + "text": "是", + "value": 1 + }] + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-share-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-share-logs.schema.json new file mode 100644 index 0000000..b527dc1 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-share-logs.schema.json @@ -0,0 +1,55 @@ +// 应用分享日志表 +{ + "bsonType": "object", + "description": "记录触发分享事件的日志", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "客户端上报的应用ID" + }, + "version": { + "bsonType": "string", + "description": "客户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "description": "客户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "客户端上报的渠道code\/场景值" + }, + "device_id": { + "bsonType": "string", + "description": "客户端携带的设备标识" + }, + "uid": { + "bsonType": "string", + "description": "用户编号, 对应uni-id-users._id" + }, + "session_id": { + "bsonType": "string", + "description": "访问会话日志ID,对应uni-stat-session-logs._id", + "foreignKey": "uni-stat-session-logs._id" + }, + "page_id": { + "bsonType": "string", + "description": "当前页面ID,对应uni-stat-pagesd", + "foreignKey": "uni-stat-pagesd" + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uniCloud-aliyun/database/uni-stat-user-session-logs.schema.json b/alpha/admin/uniCloud-aliyun/database/uni-stat-user-session-logs.schema.json new file mode 100644 index 0000000..6af7353 --- /dev/null +++ b/alpha/admin/uniCloud-aliyun/database/uni-stat-user-session-logs.schema.json @@ -0,0 +1,82 @@ +// 用户会话日志表 +{ + "bsonType": "object", + "description": "记录登录用户的会话日志", + "required": [], + "permission": { + "read": false, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "客户端携带的应用ID" + }, + "version": { + "bsonType": "string", + "description": "客户端上报的应用版本号" + }, + "platform": { + "bsonType": "string", + "description": "客户端上报的平台code" + }, + "channel": { + "bsonType": "string", + "description": "客户端上报的渠道code\/场景值" + }, + "session_id": { + "bsonType": "string", + "description": "访问会话日志ID,对应uni-stat-session-logs._id", + "foreignKey": "uni-stat-session-logs._id" + }, + "uid": { + "bsonType": "string", + "description": "本次会话最终访问用户的ID, uni-id-users._id" + }, + "last_visit_time": { + "bsonType": "timestamp", + "description": "用户最后一次访问时间" + }, + "entry_page_id": { + "bsonType": "string", + "description": "本次会话入口页面ID, 同uni-stat-pagesd" + }, + "exit_page_id": { + "bsonType": "string", + "description": "本次会话退出页面ID, 同uni-stat-pagesd" + }, + "page_count": { + "bsonType": "int", + "description": "本次会话浏览的页面数" + }, + "event_count": { + "bsonType": "int", + "description": "本次会话产生的事件数" + }, + "duration": { + "bsonType": "int", + "description": "本次会话时长,单位为秒,服务端计算" + }, + "is_finish": { + "bsonType": "int", + "defaultValue": 0, + "description": "本次会话是否结束,0:否,1是", + "enum": [{ + "text": "否", + "value": 0 + }, { + "text": "是", + "value": 1 + }] + }, + "create_time": { + "bsonType": "timestamp", + "description": "创建时间" + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/changelog.md b/alpha/admin/uni_modules/qiun-data-charts/changelog.md new file mode 100644 index 0000000..4d470a4 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/changelog.md @@ -0,0 +1,320 @@ +## 2.5.0-20230101(2023-01-01) +- 秋云图表组件 修改条件编译顺序,确保uniapp的cli方式的项目依赖不完整时可以正常显示 +- 秋云图表组件 恢复props属性directory的使用,以修复vue3项目中,开启echarts后,echarts目录识别错误的bug +- uCharts.js 修复区域图、混合图只有一个数据时图表显示不正确的bug +- uCharts.js 修复折线图、区域图中时间轴类别图表tooltip指示点显示不正确的bug +- uCharts.js 修复x轴使用labelCount时,并且boundaryGap = 'justify' 并且关闭Y轴显示的时候,最后一个坐标值不显示的bug +- uCharts.js 修复折线图只有一组数据时 ios16 渲染颜色不正确的bug +- uCharts.js 修复玫瑰图半径显示不正确的bug +- uCharts.js 柱状图、山峰图增加正负图功能,y轴网格如果需要显示0轴则由 min max 及 splitNumber 确定,后续版本优化自动显示0轴 +- uCharts.js 柱状图column增加 opts.extra.column.labelPosition,数据标签位置,有效值为 outside外部, insideTop内顶部, center内中间, bottom内底部 +- uCharts.js 雷达图radar增加 opts.extra.radar.labelShow,否显示各项标识文案是,默认true +- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.boxPadding,提示窗边框填充距离,默认3px +- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.fontSize,提示窗字体大小配置,默认13px +- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.lineHeight,提示窗文字行高,默认20px +- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShow,是否显示左侧图例,默认true +- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShape,图例形状,图例标识样式,有效值为 auto自动跟随图例, diamond◆, circle●, triangle▲, square■, rect▬, line- +- uCharts.js 标记线markLine增加 opts.extra.markLine.labelFontSize,字体大小配置,默认13px +- uCharts.js 标记线markLine增加 opts.extra.markLine.labelPadding,标签边框内填充距离,默认6px +- uCharts.js 折线图line增加 opts.extra.line.linearType,渐变色类型,可选值 none关闭渐变色,custom 自定义渐变色。使用自定义渐变色时请赋值serie.linearColor作为颜色值 +- uCharts.js 折线图line增加 serie.linearColor,渐变色数组,格式为2维数组[起始位置,颜色值],例如[[0,'#0EE2F8'],[0.3,'#2BDCA8'],[0.6,'#1890FF'],[1,'#9A60B4']] +- uCharts.js 折线图line增加 opts.extra.line.onShadow,是否开启折线阴影,开启后请赋值serie.setShadow阴影设置 +- uCharts.js 折线图line增加 serie.setShadow,阴影配置,格式为4位数组:[offsetX,offsetY,blur,color] +- uCharts.js 折线图line增加 opts.extra.line.animation,动画效果方向,可选值为vertical 垂直动画效果,horizontal 水平动画效果 +- uCharts.js X轴xAxis增加 opts.xAxis.lineHeight,X轴字体行高,默认20px +- uCharts.js X轴xAxis增加 opts.xAxis.marginTop,X轴文字距离轴线的距离,默认0px +- uCharts.js X轴xAxis增加 opts.xAxis.title,当前X轴标题 +- uCharts.js X轴xAxis增加 opts.xAxis.titleFontSize,标题字体大小,默认13px +- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetY,标题纵向偏移距离,负数为向上偏移,正数向下偏移 +- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetX,标题横向偏移距离,负数为向左偏移,正数向右偏移 +- uCharts.js X轴xAxis增加 opts.xAxis.titleFontColor,标题字体颜色,默认#666666 + +## 报错TypeError: Cannot read properties of undefined (reading 'length') +- 如果是uni-modules版本组件,请先登录HBuilderX账号; +- 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行; +- 如果是cli项目请使用码云上的非uniCloud版本组件; +- 或者添加uniCloud的依赖; +- 或者使用原生uCharts; +## 2.4.5-20221130(2022-11-30) +- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画 +- uCharts.js 折线图修复特殊情况下只有单点数据,并改变线宽后点变为圆形的bug +- uCharts.js 修复Y轴disabled启用后无效并报错的bug +- uCharts.js 修复仪表盘起始结束角度特殊情况下显示不正确的bug +- uCharts.js 雷达图新增参数 opts.extra.radar.radius , 自定义雷达图半径 +- uCharts.js 折线图、区域图增加tooltip指示点,opts.extra.line.activeType/opts.extra.area.activeType,可选值"none"不启用激活指示点,"hollow"空心点模式,"solid"实心点模式 +## 2.4.4-20221102(2022-11-02) +- 秋云图表组件 修复使用echarts时reload、reshow无法调用重新渲染的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/40) +- 秋云图表组件 修复使用echarts时,初始化时宽高不正确的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/42) +- 秋云图表组件 修复uniapp的h5使用history模式时,无法加载echarts的bug +- 秋云图表组件 小程序端@complete、@scrollLeft、@scrollRight、@getTouchStart、@getTouchMove、@getTouchEnd事件增加opts参数传出,方便一些特殊需求的交互获取数据。 + +- uCharts.js 修复calTooltipYAxisData方法内formatter格式化方法未与y轴方法同步的问题,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/43) +- uCharts.js 地图新增参数opts.series[i].fillOpacity,以透明度方式来设置颜色过度效果,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/38) +- uCharts.js 地图新增参数opts.extra.map.active,是否启用点击激活变色 +- uCharts.js 地图新增参数opts.extra.map.activeTextColor,是否启用点击激活变色 +- uCharts.js 地图新增渲染完成事件renderComplete +- uCharts.js 漏斗图修复当部分数据相同时tooltip提示窗点击错误的bug +- uCharts.js 漏斗图新增参数series.data[i].centerText 居中标签文案 +- uCharts.js 漏斗图新增参数series.data[i].centerTextSize 居中标签文案字体大小,默认opts.fontSize +- uCharts.js 漏斗图新增参数series.data[i].centerTextColor 居中标签文案字体颜色,默认#FFFFFF +- uCharts.js 漏斗图新增参数opts.extra.funnel.minSize 最小值的最小宽度,默认0 +- uCharts.js 进度条新增参数opts.extra.arcbar.direction,动画方向,可选值为cw顺时针、ccw逆时针 +- uCharts.js 混合图新增参数opts.extra.mix.line.width,折线的宽度,默认2 +- uCharts.js 修复tooltip开启horizentalLine水平横线标注时,图表显示错位的bug +- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画 +- uCharts.js 修复开启滚动条后X轴文字超出绘图区域后的隐藏逻辑 +- uCharts.js 柱状图、条状图修复堆叠模式不能通过{value,color}赋值单个柱子颜色的问题 +- uCharts.js 气泡图修复不识别series.textSize和series.textColor的bug + +## 报错TypeError: Cannot read properties of undefined (reading 'length') +1. 如果是uni-modules版本组件,请先登录HBuilderX账号; +2. 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行; +3. 如果是cli项目请使用码云上的非uniCloud版本组件; +4. 或者添加uniCloud的依赖; +5. 或者使用原生uCharts; +## 2.4.3-20220505(2022-05-05) +- 秋云图表组件 修复开启canvas2d后将series赋值为空数组显示加载图标时,再次赋值后画布闪动的bug +- 秋云图表组件 修复升级hbx最新版后ECharts的highlight方法报错的bug +- uCharts.js 雷达图新增参数opts.extra.radar.gridEval,数据点位网格抽希,默认1 +- uCharts.js 雷达图新增参数opts.extra.radar.axisLabel, 是否显示刻度点值,默认false +- uCharts.js 雷达图新增参数opts.extra.radar.axisLabelTofix,刻度点值小数位数,默认0 +- uCharts.js 雷达图新增参数opts.extra.radar.labelPointShow,是否显示末端刻度圆点,默认false +- uCharts.js 雷达图新增参数opts.extra.radar.labelPointRadius,刻度圆点的半径,默认3 +- uCharts.js 雷达图新增参数opts.extra.radar.labelPointColor,刻度圆点的颜色,默认#cccccc +- uCharts.js 雷达图新增参数opts.extra.radar.linearType,渐变色类型,可选值"none"关闭渐变,"custom"开启渐变 +- uCharts.js 雷达图新增参数opts.extra.radar.customColor,自定义渐变颜色,数组类型对应series的数组长度以匹配不同series颜色的不同配色方案,例如["#FA7D8D", "#EB88E2"] +- uCharts.js 雷达图优化支持series.textColor、series.textSize属性 +- uCharts.js 柱状图中温度计式图标,优化支持全圆角类型,修复边框有缝隙的bug,详见官网【演示】中的温度计图表 +- uCharts.js 柱状图新增参数opts.extra.column.activeWidth,当前点击柱状图的背景宽度,默认一个单元格单位 +- uCharts.js 混合图增加opts.extra.mix.area.gradient 区域图是否开启渐变色 +- uCharts.js 混合图增加opts.extra.mix.area.opacity 区域图透明度,默认0.2 +- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelText,自定义标签文字,避免formatter格式化的繁琐,详见官网【演示】中的饼图 +- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelShow,自定义是否显示某一个指示标签,避免因饼图类别太多导致标签重复或者居多导致图形变形的问题,详见官网【演示】中的饼图 +- uCharts.js 增加opts.series[i].legendText/opts.series[0].data[i].legendText(与series.name同级)自定义图例显示文字的方法 +- uCharts.js 优化X轴、Y轴formatter格式化方法增加形参,统一为fromatter:function(value,index,opts){} +- uCharts.js 修复横屏模式下无法使用双指缩放方法的bug +- uCharts.js 修复当只有一条数据或者多条数据值相等的时候Y轴自动计算的最大值错误的bug +- 【官网模板】增加外部自定义图例与图表交互的例子,[点击跳转](https://www.ucharts.cn/v2/#/layout/info?id=2) + +## 注意:非unimodules 版本如因更新 hbx 至 3.4.7 导致报错如下,请到码云更新非 unimodules 版本组件,[点击跳转](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6) +> Error in callback for immediate watcher "uchartsOpts": "SyntaxError: Unexpected token u in JSON at position 0" +## 2.4.2-20220421(2022-04-21) +- 秋云图表组件 修复HBX升级3.4.6.20220420版本后echarts报错的问题 +## 2.4.2-20220420(2022-04-20) +## 重要!此版本uCharts新增了很多功能,修复了诸多已知问题 +- 秋云图表组件 新增onzoom开启双指缩放功能(仅uCharts),前提需要直角坐标系类图表类型,并且ontouch为true、opts.enableScroll为true,详见实例项目K线图 +- 秋云图表组件 新增optsWatch是否监听opts变化,关闭optsWatch后,动态修改opts不会触发图表重绘 +- 秋云图表组件 修复开启canvas2d功能后,动态更新数据后画布闪动的bug +- 秋云图表组件 去除directory属性,改为自动获取echarts.min.js路径(升级不受影响) +- 秋云图表组件 增加getImage()方法及@getImage事件,通过ref调用getImage()方法获,触发@getImage事件获取当前画布的base64图片文件流。 +- 秋云图表组件 支付宝、字节跳动、飞书、快手小程序支持开启canvas2d同层渲染设置。 +- 秋云图表组件 新增加【非uniCloud】版本组件,避免有些不需要uniCloud的使用组件发布至小程序需要提交隐私声明问题,请到码云[【非uniCloud版本】](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6),或npm[【非uniCloud版本】](https://www.npmjs.com/package/@qiun/uni-ucharts)下载使用。 +- uCharts.js 新增dobuleZoom双指缩放功能 +- uCharts.js 新增山峰图type="mount",数据格式为饼图类格式,不需要传入categories,具体详见新版官网在线演示 +- uCharts.js 修复折线图当数据中存在null时tooltip报错的bug +- uCharts.js 修复饼图类当画布比较小时自动计算的半径是负数报错的bug +- uCharts.js 统一各图表类型的series.formatter格式化方法的形参为(val, index, series, opts),方便格式化时有更多参数可用 +- uCharts.js 标记线功能增加labelText自定义显示文字,增加labelAlign标签显示位置(左侧或右侧),增加标签显示位置微调labelOffsetX、labelOffsetY +- uCharts.js 修复条状图当数值很小时开启圆角后样式错误的bug +- uCharts.js 修复X轴开启disabled后,X轴仍占用空间的bug +- uCharts.js 修复X轴开启滚动条并且开启rotateLabel后,X轴文字与滚动条重叠的bug +- uCharts.js 增加X轴rotateAngle文字旋转自定义角度,取值范围(-90至90) +- uCharts.js 修复地图文字标签层级显示不正确的bug +- uCharts.js 修复饼图、圆环图、玫瑰图当数据全部为0的时候不显示数据标签的bug +- uCharts.js 修复当opts.padding上边距为0时,Y轴顶部刻度标签位置不正确的bug + +## 另外我们还开发了各大原生小程序组件,已发布至码云和npm +[https://gitee.com/uCharts/uCharts](https://gitee.com/uCharts/uCharts) +[https://www.npmjs.com/~qiun](https://www.npmjs.com/~qiun) + +## 对于原生uCharts文档我们已上线新版官方网站,详情点击下面链接进入官网 +[https://www.uCharts.cn/v2/](https://www.ucharts.cn/v2/) +## 2.3.7-20220122(2022-01-22) +## 重要!使用vue3编译,请使用cli模式并升级至最新依赖,HbuilderX编译需要使用3.3.8以上版本 +- uCharts.js 修复uni-app平台组件模式使用vue3编译到小程序报错的bug。 +## 2.3.7-20220118(2022-01-18) +## 注意,使用vue3的前提是需要3.3.8.20220114-alpha版本的HBuilder! +## 2.3.67-20220118(2022-01-18) +- 秋云图表组件 组件初步支持vue3,全端编译会有些问题,具体详见下面修改: +1. 小程序端运行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new uni_modules_qiunDataCharts_js_sdk_uCharts_uCharts.uCharts,将.uCharts去掉。 +2. 小程序端发行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new e.uCharts,将.uCharts去掉,变为 new e。 +3. 如果觉得上述步骤比较麻烦,如果您的项目只编译到小程序端,可以修改u-charts.js最后一行导出方式,将 export default uCharts;变更为 export default { uCharts: uCharts }; 这样变更后,H5和App端的renderjs会有问题,请开发者自行选择。(此问题非组件问题,请等待DC官方修复Vue3的小程序端) +## 2.3.6-20220111(2022-01-11) +- 秋云图表组件 修改组件 props 属性中的 background 默认值为 rgba(0,0,0,0) +## 2.3.6-20211201(2021-12-01) +- uCharts.js 修复bar条状图开启圆角模式时,值很小时圆角渲染错误的bug +## 2.3.5-20211014(2021-10-15) +- uCharts.js 增加vue3的编译支持(仅原生uCharts,qiun-data-charts组件后续会支持,请关注更新) +## 2.3.4-20211012(2021-10-12) +- 秋云图表组件 修复 mac os x 系统 mouseover 事件丢失的 bug +## 2.3.3-20210706(2021-07-06) +- uCharts.js 增加雷达图开启数据点值(opts.dataLabel)的显示 +## 2.3.2-20210627(2021-06-27) +- 秋云图表组件 修复tooltipCustom个别情况下传值不正确报错TypeError: Cannot read property 'name' of undefined的bug +## 2.3.1-20210616(2021-06-16) +- uCharts.js 修复圆角柱状图使用4角圆角时,当数值过大时不正确的bug +## 2.3.0-20210612(2021-06-12) +- uCharts.js 【重要】uCharts增加nvue兼容,可在nvue项目中使用gcanvas组件渲染uCharts,[详见码云uCharts-demo-nvue](https://gitee.com/uCharts/uCharts) +- 秋云图表组件 增加tapLegend属性,是否开启图例点击交互事件 +- 秋云图表组件 getIndex事件中增加返回uCharts实例中的opts参数,以便在页面中调用参数 +- 示例项目 pages/other/other.vue增加app端自定义tooltip的方法,详见showOptsTooltip方法 +## 2.2.1-20210603(2021-06-03) +- uCharts.js 修复饼图、圆环图、玫瑰图,当起始角度不为0时,tooltip位置不准确的bug +- uCharts.js 增加温度计式柱状图开启顶部半圆形的配置 +## 2.2.0-20210529(2021-05-29) +- uCharts.js 增加条状图type="bar" +- 示例项目 pages/ucharts/ucharts.vue增加条状图的demo +## 2.1.7-20210524(2021-05-24) +- uCharts.js 修复大数据量模式下曲线图不平滑的bug +## 2.1.6-20210523(2021-05-23) +- 秋云图表组件 修复小程序端开启滚动条更新数据后滚动条位置不符合预期的bug +## 2.1.5-2021051702(2021-05-17) +- uCharts.js 修复自定义Y轴min和max值为0时不能正确显示的bug +## 2.1.5-20210517(2021-05-17) +- uCharts.js 修复Y轴自定义min和max时,未按指定的最大值最小值显示坐标轴刻度的bug +## 2.1.4-20210516(2021-05-16) +- 秋云图表组件 优化onWindowResize防抖方法 +- 秋云图表组件 修复APP端uCharts更新数据时,清空series显示loading图标后再显示图表,图表抖动的bug +- uCharts.js 修复开启canvas2d后,x轴、y轴、series自定义字体大小未按比例缩放的bug +- 示例项目 修复format-e.vue拼写错误导致app端使用uCharts渲染图表 +## 2.1.3-20210513(2021-05-13) +- 秋云图表组件 修改uCharts变更chartData数据为updateData方法,支持带滚动条的数据动态打点 +- 秋云图表组件 增加onWindowResize防抖方法 fix by ど誓言,如尘般染指流年づ +- 秋云图表组件 H5或者APP变更chartData数据显示loading图表时,原数据闪现的bug +- 秋云图表组件 props增加errorReload禁用错误点击重新加载的方法 +- uCharts.js 增加tooltip显示category(x轴对应点位)标题的功能,opts.extra.tooltip.showCategory,默认为false +- uCharts.js 修复mix混合图只有柱状图时,tooltip的分割线显示位置不正确的bug +- uCharts.js 修复开启滚动条,图表在拖动中动态打点,滚动条位置不正确的bug +- uCharts.js 修复饼图类数据格式为echarts数据格式,series为空数组报错的bug +- 示例项目 修改uCharts.js更新到v2.1.2版本后,@getIndex方法获取索引值变更为e.currentIndex.index +- 示例项目 pages/updata/updata.vue增加滚动条拖动更新(数据动态打点)的demo +- 示例项目 pages/other/other.vue增加errorReload禁用错误点击重新加载的demo +## 2.1.2-20210509(2021-05-09) +秋云图表组件 修复APP端初始化时就传入chartData或lacaldata不显示图表的bug +## 2.1.1-20210509(2021-05-09) +- 秋云图表组件 变更ECharts的eopts配置在renderjs内执行,支持在config-echarts.js配置文件内写function配置。 +- 秋云图表组件 修复APP端报错Prop being mutated: "onmouse"错误的bug。 +- 秋云图表组件 修复APP端报错Error: Not Found:Page[6][-1,27] at view.umd.min.js:1的bug。 +## 2.1.0-20210507(2021-05-07) +- 秋云图表组件 修复初始化时就有数据或者数据更新的时候loading加载动画闪动的bug +- uCharts.js 修复x轴format方法categories为字符串类型时返回NaN的bug +- uCharts.js 修复series.textColor、legend.fontColor未执行全局默认颜色的bug +## 2.1.0-20210506(2021-05-06) +- 秋云图表组件 修复极个别情况下报错item.properties undefined的bug +- 秋云图表组件 修复极个别情况下关闭加载动画reshow不起作用,无法显示图表的bug +- 示例项目 pages/ucharts/ucharts.vue 增加时间轴折线图(type="tline")、时间轴区域图(type="tarea")、散点图(type="scatter")、气泡图demo(type="bubble")、倒三角形漏斗图(opts.extra.funnel.type="triangle")、金字塔形漏斗图(opts.extra.funnel.type="pyramid") +- 示例项目 pages/format-u/format-u.vue 增加X轴format格式化示例 +- uCharts.js 升级至v2.1.0版本 +- uCharts.js 修复 玫瑰图面积模式点击tooltip位置不正确的bug +- uCharts.js 修复 玫瑰图点击图例,只剩一个类别显示空白的bug +- uCharts.js 修复 饼图类图点击图例,其他图表tooltip位置某些情况下不准的bug +- uCharts.js 修复 x轴为矢量轴(时间轴)情况下,点击tooltip位置不正确的bug +- uCharts.js 修复 词云图获取点击索引偶尔不准的bug +- uCharts.js 增加 直角坐标系图表X轴format格式化方法(原生uCharts.js用法请使用formatter) +- uCharts.js 增加 漏斗图扩展配置,倒三角形(opts.extra.funnel.type="triangle"),金字塔形(opts.extra.funnel.type="pyramid") +- uCharts.js 增加 散点图(opts.type="scatter")、气泡图(opts.type="bubble") +- 后期计划 完善散点图、气泡图,增加markPoints标记点,增加横向条状图。 +## 2.0.0-20210502(2021-05-02) +- uCharts.js 修复词云图获取点击索引不正确的bug +## 2.0.0-20210501(2021-05-01) +- 秋云图表组件 修复QQ小程序、百度小程序在关闭动画效果情况下,v-for循环使用图表,显示不正确的bug +## 2.0.0-20210426(2021-04-26) +- 秋云图表组件 修复QQ小程序不支持canvas2d的bug +- 秋云图表组件 修复钉钉小程序某些情况点击坐标计算错误的bug +- uCharts.js 增加 extra.column.categoryGap 参数,柱状图类每个category点位(X轴点)柱子组之间的间距 +- uCharts.js 增加 yAxis.data[i].titleOffsetY 参数,标题纵向偏移距离,负数为向上偏移,正数向下偏移 +- uCharts.js 增加 yAxis.data[i].titleOffsetX 参数,标题横向偏移距离,负数为向左偏移,正数向右偏移 +- uCharts.js 增加 extra.gauge.labelOffset 参数,仪表盘标签文字径向便宜距离,默认13px +## 2.0.0-20210422-2(2021-04-22) +秋云图表组件 修复 formatterAssign 未判断 args[key] == null 的情况导致栈溢出的 bug +## 2.0.0-20210422(2021-04-22) +- 秋云图表组件 修复H5、APP、支付宝小程序、微信小程序canvas2d模式下横屏模式的bug +## 2.0.0-20210421(2021-04-21) +- uCharts.js 修复多行图例的情况下,图例在上方或者下方时,图例float为左侧或者右侧时,第二行及以后的图例对齐方式不正确的bug +## 2.0.0-20210420(2021-04-20) +- 秋云图表组件 修复微信小程序开启canvas2d模式后,windows版微信小程序不支持canvas2d模式的bug +- 秋云图表组件 修改非uni_modules版本为v2.0版本qiun-data-charts组件 +## 2.0.0-20210419(2021-04-19) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。 +## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX,如仍不好用,请重启电脑; +## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。 +## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。 +## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn) +## 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! +## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn) +## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- uCharts.js 修复混合图中柱状图单独设置颜色不生效的bug +- uCharts.js 修复多Y轴单独设置fontSize时,开启canvas2d后,未对应放大字体的bug +## 2.0.0-20210418(2021-04-18) +- 秋云图表组件 增加directory配置,修复H5端history模式下如果发布到二级目录无法正确加载echarts.min.js的bug +## 2.0.0-20210416(2021-04-16) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。 +## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX,如仍不好用,请重启电脑; +## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。 +## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。 +## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn) +## 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! +## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn) +## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- 秋云图表组件 修复APP端某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员 +- 示例项目 修复APP端v-for循环某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员 +- uCharts.js 修复非直角坐标系tooltip提示窗右侧超出未变换方向显示的bug +## 2.0.0-20210415(2021-04-15) +- 秋云图表组件 修复H5端发布到二级目录下echarts无法加载的bug +- 秋云图表组件 修复某些情况下echarts.off('finished')移除监听事件报错的bug +## 2.0.0-20210414(2021-04-14) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。 +## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX,如仍不好用,请重启电脑; +## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。 +## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。 +## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn) +## 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! +## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn) +## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- 秋云图表组件 修复H5端在cli项目下ECharts引用地址错误的bug +- 示例项目 增加ECharts的formatter用法的示例(详见示例项目format-e.vue) +- uCharts.js 增加圆环图中心背景色的配置extra.ring.centerColor +- uCharts.js 修复微信小程序安卓端柱状图开启透明色后显示不正确的bug +## 2.0.0-20210413(2021-04-13) +- 秋云图表组件 修复百度小程序多个图表真机未能正确获取根元素dom尺寸的bug +- 秋云图表组件 修复百度小程序横屏模式方向不正确的bug +- 秋云图表组件 修改ontouch时,@getTouchStart@getTouchMove@getTouchEnd的触发条件 +- uCharts.js 修复饼图类数据格式series属性不生效的bug +- uCharts.js 增加时序区域图 详见示例项目中ucharts.vue +## 2.0.0-20210412-2(2021-04-12) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。 +## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX。如仍不好用,请重启电脑,此问题已于DCloud官方确认,HBuilderX下个版本会修复。 +## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn) +## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- 秋云图表组件 修复uCharts在APP端横屏模式下不能正确渲染的bug +- 示例项目 增加ECharts柱状图渐变色、圆角柱状图、横向柱状图(条状图)的示例 +## 2.0.0-20210412(2021-04-12) +- 秋云图表组件 修复created中判断echarts导致APP端无法识别,改回mounted中判断echarts初始化 +- uCharts.js 修复2d模式下series.textOffset未乘像素比的bug +## 2.0.0-20210411(2021-04-11) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。 +## 初次使用如果提示未注册组件,请重启HBuilderX,并清空小程序开发者工具缓存。 +## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn) +## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- uCharts.js 折线图区域图增加connectNulls断点续连的功能,详见示例项目中ucharts.vue +- 秋云图表组件 变更初始化方法为created,变更type2d默认值为true,优化2d模式下组件初始化后dom获取不到的bug +- 秋云图表组件 修复左右布局时,右侧图表点击坐标错误的bug,修复tooltip柱状图自定义颜色显示object的bug +## 2.0.0-20210410(2021-04-10) +- 修复左右布局时,右侧图表点击坐标错误的bug,修复柱状图自定义颜色tooltip显示object的bug +- 增加标记线及柱状图自定义颜色的demo +## 2.0.0-20210409(2021-04-08) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn) +## 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +- uCharts.js 修复钉钉小程序百度小程序measureText不准确的bug,修复2d模式下饼图类activeRadius为按比例放大的bug +- 修复组件在支付宝小程序端点击位置不准确的bug +## 2.0.0-20210408(2021-04-07) +- 修复组件在支付宝小程序端不能显示的bug(目前支付宝小程不能点击交互,后续修复) +- uCharts.js 修复高分屏下柱状图类,圆弧进度条 自定义宽度不能按比例放大的bug +## 2.0.0-20210407(2021-04-06) +## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn) +## 增加 通过tofix和unit快速格式化y轴的demo add by `howcode` +## 增加 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) +## 2.0.0-20210406(2021-04-05) +# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页 +## 2.0.0(2021-04-05) +# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页 diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue new file mode 100644 index 0000000..5f42afc --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue @@ -0,0 +1,1625 @@ + + + + + + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue new file mode 100644 index 0000000..b15b19f --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue new file mode 100644 index 0000000..b701394 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue new file mode 100644 index 0000000..7541b31 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue new file mode 100644 index 0000000..8e14db3 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue new file mode 100644 index 0000000..77c55b7 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue new file mode 100644 index 0000000..cb93a55 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue @@ -0,0 +1,229 @@ + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue new file mode 100644 index 0000000..7789060 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js new file mode 100644 index 0000000..7b8168f --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js @@ -0,0 +1,422 @@ +/* + * uCharts® + * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台 + * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved. + * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) + * 复制使用请保留本段注释,感谢支持开源! + * + * uCharts®官方网站 + * https://www.uCharts.cn + * + * 开源地址: + * https://gitee.com/uCharts/uCharts + * + * uni-app插件市场地址: + * http://ext.dcloud.net.cn/plugin?id=271 + * + */ + +// 通用配置项 + +// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性 +const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc']; + +const cfe = { + //demotype为自定义图表类型 + "type": ["pie", "ring", "rose", "funnel", "line", "column", "area", "radar", "gauge","candle","demotype"], + //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型例如最后的"demotype" + "categories": ["line", "column", "area", "radar", "gauge", "candle","demotype"], + //instance为实例变量承载属性,option为eopts承载属性,不要删除 + "instance": {}, + "option": {}, + //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换 + "formatter":{ + "tooltipDemo1":function(res){ + let result = '' + for (let i in res) { + if (i == 0) { + result += res[i].axisValueLabel + '年销售额' + } + let value = '--' + if (res[i].data !== null) { + value = res[i].data + } + // #ifdef H5 + result += '\n' + res[i].seriesName + ':' + value + ' 万元' + // #endif + + // #ifdef APP-PLUS + result += '
' + res[i].marker + res[i].seriesName + ':' + value + ' 万元' + // #endif + } + return result; + }, + legendFormat:function(name){ + return "自定义图例+"+name; + }, + yAxisFormatDemo:function (value, index) { + return value + '元'; + }, + seriesFormatDemo:function(res){ + return res.name + '年' + res.value + '元'; + } + }, + //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在eopts参数,会将demotype与eopts中option合并后渲染图表。 + "demotype":{ + "color": color, + //在这里填写echarts的option即可 + + }, + //下面是自定义配置,请添加项目所需的通用配置 + "column": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'axis' + }, + "grid": { + "top": 30, + "bottom": 50, + "right": 15, + "left": 40 + }, + "legend": { + "bottom": 'left', + }, + "toolbox": { + "show": false, + }, + "xAxis": { + "type": 'category', + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + "boundaryGap": true, + "data": [] + }, + "yAxis": { + "type": 'value', + "axisTick": { + "show": false, + }, + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + }, + "seriesTemplate": { + "name": '', + "type": 'bar', + "data": [], + "barwidth": 20, + "label": { + "show": true, + "color": "#666666", + "position": 'top', + }, + }, + }, + "line": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'axis' + }, + "grid": { + "top": 30, + "bottom": 50, + "right": 15, + "left": 40 + }, + "legend": { + "bottom": 'left', + }, + "toolbox": { + "show": false, + }, + "xAxis": { + "type": 'category', + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + "boundaryGap": true, + "data": [] + }, + "yAxis": { + "type": 'value', + "axisTick": { + "show": false, + }, + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + }, + "seriesTemplate": { + "name": '', + "type": 'line', + "data": [], + "barwidth": 20, + "label": { + "show": true, + "color": "#666666", + "position": 'top', + }, + }, + }, + "area": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'axis' + }, + "grid": { + "top": 30, + "bottom": 50, + "right": 15, + "left": 40 + }, + "legend": { + "bottom": 'left', + }, + "toolbox": { + "show": false, + }, + "xAxis": { + "type": 'category', + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + "boundaryGap": true, + "data": [] + }, + "yAxis": { + "type": 'value', + "axisTick": { + "show": false, + }, + "axisLabel": { + "color": '#666666' + }, + "axisLine": { + "lineStyle": { + "color": '#CCCCCC' + } + }, + }, + "seriesTemplate": { + "name": '', + "type": 'line', + "data": [], + "areaStyle": {}, + "label": { + "show": true, + "color": "#666666", + "position": 'top', + }, + }, + }, + "pie": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'item' + }, + "grid": { + "top": 40, + "bottom": 30, + "right": 15, + "left": 15 + }, + "legend": { + "bottom": 'left', + }, + "seriesTemplate": { + "name": '', + "type": 'pie', + "data": [], + "radius": '50%', + "label": { + "show": true, + "color": "#666666", + "position": 'top', + }, + }, + }, + "ring": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'item' + }, + "grid": { + "top": 40, + "bottom": 30, + "right": 15, + "left": 15 + }, + "legend": { + "bottom": 'left', + }, + "seriesTemplate": { + "name": '', + "type": 'pie', + "data": [], + "radius": ['40%', '70%'], + "avoidLabelOverlap": false, + "label": { + "show": true, + "color": "#666666", + "position": 'top', + }, + "labelLine": { + "show": true + }, + }, + }, + "rose": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'item' + }, + "legend": { + "top": 'bottom' + }, + "seriesTemplate": { + "name": '', + "type": 'pie', + "data": [], + "radius": "55%", + "center": ['50%', '50%'], + "roseType": 'area', + }, + }, + "funnel": { + "color": color, + "title": { + "text": '' + }, + "tooltip": { + "trigger": 'item', + "formatter": "{b} : {c}%" + }, + "legend": { + "top": 'bottom' + }, + "seriesTemplate": { + "name": '', + "type": 'funnel', + "left": '10%', + "top": 60, + "bottom": 60, + "width": '80%', + "min": 0, + "max": 100, + "minSize": '0%', + "maxSize": '100%', + "sort": 'descending', + "gap": 2, + "label": { + "show": true, + "position": 'inside' + }, + "labelLine": { + "length": 10, + "lineStyle": { + "width": 1, + "type": 'solid' + } + }, + "itemStyle": { + "bordercolor": '#fff', + "borderwidth": 1 + }, + "emphasis": { + "label": { + "fontSize": 20 + } + }, + "data": [], + }, + }, + "gauge": { + "color": color, + "tooltip": { + "formatter": '{a}
{b} : {c}%' + }, + "seriesTemplate": { + "name": '业务指标', + "type": 'gauge', + "detail": {"formatter": '{value}%'}, + "data": [{"value": 50, "name": '完成率'}] + }, + }, + "candle": { + "xAxis": { + "data": [] + }, + "yAxis": {}, + "color": color, + "title": { + "text": '' + }, + "dataZoom": [{ + "type": 'inside', + "xAxisIndex": [0, 1], + "start": 10, + "end": 100 + }, + { + "show": true, + "xAxisIndex": [0, 1], + "type": 'slider', + "bottom": 10, + "start": 10, + "end": 100 + } + ], + "seriesTemplate": { + "name": '', + "type": 'k', + "data": [], + }, + } +} + +export default cfe; \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js new file mode 100644 index 0000000..17b28b3 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js @@ -0,0 +1,606 @@ +/* + * uCharts® + * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台 + * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved. + * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) + * 复制使用请保留本段注释,感谢支持开源! + * + * uCharts®官方网站 + * https://www.uCharts.cn + * + * 开源地址: + * https://gitee.com/uCharts/uCharts + * + * uni-app插件市场地址: + * http://ext.dcloud.net.cn/plugin?id=271 + * + */ + +// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性 +const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc']; + +//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改 +const formatDateTime = (timeStamp, returnType)=>{ + var date = new Date(); + date.setTime(timeStamp * 1000); + var y = date.getFullYear(); + var m = date.getMonth() + 1; + m = m < 10 ? ('0' + m) : m; + var d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + var h = date.getHours(); + h = h < 10 ? ('0' + h) : h; + var minute = date.getMinutes(); + var second = date.getSeconds(); + minute = minute < 10 ? ('0' + minute) : minute; + second = second < 10 ? ('0' + second) : second; + if(returnType == 'full'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;} + if(returnType == 'y-m-d'){return y + '-' + m + '-' + d;} + if(returnType == 'h:m'){return h +':' + minute;} + if(returnType == 'h:m:s'){return h +':' + minute +':' + second;} + return [y, m, d, h, minute, second]; +} + +const cfu = { + //demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可 + "type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","bar","area","radar","gauge","candle","mix","tline","tarea","scatter","bubble","demotype"], + "range":["饼状图","圆环图","玫瑰图","词云图","漏斗图","地图","圆弧进度条","折线图","柱状图","山峰图","条状图","区域图","雷达图","仪表盘","K线图","混合图","时间轴折线","时间轴区域","散点图","气泡图","自定义类型"], + //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype" + //自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories + "categories":["line","column","mount","bar","area","radar","gauge","candle","mix","demotype"], + //instance为实例变量承载属性,不要删除 + "instance":{}, + //option为opts及eopts承载属性,不要删除 + "option":{}, + //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换 + "formatter":{ + "yAxisDemo1":function(val, index, opts){return val+'元'}, + "yAxisDemo2":function(val, index, opts){return val.toFixed(2)}, + "xAxisDemo1":function(val, index, opts){return val+'年';}, + "xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')}, + "seriesDemo1":function(val, index, series, opts){return val+'元'}, + "tooltipDemo1":function(item, category, index, opts){ + if(index==0){ + return '随便用'+item.data+'年' + }else{ + return '其他我没改'+item.data+'天' + } + }, + "pieDemo":function(val, index, series, opts){ + if(index !== undefined){ + return series[index].name+':'+series[index].data+'元' + } + }, + }, + //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。 + "demotype":{ + //我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置 + "type": "line", + "color": color, + "padding": [15,10,0,15], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "gridType": "dash", + "dashLength": 2, + }, + "legend": { + }, + "extra": { + "line": { + "type": "curve", + "width": 2 + }, + } + }, + //下面是自定义配置,请添加项目所需的通用配置 + "pie":{ + "type": "pie", + "color": color, + "padding": [5,5,5,5], + "extra": { + "pie": { + "activeOpacity": 0.5, + "activeRadius": 10, + "offsetAngle": 0, + "labelWidth": 15, + "border": true, + "borderWidth": 3, + "borderColor": "#FFFFFF" + }, + } + }, + "ring":{ + "type": "ring", + "color": color, + "padding": [5,5,5,5], + "rotate": false, + "dataLabel": true, + "legend": { + "show": true, + "position": "right", + "lineHeight": 25, + }, + "title": { + "name": "收益率", + "fontSize": 15, + "color": "#666666" + }, + "subtitle": { + "name": "70%", + "fontSize": 25, + "color": "#7cb5ec" + }, + "extra": { + "ring": { + "ringWidth":30, + "activeOpacity": 0.5, + "activeRadius": 10, + "offsetAngle": 0, + "labelWidth": 15, + "border": true, + "borderWidth": 3, + "borderColor": "#FFFFFF" + }, + }, + }, + "rose":{ + "type": "rose", + "color": color, + "padding": [5,5,5,5], + "legend": { + "show": true, + "position": "left", + "lineHeight": 25, + }, + "extra": { + "rose": { + "type": "area", + "minRadius": 50, + "activeOpacity": 0.5, + "activeRadius": 10, + "offsetAngle": 0, + "labelWidth": 15, + "border": false, + "borderWidth": 2, + "borderColor": "#FFFFFF" + }, + } + }, + "word":{ + "type": "word", + "color": color, + "extra": { + "word": { + "type": "normal", + "autoColors": false + } + } + }, + "funnel":{ + "type": "funnel", + "color": color, + "padding": [15,15,0,15], + "extra": { + "funnel": { + "activeOpacity": 0.3, + "activeWidth": 10, + "border": true, + "borderWidth": 2, + "borderColor": "#FFFFFF", + "fillOpacity": 1, + "labelAlign": "right" + }, + } + }, + "map":{ + "type": "map", + "color": color, + "padding": [0,0,0,0], + "dataLabel": true, + "extra": { + "map": { + "border": true, + "borderWidth": 1, + "borderColor": "#666666", + "fillOpacity": 0.6, + "activeBorderColor": "#F04864", + "activeFillColor": "#FACC14", + "activeFillOpacity": 1 + }, + } + }, + "arcbar":{ + "type": "arcbar", + "color": color, + "title": { + "name": "百分比", + "fontSize": 25, + "color": "#00FF00" + }, + "subtitle": { + "name": "默认标题", + "fontSize": 15, + "color": "#666666" + }, + "extra": { + "arcbar": { + "type": "default", + "width": 12, + "backgroundColor": "#E9E9E9", + "startAngle": 0.75, + "endAngle": 0.25, + "gap": 2 + } + } + }, + "line":{ + "type": "line", + "color": color, + "padding": [15,10,0,15], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "gridType": "dash", + "dashLength": 2, + }, + "legend": { + }, + "extra": { + "line": { + "type": "straight", + "width": 2, + "activeType": "hollow" + }, + } + }, + "tline":{ + "type": "line", + "color": color, + "padding": [15,10,0,15], + "xAxis": { + "disableGrid": false, + "boundaryGap":"justify", + }, + "yAxis": { + "gridType": "dash", + "dashLength": 2, + "data":[ + { + "min":0, + "max":80 + } + ] + }, + "legend": { + }, + "extra": { + "line": { + "type": "curve", + "width": 2, + "activeType": "hollow" + }, + } + }, + "tarea":{ + "type": "area", + "color": color, + "padding": [15,10,0,15], + "xAxis": { + "disableGrid": true, + "boundaryGap":"justify", + }, + "yAxis": { + "gridType": "dash", + "dashLength": 2, + "data":[ + { + "min":0, + "max":80 + } + ] + }, + "legend": { + }, + "extra": { + "area": { + "type": "curve", + "opacity": 0.2, + "addLine": true, + "width": 2, + "gradient": true, + "activeType": "hollow" + }, + } + }, + "column":{ + "type": "column", + "color": color, + "padding": [15,15,0,5], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "data":[{"min":0}] + }, + "legend": { + }, + "extra": { + "column": { + "type": "group", + "width": 30, + "activeBgColor": "#000000", + "activeBgOpacity": 0.08 + }, + } + }, + "mount":{ + "type": "mount", + "color": color, + "padding": [15,15,0,5], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "data":[{"min":0}] + }, + "legend": { + }, + "extra": { + "mount": { + "type": "mount", + "widthRatio": 1.5, + }, + } + }, + "bar":{ + "type": "bar", + "color": color, + "padding": [15,30,0,5], + "xAxis": { + "boundaryGap":"justify", + "disableGrid":false, + "min":0, + "axisLine":false + }, + "yAxis": { + }, + "legend": { + }, + "extra": { + "bar": { + "type": "group", + "width": 30, + "meterBorde": 1, + "meterFillColor": "#FFFFFF", + "activeBgColor": "#000000", + "activeBgOpacity": 0.08 + }, + } + }, + "area":{ + "type": "area", + "color": color, + "padding": [15,15,0,15], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "gridType": "dash", + "dashLength": 2, + }, + "legend": { + }, + "extra": { + "area": { + "type": "straight", + "opacity": 0.2, + "addLine": true, + "width": 2, + "gradient": false, + "activeType": "hollow" + }, + } + }, + "radar":{ + "type": "radar", + "color": color, + "padding": [5,5,5,5], + "dataLabel": false, + "legend": { + "show": true, + "position": "right", + "lineHeight": 25, + }, + "extra": { + "radar": { + "gridType": "radar", + "gridColor": "#CCCCCC", + "gridCount": 3, + "opacity": 0.2, + "max": 200, + "labelShow": true + }, + } + }, + "gauge":{ + "type": "gauge", + "color": color, + "title": { + "name": "66Km/H", + "fontSize": 25, + "color": "#2fc25b", + "offsetY": 50 + }, + "subtitle": { + "name": "实时速度", + "fontSize": 15, + "color": "#1890ff", + "offsetY": -50 + }, + "extra": { + "gauge": { + "type": "default", + "width": 30, + "labelColor": "#666666", + "startAngle": 0.75, + "endAngle": 0.25, + "startNumber": 0, + "endNumber": 100, + "labelFormat": "", + "splitLine": { + "fixRadius": 0, + "splitNumber": 10, + "width": 30, + "color": "#FFFFFF", + "childNumber": 5, + "childWidth": 12 + }, + "pointer": { + "width": 24, + "color": "auto" + } + } + } + }, + "candle":{ + "type": "candle", + "color": color, + "padding": [15,15,0,15], + "enableScroll": true, + "enableMarkLine": true, + "dataLabel": false, + "xAxis": { + "labelCount": 4, + "itemCount": 40, + "disableGrid": true, + "gridColor": "#CCCCCC", + "gridType": "solid", + "dashLength": 4, + "scrollShow": true, + "scrollAlign": "left", + "scrollColor": "#A6A6A6", + "scrollBackgroundColor": "#EFEBEF" + }, + "yAxis": { + }, + "legend": { + }, + "extra": { + "candle": { + "color": { + "upLine": "#f04864", + "upFill": "#f04864", + "downLine": "#2fc25b", + "downFill": "#2fc25b" + }, + "average": { + "show": true, + "name": ["MA5","MA10","MA30"], + "day": [5,10,20], + "color": ["#1890ff","#2fc25b","#facc14"] + } + }, + "markLine": { + "type": "dash", + "dashLength": 5, + "data": [ + { + "value": 2150, + "lineColor": "#f04864", + "showLabel": true + }, + { + "value": 2350, + "lineColor": "#f04864", + "showLabel": true + } + ] + } + } + }, + "mix":{ + "type": "mix", + "color": color, + "padding": [15,15,0,15], + "xAxis": { + "disableGrid": true, + }, + "yAxis": { + "disabled": false, + "disableGrid": false, + "splitNumber": 5, + "gridType": "dash", + "dashLength": 4, + "gridColor": "#CCCCCC", + "padding": 10, + "showTitle": true, + "data": [] + }, + "legend": { + }, + "extra": { + "mix": { + "column": { + "width": 20 + } + }, + } + }, + "scatter":{ + "type": "scatter", + "color":color, + "padding":[15,15,0,15], + "dataLabel":false, + "xAxis": { + "disableGrid": false, + "gridType":"dash", + "splitNumber":5, + "boundaryGap":"justify", + "min":0 + }, + "yAxis": { + "disableGrid": false, + "gridType":"dash", + }, + "legend": { + }, + "extra": { + "scatter": { + }, + } + }, + "bubble":{ + "type": "bubble", + "color":color, + "padding":[15,15,0,15], + "xAxis": { + "disableGrid": false, + "gridType":"dash", + "splitNumber":5, + "boundaryGap":"justify", + "min":0, + "max":250 + }, + "yAxis": { + "disableGrid": false, + "gridType":"dash", + "data":[{ + "min":0, + "max":150 + }] + }, + "legend": { + }, + "extra": { + "bubble": { + "border":2, + "opacity": 0.5, + }, + } + } +} + +export default cfu; \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md new file mode 100644 index 0000000..d307ba3 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md @@ -0,0 +1,5 @@ +# uCharts JSSDK说明 +1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`120kb`。 +2、如果120kb的体积仍需压缩,请手到uCharts官网通过在线定制选择您需要的图表。 +3、config-ucharts.js为uCharts组件的用户配置文件,升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。 +4、config-echarts.js为ECharts组件的用户配置文件,升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。 \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js new file mode 100644 index 0000000..f78bde5 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js @@ -0,0 +1,7706 @@ +/* + * uCharts (R) + * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台 + * Copyright (C) 2018-2022 QIUN (R) 秋云 https://www.ucharts.cn All rights reserved. + * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) + * 复制使用请保留本段注释,感谢支持开源! + * + * uCharts (R) 官方网站 + * https://www.uCharts.cn + * + * 开源地址: + * https://gitee.com/uCharts/uCharts + * + * uni-app插件市场地址: + * http://ext.dcloud.net.cn/plugin?id=271 + * + */ + +'use strict'; + +var config = { + version: 'v2.5.0-20230101', + yAxisWidth: 15, + xAxisHeight: 22, + padding: [10, 10, 10, 10], + rotate: false, + fontSize: 13, + fontColor: '#666666', + dataPointShape: ['circle', 'circle', 'circle', 'circle'], + color: ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'], + linearColor: ['#0EE2F8', '#2BDCA8', '#FA7D8D', '#EB88E2', '#2AE3A0', '#0EE2F8', '#EB88E2', '#6773E3', '#F78A85'], + pieChartLinePadding: 15, + pieChartTextPadding: 5, + titleFontSize: 20, + subtitleFontSize: 15, + radarLabelTextMargin: 13, +}; + +var assign = function(target, ...varArgs) { + if (target == null) { + throw new TypeError('[uCharts] Cannot convert undefined or null to object'); + } + if (!varArgs || varArgs.length <= 0) { + return target; + } + // 深度合并对象 + function deepAssign(obj1, obj2) { + for (let key in obj2) { + obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ? + deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key]; + } + return obj1; + } + varArgs.forEach(val => { + target = deepAssign(target, val); + }); + return target; +}; + +var util = { + toFixed: function toFixed(num, limit) { + limit = limit || 2; + if (this.isFloat(num)) { + num = num.toFixed(limit); + } + return num; + }, + isFloat: function isFloat(num) { + return num % 1 !== 0; + }, + approximatelyEqual: function approximatelyEqual(num1, num2) { + return Math.abs(num1 - num2) < 1e-10; + }, + isSameSign: function isSameSign(num1, num2) { + return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2; + }, + isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) { + return this.isSameSign(p1.x, p2.x); + }, + isCollision: function isCollision(obj1, obj2) { + obj1.end = {}; + obj1.end.x = obj1.start.x + obj1.width; + obj1.end.y = obj1.start.y - obj1.height; + obj2.end = {}; + obj2.end.x = obj2.start.x + obj2.width; + obj2.end.y = obj2.start.y - obj2.height; + var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y < obj1.end.y; + return !flag; + } +}; + +//兼容H5点击事件 +function getH5Offset(e) { + e.mp = { + changedTouches: [] + }; + e.mp.changedTouches.push({ + x: e.offsetX, + y: e.offsetY + }); + return e; +} + +// hex 转 rgba +function hexToRgb(hexValue, opc) { + var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + var hex = hexValue.replace(rgx, function(m, r, g, b) { + return r + r + g + g + b + b; + }); + var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + var r = parseInt(rgb[1], 16); + var g = parseInt(rgb[2], 16); + var b = parseInt(rgb[3], 16); + return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')'; +} + +function findRange(num, type, limit) { + if (isNaN(num)) { + throw new Error('[uCharts] series数据需为Number格式'); + } + limit = limit || 10; + type = type ? type : 'upper'; + var multiple = 1; + while (limit < 1) { + limit *= 10; + multiple *= 10; + } + if (type === 'upper') { + num = Math.ceil(num * multiple); + } else { + num = Math.floor(num * multiple); + } + while (num % limit !== 0) { + if (type === 'upper') { + if (num == num + 1) { //修复数据值过大num++无效的bug by 向日葵 @xrk_jy + break; + } + num++; + } else { + num--; + } + } + return num / multiple; +} + +function calCandleMA(dayArr, nameArr, colorArr, kdata) { + let seriesTemp = []; + for (let k = 0; k < dayArr.length; k++) { + let seriesItem = { + data: [], + name: nameArr[k], + color: colorArr[k] + }; + for (let i = 0, len = kdata.length; i < len; i++) { + if (i < dayArr[k]) { + seriesItem.data.push(null); + continue; + } + let sum = 0; + for (let j = 0; j < dayArr[k]; j++) { + sum += kdata[i - j][1]; + } + seriesItem.data.push(+(sum / dayArr[k]).toFixed(3)); + } + seriesTemp.push(seriesItem); + } + return seriesTemp; +} + +function calValidDistance(self, distance, chartData, config, opts) { + var dataChartAreaWidth = opts.width - opts.area[1] - opts.area[3]; + var dataChartWidth = chartData.eachSpacing * (opts.chartData.xAxisData.xAxisPoints.length - 1); + if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ + if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 + dataChartWidth += (opts.extra.mount.widthRatio - 1)*chartData.eachSpacing; + } + var validDistance = distance; + if (distance >= 0) { + validDistance = 0; + self.uevent.trigger('scrollLeft'); + self.scrollOption.position = 'left' + opts.xAxis.scrollPosition = 'left'; + } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) { + validDistance = dataChartAreaWidth - dataChartWidth; + self.uevent.trigger('scrollRight'); + self.scrollOption.position = 'right' + opts.xAxis.scrollPosition = 'right'; + } else { + self.scrollOption.position = distance + opts.xAxis.scrollPosition = distance; + } + return validDistance; +} + +function isInAngleRange(angle, startAngle, endAngle) { + function adjust(angle) { + while (angle < 0) { + angle += 2 * Math.PI; + } + while (angle > 2 * Math.PI) { + angle -= 2 * Math.PI; + } + return angle; + } + angle = adjust(angle); + startAngle = adjust(startAngle); + endAngle = adjust(endAngle); + if (startAngle > endAngle) { + endAngle += 2 * Math.PI; + if (angle < startAngle) { + angle += 2 * Math.PI; + } + } + return angle >= startAngle && angle <= endAngle; +} + +function createCurveControlPoints(points, i) { + function isNotMiddlePoint(points, i) { + if (points[i - 1] && points[i + 1]) { + return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y, + points[i + 1].y); + } else { + return false; + } + } + function isNotMiddlePointX(points, i) { + if (points[i - 1] && points[i + 1]) { + return points[i].x >= Math.max(points[i - 1].x, points[i + 1].x) || points[i].x <= Math.min(points[i - 1].x, + points[i + 1].x); + } else { + return false; + } + } + var a = 0.2; + var b = 0.2; + var pAx = null; + var pAy = null; + var pBx = null; + var pBy = null; + if (i < 1) { + pAx = points[0].x + (points[1].x - points[0].x) * a; + pAy = points[0].y + (points[1].y - points[0].y) * a; + } else { + pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a; + pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a; + } + + if (i > points.length - 3) { + var last = points.length - 1; + pBx = points[last].x - (points[last].x - points[last - 1].x) * b; + pBy = points[last].y - (points[last].y - points[last - 1].y) * b; + } else { + pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b; + pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b; + } + if (isNotMiddlePoint(points, i + 1)) { + pBy = points[i + 1].y; + } + if (isNotMiddlePoint(points, i)) { + pAy = points[i].y; + } + if (isNotMiddlePointX(points, i + 1)) { + pBx = points[i + 1].x; + } + if (isNotMiddlePointX(points, i)) { + pAx = points[i].x; + } + if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) { + pAy = points[i].y; + } + if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) { + pBy = points[i + 1].y; + } + if (pAx >= Math.max(points[i].x, points[i + 1].x) || pAx <= Math.min(points[i].x, points[i + 1].x)) { + pAx = points[i].x; + } + if (pBx >= Math.max(points[i].x, points[i + 1].x) || pBx <= Math.min(points[i].x, points[i + 1].x)) { + pBx = points[i + 1].x; + } + return { + ctrA: { + x: pAx, + y: pAy + }, + ctrB: { + x: pBx, + y: pBy + } + }; +} + + +function convertCoordinateOrigin(x, y, center) { + return { + x: center.x + x, + y: center.y - y + }; +} + +function avoidCollision(obj, target) { + if (target) { + // is collision test + while (util.isCollision(obj, target)) { + if (obj.start.x > 0) { + obj.start.y--; + } else if (obj.start.x < 0) { + obj.start.y++; + } else { + if (obj.start.y > 0) { + obj.start.y++; + } else { + obj.start.y--; + } + } + } + } + return obj; +} + +function fixPieSeries(series, opts, config){ + let pieSeriesArr = []; + if(series.length>0 && series[0].data.constructor.toString().indexOf('Array') > -1){ + opts._pieSeries_ = series; + let oldseries = series[0].data; + for (var i = 0; i < oldseries.length; i++) { + oldseries[i].formatter = series[0].formatter; + oldseries[i].data = oldseries[i].value; + pieSeriesArr.push(oldseries[i]); + } + opts.series = pieSeriesArr; + }else{ + pieSeriesArr = series; + } + return pieSeriesArr; +} + +function fillSeries(series, opts, config) { + var index = 0; + for (var i = 0; i < series.length; i++) { + let item = series[i]; + if (!item.color) { + item.color = config.color[index]; + index = (index + 1) % config.color.length; + } + if (!item.linearIndex) { + item.linearIndex = i; + } + if (!item.index) { + item.index = 0; + } + if (!item.type) { + item.type = opts.type; + } + if (typeof item.show == "undefined") { + item.show = true; + } + if (!item.type) { + item.type = opts.type; + } + if (!item.pointShape) { + item.pointShape = "circle"; + } + if (!item.legendShape) { + switch (item.type) { + case 'line': + item.legendShape = "line"; + break; + case 'column': + case 'bar': + item.legendShape = "rect"; + break; + case 'area': + case 'mount': + item.legendShape = "triangle"; + break; + default: + item.legendShape = "circle"; + } + } + } + return series; +} + +function fillCustomColor(linearType, customColor, series, config) { + var newcolor = customColor || []; + if (linearType == 'custom' && newcolor.length == 0 ) { + newcolor = config.linearColor; + } + if (linearType == 'custom' && newcolor.length < series.length) { + let chazhi = series.length - newcolor.length; + for (var i = 0; i < chazhi; i++) { + newcolor.push(config.linearColor[(i + 1) % config.linearColor.length]); + } + } + return newcolor; +} + +function getDataRange(minData, maxData) { + var limit = 0; + var range = maxData - minData; + if (range >= 10000) { + limit = 1000; + } else if (range >= 1000) { + limit = 100; + } else if (range >= 100) { + limit = 10; + } else if (range >= 10) { + limit = 5; + } else if (range >= 1) { + limit = 1; + } else if (range >= 0.1) { + limit = 0.1; + } else if (range >= 0.01) { + limit = 0.01; + } else if (range >= 0.001) { + limit = 0.001; + } else if (range >= 0.0001) { + limit = 0.0001; + } else if (range >= 0.00001) { + limit = 0.00001; + } else { + limit = 0.000001; + } + return { + minRange: findRange(minData, 'lower', limit), + maxRange: findRange(maxData, 'upper', limit) + }; +} + +function measureText(text, fontSize, context) { + var width = 0; + text = String(text); + // #ifdef MP-ALIPAY || MP-BAIDU || APP-NVUE + context = false; + // #endif + if (context !== false && context !== undefined && context.setFontSize && context.measureText) { + context.setFontSize(fontSize); + return context.measureText(text).width; + } else { + var text = text.split(''); + for (let i = 0; i < text.length; i++) { + let item = text[i]; + if (/[a-zA-Z]/.test(item)) { + width += 7; + } else if (/[0-9]/.test(item)) { + width += 5.5; + } else if (/\./.test(item)) { + width += 2.7; + } else if (/-/.test(item)) { + width += 3.25; + } else if (/:/.test(item)) { + width += 2.5; + } else if (/[\u4e00-\u9fa5]/.test(item)) { + width += 10; + } else if (/\(|\)/.test(item)) { + width += 3.73; + } else if (/\s/.test(item)) { + width += 2.5; + } else if (/%/.test(item)) { + width += 8; + } else { + width += 10; + } + } + return width * fontSize / 10; + } +} + +function dataCombine(series) { + return series.reduce(function(a, b) { + return (a.data ? a.data : a).concat(b.data); + }, []); +} + +function dataCombineStack(series, len) { + var sum = new Array(len); + for (var j = 0; j < sum.length; j++) { + sum[j] = 0; + } + for (var i = 0; i < series.length; i++) { + for (var j = 0; j < sum.length; j++) { + sum[j] += series[i].data[j]; + } + } + return series.reduce(function(a, b) { + return (a.data ? a.data : a).concat(b.data).concat(sum); + }, []); +} + +function getTouches(touches, opts, e) { + let x, y; + if (touches.clientX) { + if (opts.rotate) { + y = opts.height - touches.clientX * opts.pix; + x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix; + } else { + x = touches.clientX * opts.pix; + y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix; + } + } else { + if (opts.rotate) { + y = opts.height - touches.x * opts.pix; + x = touches.y * opts.pix; + } else { + x = touches.x * opts.pix; + y = touches.y * opts.pix; + } + } + return { + x: x, + y: y + } +} + +function getSeriesDataItem(series, index, group) { + var data = []; + var newSeries = []; + var indexIsArr = index.constructor.toString().indexOf('Array') > -1; + if(indexIsArr){ + let tempSeries = filterSeries(series); + for (var i = 0; i < group.length; i++) { + newSeries.push(tempSeries[group[i]]); + } + }else{ + newSeries = series; + }; + for (let i = 0; i < newSeries.length; i++) { + let item = newSeries[i]; + let tmpindex = -1; + if(indexIsArr){ + tmpindex = index[i]; + }else{ + tmpindex = index; + } + if (item.data[tmpindex] !== null && typeof item.data[tmpindex] !== 'undefined' && item.show) { + let seriesItem = {}; + seriesItem.color = item.color; + seriesItem.type = item.type; + seriesItem.style = item.style; + seriesItem.pointShape = item.pointShape; + seriesItem.disableLegend = item.disableLegend; + seriesItem.legendShape = item.legendShape; + seriesItem.name = item.name; + seriesItem.show = item.show; + seriesItem.data = item.formatter ? item.formatter(item.data[tmpindex]) : item.data[tmpindex]; + data.push(seriesItem); + } + } + return data; +} + +function getMaxTextListLength(list, fontSize, context) { + var lengthList = list.map(function(item) { + return measureText(item, fontSize, context); + }); + return Math.max.apply(null, lengthList); +} + +function getRadarCoordinateSeries(length) { + var eachAngle = 2 * Math.PI / length; + var CoordinateSeries = []; + for (var i = 0; i < length; i++) { + CoordinateSeries.push(eachAngle * i); + } + return CoordinateSeries.map(function(item) { + return -1 * item + Math.PI / 2; + }); +} + +function getToolTipData(seriesData, opts, index, group, categories) { + var option = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + var calPoints = opts.chartData.calPoints?opts.chartData.calPoints:[]; + let points = {}; + if(group.length > 0){ + let filterPoints = []; + for (let i = 0; i < group.length; i++) { + filterPoints.push(calPoints[group[i]]) + } + points = filterPoints[0][index[0]]; + }else{ + for (let i = 0; i < calPoints.length; i++) { + if(calPoints[i][index]){ + points = calPoints[i][index]; + break; + } + } + }; + var textList = seriesData.map(function(item) { + let titleText = null; + if (opts.categories && opts.categories.length>0) { + titleText = categories[index]; + }; + return { + text: option.formatter ? option.formatter(item, titleText, index, opts) : item.name + ': ' + item.data, + color: item.color, + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + }); + var offset = { + x: Math.round(points.x), + y: Math.round(points.y) + }; + return { + textList: textList, + offset: offset + }; +} + +function getMixToolTipData(seriesData, opts, index, categories) { + var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + var points = opts.chartData.xAxisPoints[index] + opts.chartData.eachSpacing / 2; + var textList = seriesData.map(function(item) { + return { + text: option.formatter ? option.formatter(item, categories[index], index, opts) : item.name + ': ' + item.data, + color: item.color, + disableLegend: item.disableLegend ? true : false, + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + }); + textList = textList.filter(function(item) { + if (item.disableLegend !== true) { + return item; + } + }); + var offset = { + x: Math.round(points), + y: 0 + }; + return { + textList: textList, + offset: offset + }; +} + +function getCandleToolTipData(series, seriesData, opts, index, categories, extra) { + var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {}; + var calPoints = opts.chartData.calPoints; + let upColor = extra.color.upFill; + let downColor = extra.color.downFill; + //颜色顺序为开盘,收盘,最低,最高 + let color = [upColor, upColor, downColor, upColor]; + var textList = []; + seriesData.map(function(item) { + if (index == 0) { + if (item.data[1] - item.data[0] < 0) { + color[1] = downColor; + } else { + color[1] = upColor; + } + } else { + if (item.data[0] < series[index - 1][1]) { + color[0] = downColor; + } + if (item.data[1] < item.data[0]) { + color[1] = downColor; + } + if (item.data[2] > series[index - 1][1]) { + color[2] = upColor; + } + if (item.data[3] < series[index - 1][1]) { + color[3] = downColor; + } + } + let text1 = { + text: '开盘:' + item.data[0], + color: color[0], + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + let text2 = { + text: '收盘:' + item.data[1], + color: color[1], + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + let text3 = { + text: '最低:' + item.data[2], + color: color[2], + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + let text4 = { + text: '最高:' + item.data[3], + color: color[3], + legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape + }; + textList.push(text1, text2, text3, text4); + }); + var validCalPoints = []; + var offset = { + x: 0, + y: 0 + }; + for (let i = 0; i < calPoints.length; i++) { + let points = calPoints[i]; + if (typeof points[index] !== 'undefined' && points[index] !== null) { + validCalPoints.push(points[index]); + } + } + offset.x = Math.round(validCalPoints[0][0].x); + return { + textList: textList, + offset: offset + }; +} + +function filterSeries(series) { + let tempSeries = []; + for (let i = 0; i < series.length; i++) { + if (series[i].show == true) { + tempSeries.push(series[i]) + } + } + return tempSeries; +} + +function findCurrentIndex(currentPoints, calPoints, opts, config) { + var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; + var current={ index:-1, group:[] }; + var spacing = opts.chartData.eachSpacing / 2; + let xAxisPoints = []; + if (calPoints && calPoints.length > 0) { + if (!opts.categories) { + spacing = 0; + }else{ + for (let i = 1; i < opts.chartData.xAxisPoints.length; i++) { + xAxisPoints.push(opts.chartData.xAxisPoints[i] - spacing); + } + if ((opts.type == 'line' || opts.type == 'area') && opts.xAxis.boundaryGap == 'justify') { + xAxisPoints = opts.chartData.xAxisPoints; + } + } + if (isInExactChartArea(currentPoints, opts, config)) { + if (!opts.categories) { + let timePoints = Array(calPoints.length); + for (let i = 0; i < calPoints.length; i++) { + timePoints[i] = Array(calPoints[i].length) + for (let j = 0; j < calPoints[i].length; j++) { + timePoints[i][j] = (Math.abs(calPoints[i][j].x - currentPoints.x)); + } + }; + let pointValue = Array(timePoints.length); + let pointIndex = Array(timePoints.length); + for (let i = 0; i < timePoints.length; i++) { + pointValue[i] = Math.min.apply(null, timePoints[i]); + pointIndex[i] = timePoints[i].indexOf(pointValue[i]); + } + let minValue = Math.min.apply(null, pointValue); + current.index = []; + for (let i = 0; i < pointValue.length; i++) { + if(pointValue[i] == minValue){ + current.group.push(i); + current.index.push(pointIndex[i]); + } + }; + }else{ + xAxisPoints.forEach(function(item, index) { + if (currentPoints.x + offset + spacing > item) { + current.index = index; + } + }); + } + } + } + return current; +} + +function findBarChartCurrentIndex(currentPoints, calPoints, opts, config) { + var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; + var current={ index:-1, group:[] }; + var spacing = opts.chartData.eachSpacing / 2; + let yAxisPoints = opts.chartData.yAxisPoints; + if (calPoints && calPoints.length > 0) { + if (isInExactChartArea(currentPoints, opts, config)) { + yAxisPoints.forEach(function(item, index) { + if (currentPoints.y + offset + spacing > item) { + current.index = index; + } + }); + } + } + return current; +} + +function findLegendIndex(currentPoints, legendData, opts) { + let currentIndex = -1; + let gap = 0; + if (isInExactLegendArea(currentPoints, legendData.area)) { + let points = legendData.points; + let index = -1; + for (let i = 0, len = points.length; i < len; i++) { + let item = points[i]; + for (let j = 0; j < item.length; j++) { + index += 1; + let area = item[j]['area']; + if (area && currentPoints.x > area[0] - gap && currentPoints.x < area[2] + gap && currentPoints.y > area[1] - gap && currentPoints.y < area[3] + gap) { + currentIndex = index; + break; + } + } + } + return currentIndex; + } + return currentIndex; +} + +function isInExactLegendArea(currentPoints, area) { + return currentPoints.x > area.start.x && currentPoints.x < area.end.x && currentPoints.y > area.start.y && currentPoints.y < area.end.y; +} + +function isInExactChartArea(currentPoints, opts, config) { + return currentPoints.x <= opts.width - opts.area[1] + 10 && currentPoints.x >= opts.area[3] - 10 && currentPoints.y >= opts.area[0] && currentPoints.y <= opts.height - opts.area[2]; +} + +function findRadarChartCurrentIndex(currentPoints, radarData, count) { + var eachAngleArea = 2 * Math.PI / count; + var currentIndex = -1; + if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) { + var fixAngle = function fixAngle(angle) { + if (angle < 0) { + angle += 2 * Math.PI; + } + if (angle > 2 * Math.PI) { + angle -= 2 * Math.PI; + } + return angle; + }; + var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x); + angle = -1 * angle; + if (angle < 0) { + angle += 2 * Math.PI; + } + var angleList = radarData.angleList.map(function(item) { + item = fixAngle(-1 * item); + return item; + }); + angleList.forEach(function(item, index) { + var rangeStart = fixAngle(item - eachAngleArea / 2); + var rangeEnd = fixAngle(item + eachAngleArea / 2); + if (rangeEnd < rangeStart) { + rangeEnd += 2 * Math.PI; + } + if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <= rangeEnd) { + currentIndex = index; + } + }); + } + return currentIndex; +} + +function findFunnelChartCurrentIndex(currentPoints, funnelData) { + var currentIndex = -1; + for (var i = 0, len = funnelData.series.length; i < len; i++) { + var item = funnelData.series[i]; + if (currentPoints.x > item.funnelArea[0] && currentPoints.x < item.funnelArea[2] && currentPoints.y > item.funnelArea[1] && currentPoints.y < item.funnelArea[3]) { + currentIndex = i; + break; + } + } + return currentIndex; +} + +function findWordChartCurrentIndex(currentPoints, wordData) { + var currentIndex = -1; + for (var i = 0, len = wordData.length; i < len; i++) { + var item = wordData[i]; + if (currentPoints.x > item.area[0] && currentPoints.x < item.area[2] && currentPoints.y > item.area[1] && currentPoints.y < item.area[3]) { + currentIndex = i; + break; + } + } + return currentIndex; +} + +function findMapChartCurrentIndex(currentPoints, opts) { + var currentIndex = -1; + var cData = opts.chartData.mapData; + var data = opts.series; + var tmp = pointToCoordinate(currentPoints.y, currentPoints.x, cData.bounds, cData.scale, cData.xoffset, cData.yoffset); + var poi = [tmp.x, tmp.y]; + for (var i = 0, len = data.length; i < len; i++) { + var item = data[i].geometry.coordinates; + if (isPoiWithinPoly(poi, item, opts.chartData.mapData.mercator)) { + currentIndex = i; + break; + } + } + return currentIndex; +} + +function findRoseChartCurrentIndex(currentPoints, pieData, opts) { + var currentIndex = -1; + var series = getRoseDataPoints(opts._series_, opts.extra.rose.type, pieData.radius, pieData.radius); + if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) { + var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x); + angle = -angle; + if(opts.extra.rose && opts.extra.rose.offsetAngle){ + angle = angle - opts.extra.rose.offsetAngle * Math.PI / 180; + } + for (var i = 0, len = series.length; i < len; i++) { + if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._rose_proportion_ * 2 * Math.PI)) { + currentIndex = i; + break; + } + } + } + return currentIndex; +} + +function findPieChartCurrentIndex(currentPoints, pieData, opts) { + var currentIndex = -1; + var series = getPieDataPoints(pieData.series); + if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) { + var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x); + angle = -angle; + if(opts.extra.pie && opts.extra.pie.offsetAngle){ + angle = angle - opts.extra.pie.offsetAngle * Math.PI / 180; + } + if(opts.extra.ring && opts.extra.ring.offsetAngle){ + angle = angle - opts.extra.ring.offsetAngle * Math.PI / 180; + } + for (var i = 0, len = series.length; i < len; i++) { + if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._proportion_ * 2 * Math.PI)) { + currentIndex = i; + break; + } + } + } + return currentIndex; +} + +function isInExactPieChartArea(currentPoints, center, radius) { + return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2); +} + + +function splitPoints(points,eachSeries) { + var newPoints = []; + var items = []; + points.forEach(function(item, index) { + if(eachSeries.connectNulls){ + if (item !== null) { + items.push(item); + } + }else{ + if (item !== null) { + items.push(item); + } else { + if (items.length) { + newPoints.push(items); + } + items = []; + } + } + + }); + if (items.length) { + newPoints.push(items); + } + return newPoints; +} + + +function calLegendData(series, opts, config, chartData, context) { + let legendData = { + area: { + start: { + x: 0, + y: 0 + }, + end: { + x: 0, + y: 0 + }, + width: 0, + height: 0, + wholeWidth: 0, + wholeHeight: 0 + }, + points: [], + widthArr: [], + heightArr: [] + }; + if (opts.legend.show === false) { + chartData.legendData = legendData; + return legendData; + } + let padding = opts.legend.padding * opts.pix; + let margin = opts.legend.margin * opts.pix; + let fontSize = opts.legend.fontSize ? opts.legend.fontSize * opts.pix : config.fontSize; + let shapeWidth = 15 * opts.pix; + let shapeRight = 5 * opts.pix; + let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize); + if (opts.legend.position == 'top' || opts.legend.position == 'bottom') { + let legendList = []; + let widthCount = 0; + let widthCountArr = []; + let currentRow = []; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + const legendText = item.legendText ? item.legendText : item.name; + let itemWidth = shapeWidth + shapeRight + measureText(legendText || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix; + if (widthCount + itemWidth > opts.width - opts.area[1] - opts.area[3]) { + legendList.push(currentRow); + widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix); + widthCount = itemWidth; + currentRow = [item]; + } else { + widthCount += itemWidth; + currentRow.push(item); + } + } + if (currentRow.length) { + legendList.push(currentRow); + widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix); + legendData.widthArr = widthCountArr; + let legendWidth = Math.max.apply(null, widthCountArr); + switch (opts.legend.float) { + case 'left': + legendData.area.start.x = opts.area[3]; + legendData.area.end.x = opts.area[3] + legendWidth + 2 * padding; + break; + case 'right': + legendData.area.start.x = opts.width - opts.area[1] - legendWidth - 2 * padding; + legendData.area.end.x = opts.width - opts.area[1]; + break; + default: + legendData.area.start.x = (opts.width - legendWidth) / 2 - padding; + legendData.area.end.x = (opts.width + legendWidth) / 2 + padding; + } + legendData.area.width = legendWidth + 2 * padding; + legendData.area.wholeWidth = legendWidth + 2 * padding; + legendData.area.height = legendList.length * lineHeight + 2 * padding; + legendData.area.wholeHeight = legendList.length * lineHeight + 2 * padding + 2 * margin; + legendData.points = legendList; + } + } else { + let len = series.length; + let maxHeight = opts.height - opts.area[0] - opts.area[2] - 2 * margin - 2 * padding; + let maxLength = Math.min(Math.floor(maxHeight / lineHeight), len); + legendData.area.height = maxLength * lineHeight + padding * 2; + legendData.area.wholeHeight = maxLength * lineHeight + padding * 2; + switch (opts.legend.float) { + case 'top': + legendData.area.start.y = opts.area[0] + margin; + legendData.area.end.y = opts.area[0] + margin + legendData.area.height; + break; + case 'bottom': + legendData.area.start.y = opts.height - opts.area[2] - margin - legendData.area.height; + legendData.area.end.y = opts.height - opts.area[2] - margin; + break; + default: + legendData.area.start.y = (opts.height - legendData.area.height) / 2; + legendData.area.end.y = (opts.height + legendData.area.height) / 2; + } + let lineNum = len % maxLength === 0 ? len / maxLength : Math.floor((len / maxLength) + 1); + let currentRow = []; + for (let i = 0; i < lineNum; i++) { + let temp = series.slice(i * maxLength, i * maxLength + maxLength); + currentRow.push(temp); + } + legendData.points = currentRow; + if (currentRow.length) { + for (let i = 0; i < currentRow.length; i++) { + let item = currentRow[i]; + let maxWidth = 0; + for (let j = 0; j < item.length; j++) { + let itemWidth = shapeWidth + shapeRight + measureText(item[j].name || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix; + if (itemWidth > maxWidth) { + maxWidth = itemWidth; + } + } + legendData.widthArr.push(maxWidth); + legendData.heightArr.push(item.length * lineHeight + padding * 2); + } + let legendWidth = 0 + for (let i = 0; i < legendData.widthArr.length; i++) { + legendWidth += legendData.widthArr[i]; + } + legendData.area.width = legendWidth - opts.legend.itemGap * opts.pix + 2 * padding; + legendData.area.wholeWidth = legendData.area.width + padding; + } + } + switch (opts.legend.position) { + case 'top': + legendData.area.start.y = opts.area[0] + margin; + legendData.area.end.y = opts.area[0] + margin + legendData.area.height; + break; + case 'bottom': + legendData.area.start.y = opts.height - opts.area[2] - legendData.area.height - margin; + legendData.area.end.y = opts.height - opts.area[2] - margin; + break; + case 'left': + legendData.area.start.x = opts.area[3]; + legendData.area.end.x = opts.area[3] + legendData.area.width; + break; + case 'right': + legendData.area.start.x = opts.width - opts.area[1] - legendData.area.width; + legendData.area.end.x = opts.width - opts.area[1]; + break; + } + chartData.legendData = legendData; + return legendData; +} + +function calCategoriesData(categories, opts, config, eachSpacing, context) { + var result = { + angle: 0, + xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix + }; + var fontSize = opts.xAxis.fontSize * opts.pix; + var categoriesTextLenth = categories.map(function(item,index) { + var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item; + return measureText(String(xitem), fontSize, context); + }); + var maxTextLength = Math.max.apply(this, categoriesTextLenth); + if (opts.xAxis.rotateLabel == true) { + result.angle = opts.xAxis.rotateAngle * Math.PI / 180; + let tempHeight = opts.xAxis.marginTop * opts.pix * 2 + Math.abs(maxTextLength * Math.sin(result.angle)) + tempHeight = tempHeight < fontSize + opts.xAxis.marginTop * opts.pix * 2 ? tempHeight + opts.xAxis.marginTop * opts.pix * 2 : tempHeight; + result.xAxisHeight = tempHeight; + } + if (opts.enableScroll && opts.xAxis.scrollShow) { + result.xAxisHeight += 6 * opts.pix; + } + if (opts.xAxis.disabled){ + result.xAxisHeight = 0; + } + return result; +} + +function getXAxisTextList(series, opts, config, stack) { + var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1; + var data; + if (stack == 'stack') { + data = dataCombineStack(series, opts.categories.length); + } else { + data = dataCombine(series); + } + var sorted = []; + // remove null from data + data = data.filter(function(item) { + //return item !== null; + if (typeof item === 'object' && item !== null) { + if (item.constructor.toString().indexOf('Array') > -1) { + return item !== null; + } else { + return item.value !== null; + } + } else { + return item !== null; + } + }); + data.map(function(item) { + if (typeof item === 'object') { + if (item.constructor.toString().indexOf('Array') > -1) { + if (opts.type == 'candle') { + item.map(function(subitem) { + sorted.push(subitem); + }) + } else { + sorted.push(item[0]); + } + } else { + sorted.push(item.value); + } + } else { + sorted.push(item); + } + }) + + var minData = 0; + var maxData = 0; + if (sorted.length > 0) { + minData = Math.min.apply(this, sorted); + maxData = Math.max.apply(this, sorted); + } + //为了兼容v1.9.0之前的项目 + if (index > -1) { + if (typeof opts.xAxis.data[index].min === 'number') { + minData = Math.min(opts.xAxis.data[index].min, minData); + } + if (typeof opts.xAxis.data[index].max === 'number') { + maxData = Math.max(opts.xAxis.data[index].max, maxData); + } + } else { + if (typeof opts.xAxis.min === 'number') { + minData = Math.min(opts.xAxis.min, minData); + } + if (typeof opts.xAxis.max === 'number') { + maxData = Math.max(opts.xAxis.max, maxData); + } + } + if (minData === maxData) { + var rangeSpan = maxData || 10; + maxData += rangeSpan; + } + //var dataRange = getDataRange(minData, maxData); + var minRange = minData; + var maxRange = maxData; + var range = []; + var eachRange = (maxRange - minRange) / opts.xAxis.splitNumber; + for (var i = 0; i <= opts.xAxis.splitNumber; i++) { + range.push(minRange + eachRange * i); + } + return range; +} + +function calXAxisData(series, opts, config, context) { + //堆叠图重算Y轴 + var columnstyle = assign({}, { + type: "" + }, opts.extra.bar); + var result = { + angle: 0, + xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix + }; + result.ranges = getXAxisTextList(series, opts, config, columnstyle.type); + result.rangesFormat = result.ranges.map(function(item) { + //item = opts.xAxis.formatter ? opts.xAxis.formatter(item) : util.toFixed(item, 2); + item = util.toFixed(item, 2); + return item; + }); + var xAxisScaleValues = result.ranges.map(function(item) { + // 如果刻度值是浮点数,则保留两位小数 + item = util.toFixed(item, 2); + // 若有自定义格式则调用自定义的格式化函数 + //item = opts.xAxis.formatter ? opts.xAxis.formatter(Number(item)) : item; + return item; + }); + result = Object.assign(result, getXAxisPoints(xAxisScaleValues, opts, config)); + // 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长 + var eachSpacing = result.eachSpacing; + var textLength = xAxisScaleValues.map(function(item) { + return measureText(item, opts.xAxis.fontSize * opts.pix, context); + }); + if (opts.xAxis.disabled === true) { + result.xAxisHeight = 0; + } + return result; +} + +function getRadarDataPoints(angleList, center, radius, series, opts) { + var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1; + var radarOption = opts.extra.radar || {}; + radarOption.max = radarOption.max || 0; + var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series))); + var data = []; + for (let i = 0; i < series.length; i++) { + let each = series[i]; + let listItem = {}; + listItem.color = each.color; + listItem.legendShape = each.legendShape; + listItem.pointShape = each.pointShape; + listItem.data = []; + each.data.forEach(function(item, index) { + let tmp = {}; + tmp.angle = angleList[index]; + tmp.proportion = item / maxData; + tmp.value = item; + tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion * process * Math.sin(tmp.angle), center); + listItem.data.push(tmp); + }); + data.push(listItem); + } + return data; +} + +function getPieDataPoints(series, radius) { + var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var count = 0; + var _start_ = 0; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + count += item.data; + } + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + if (count === 0) { + item._proportion_ = 1 / series.length * process; + } else { + item._proportion_ = item.data / count * process; + } + item._radius_ = radius; + } + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item._start_ = _start_; + _start_ += 2 * item._proportion_ * Math.PI; + } + return series; +} + +function getFunnelDataPoints(series, radius, option, eachSpacing) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + for (let i = 0; i < series.length; i++) { + if(option.type == 'funnel'){ + series[i].radius = series[i].data / series[0].data * radius * process; + }else{ + series[i].radius = (eachSpacing * (series.length - i)) / (eachSpacing * series.length) * radius * process; + } + series[i]._proportion_ = series[i].data / series[0].data; + } + // if(option.type !== 'pyramid'){ + // series.reverse(); + // } + return series; +} + +function getRoseDataPoints(series, type, minRadius, radius) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var count = 0; + var _start_ = 0; + var dataArr = []; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + count += item.data; + dataArr.push(item.data); + } + var minData = Math.min.apply(null, dataArr); + var maxData = Math.max.apply(null, dataArr); + var radiusLength = radius - minRadius; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + if (count === 0) { + item._proportion_ = 1 / series.length * process; + item._rose_proportion_ = 1 / series.length * process; + } else { + item._proportion_ = item.data / count * process; + if(type == 'area'){ + item._rose_proportion_ = 1 / series.length * process; + }else{ + item._rose_proportion_ = item.data / count * process; + } + } + item._radius_ = minRadius + radiusLength * ((item.data - minData) / (maxData - minData)) || radius; + } + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item._start_ = _start_; + _start_ += 2 * item._rose_proportion_ * Math.PI; + } + return series; +} + +function getArcbarDataPoints(series, arcbarOption) { + var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + if (process == 1) { + process = 0.999999; + } + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + let totalAngle; + if (arcbarOption.type == 'circle') { + totalAngle = 2; + } else { + if(arcbarOption.direction == 'ccw'){ + if (arcbarOption.startAngle < arcbarOption.endAngle) { + totalAngle = 2 + arcbarOption.startAngle - arcbarOption.endAngle; + } else { + totalAngle = arcbarOption.startAngle - arcbarOption.endAngle; + } + }else{ + if (arcbarOption.endAngle < arcbarOption.startAngle) { + totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle; + } else { + totalAngle = arcbarOption.startAngle - arcbarOption.endAngle; + } + } + } + item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle; + if(arcbarOption.direction == 'ccw'){ + item._proportion_ = arcbarOption.startAngle - totalAngle * item.data * process ; + } + if (item._proportion_ >= 2) { + item._proportion_ = item._proportion_ % 2; + } + } + return series; +} + +function getGaugeArcbarDataPoints(series, arcbarOption) { + var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + if (process == 1) { + process = 0.999999; + } + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + let totalAngle; + if (arcbarOption.type == 'circle') { + totalAngle = 2; + } else { + if (arcbarOption.endAngle < arcbarOption.startAngle) { + totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle; + } else { + totalAngle = arcbarOption.startAngle - arcbarOption.endAngle; + } + } + item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle; + if (item._proportion_ >= 2) { + item._proportion_ = item._proportion_ % 2; + } + } + return series; +} + +function getGaugeAxisPoints(categories, startAngle, endAngle) { + let totalAngle; + if (endAngle < startAngle) { + totalAngle = 2 + endAngle - startAngle; + } else { + totalAngle = startAngle - endAngle; + } + let tempStartAngle = startAngle; + for (let i = 0; i < categories.length; i++) { + categories[i].value = categories[i].value === null ? 0 : categories[i].value; + categories[i]._startAngle_ = tempStartAngle; + categories[i]._endAngle_ = totalAngle * categories[i].value + startAngle; + if (categories[i]._endAngle_ >= 2) { + categories[i]._endAngle_ = categories[i]._endAngle_ % 2; + } + tempStartAngle = categories[i]._endAngle_; + } + return categories; +} + +function getGaugeDataPoints(series, categories, gaugeOption) { + let process = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + item.data = item.data === null ? 0 : item.data; + if (gaugeOption.pointer.color == 'auto') { + for (let i = 0; i < categories.length; i++) { + if (item.data <= categories[i].value) { + item.color = categories[i].color; + break; + } + } + } else { + item.color = gaugeOption.pointer.color; + } + let totalAngle; + if (gaugeOption.endAngle < gaugeOption.startAngle) { + totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; + } else { + totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; + } + item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle; + item._oldAngle_ = gaugeOption.oldAngle; + if (gaugeOption.oldAngle < gaugeOption.endAngle) { + item._oldAngle_ += 2; + } + if (item.data >= gaugeOption.oldData) { + item._proportion_ = (item._endAngle_ - item._oldAngle_) * process + gaugeOption.oldAngle; + } else { + item._proportion_ = item._oldAngle_ - (item._oldAngle_ - item._endAngle_) * process; + } + if (item._proportion_ >= 2) { + item._proportion_ = item._proportion_ % 2; + } + } + return series; +} + +function getPieTextMaxLength(series, config, context, opts) { + series = getPieDataPoints(series); + let maxLength = 0; + for (let i = 0; i < series.length; i++) { + let item = series[i]; + let text = item.formatter ? item.formatter(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%'; + maxLength = Math.max(maxLength, measureText(text, item.textSize * opts.pix || config.fontSize, context)); + } + return maxLength; +} + +function fixColumeData(points, eachSpacing, columnLen, index, config, opts) { + return points.map(function(item) { + if (item === null) { + return null; + } + var seriesGap = 0; + var categoryGap = 0; + if (opts.type == 'mix') { + seriesGap = opts.extra.mix.column.seriesGap * opts.pix || 0; + categoryGap = opts.extra.mix.column.categoryGap * opts.pix || 0; + } else { + seriesGap = opts.extra.column.seriesGap * opts.pix || 0; + categoryGap = opts.extra.column.categoryGap * opts.pix || 0; + } + seriesGap = Math.min(seriesGap, eachSpacing / columnLen) + categoryGap = Math.min(categoryGap, eachSpacing / columnLen) + item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen); + if (opts.extra.mix && opts.extra.mix.column.width && +opts.extra.mix.column.width > 0) { + item.width = Math.min(item.width, +opts.extra.mix.column.width * opts.pix); + } + if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) { + item.width = Math.min(item.width, +opts.extra.column.width * opts.pix); + } + if (item.width <= 0) { + item.width = 1; + } + item.x += (index + 0.5 - columnLen / 2) * (item.width + seriesGap); + return item; + }); +} + +function fixBarData(points, eachSpacing, columnLen, index, config, opts) { + return points.map(function(item) { + if (item === null) { + return null; + } + var seriesGap = 0; + var categoryGap = 0; + seriesGap = opts.extra.bar.seriesGap * opts.pix || 0; + categoryGap = opts.extra.bar.categoryGap * opts.pix || 0; + seriesGap = Math.min(seriesGap, eachSpacing / columnLen) + categoryGap = Math.min(categoryGap, eachSpacing / columnLen) + item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen); + if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) { + item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix); + } + if (item.width <= 0) { + item.width = 1; + } + item.y += (index + 0.5 - columnLen / 2) * (item.width + seriesGap); + return item; + }); +} + +function fixColumeMeterData(points, eachSpacing, columnLen, index, config, opts, border) { + var categoryGap = opts.extra.column.categoryGap * opts.pix || 0; + return points.map(function(item) { + if (item === null) { + return null; + } + item.width = eachSpacing - 2 * categoryGap; + if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) { + item.width = Math.min(item.width, +opts.extra.column.width * opts.pix); + } + if (index > 0) { + item.width -= border; + } + return item; + }); +} + +function fixColumeStackData(points, eachSpacing, columnLen, index, config, opts, series) { + var categoryGap = opts.extra.column.categoryGap * opts.pix || 0; + return points.map(function(item, indexn) { + if (item === null) { + return null; + } + item.width = Math.ceil(eachSpacing - 2 * categoryGap); + if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) { + item.width = Math.min(item.width, +opts.extra.column.width * opts.pix); + } + if (item.width <= 0) { + item.width = 1; + } + return item; + }); +} + +function fixBarStackData(points, eachSpacing, columnLen, index, config, opts, series) { + var categoryGap = opts.extra.bar.categoryGap * opts.pix || 0; + return points.map(function(item, indexn) { + if (item === null) { + return null; + } + item.width = Math.ceil(eachSpacing - 2 * categoryGap); + if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) { + item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix); + } + if (item.width <= 0) { + item.width = 1; + } + return item; + }); +} + +function getXAxisPoints(categories, opts, config) { + var spacingValid = opts.width - opts.area[1] - opts.area[3]; + var dataCount = opts.enableScroll ? Math.min(opts.xAxis.itemCount, categories.length) : categories.length; + if ((opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' || opts.type == 'bar') && dataCount > 1 && opts.xAxis.boundaryGap == 'justify') { + dataCount -= 1; + } + var widthRatio = 0; + if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ + if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 + widthRatio = opts.extra.mount.widthRatio - 1; + dataCount += widthRatio; + } + var eachSpacing = spacingValid / dataCount; + var xAxisPoints = []; + var startX = opts.area[3]; + var endX = opts.width - opts.area[1]; + categories.forEach(function(item, index) { + xAxisPoints.push(startX + widthRatio / 2 * eachSpacing + index * eachSpacing); + }); + if (opts.xAxis.boundaryGap !== 'justify') { + if (opts.enableScroll === true) { + xAxisPoints.push(startX + widthRatio * eachSpacing + categories.length * eachSpacing); + } else { + xAxisPoints.push(endX); + } + } + return { + xAxisPoints: xAxisPoints, + startX: startX, + endX: endX, + eachSpacing: eachSpacing + }; +} + +function getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) { + var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var cPoints = []; + item.forEach(function(items, indexs) { + var point = {}; + point.x = xAxisPoints[index] + Math.round(eachSpacing / 2); + var value = items.value || items; + var height = validHeight * (value - minRange) / (maxRange - minRange); + height *= process; + point.y = opts.height - Math.round(height) - opts.area[2]; + cPoints.push(point); + }); + points.push(cPoints); + } + }); + return points; +} + +function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) { + var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; + var boundaryGap = 'center'; + if (opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' ) { + boundaryGap = opts.xAxis.boundaryGap; + } + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + var validWidth = opts.width - opts.area[1] - opts.area[3]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.x = xAxisPoints[index]; + var value = item; + if (typeof item === 'object' && item !== null) { + if (item.constructor.toString().indexOf('Array') > -1) { + let xranges, xminRange, xmaxRange; + xranges = [].concat(opts.chartData.xAxisData.ranges); + xminRange = xranges.shift(); + xmaxRange = xranges.pop(); + value = item[1]; + point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange); + if(opts.type == 'bubble'){ + point.r = item[2]; + point.t = item[3]; + } + } else { + value = item.value; + } + } + if (boundaryGap == 'center') { + point.x += eachSpacing / 2; + } + var height = validHeight * (value - minRange) / (maxRange - minRange); + height *= process; + point.y = opts.height - height - opts.area[2]; + points.push(point); + } + }); + return points; +} + +function getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process){ + var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; + var boundaryGap = opts.xAxis.boundaryGap; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + var validWidth = opts.width - opts.area[1] - opts.area[3]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + if(lineOption.animation == 'vertical'){ + point.x = xAxisPoints[index]; + var value = item; + if (typeof item === 'object' && item !== null) { + if (item.constructor.toString().indexOf('Array') > -1) { + let xranges, xminRange, xmaxRange; + xranges = [].concat(opts.chartData.xAxisData.ranges); + xminRange = xranges.shift(); + xmaxRange = xranges.pop(); + value = item[1]; + point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange); + } else { + value = item.value; + } + } + if (boundaryGap == 'center') { + point.x += eachSpacing / 2; + } + var height = validHeight * (value - minRange) / (maxRange - minRange); + height *= process; + point.y = opts.height - height - opts.area[2]; + points.push(point); + }else{ + point.x = xAxisPoints[0] + eachSpacing * index * process; + var value = item; + if (boundaryGap == 'center') { + point.x += eachSpacing / 2; + } + var height = validHeight * (value - minRange) / (maxRange - minRange); + point.y = opts.height - height - opts.area[2]; + points.push(point); + } + } + }); + return points; +} + +function getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process){ + var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + var validWidth = opts.width - opts.area[1] - opts.area[3]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.x = xAxisPoints[index]; + var value = item; + if (typeof item === 'object' && item !== null) { + if (item.constructor.toString().indexOf('Array') > -1) { + let xranges, xminRange, xmaxRange; + xranges = [].concat(opts.chartData.xAxisData.ranges); + xminRange = xranges.shift(); + xmaxRange = xranges.pop(); + value = item[1]; + point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange); + } else { + value = item.value; + } + } + point.x += eachSpacing / 2; + var height = validHeight * (value * process - minRange) / (maxRange - minRange); + point.y = opts.height - height - opts.area[2]; + points.push(point); + } + }); + return points; +} + +function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints) { + var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + var validWidth = opts.width - opts.area[1] - opts.area[3]; + var mountWidth = eachSpacing * mountOption.widthRatio; + series.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.x = xAxisPoints[index]; + point.x += eachSpacing / 2; + var value = item.data; + var height = validHeight * (value * process - minRange) / (maxRange - minRange); + point.y = opts.height - height - opts.area[2]; + point.value = value; + point.width = mountWidth; + points.push(point); + } + }); + return points; +} + +function getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config) { + var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + var validWidth = opts.width - opts.area[1] - opts.area[3]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.y = yAxisPoints[index]; + var value = item; + if (typeof item === 'object' && item !== null) { + value = item.value; + } + var height = validWidth * (value - minRange) / (maxRange - minRange); + height *= process; + point.height = height; + point.value = value; + point.x = height + opts.area[3]; + points.push(point); + } + }); + return points; +} + +function getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) { + var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1; + var points = []; + var validHeight = opts.height - opts.area[0] - opts.area[2]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.x = xAxisPoints[index] + Math.round(eachSpacing / 2); + + if (seriesIndex > 0) { + var value = 0; + for (let i = 0; i <= seriesIndex; i++) { + value += stackSeries[i].data[index]; + } + var value0 = value - item; + var height = validHeight * (value - minRange) / (maxRange - minRange); + var height0 = validHeight * (value0 - minRange) / (maxRange - minRange); + } else { + var value = item; + if (typeof item === 'object' && item !== null) { + value = item.value; + } + var height = validHeight * (value - minRange) / (maxRange - minRange); + var height0 = 0; + } + var heightc = height0; + height *= process; + heightc *= process; + point.y = opts.height - Math.round(height) - opts.area[2]; + point.y0 = opts.height - Math.round(heightc) - opts.area[2]; + points.push(point); + } + }); + return points; +} + +function getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) { + var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1; + var points = []; + var validHeight = opts.width - opts.area[1] - opts.area[3]; + data.forEach(function(item, index) { + if (item === null) { + points.push(null); + } else { + var point = {}; + point.color = item.color; + point.y = yAxisPoints[index]; + if (seriesIndex > 0) { + var value = 0; + for (let i = 0; i <= seriesIndex; i++) { + value += stackSeries[i].data[index]; + } + var value0 = value - item; + var height = validHeight * (value - minRange) / (maxRange - minRange); + var height0 = validHeight * (value0 - minRange) / (maxRange - minRange); + } else { + var value = item; + if (typeof item === 'object' && item !== null) { + value = item.value; + } + var height = validHeight * (value - minRange) / (maxRange - minRange); + var height0 = 0; + } + var heightc = height0; + height *= process; + heightc *= process; + point.height = height - heightc; + point.x = opts.area[3] + height; + point.x0 = opts.area[3] + heightc; + points.push(point); + } + }); + return points; +} + +function getYAxisTextList(series, opts, config, stack, yData) { + var index = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : -1; + var data; + if (stack == 'stack') { + data = dataCombineStack(series, opts.categories.length); + } else { + data = dataCombine(series); + } + var sorted = []; + // remove null from data + data = data.filter(function(item) { + //return item !== null; + if (typeof item === 'object' && item !== null) { + if (item.constructor.toString().indexOf('Array') > -1) { + return item !== null; + } else { + return item.value !== null; + } + } else { + return item !== null; + } + }); + data.map(function(item) { + if (typeof item === 'object') { + if (item.constructor.toString().indexOf('Array') > -1) { + if (opts.type == 'candle') { + item.map(function(subitem) { + sorted.push(subitem); + }) + } else { + sorted.push(item[1]); + } + } else { + sorted.push(item.value); + } + } else { + sorted.push(item); + } + }) + var minData = yData.min || 0; + var maxData = yData.max || 0; + if (sorted.length > 0) { + minData = Math.min.apply(this, sorted); + maxData = Math.max.apply(this, sorted); + } + if (minData === maxData) { + if(maxData == 0){ + maxData = 10; + }else{ + minData = 0; + } + } + var dataRange = getDataRange(minData, maxData); + var minRange = (yData.min === undefined || yData.min === null) ? dataRange.minRange : yData.min; + var maxRange = (yData.max === undefined || yData.max === null) ? dataRange.maxRange : yData.max; + var eachRange = (maxRange - minRange) / opts.yAxis.splitNumber; + var range = []; + for (var i = 0; i <= opts.yAxis.splitNumber; i++) { + range.push(minRange + eachRange * i); + } + return range.reverse(); +} + +function calYAxisData(series, opts, config, context) { + //堆叠图重算Y轴 + var columnstyle = assign({}, { + type: "" + }, opts.extra.column); + //如果是多Y轴,重新计算 + var YLength = opts.yAxis.data.length; + var newSeries = new Array(YLength); + if (YLength > 0) { + for (let i = 0; i < YLength; i++) { + newSeries[i] = []; + for (let j = 0; j < series.length; j++) { + if (series[j].index == i) { + newSeries[i].push(series[j]); + } + } + } + var rangesArr = new Array(YLength); + var rangesFormatArr = new Array(YLength); + var yAxisWidthArr = new Array(YLength); + + for (let i = 0; i < YLength; i++) { + let yData = opts.yAxis.data[i]; + //如果总开关不显示,强制每个Y轴为不显示 + if (opts.yAxis.disabled == true) { + yData.disabled = true; + } + if(yData.type === 'categories'){ + if(!yData.formatter){ + yData.formatter = (val,index,opts) => {return val + (yData.unit || '')}; + } + yData.categories = yData.categories || opts.categories; + rangesArr[i] = yData.categories; + }else{ + if(!yData.formatter){ + yData.formatter = (val,index,opts) => {return util.toFixed(val, yData.tofix || 0) + (yData.unit || '')}; + } + rangesArr[i] = getYAxisTextList(newSeries[i], opts, config, columnstyle.type, yData, i); + } + let yAxisFontSizes = yData.fontSize * opts.pix || config.fontSize; + yAxisWidthArr[i] = { + position: yData.position ? yData.position : 'left', + width: 0 + }; + rangesFormatArr[i] = rangesArr[i].map(function(items,index) { + items = yData.formatter(items,index,opts); + yAxisWidthArr[i].width = Math.max(yAxisWidthArr[i].width, measureText(items, yAxisFontSizes, context) + 5); + return items; + }); + let calibration = yData.calibration ? 4 * opts.pix : 0; + yAxisWidthArr[i].width += calibration + 3 * opts.pix; + if (yData.disabled === true) { + yAxisWidthArr[i].width = 0; + } + } + } else { + var rangesArr = new Array(1); + var rangesFormatArr = new Array(1); + var yAxisWidthArr = new Array(1); + if(opts.type === 'bar'){ + rangesArr[0] = opts.categories; + if(!opts.yAxis.formatter){ + opts.yAxis.formatter = (val,index,opts) => {return val + (opts.yAxis.unit || '')} + } + }else{ + if(!opts.yAxis.formatter){ + opts.yAxis.formatter = (val,index,opts) => {return val.toFixed(opts.yAxis.tofix ) + (opts.yAxis.unit || '')} + } + rangesArr[0] = getYAxisTextList(series, opts, config, columnstyle.type, {}); + } + yAxisWidthArr[0] = { + position: 'left', + width: 0 + }; + var yAxisFontSize = opts.yAxis.fontSize * opts.pix || config.fontSize; + rangesFormatArr[0] = rangesArr[0].map(function(item,index) { + item = opts.yAxis.formatter(item,index,opts); + yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize, context) + 5); + return item; + }); + yAxisWidthArr[0].width += 3 * opts.pix; + if (opts.yAxis.disabled === true) { + yAxisWidthArr[0] = { + position: 'left', + width: 0 + }; + opts.yAxis.data[0] = { + disabled: true + }; + } else { + opts.yAxis.data[0] = { + disabled: false, + position: 'left', + max: opts.yAxis.max, + min: opts.yAxis.min, + formatter: opts.yAxis.formatter + }; + if(opts.type === 'bar'){ + opts.yAxis.data[0].categories = opts.categories; + opts.yAxis.data[0].type = 'categories'; + } + } + } + return { + rangesFormat: rangesFormatArr, + ranges: rangesArr, + yAxisWidth: yAxisWidthArr + }; +} + +function calTooltipYAxisData(point, series, opts, config, eachSpacing) { + let ranges = [].concat(opts.chartData.yAxisData.ranges); + let spacingValid = opts.height - opts.area[0] - opts.area[2]; + let minAxis = opts.area[0]; + let items = []; + for (let i = 0; i < ranges.length; i++) { + let maxVal = Math.max.apply(this, ranges[i]); + let minVal = Math.min.apply(this, ranges[i]); + let item = maxVal - (maxVal - minVal) * (point - minAxis) / spacingValid; + item = opts.yAxis.data && opts.yAxis.data[i].formatter ? opts.yAxis.data[i].formatter(item, i, opts) : item.toFixed(0); + items.push(String(item)) + } + return items; +} + +function calMarkLineData(points, opts) { + let minRange, maxRange; + let spacingValid = opts.height - opts.area[0] - opts.area[2]; + for (let i = 0; i < points.length; i++) { + points[i].yAxisIndex = points[i].yAxisIndex ? points[i].yAxisIndex : 0; + let range = [].concat(opts.chartData.yAxisData.ranges[points[i].yAxisIndex]); + minRange = range.pop(); + maxRange = range.shift(); + let height = spacingValid * (points[i].value - minRange) / (maxRange - minRange); + points[i].y = opts.height - Math.round(height) - opts.area[2]; + } + return points; +} + +function contextRotate(context, opts) { + if (opts.rotateLock !== true) { + context.translate(opts.height, 0); + context.rotate(90 * Math.PI / 180); + } else if (opts._rotate_ !== true) { + context.translate(opts.height, 0); + context.rotate(90 * Math.PI / 180); + opts._rotate_ = true; + } +} + +function drawPointShape(points, color, shape, context, opts) { + context.beginPath(); + if (opts.dataPointShapeType == 'hollow') { + context.setStrokeStyle(color); + context.setFillStyle(opts.background); + context.setLineWidth(2 * opts.pix); + } else { + context.setStrokeStyle("#ffffff"); + context.setFillStyle(color); + context.setLineWidth(1 * opts.pix); + } + if (shape === 'diamond') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y); + context.lineTo(item.x, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'circle') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x + 2.5 * opts.pix, item.y); + context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false); + } + }); + } else if (shape === 'square') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x - 3.5, item.y - 3.5); + context.rect(item.x - 3.5, item.y - 3.5, 7, 7); + } + }); + } else if (shape === 'triangle') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y + 4.5); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'none') { + return; + } + context.closePath(); + context.fill(); + context.stroke(); +} + +function drawActivePoint(points, color, shape, context, opts, option, seriesIndex) { + if(!opts.tooltip){ + return + } + if(opts.tooltip.group.length>0 && opts.tooltip.group.includes(seriesIndex) == false){ + return + } + var pointIndex = typeof opts.tooltip.index === 'number' ? opts.tooltip.index : opts.tooltip.index[opts.tooltip.group.indexOf(seriesIndex)]; + context.beginPath(); + if (option.activeType == 'hollow') { + context.setStrokeStyle(color); + context.setFillStyle(opts.background); + context.setLineWidth(2 * opts.pix); + } else { + context.setStrokeStyle("#ffffff"); + context.setFillStyle(color); + context.setLineWidth(1 * opts.pix); + } + if (shape === 'diamond') { + points.forEach(function(item, index) { + if (item !== null && pointIndex == index ) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y); + context.lineTo(item.x, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'circle') { + points.forEach(function(item, index) { + if (item !== null && pointIndex == index) { + context.moveTo(item.x + 2.5 * opts.pix, item.y); + context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false); + } + }); + } else if (shape === 'square') { + points.forEach(function(item, index) { + if (item !== null && pointIndex == index) { + context.moveTo(item.x - 3.5, item.y - 3.5); + context.rect(item.x - 3.5, item.y - 3.5, 7, 7); + } + }); + } else if (shape === 'triangle') { + points.forEach(function(item, index) { + if (item !== null && pointIndex == index) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y + 4.5); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'none') { + return; + } + context.closePath(); + context.fill(); + context.stroke(); +} + +function drawRingTitle(opts, config, context, center) { + var titlefontSize = opts.title.fontSize || config.titleFontSize; + var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize; + var title = opts.title.name || ''; + var subtitle = opts.subtitle.name || ''; + var titleFontColor = opts.title.color || opts.fontColor; + var subtitleFontColor = opts.subtitle.color || opts.fontColor; + var titleHeight = title ? titlefontSize : 0; + var subtitleHeight = subtitle ? subtitlefontSize : 0; + var margin = 5; + if (subtitle) { + var textWidth = measureText(subtitle, subtitlefontSize * opts.pix, context); + var startX = center.x - textWidth / 2 + (opts.subtitle.offsetX|| 0) * opts.pix ; + var startY = center.y + subtitlefontSize * opts.pix / 2 + (opts.subtitle.offsetY || 0) * opts.pix; + if (title) { + startY += (titleHeight * opts.pix + margin) / 2; + } + context.beginPath(); + context.setFontSize(subtitlefontSize * opts.pix); + context.setFillStyle(subtitleFontColor); + context.fillText(subtitle, startX, startY); + context.closePath(); + context.stroke(); + } + if (title) { + var _textWidth = measureText(title, titlefontSize * opts.pix, context); + var _startX = center.x - _textWidth / 2 + (opts.title.offsetX || 0); + var _startY = center.y + titlefontSize * opts.pix / 2 + (opts.title.offsetY || 0) * opts.pix; + if (subtitle) { + _startY -= (subtitleHeight * opts.pix + margin) / 2; + } + context.beginPath(); + context.setFontSize(titlefontSize * opts.pix); + context.setFillStyle(titleFontColor); + context.fillText(title, _startX, _startY); + context.closePath(); + context.stroke(); + } +} + +function drawPointText(points, series, config, context, opts) { + // 绘制数据文案 + var data = series.data; + var textOffset = series.textOffset ? series.textOffset : 0; + points.forEach(function(item, index) { + if (item !== null) { + context.beginPath(); + var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(series.textColor || opts.fontColor); + var value = data[index] + if (typeof data[index] === 'object' && data[index] !== null) { + if (data[index].constructor.toString().indexOf('Array')>-1) { + value = data[index][1]; + } else { + value = data[index].value + } + } + var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; + context.setTextAlign('center'); + context.fillText(String(formatVal), item.x, item.y - 4 + textOffset * opts.pix); + context.closePath(); + context.stroke(); + context.setTextAlign('left'); + } + }); +} + +function drawColumePointText(points, series, config, context, opts) { + // 绘制数据文案 + var data = series.data; + var textOffset = series.textOffset ? series.textOffset : 0; + var Position = opts.extra.column.labelPosition; + points.forEach(function(item, index) { + if (item !== null) { + context.beginPath(); + var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(series.textColor || opts.fontColor); + var value = data[index] + if (typeof data[index] === 'object' && data[index] !== null) { + if (data[index].constructor.toString().indexOf('Array')>-1) { + value = data[index][1]; + } else { + value = data[index].value + } + } + var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; + context.setTextAlign('center'); + var startY = item.y - 4 * opts.pix + textOffset * opts.pix; + if(item.y > series.zeroPoints){ + startY = item.y + textOffset * opts.pix + fontSize; + } + if(Position == 'insideTop'){ + startY = item.y + fontSize + textOffset * opts.pix; + if(item.y > series.zeroPoints){ + startY = item.y - textOffset * opts.pix - 4 * opts.pix; + } + } + if(Position == 'center'){ + startY = item.y + textOffset * opts.pix + (opts.height - opts.area[2] - item.y + fontSize)/2; + if(series.zeroPoints < opts.height - opts.area[2]){ + startY = item.y + textOffset * opts.pix + (series.zeroPoints - item.y + fontSize)/2; + } + if(item.y > series.zeroPoints){ + startY = item.y - textOffset * opts.pix - (item.y - series.zeroPoints - fontSize)/2; + } + if(opts.extra.column.type == 'stack'){ + startY = item.y + textOffset * opts.pix + (item.y0 - item.y + fontSize)/2; + } + } + if(Position == 'bottom'){ + startY = opts.height - opts.area[2] + textOffset * opts.pix - 4 * opts.pix; + if(series.zeroPoints < opts.height - opts.area[2]){ + startY = series.zeroPoints + textOffset * opts.pix - 4 * opts.pix; + } + if(item.y > series.zeroPoints){ + startY = series.zeroPoints - textOffset * opts.pix + fontSize + 2 * opts.pix; + } + if(opts.extra.column.type == 'stack'){ + startY = item.y0 + textOffset * opts.pix - 4 * opts.pix; + } + } + context.fillText(String(formatVal), item.x, startY); + context.closePath(); + context.stroke(); + context.setTextAlign('left'); + } + }); +} + +function drawMountPointText(points, series, config, context, opts, zeroPoints) { + // 绘制数据文案 + var data = series.data; + var textOffset = series.textOffset ? series.textOffset : 0; + var Position = opts.extra.mount.labelPosition; + points.forEach(function(item, index) { + if (item !== null) { + context.beginPath(); + var fontSize = series[index].textSize ? series[index].textSize * opts.pix : config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(series[index].textColor || opts.fontColor); + var value = item.value + var formatVal = series[index].formatter ? series[index].formatter(value,index,series,opts) : value; + context.setTextAlign('center'); + var startY = item.y - 4 * opts.pix + textOffset * opts.pix; + if(item.y > zeroPoints){ + startY = item.y + textOffset * opts.pix + fontSize; + } + context.fillText(String(formatVal), item.x, startY); + context.closePath(); + context.stroke(); + context.setTextAlign('left'); + } + }); +} + +function drawBarPointText(points, series, config, context, opts) { + // 绘制数据文案 + var data = series.data; + var textOffset = series.textOffset ? series.textOffset : 0; + points.forEach(function(item, index) { + if (item !== null) { + context.beginPath(); + var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(series.textColor || opts.fontColor); + var value = data[index] + if (typeof data[index] === 'object' && data[index] !== null) { + value = data[index].value ; + } + var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; + context.setTextAlign('left'); + context.fillText(String(formatVal), item.x + 4 * opts.pix , item.y + fontSize / 2 - 3 ); + context.closePath(); + context.stroke(); + } + }); +} + +function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) { + radius -= gaugeOption.width / 2 + gaugeOption.labelOffset * opts.pix; + radius = radius < 10 ? 10 : radius; + let totalAngle; + if (gaugeOption.endAngle < gaugeOption.startAngle) { + totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; + } else { + totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; + } + let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; + let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber; + let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber; + let nowAngle = gaugeOption.startAngle; + let nowNumber = gaugeOption.startNumber; + for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) { + var pos = { + x: radius * Math.cos(nowAngle * Math.PI), + y: radius * Math.sin(nowAngle * Math.PI) + }; + var labelText = gaugeOption.formatter ? gaugeOption.formatter(nowNumber,i,opts) : nowNumber; + pos.x += centerPosition.x - measureText(labelText, config.fontSize, context) / 2; + pos.y += centerPosition.y; + var startX = pos.x; + var startY = pos.y; + context.beginPath(); + context.setFontSize(config.fontSize); + context.setFillStyle(gaugeOption.labelColor || opts.fontColor); + context.fillText(labelText, startX, startY + config.fontSize / 2); + context.closePath(); + context.stroke(); + nowAngle += splitAngle; + if (nowAngle >= 2) { + nowAngle = nowAngle % 2; + } + nowNumber += splitNumber; + } +} + +function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) { + var radarOption = opts.extra.radar || {}; + angleList.forEach(function(angle, index) { + if(radarOption.labelPointShow === true && opts.categories[index] !== ''){ + var posPoint = { + x: radius * Math.cos(angle), + y: radius * Math.sin(angle) + }; + var posPointAxis = convertCoordinateOrigin(posPoint.x, posPoint.y, centerPosition); + context.setFillStyle(radarOption.labelPointColor); + context.beginPath(); + context.arc(posPointAxis.x, posPointAxis.y, radarOption.labelPointRadius * opts.pix, 0, 2 * Math.PI, false); + context.closePath(); + context.fill(); + } + if(radarOption.labelShow === true){ + var pos = { + x: (radius + config.radarLabelTextMargin * opts.pix) * Math.cos(angle), + y: (radius + config.radarLabelTextMargin * opts.pix) * Math.sin(angle) + }; + var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition); + var startX = posRelativeCanvas.x; + var startY = posRelativeCanvas.y; + if (util.approximatelyEqual(pos.x, 0)) { + startX -= measureText(opts.categories[index] || '', config.fontSize, context) / 2; + } else if (pos.x < 0) { + startX -= measureText(opts.categories[index] || '', config.fontSize, context); + } + context.beginPath(); + context.setFontSize(config.fontSize); + context.setFillStyle(radarOption.labelColor || opts.fontColor); + context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2); + context.closePath(); + context.stroke(); + } + }); + +} + +function drawPieText(series, opts, config, context, radius, center) { + var lineRadius = config.pieChartLinePadding; + var textObjectCollection = []; + var lastTextObject = null; + var seriesConvert = series.map(function(item,index) { + var text = item.formatter ? item.formatter(item,index,series,opts) : util.toFixed(item._proportion_.toFixed(4) * 100) + '%'; + text = item.labelText ? item.labelText : text; + var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2); + if (item._rose_proportion_) { + arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._rose_proportion_ / 2); + } + var color = item.color; + var radius = item._radius_; + return { + arc: arc, + text: text, + color: color, + radius: radius, + textColor: item.textColor, + textSize: item.textSize, + labelShow: item.labelShow + }; + }); + for (let i = 0; i < seriesConvert.length; i++) { + let item = seriesConvert[i]; + // line end + let orginX1 = Math.cos(item.arc) * (item.radius + lineRadius); + let orginY1 = Math.sin(item.arc) * (item.radius + lineRadius); + // line start + let orginX2 = Math.cos(item.arc) * item.radius; + let orginY2 = Math.sin(item.arc) * item.radius; + // text start + let orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding; + let orginY3 = orginY1; + let textWidth = measureText(item.text, item.textSize * opts.pix || config.fontSize, context); + let startY = orginY3; + if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, { + x: orginX3 + })) { + if (orginX3 > 0) { + startY = Math.min(orginY3, lastTextObject.start.y); + } else if (orginX1 < 0) { + startY = Math.max(orginY3, lastTextObject.start.y); + } else { + if (orginY3 > 0) { + startY = Math.max(orginY3, lastTextObject.start.y); + } else { + startY = Math.min(orginY3, lastTextObject.start.y); + } + } + } + if (orginX3 < 0) { + orginX3 -= textWidth; + } + let textObject = { + lineStart: { + x: orginX2, + y: orginY2 + }, + lineEnd: { + x: orginX1, + y: orginY1 + }, + start: { + x: orginX3, + y: startY + }, + width: textWidth, + height: config.fontSize, + text: item.text, + color: item.color, + textColor: item.textColor, + textSize: item.textSize + }; + lastTextObject = avoidCollision(textObject, lastTextObject); + textObjectCollection.push(lastTextObject); + } + for (let i = 0; i < textObjectCollection.length; i++) { + if(seriesConvert[i].labelShow === false){ + continue; + } + let item = textObjectCollection[i]; + let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center); + let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center); + let textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center); + context.setLineWidth(1 * opts.pix); + context.setFontSize(item.textSize * opts.pix || config.fontSize); + context.beginPath(); + context.setStrokeStyle(item.color); + context.setFillStyle(item.color); + context.moveTo(lineStartPoistion.x, lineStartPoistion.y); + let curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x; + let textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5; + context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y); + context.moveTo(lineStartPoistion.x, lineStartPoistion.y); + context.stroke(); + context.closePath(); + context.beginPath(); + context.moveTo(textPosition.x + item.width, textPosition.y); + context.arc(curveStartX, textPosition.y, 2 * opts.pix, 0, 2 * Math.PI); + context.closePath(); + context.fill(); + context.beginPath(); + context.setFontSize(item.textSize * opts.pix || config.fontSize); + context.setFillStyle(item.textColor || opts.fontColor); + context.fillText(item.text, textStartX, textPosition.y + 3); + context.closePath(); + context.stroke(); + context.closePath(); + } +} + +function drawToolTipSplitLine(offsetX, opts, config, context) { + var toolTipOption = opts.extra.tooltip || {}; + toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType; + toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength; + var startY = opts.area[0]; + var endY = opts.height - opts.area[2]; + if (toolTipOption.gridType == 'dash') { + context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]); + } + context.setStrokeStyle(toolTipOption.gridColor || '#cccccc'); + context.setLineWidth(1 * opts.pix); + context.beginPath(); + context.moveTo(offsetX, startY); + context.lineTo(offsetX, endY); + context.stroke(); + context.setLineDash([]); + if (toolTipOption.xAxisLabel) { + let labelText = opts.categories[opts.tooltip.index]; + context.setFontSize(config.fontSize); + let textWidth = measureText(labelText, config.fontSize, context); + let textX = offsetX - 0.5 * textWidth; + let textY = endY + 2 * opts.pix; + context.beginPath(); + context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity)); + context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground); + context.setLineWidth(1 * opts.pix); + context.rect(textX - toolTipOption.boxPadding * opts.pix, textY, textWidth + 2 * toolTipOption.boxPadding * opts.pix, config.fontSize + 2 * toolTipOption.boxPadding * opts.pix); + context.closePath(); + context.stroke(); + context.fill(); + context.beginPath(); + context.setFontSize(config.fontSize); + context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor); + context.fillText(String(labelText), textX, textY + toolTipOption.boxPadding * opts.pix + config.fontSize); + context.closePath(); + context.stroke(); + } +} + +function drawMarkLine(opts, config, context) { + let markLineOption = assign({}, { + type: 'solid', + dashLength: 4, + data: [] + }, opts.extra.markLine); + let startX = opts.area[3]; + let endX = opts.width - opts.area[1]; + let points = calMarkLineData(markLineOption.data, opts); + for (let i = 0; i < points.length; i++) { + let item = assign({}, { + lineColor: '#DE4A42', + showLabel: false, + labelFontSize: 13, + labelPadding: 6, + labelFontColor: '#666666', + labelBgColor: '#DFE8FF', + labelBgOpacity: 0.8, + labelAlign: 'left', + labelOffsetX: 0, + labelOffsetY: 0, + }, points[i]); + if (markLineOption.type == 'dash') { + context.setLineDash([markLineOption.dashLength, markLineOption.dashLength]); + } + context.setStrokeStyle(item.lineColor); + context.setLineWidth(1 * opts.pix); + context.beginPath(); + context.moveTo(startX, item.y); + context.lineTo(endX, item.y); + context.stroke(); + context.setLineDash([]); + if (item.showLabel) { + let fontSize = item.labelFontSize * opts.pix; + let labelText = item.labelText ? item.labelText : item.value; + context.setFontSize(fontSize); + let textWidth = measureText(labelText, fontSize, context); + let bgWidth = textWidth + item.labelPadding * opts.pix * 2; + let bgStartX = item.labelAlign == 'left' ? opts.area[3] - bgWidth : opts.width - opts.area[1]; + bgStartX += item.labelOffsetX; + let bgStartY = item.y - 0.5 * fontSize - item.labelPadding * opts.pix; + bgStartY += item.labelOffsetY; + let textX = bgStartX + item.labelPadding * opts.pix; + let textY = item.y; + context.setFillStyle(hexToRgb(item.labelBgColor, item.labelBgOpacity)); + context.setStrokeStyle(item.labelBgColor); + context.setLineWidth(1 * opts.pix); + context.beginPath(); + context.rect(bgStartX, bgStartY, bgWidth, fontSize + 2 * item.labelPadding * opts.pix); + context.closePath(); + context.stroke(); + context.fill(); + context.setFontSize(fontSize); + context.setTextAlign('left'); + context.setFillStyle(item.labelFontColor); + context.fillText(String(labelText), textX, bgStartY + fontSize + item.labelPadding * opts.pix/2); + context.stroke(); + context.setTextAlign('left'); + } + } +} + +function drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) { + var toolTipOption = assign({}, { + gridType: 'solid', + dashLength: 4 + }, opts.extra.tooltip); + var startX = opts.area[3]; + var endX = opts.width - opts.area[1]; + if (toolTipOption.gridType == 'dash') { + context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]); + } + context.setStrokeStyle(toolTipOption.gridColor || '#cccccc'); + context.setLineWidth(1 * opts.pix); + context.beginPath(); + context.moveTo(startX, opts.tooltip.offset.y); + context.lineTo(endX, opts.tooltip.offset.y); + context.stroke(); + context.setLineDash([]); + if (toolTipOption.yAxisLabel) { + let boxPadding = toolTipOption.boxPadding * opts.pix; + let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing); + let widthArr = opts.chartData.yAxisData.yAxisWidth; + let tStartLeft = opts.area[3]; + let tStartRight = opts.width - opts.area[1]; + for (let i = 0; i < labelText.length; i++) { + context.setFontSize(toolTipOption.fontSize * opts.pix); + let textWidth = measureText(labelText[i], toolTipOption.fontSize * opts.pix, context); + let bgStartX, bgEndX, bgWidth; + if (widthArr[i].position == 'left') { + bgStartX = tStartLeft - (textWidth + boxPadding * 2) - 2 * opts.pix; + bgEndX = Math.max(bgStartX, bgStartX + textWidth + boxPadding * 2); + } else { + bgStartX = tStartRight + 2 * opts.pix; + bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + boxPadding * 2); + } + bgWidth = bgEndX - bgStartX; + let textX = bgStartX + (bgWidth - textWidth) / 2; + let textY = opts.tooltip.offset.y; + context.beginPath(); + context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity)); + context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground); + context.setLineWidth(1 * opts.pix); + context.rect(bgStartX, textY - 0.5 * config.fontSize - boxPadding, bgWidth, config.fontSize + 2 * boxPadding); + context.closePath(); + context.stroke(); + context.fill(); + context.beginPath(); + context.setFontSize(config.fontSize); + context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor); + context.fillText(labelText[i], textX, textY + 0.5 * config.fontSize); + context.closePath(); + context.stroke(); + if (widthArr[i].position == 'left') { + tStartLeft -= (widthArr[i].width + opts.yAxis.padding * opts.pix); + } else { + tStartRight += widthArr[i].width + opts.yAxis.padding * opts.pix; + } + } + } +} + +function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) { + var toolTipOption = assign({}, { + activeBgColor: '#000000', + activeBgOpacity: 0.08, + activeWidth: eachSpacing + }, opts.extra.column); + toolTipOption.activeWidth = toolTipOption.activeWidth > eachSpacing ? eachSpacing : toolTipOption.activeWidth; + var startY = opts.area[0]; + var endY = opts.height - opts.area[2]; + context.beginPath(); + context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity)); + context.rect(offsetX - toolTipOption.activeWidth / 2, startY, toolTipOption.activeWidth, endY - startY); + context.closePath(); + context.fill(); + context.setFillStyle("#FFFFFF"); +} + +function drawBarToolTipSplitArea(offsetX, opts, config, context, eachSpacing) { + var toolTipOption = assign({}, { + activeBgColor: '#000000', + activeBgOpacity: 0.08 + }, opts.extra.bar); + var startX = opts.area[3]; + var endX = opts.width - opts.area[1]; + context.beginPath(); + context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity)); + context.rect( startX ,offsetX - eachSpacing / 2 , endX - startX,eachSpacing); + context.closePath(); + context.fill(); + context.setFillStyle("#FFFFFF"); +} + + +function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) { + var toolTipOption = assign({}, { + showBox: true, + showArrow: true, + showCategory: false, + bgColor: '#000000', + bgOpacity: 0.7, + borderColor: '#000000', + borderWidth: 0, + borderRadius: 0, + borderOpacity: 0.7, + boxPadding: 3, + fontColor: '#FFFFFF', + fontSize: 13, + lineHeight: 20, + legendShow: true, + legendShape: 'auto', + splitLine: true, + }, opts.extra.tooltip); + if(toolTipOption.showCategory==true && opts.categories){ + textList.unshift({text:opts.categories[opts.tooltip.index],color:null}) + } + var fontSize = toolTipOption.fontSize * opts.pix; + var lineHeight = toolTipOption.lineHeight * opts.pix; + var boxPadding = toolTipOption.boxPadding * opts.pix; + var legendWidth = fontSize; + var legendMarginRight = 5 * opts.pix; + if(toolTipOption.legendShow == false){ + legendWidth = 0; + legendMarginRight = 0; + } + var arrowWidth = toolTipOption.showArrow ? 8 * opts.pix : 0; + var isOverRightBorder = false; + if (opts.type == 'line' || opts.type == 'mount' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') { + if (toolTipOption.splitLine == true) { + drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context); + } + } + offset = assign({ + x: 0, + y: 0 + }, offset); + offset.y -= 8 * opts.pix; + var textWidth = textList.map(function(item) { + return measureText(item.text, fontSize, context); + }); + var toolTipWidth = legendWidth + legendMarginRight + 4 * boxPadding + Math.max.apply(null, textWidth); + var toolTipHeight = 2 * boxPadding + textList.length * lineHeight; + if (toolTipOption.showBox == false) { + return + } + // if beyond the right border + if (offset.x - Math.abs(opts._scrollDistance_ || 0) + arrowWidth + toolTipWidth > opts.width) { + isOverRightBorder = true; + } + if (toolTipHeight + offset.y > opts.height) { + offset.y = opts.height - toolTipHeight; + } + // draw background rect + context.beginPath(); + context.setFillStyle(hexToRgb(toolTipOption.bgColor, toolTipOption.bgOpacity)); + context.setLineWidth(toolTipOption.borderWidth * opts.pix); + context.setStrokeStyle(hexToRgb(toolTipOption.borderColor, toolTipOption.borderOpacity)); + var radius = toolTipOption.borderRadius; + if (isOverRightBorder) { + // 增加左侧仍然超出的判断 + if(toolTipWidth + arrowWidth > opts.width){ + offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width) + } + if(toolTipWidth > offset.x){ + offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width) + } + if (toolTipOption.showArrow) { + context.moveTo(offset.x, offset.y + 10 * opts.pix); + context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix); + } + context.arc(offset.x - arrowWidth - radius, offset.y + toolTipHeight - radius, radius, 0, Math.PI / 2, false); + context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + toolTipHeight - radius, radius, + Math.PI / 2, Math.PI, false); + context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false); + context.arc(offset.x - arrowWidth - radius, offset.y + radius, radius, -Math.PI / 2, 0, false); + if (toolTipOption.showArrow) { + context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix); + context.lineTo(offset.x, offset.y + 10 * opts.pix); + } + } else { + if (toolTipOption.showArrow) { + context.moveTo(offset.x, offset.y + 10 * opts.pix); + context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix); + } + context.arc(offset.x + arrowWidth + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false); + context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + radius, radius, -Math.PI / 2, 0, + false); + context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + toolTipHeight - radius, radius, 0, + Math.PI / 2, false); + context.arc(offset.x + arrowWidth + radius, offset.y + toolTipHeight - radius, radius, Math.PI / 2, Math.PI, false); + if (toolTipOption.showArrow) { + context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix); + context.lineTo(offset.x, offset.y + 10 * opts.pix); + } + } + context.closePath(); + context.fill(); + if (toolTipOption.borderWidth > 0) { + context.stroke(); + } + // draw legend + if(toolTipOption.legendShow){ + textList.forEach(function(item, index) { + if (item.color !== null) { + context.beginPath(); + context.setFillStyle(item.color); + var startX = offset.x + arrowWidth + 2 * boxPadding; + var startY = offset.y + (lineHeight - fontSize) / 2 + lineHeight * index + boxPadding + 1; + if (isOverRightBorder) { + startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding; + } + switch (item.legendShape) { + case 'line': + context.moveTo(startX, startY + 0.5 * legendWidth - 2 * opts.pix); + context.fillRect(startX, startY + 0.5 * legendWidth - 2 * opts.pix, legendWidth, 4 * opts.pix); + break; + case 'triangle': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); + context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); + context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); + break; + case 'diamond': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); + context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); + context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); + break; + case 'circle': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth); + context.arc(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth, 5 * opts.pix, 0, 2 * Math.PI); + break; + case 'rect': + context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix); + context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); + break; + case 'square': + context.moveTo(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); + context.fillRect(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix); + break; + default: + context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix); + context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); + } + context.closePath(); + context.fill(); + } + }); + } + + // draw text list + textList.forEach(function(item, index) { + var startX = offset.x + arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight; + if (isOverRightBorder) { + startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight; + } + var startY = offset.y + lineHeight * index + (lineHeight - fontSize)/2 - 1 + boxPadding + fontSize; + context.beginPath(); + context.setFontSize(fontSize); + context.setTextBaseline('normal'); + context.setFillStyle(toolTipOption.fontColor); + context.fillText(item.text, startX, startY); + context.closePath(); + context.stroke(); + }); +} + +function drawColumnDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + let columnOption = assign({}, { + type: 'group', + width: eachSpacing / 2, + meterBorder: 4, + meterFillColor: '#FFFFFF', + barBorderCircle: false, + barBorderRadius: [], + seriesGap: 2, + linearType: 'none', + linearOpacity: 1, + customColor: [], + colorStop: 0, + labelPosition: 'outside' + }, opts.extra.column); + let calPoints = []; + context.save(); + let leftNum = -2; + let rightNum = xAxisPoints.length + 2; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2; + rightNum = leftNum + opts.xAxis.itemCount + 4; + } + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { + drawToolTipSplitArea(opts.tooltip.offset.x, opts, config, context, eachSpacing); + } + columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config); + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + + // 计算0轴坐标 + let spacingValid = opts.height - opts.area[0] - opts.area[2]; + let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange); + let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2]; + eachSeries.zeroPoints = zeroPoints; + var data = eachSeries.data; + switch (columnOption.type) { + case 'group': + var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process); + var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + calPoints.push(tooltipPoints); + points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + //fix issues/I27B1N yyoinge & Joeshu + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - item.width / 2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || eachSeries.color + var strokeColor = item.color || eachSeries.color + if (columnOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); + //透明渐变 + if (columnOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity)); + grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + // 圆角边框 + if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) { + const left = startX; + const top = item.y > zeroPoints ? zeroPoints : item.y; + const width = item.width; + const height = Math.abs(zeroPoints - item.y); + if (columnOption.barBorderCircle) { + columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; + } + if(item.y > zeroPoints){ + columnOption.barBorderRadius = [0, 0,width / 2, width / 2]; + } + let [r0, r1, r2, r3] = columnOption.barBorderRadius; + let minRadius = Math.min(width/2,height/2); + r0 = r0 > minRadius ? minRadius : r0; + r1 = r1 > minRadius ? minRadius : r1; + r2 = r2 > minRadius ? minRadius : r2; + r3 = r3 > minRadius ? minRadius : r3; + r0 = r0 < 0 ? 0 : r0; + r1 = r1 < 0 ? 0 : r1; + r2 = r2 < 0 ? 0 : r2; + r3 = r3 < 0 ? 0 : r3; + context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); + context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); + context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); + context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); + } else { + context.moveTo(startX, item.y); + context.lineTo(startX + item.width, item.y); + context.lineTo(startX + item.width, zeroPoints); + context.lineTo(startX, zeroPoints); + context.lineTo(startX, item.y); + context.setLineWidth(1) + context.setStrokeStyle(strokeColor); + } + context.setFillStyle(fillColor); + context.closePath(); + //context.stroke(); + context.fill(); + } + }; + break; + case 'stack': + // 绘制堆叠数据图 + var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + calPoints.push(points); + points = fixColumeStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + context.beginPath(); + var fillColor = item.color || eachSeries.color; + var startX = item.x - item.width / 2 + 1; + var height = opts.height - item.y - opts.area[2]; + var height0 = opts.height - item.y0 - opts.area[2]; + if (seriesIndex > 0) { + height -= height0; + } + context.setFillStyle(fillColor); + context.moveTo(startX, item.y); + context.fillRect(startX, item.y, item.width, height); + context.closePath(); + context.fill(); + } + }; + break; + case 'meter': + // 绘制温度计数据图 + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + calPoints.push(points); + points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meterBorder); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + //画背景颜色 + context.beginPath(); + if (seriesIndex == 0 && columnOption.meterBorder > 0) { + context.setStrokeStyle(eachSeries.color); + context.setLineWidth(columnOption.meterBorder * opts.pix); + } + if(seriesIndex == 0){ + context.setFillStyle(columnOption.meterFillColor); + }else{ + context.setFillStyle(item.color || eachSeries.color); + } + var startX = item.x - item.width / 2; + var height = opts.height - item.y - opts.area[2]; + if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) { + const left = startX; + const top = item.y; + const width = item.width; + const height = zeroPoints - item.y; + if (columnOption.barBorderCircle) { + columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; + } + let [r0, r1, r2, r3] = columnOption.barBorderRadius; + let minRadius = Math.min(width/2,height/2); + r0 = r0 > minRadius ? minRadius : r0; + r1 = r1 > minRadius ? minRadius : r1; + r2 = r2 > minRadius ? minRadius : r2; + r3 = r3 > minRadius ? minRadius : r3; + r0 = r0 < 0 ? 0 : r0; + r1 = r1 < 0 ? 0 : r1; + r2 = r2 < 0 ? 0 : r2; + r3 = r3 < 0 ? 0 : r3; + context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); + context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); + context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); + context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); + context.fill(); + }else{ + context.moveTo(startX, item.y); + context.lineTo(startX + item.width, item.y); + context.lineTo(startX + item.width, zeroPoints); + context.lineTo(startX, zeroPoints); + context.lineTo(startX, item.y); + context.fill(); + } + if (seriesIndex == 0 && columnOption.meterBorder > 0) { + context.closePath(); + context.stroke(); + } + } + } + break; + } + }); + + if (opts.dataLabel !== false && process === 1) { + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + switch (columnOption.type) { + case 'group': + var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); + drawColumePointText(points, eachSeries, config, context, opts); + break; + case 'stack': + var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + drawColumePointText(points, eachSeries, config, context, opts); + break; + case 'meter': + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + drawColumePointText(points, eachSeries, config, context, opts); + break; + } + }); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawMountDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + let mountOption = assign({}, { + type: 'mount', + widthRatio: 1, + borderWidth: 1, + barBorderCircle: false, + barBorderRadius: [], + linearType: 'none', + linearOpacity: 1, + customColor: [], + colorStop: 0, + }, opts.extra.mount); + mountOption.widthRatio = mountOption.widthRatio <= 0 ? 0 : mountOption.widthRatio; + mountOption.widthRatio = mountOption.widthRatio >= 2 ? 2 : mountOption.widthRatio; + let calPoints = []; + context.save(); + let leftNum = -2; + let rightNum = xAxisPoints.length + 2; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2; + rightNum = leftNum + opts.xAxis.itemCount + 4; + } + mountOption.customColor = fillCustomColor(mountOption.linearType, mountOption.customColor, series, config); + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[0]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + + // 计算0轴坐标 + let spacingValid = opts.height - opts.area[0] - opts.area[2]; + let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange); + let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2]; + + var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process); + switch (mountOption.type) { + case 'bar': + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - eachSpacing*mountOption.widthRatio/2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || series[i].color + var strokeColor = item.color || series[i].color + if (mountOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); + //透明渐变 + if (mountOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); + grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + // 圆角边框 + if ((mountOption.barBorderRadius && mountOption.barBorderRadius.length === 4) || mountOption.barBorderCircle === true) { + const left = startX; + const top = item.y > zeroPoints ? zeroPoints : item.y; + const width = item.width; + const height = Math.abs(zeroPoints - item.y); + if (mountOption.barBorderCircle) { + mountOption.barBorderRadius = [width / 2, width / 2, 0, 0]; + } + if(item.y > zeroPoints){ + mountOption.barBorderRadius = [0, 0,width / 2, width / 2]; + } + let [r0, r1, r2, r3] = mountOption.barBorderRadius; + let minRadius = Math.min(width/2,height/2); + r0 = r0 > minRadius ? minRadius : r0; + r1 = r1 > minRadius ? minRadius : r1; + r2 = r2 > minRadius ? minRadius : r2; + r3 = r3 > minRadius ? minRadius : r3; + r0 = r0 < 0 ? 0 : r0; + r1 = r1 < 0 ? 0 : r1; + r2 = r2 < 0 ? 0 : r2; + r3 = r3 < 0 ? 0 : r3; + context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); + context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); + context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); + context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); + } else { + context.moveTo(startX, item.y); + context.lineTo(startX + item.width, item.y); + context.lineTo(startX + item.width, zeroPoints); + context.lineTo(startX, zeroPoints); + context.lineTo(startX, item.y); + } + context.setStrokeStyle(strokeColor); + context.setFillStyle(fillColor); + if(mountOption.borderWidth > 0){ + context.setLineWidth(mountOption.borderWidth * opts.pix); + context.closePath(); + context.stroke(); + } + context.fill(); + } + }; + break; + case 'triangle': + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - eachSpacing*mountOption.widthRatio/2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || series[i].color + var strokeColor = item.color || series[i].color + if (mountOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); + //透明渐变 + if (mountOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); + grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + context.moveTo(startX, zeroPoints); + context.lineTo(item.x, item.y); + context.lineTo(startX + item.width, zeroPoints); + context.setStrokeStyle(strokeColor); + context.setFillStyle(fillColor); + if(mountOption.borderWidth > 0){ + context.setLineWidth(mountOption.borderWidth * opts.pix); + context.stroke(); + } + context.fill(); + } + }; + break; + case 'mount': + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - eachSpacing*mountOption.widthRatio/2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || series[i].color + var strokeColor = item.color || series[i].color + if (mountOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); + //透明渐变 + if (mountOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); + grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + context.moveTo(startX, zeroPoints); + context.bezierCurveTo(item.x - item.width/4, zeroPoints, item.x - item.width/4, item.y, item.x, item.y); + context.bezierCurveTo(item.x + item.width/4, item.y, item.x + item.width/4, zeroPoints, startX + item.width, zeroPoints); + context.setStrokeStyle(strokeColor); + context.setFillStyle(fillColor); + if(mountOption.borderWidth > 0){ + context.setLineWidth(mountOption.borderWidth * opts.pix); + context.stroke(); + } + context.fill(); + } + }; + break; + case 'sharp': + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - eachSpacing*mountOption.widthRatio/2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || series[i].color + var strokeColor = item.color || series[i].color + if (mountOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); + //透明渐变 + if (mountOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); + grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + context.moveTo(startX, zeroPoints); + context.quadraticCurveTo(item.x - 0, zeroPoints - height/4, item.x, item.y); + context.quadraticCurveTo(item.x + 0, zeroPoints - height/4, startX + item.width, zeroPoints) + context.setStrokeStyle(strokeColor); + context.setFillStyle(fillColor); + if(mountOption.borderWidth > 0){ + context.setLineWidth(mountOption.borderWidth * opts.pix); + context.stroke(); + } + context.fill(); + } + }; + break; + } + + if (opts.dataLabel !== false && process === 1) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[0]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process); + drawMountPointText(points, series, config, context, opts, zeroPoints); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: points, + eachSpacing: eachSpacing + }; +} + +function drawBarDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let yAxisPoints = []; + let eachSpacing = (opts.height - opts.area[0] - opts.area[2])/opts.categories.length; + for (let i = 0; i < opts.categories.length; i++) { + yAxisPoints.push(opts.area[0] + eachSpacing / 2 + eachSpacing * i); + } + let columnOption = assign({}, { + type: 'group', + width: eachSpacing / 2, + meterBorder: 4, + meterFillColor: '#FFFFFF', + barBorderCircle: false, + barBorderRadius: [], + seriesGap: 2, + linearType: 'none', + linearOpacity: 1, + customColor: [], + colorStop: 0, + }, opts.extra.bar); + let calPoints = []; + context.save(); + let leftNum = -2; + let rightNum = yAxisPoints.length + 2; + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { + drawBarToolTipSplitArea(opts.tooltip.offset.y, opts, config, context, eachSpacing); + } + columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config); + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.xAxisData.ranges); + maxRange = ranges.pop(); + minRange = ranges.shift(); + var data = eachSeries.data; + switch (columnOption.type) { + case 'group': + var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process); + var tooltipPoints = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + calPoints.push(tooltipPoints); + points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + //fix issues/I27B1N yyoinge & Joeshu + if (item !== null && i > leftNum && i < rightNum) { + //var startX = item.x - item.width / 2; + var startX = opts.area[3]; + var startY = item.y - item.width / 2; + var height = item.height; + context.beginPath(); + var fillColor = item.color || eachSeries.color + var strokeColor = item.color || eachSeries.color + if (columnOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, item.x, item.y); + //透明渐变 + if (columnOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity)); + grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + // 圆角边框 + if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) { + const left = startX; + const width = item.width; + const top = item.y - item.width / 2; + const height = item.height; + if (columnOption.barBorderCircle) { + columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; + } + let [r0, r1, r2, r3] = columnOption.barBorderRadius; + let minRadius = Math.min(width/2,height/2); + r0 = r0 > minRadius ? minRadius : r0; + r1 = r1 > minRadius ? minRadius : r1; + r2 = r2 > minRadius ? minRadius : r2; + r3 = r3 > minRadius ? minRadius : r3; + r0 = r0 < 0 ? 0 : r0; + r1 = r1 < 0 ? 0 : r1; + r2 = r2 < 0 ? 0 : r2; + r3 = r3 < 0 ? 0 : r3; + + context.arc(left + r3, top + r3, r3, -Math.PI, -Math.PI / 2); + context.arc(item.x - r0, top + r0, r0, -Math.PI / 2, 0); + context.arc(item.x - r1, top + width - r1, r1, 0, Math.PI / 2); + context.arc(left + r2, top + width - r2, r2, Math.PI / 2, Math.PI); + } else { + context.moveTo(startX, startY); + context.lineTo(item.x, startY); + context.lineTo(item.x, startY + item.width); + context.lineTo(startX, startY + item.width); + context.lineTo(startX, startY); + context.setLineWidth(1) + context.setStrokeStyle(strokeColor); + } + context.setFillStyle(fillColor); + context.closePath(); + //context.stroke(); + context.fill(); + } + }; + break; + case 'stack': + // 绘制堆叠数据图 + var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + calPoints.push(points); + points = fixBarStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + context.beginPath(); + var fillColor = item.color || eachSeries.color; + var startX = item.x0; + context.setFillStyle(fillColor); + context.moveTo(startX, item.y - item.width/2); + context.fillRect(startX, item.y - item.width/2, item.height , item.width); + context.closePath(); + context.fill(); + } + }; + break; + } + }); + + if (opts.dataLabel !== false && process === 1) { + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.xAxisData.ranges); + maxRange = ranges.pop(); + minRange = ranges.shift(); + var data = eachSeries.data; + switch (columnOption.type) { + case 'group': + var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process); + points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts); + drawBarPointText(points, eachSeries, config, context, opts); + break; + case 'stack': + var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); + drawBarPointText(points, eachSeries, config, context, opts); + break; + } + }); + } + return { + yAxisPoints: yAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawCandleDataPoints(series, seriesMA, opts, config, context) { + var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1; + var candleOption = assign({}, { + color: {}, + average: {} + }, opts.extra.candle); + candleOption.color = assign({}, { + upLine: '#f04864', + upFill: '#f04864', + downLine: '#2fc25b', + downFill: '#2fc25b' + }, candleOption.color); + candleOption.average = assign({}, { + show: false, + name: [], + day: [], + color: config.color + }, candleOption.average); + opts.extra.candle = candleOption; + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + let calPoints = []; + context.save(); + let leftNum = -2; + let rightNum = xAxisPoints.length + 2; + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2; + rightNum = leftNum + opts.xAxis.itemCount + 4; + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + //画均线 + if (candleOption.average.show || seriesMA) { //Merge pull request !12 from 邱贵翔 + seriesMA.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + var splitPointList = splitPoints(points,eachSeries); + for (let i = 0; i < splitPointList.length; i++) { + let points = splitPointList[i]; + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setLineWidth(1); + if (points.length === 1) { + context.moveTo(points[0].x, points[0].y); + context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); + } else { + context.moveTo(points[0].x, points[0].y); + let startPoint = 0; + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + var ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, + item.y); + } + } + context.moveTo(points[0].x, points[0].y); + } + context.closePath(); + context.stroke(); + } + }); + } + //画K线 + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + calPoints.push(points); + var splitPointList = splitPoints(points,eachSeries); + for (let i = 0; i < splitPointList[0].length; i++) { + if (i > leftNum && i < rightNum) { + let item = splitPointList[0][i]; + context.beginPath(); + //如果上涨 + if (data[i][1] - data[i][0] > 0) { + context.setStrokeStyle(candleOption.color.upLine); + context.setFillStyle(candleOption.color.upFill); + context.setLineWidth(1 * opts.pix); + context.moveTo(item[3].x, item[3].y); //顶点 + context.lineTo(item[1].x, item[1].y); //收盘中间点 + context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点 + context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点 + context.lineTo(item[0].x, item[0].y); //开盘中间点 + context.lineTo(item[2].x, item[2].y); //底点 + context.lineTo(item[0].x, item[0].y); //开盘中间点 + context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点 + context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点 + context.lineTo(item[1].x, item[1].y); //收盘中间点 + context.moveTo(item[3].x, item[3].y); //顶点 + } else { + context.setStrokeStyle(candleOption.color.downLine); + context.setFillStyle(candleOption.color.downFill); + context.setLineWidth(1 * opts.pix); + context.moveTo(item[3].x, item[3].y); //顶点 + context.lineTo(item[0].x, item[0].y); //开盘中间点 + context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点 + context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点 + context.lineTo(item[1].x, item[1].y); //收盘中间点 + context.lineTo(item[2].x, item[2].y); //底点 + context.lineTo(item[1].x, item[1].y); //收盘中间点 + context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点 + context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点 + context.lineTo(item[0].x, item[0].y); //开盘中间点 + context.moveTo(item[3].x, item[3].y); //顶点 + } + context.closePath(); + context.fill(); + context.stroke(); + } + } + }); + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawAreaDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var areaOption = assign({}, { + type: 'straight', + opacity: 0.2, + addLine: false, + width: 2, + gradient: false, + activeType: 'none' + }, opts.extra.area); + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + let endY = opts.height - opts.area[2]; + let calPoints = []; + context.save(); + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + let data = eachSeries.data; + let points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + calPoints.push(points); + let splitPointList = splitPoints(points,eachSeries); + for (let i = 0; i < splitPointList.length; i++) { + let points = splitPointList[i]; + // 绘制区域数 + context.beginPath(); + context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity)); + if (areaOption.gradient) { + let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]); + gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity)); + gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1)); + context.setFillStyle(gradient); + } else { + context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity)); + } + context.setLineWidth(areaOption.width * opts.pix); + if (points.length > 1) { + let firstPoint = points[0]; + let lastPoint = points[points.length - 1]; + context.moveTo(firstPoint.x, firstPoint.y); + let startPoint = 0; + if (areaOption.type === 'curve') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + let ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); + } + }; + } + if (areaOption.type === 'straight') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, item.y); + } + }; + } + if (areaOption.type === 'step') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, points[j - 1].y); + context.lineTo(item.x, item.y); + } + }; + } + context.lineTo(lastPoint.x, endY); + context.lineTo(firstPoint.x, endY); + context.lineTo(firstPoint.x, firstPoint.y); + } else { + let item = points[0]; + context.moveTo(item.x - eachSpacing / 2, item.y); + // context.lineTo(item.x + eachSpacing / 2, item.y); + // context.lineTo(item.x + eachSpacing / 2, endY); + // context.lineTo(item.x - eachSpacing / 2, endY); + // context.moveTo(item.x - eachSpacing / 2, item.y); + } + context.closePath(); + context.fill(); + //画连线 + if (areaOption.addLine) { + if (eachSeries.lineType == 'dash') { + let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8; + dashLength *= opts.pix; + context.setLineDash([dashLength, dashLength]); + } + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setLineWidth(areaOption.width * opts.pix); + if (points.length === 1) { + context.moveTo(points[0].x, points[0].y); + // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); + } else { + context.moveTo(points[0].x, points[0].y); + let startPoint = 0; + if (areaOption.type === 'curve') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + let ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); + } + }; + } + if (areaOption.type === 'straight') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, item.y); + } + }; + } + if (areaOption.type === 'step') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, points[j - 1].y); + context.lineTo(item.x, item.y); + } + }; + } + context.moveTo(points[0].x, points[0].y); + } + context.stroke(); + context.setLineDash([]); + } + } + //画点 + if (opts.dataPointShape !== false) { + drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); + } + drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, areaOption,seriesIndex); + }); + + if (opts.dataLabel !== false && process === 1) { + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + drawPointText(points, eachSeries, config, context, opts); + }); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawScatterDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var scatterOption = assign({}, { + type: 'circle' + }, opts.extra.scatter); + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + var calPoints = []; + context.save(); + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setFillStyle(eachSeries.color); + context.setLineWidth(1 * opts.pix); + var shape = eachSeries.pointShape; + if (shape === 'diamond') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y); + context.lineTo(item.x, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'circle') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x + 2.5 * opts.pix, item.y); + context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false); + } + }); + } else if (shape === 'square') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x - 3.5, item.y - 3.5); + context.rect(item.x - 3.5, item.y - 3.5, 7, 7); + } + }); + } else if (shape === 'triangle') { + points.forEach(function(item, index) { + if (item !== null) { + context.moveTo(item.x, item.y - 4.5); + context.lineTo(item.x - 4.5, item.y + 4.5); + context.lineTo(item.x + 4.5, item.y + 4.5); + context.lineTo(item.x, item.y - 4.5); + } + }); + } else if (shape === 'triangle') { + return; + } + context.closePath(); + context.fill(); + context.stroke(); + }); + if (opts.dataLabel !== false && process === 1) { + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + drawPointText(points, eachSeries, config, context, opts); + }); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawBubbleDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var bubbleOption = assign({}, { + opacity: 1, + border:2 + }, opts.extra.bubble); + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + var calPoints = []; + context.save(); + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setLineWidth(bubbleOption.border * opts.pix); + context.setFillStyle(hexToRgb(eachSeries.color, bubbleOption.opacity)); + points.forEach(function(item, index) { + context.moveTo(item.x + item.r, item.y); + context.arc(item.x, item.y, item.r * opts.pix, 0, 2 * Math.PI, false); + }); + context.closePath(); + context.fill(); + context.stroke(); + + if (opts.dataLabel !== false && process === 1) { + points.forEach(function(item, index) { + context.beginPath(); + var fontSize = eachSeries.textSize * opts.pix || config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(eachSeries.textColor || "#FFFFFF"); + context.setTextAlign('center'); + context.fillText(String(item.t), item.x, item.y + fontSize/2); + context.closePath(); + context.stroke(); + context.setTextAlign('left'); + }); + } + }); + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawLineDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var lineOption = assign({}, { + type: 'straight', + width: 2, + activeType: 'none', + linearType: 'none', + onShadow: false, + animation: 'vertical', + }, opts.extra.line); + lineOption.width *= opts.pix; + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + var calPoints = []; + context.save(); + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + series.forEach(function(eachSeries, seriesIndex) { + // 这段很神奇的代码用于解决ios16的setStrokeStyle失效的bug + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.moveTo(-10000, -10000); + context.lineTo(-10001, -10001); + context.stroke(); + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process); + calPoints.push(points); + var splitPointList = splitPoints(points,eachSeries); + if (eachSeries.lineType == 'dash') { + let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8; + dashLength *= opts.pix; + context.setLineDash([dashLength, dashLength]); + } + context.beginPath(); + var strokeColor = eachSeries.color; + if (lineOption.linearType !== 'none' && eachSeries.linearColor && eachSeries.linearColor.length > 0) { + var grd = context.createLinearGradient(opts.chartData.xAxisData.startX, opts.height/2, opts.chartData.xAxisData.endX, opts.height/2); + for (var i = 0; i < eachSeries.linearColor.length; i++) { + grd.addColorStop(eachSeries.linearColor[i][0], hexToRgb(eachSeries.linearColor[i][1], 1)); + } + strokeColor = grd + } + context.setStrokeStyle(strokeColor); + if (lineOption.onShadow == true && eachSeries.setShadow && eachSeries.setShadow.length > 0) { + context.setShadow(eachSeries.setShadow[0], eachSeries.setShadow[1], eachSeries.setShadow[2], eachSeries.setShadow[3]); + }else{ + context.setShadow(0, 0, 0, 'rgba(0,0,0,0)'); + } + context.setLineWidth(lineOption.width); + splitPointList.forEach(function(points, index) { + if (points.length === 1) { + context.moveTo(points[0].x, points[0].y); + // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); + } else { + context.moveTo(points[0].x, points[0].y); + let startPoint = 0; + if (lineOption.type === 'curve') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + var ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); + } + }; + } + if (lineOption.type === 'straight') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, item.y); + } + }; + } + if (lineOption.type === 'step') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, points[j - 1].y); + context.lineTo(item.x, item.y); + } + }; + } + context.moveTo(points[0].x, points[0].y); + } + }); + context.stroke(); + context.setLineDash([]); + if (opts.dataPointShape !== false) { + drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); + } + drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, lineOption); + }); + if (opts.dataLabel !== false && process === 1) { + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + drawPointText(points, eachSeries, config, context, opts); + }); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing + }; +} + +function drawMixDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + eachSpacing = xAxisData.eachSpacing; + let columnOption = assign({}, { + width: eachSpacing / 2, + barBorderCircle: false, + barBorderRadius: [], + seriesGap: 2, + linearType: 'none', + linearOpacity: 1, + customColor: [], + colorStop: 0, + }, opts.extra.mix.column); + let areaOption = assign({}, { + opacity: 0.2, + gradient: false + }, opts.extra.mix.area); + let lineOption = assign({}, { + width: 2 + }, opts.extra.mix.line); + let endY = opts.height - opts.area[2]; + let calPoints = []; + var columnIndex = 0; + var columnLength = 0; + series.forEach(function(eachSeries, seriesIndex) { + if (eachSeries.type == 'column') { + columnLength += 1; + } + }); + context.save(); + let leftNum = -2; + let rightNum = xAxisPoints.length + 2; + let leftSpace = 0; + let rightSpace = opts.width + eachSpacing; + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2; + rightNum = leftNum + opts.xAxis.itemCount + 4; + leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3]; + rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; + } + columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config); + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + calPoints.push(points); + // 绘制柱状数据图 + if (eachSeries.type == 'column') { + points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts); + for (let i = 0; i < points.length; i++) { + let item = points[i]; + if (item !== null && i > leftNum && i < rightNum) { + var startX = item.x - item.width / 2; + var height = opts.height - item.y - opts.area[2]; + context.beginPath(); + var fillColor = item.color || eachSeries.color + var strokeColor = item.color || eachSeries.color + if (columnOption.linearType !== 'none') { + var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); + //透明渐变 + if (columnOption.linearType == 'opacity') { + grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } else { + grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity)); + grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity)); + grd.addColorStop(1, hexToRgb(fillColor, 1)); + } + fillColor = grd + } + // 圆角边框 + if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle) { + const left = startX; + const top = item.y; + const width = item.width; + const height = opts.height - opts.area[2] - item.y; + if (columnOption.barBorderCircle) { + columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; + } + let [r0, r1, r2, r3] = columnOption.barBorderRadius; + let minRadius = Math.min(width/2,height/2); + r0 = r0 > minRadius ? minRadius : r0; + r1 = r1 > minRadius ? minRadius : r1; + r2 = r2 > minRadius ? minRadius : r2; + r3 = r3 > minRadius ? minRadius : r3; + r0 = r0 < 0 ? 0 : r0; + r1 = r1 < 0 ? 0 : r1; + r2 = r2 < 0 ? 0 : r2; + r3 = r3 < 0 ? 0 : r3; + context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); + context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); + context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); + context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); + } else { + context.moveTo(startX, item.y); + context.lineTo(startX + item.width, item.y); + context.lineTo(startX + item.width, opts.height - opts.area[2]); + context.lineTo(startX, opts.height - opts.area[2]); + context.lineTo(startX, item.y); + context.setLineWidth(1) + context.setStrokeStyle(strokeColor); + } + context.setFillStyle(fillColor); + context.closePath(); + context.fill(); + } + } + columnIndex += 1; + } + //绘制区域图数据 + if (eachSeries.type == 'area') { + let splitPointList = splitPoints(points,eachSeries); + for (let i = 0; i < splitPointList.length; i++) { + let points = splitPointList[i]; + // 绘制区域数据 + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity)); + if (areaOption.gradient) { + let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]); + gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity)); + gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1)); + context.setFillStyle(gradient); + } else { + context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity)); + } + context.setLineWidth(2 * opts.pix); + if (points.length > 1) { + var firstPoint = points[0]; + let lastPoint = points[points.length - 1]; + context.moveTo(firstPoint.x, firstPoint.y); + let startPoint = 0; + if (eachSeries.style === 'curve') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + var ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); + } + }; + } else { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, item.y); + } + }; + } + context.lineTo(lastPoint.x, endY); + context.lineTo(firstPoint.x, endY); + context.lineTo(firstPoint.x, firstPoint.y); + } else { + let item = points[0]; + context.moveTo(item.x - eachSpacing / 2, item.y); + // context.lineTo(item.x + eachSpacing / 2, item.y); + // context.lineTo(item.x + eachSpacing / 2, endY); + // context.lineTo(item.x - eachSpacing / 2, endY); + // context.moveTo(item.x - eachSpacing / 2, item.y); + } + context.closePath(); + context.fill(); + } + } + // 绘制折线数据图 + if (eachSeries.type == 'line') { + var splitPointList = splitPoints(points,eachSeries); + splitPointList.forEach(function(points, index) { + if (eachSeries.lineType == 'dash') { + let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8; + dashLength *= opts.pix; + context.setLineDash([dashLength, dashLength]); + } + context.beginPath(); + context.setStrokeStyle(eachSeries.color); + context.setLineWidth(lineOption.width * opts.pix); + if (points.length === 1) { + context.moveTo(points[0].x, points[0].y); + // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); + } else { + context.moveTo(points[0].x, points[0].y); + let startPoint = 0; + if (eachSeries.style == 'curve') { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + var ctrlPoint = createCurveControlPoints(points, j - 1); + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, + item.x, item.y); + } + } + } else { + for (let j = 0; j < points.length; j++) { + let item = points[j]; + if (startPoint == 0 && item.x > leftSpace) { + context.moveTo(item.x, item.y); + startPoint = 1; + } + if (j > 0 && item.x > leftSpace && item.x < rightSpace) { + context.lineTo(item.x, item.y); + } + } + } + context.moveTo(points[0].x, points[0].y); + } + context.stroke(); + context.setLineDash([]); + }); + } + // 绘制点数据图 + if (eachSeries.type == 'point') { + eachSeries.addPoint = true; + } + if (eachSeries.addPoint == true && eachSeries.type !== 'column') { + drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); + } + }); + if (opts.dataLabel !== false && process === 1) { + var columnIndex = 0; + series.forEach(function(eachSeries, seriesIndex) { + let ranges, minRange, maxRange; + ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); + minRange = ranges.pop(); + maxRange = ranges.shift(); + var data = eachSeries.data; + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); + if (eachSeries.type !== 'column') { + drawPointText(points, eachSeries, config, context, opts); + } else { + points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts); + drawPointText(points, eachSeries, config, context, opts); + columnIndex += 1; + } + }); + } + context.restore(); + return { + xAxisPoints: xAxisPoints, + calPoints: calPoints, + eachSpacing: eachSpacing, + } +} + + +function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) { + var toolTipOption = opts.extra.tooltip || {}; + if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' || opts.type == 'column' || opts.type == 'mount' || opts.type == 'candle' || opts.type == 'mix')) { + drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) + } + context.save(); + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { + context.translate(opts._scrollDistance_, 0); + } + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { + drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context, eachSpacing, xAxisPoints); + } + context.restore(); + +} + +function drawXAxis(categories, opts, config, context) { + + let xAxisData = opts.chartData.xAxisData, + xAxisPoints = xAxisData.xAxisPoints, + startX = xAxisData.startX, + endX = xAxisData.endX, + eachSpacing = xAxisData.eachSpacing; + var boundaryGap = 'center'; + if (opts.type == 'bar' || opts.type == 'line' || opts.type == 'area'|| opts.type == 'scatter' || opts.type == 'bubble') { + boundaryGap = opts.xAxis.boundaryGap; + } + var startY = opts.height - opts.area[2]; + var endY = opts.area[0]; + + //绘制滚动条 + if (opts.enableScroll && opts.xAxis.scrollShow) { + var scrollY = opts.height - opts.area[2] + config.xAxisHeight; + var scrollScreenWidth = endX - startX; + var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1); + if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ + if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 + scrollTotalWidth += (opts.extra.mount.widthRatio - 1)*eachSpacing; + } + var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth; + var scrollLeft = 0; + if (opts._scrollDistance_) { + scrollLeft = -opts._scrollDistance_ * (scrollScreenWidth) / scrollTotalWidth; + } + context.beginPath(); + context.setLineCap('round'); + context.setLineWidth(6 * opts.pix); + context.setStrokeStyle(opts.xAxis.scrollBackgroundColor || "#EFEBEF"); + context.moveTo(startX, scrollY); + context.lineTo(endX, scrollY); + context.stroke(); + context.closePath(); + context.beginPath(); + context.setLineCap('round'); + context.setLineWidth(6 * opts.pix); + context.setStrokeStyle(opts.xAxis.scrollColor || "#A6A6A6"); + context.moveTo(startX + scrollLeft, scrollY); + context.lineTo(startX + scrollLeft + scrollWidth, scrollY); + context.stroke(); + context.closePath(); + context.setLineCap('butt'); + } + context.save(); + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) { + context.translate(opts._scrollDistance_, 0); + } + //绘制X轴刻度线 + if (opts.xAxis.calibration === true) { + context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc"); + context.setLineCap('butt'); + context.setLineWidth(1 * opts.pix); + xAxisPoints.forEach(function(item, index) { + if (index > 0) { + context.beginPath(); + context.moveTo(item - eachSpacing / 2, startY); + context.lineTo(item - eachSpacing / 2, startY + 3 * opts.pix); + context.closePath(); + context.stroke(); + } + }); + } + //绘制X轴网格 + if (opts.xAxis.disableGrid !== true) { + context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc"); + context.setLineCap('butt'); + context.setLineWidth(1 * opts.pix); + if (opts.xAxis.gridType == 'dash') { + context.setLineDash([opts.xAxis.dashLength * opts.pix, opts.xAxis.dashLength * opts.pix]); + } + opts.xAxis.gridEval = opts.xAxis.gridEval || 1; + xAxisPoints.forEach(function(item, index) { + if (index % opts.xAxis.gridEval == 0) { + context.beginPath(); + context.moveTo(item, startY); + context.lineTo(item, endY); + context.stroke(); + } + }); + context.setLineDash([]); + } + //绘制X轴文案 + if (opts.xAxis.disabled !== true) { + // 对X轴列表做抽稀处理 + //默认全部显示X轴标签 + let maxXAxisListLength = categories.length; + //如果设置了X轴单屏数量 + if (opts.xAxis.labelCount) { + //如果设置X轴密度 + if (opts.xAxis.itemCount) { + maxXAxisListLength = Math.ceil(categories.length / opts.xAxis.itemCount * opts.xAxis.labelCount); + } else { + maxXAxisListLength = opts.xAxis.labelCount; + } + maxXAxisListLength -= 1; + } + + let ratio = Math.ceil(categories.length / maxXAxisListLength); + + let newCategories = []; + let cgLength = categories.length; + for (let i = 0; i < cgLength; i++) { + if (i % ratio !== 0) { + newCategories.push(""); + } else { + newCategories.push(categories[i]); + } + } + newCategories[cgLength - 1] = categories[cgLength - 1]; + var xAxisFontSize = opts.xAxis.fontSize * opts.pix || config.fontSize; + if (config._xAxisTextAngle_ === 0) { + newCategories.forEach(function(item, index) { + var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item; + var offset = -measureText(String(xitem), xAxisFontSize, context) / 2; + if (boundaryGap == 'center') { + offset += eachSpacing / 2; + } + var scrollHeight = 0; + if (opts.xAxis.scrollShow) { + scrollHeight = 6 * opts.pix; + } + // 如果在主视图区域内 + var _scrollDistance_ = opts._scrollDistance_ || 0; + var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index]; + if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){ + context.beginPath(); + context.setFontSize(xAxisFontSize); + context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); + context.fillText(String(xitem), xAxisPoints[index] + offset, startY + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.fontSize) * opts.pix / 2 + opts.xAxis.fontSize * opts.pix); + context.closePath(); + context.stroke(); + } + }); + } else { + newCategories.forEach(function(item, index) { + var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item) : item; + // 如果在主视图区域内 + var _scrollDistance_ = opts._scrollDistance_ || 0; + var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index]; + if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){ + context.save(); + context.beginPath(); + context.setFontSize(xAxisFontSize); + context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); + var textWidth = measureText(String(xitem), xAxisFontSize, context); + var offsetX = xAxisPoints[index]; + if (boundaryGap == 'center') { + offsetX = xAxisPoints[index] + eachSpacing / 2; + } + var scrollHeight = 0; + if (opts.xAxis.scrollShow) { + scrollHeight = 6 * opts.pix; + } + var offsetY = startY + opts.xAxis.marginTop * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_)); + if(opts.xAxis.rotateAngle < 0){ + offsetX -= xAxisFontSize / 2; + textWidth = 0; + }else{ + offsetX += xAxisFontSize / 2; + textWidth = -textWidth; + } + context.translate(offsetX, offsetY); + context.rotate(-1 * config._xAxisTextAngle_); + context.fillText(String(xitem), textWidth , 0 ); + context.closePath(); + context.stroke(); + context.restore(); + } + }); + } + } + context.restore(); + + //画X轴标题 + if (opts.xAxis.title) { + context.beginPath(); + context.setFontSize(opts.xAxis.titleFontSize * opts.pix); + context.setFillStyle(opts.xAxis.titleFontColor); + context.fillText(String(opts.xAxis.title), opts.width - opts.area[1] + opts.xAxis.titleOffsetX * opts.pix,opts.height - opts.area[2] + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.titleFontSize) * opts.pix / 2 + (opts.xAxis.titleFontSize + opts.xAxis.titleOffsetY) * opts.pix); + context.closePath(); + context.stroke(); + } + + //绘制X轴轴线 + if (opts.xAxis.axisLine) { + context.beginPath(); + context.setStrokeStyle(opts.xAxis.axisLineColor); + context.setLineWidth(1 * opts.pix); + context.moveTo(startX, opts.height - opts.area[2]); + context.lineTo(endX, opts.height - opts.area[2]); + context.stroke(); + } +} + +function drawYAxisGrid(categories, opts, config, context) { + if (opts.yAxis.disableGrid === true) { + return; + } + let spacingValid = opts.height - opts.area[0] - opts.area[2]; + let eachSpacing = spacingValid / opts.yAxis.splitNumber; + let startX = opts.area[3]; + let xAxisPoints = opts.chartData.xAxisData.xAxisPoints, + xAxiseachSpacing = opts.chartData.xAxisData.eachSpacing; + let TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1); + if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1 ){ + if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 + TotalWidth += (opts.extra.mount.widthRatio - 1) * xAxiseachSpacing; + } + let endX = startX + TotalWidth; + let points = []; + let startY = 1 + if (opts.xAxis.axisLine === false) { + startY = 0 + } + for (let i = startY; i < opts.yAxis.splitNumber + 1; i++) { + points.push(opts.height - opts.area[2] - eachSpacing * i); + } + context.save(); + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) { + context.translate(opts._scrollDistance_, 0); + } + if (opts.yAxis.gridType == 'dash') { + context.setLineDash([opts.yAxis.dashLength * opts.pix, opts.yAxis.dashLength * opts.pix]); + } + context.setStrokeStyle(opts.yAxis.gridColor); + context.setLineWidth(1 * opts.pix); + points.forEach(function(item, index) { + context.beginPath(); + context.moveTo(startX, item); + context.lineTo(endX, item); + context.stroke(); + }); + context.setLineDash([]); + context.restore(); +} + +function drawYAxis(series, opts, config, context) { + if (opts.yAxis.disabled === true) { + return; + } + var spacingValid = opts.height - opts.area[0] - opts.area[2]; + var eachSpacing = spacingValid / opts.yAxis.splitNumber; + var startX = opts.area[3]; + var endX = opts.width - opts.area[1]; + var endY = opts.height - opts.area[2]; + // set YAxis background + context.beginPath(); + context.setFillStyle(opts.background); + if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'left') { + context.fillRect(0, 0, startX, endY + 2 * opts.pix); + } + if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'right') { + context.fillRect(endX, 0, opts.width, endY + 2 * opts.pix); + } + context.closePath(); + context.stroke(); + + let tStartLeft = opts.area[3]; + let tStartRight = opts.width - opts.area[1]; + let tStartCenter = opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2; + if (opts.yAxis.data) { + for (let i = 0; i < opts.yAxis.data.length; i++) { + let yData = opts.yAxis.data[i]; + var points = []; + if(yData.type === 'categories'){ + for (let i = 0; i <= yData.categories.length; i++) { + points.push(opts.area[0] + spacingValid / yData.categories.length / 2 + spacingValid / yData.categories.length * i); + } + }else{ + for (let i = 0; i <= opts.yAxis.splitNumber; i++) { + points.push(opts.area[0] + eachSpacing * i); + } + } + if (yData.disabled !== true) { + let rangesFormat = opts.chartData.yAxisData.rangesFormat[i]; + let yAxisFontSize = yData.fontSize ? yData.fontSize * opts.pix : config.fontSize; + let yAxisWidth = opts.chartData.yAxisData.yAxisWidth[i]; + let textAlign = yData.textAlign || "right"; + //画Y轴刻度及文案 + rangesFormat.forEach(function(item, index) { + var pos = points[index]; + context.beginPath(); + context.setFontSize(yAxisFontSize); + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(yData.axisLineColor || '#cccccc'); + context.setFillStyle(yData.fontColor || opts.fontColor); + let tmpstrat = 0; + let gapwidth = 4 * opts.pix; + if (yAxisWidth.position == 'left') { + //画刻度线 + if (yData.calibration == true) { + context.moveTo(tStartLeft, pos); + context.lineTo(tStartLeft - 3 * opts.pix, pos); + gapwidth += 3 * opts.pix; + } + //画文字 + switch (textAlign) { + case "left": + context.setTextAlign('left'); + tmpstrat = tStartLeft - yAxisWidth.width + break; + case "right": + context.setTextAlign('right'); + tmpstrat = tStartLeft - gapwidth + break; + default: + context.setTextAlign('center'); + tmpstrat = tStartLeft - yAxisWidth.width / 2 + } + context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix); + + } else if (yAxisWidth.position == 'right') { + //画刻度线 + if (yData.calibration == true) { + context.moveTo(tStartRight, pos); + context.lineTo(tStartRight + 3 * opts.pix, pos); + gapwidth += 3 * opts.pix; + } + switch (textAlign) { + case "left": + context.setTextAlign('left'); + tmpstrat = tStartRight + gapwidth + break; + case "right": + context.setTextAlign('right'); + tmpstrat = tStartRight + yAxisWidth.width + break; + default: + context.setTextAlign('center'); + tmpstrat = tStartRight + yAxisWidth.width / 2 + } + context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix); + } else if (yAxisWidth.position == 'center') { + //画刻度线 + if (yData.calibration == true) { + context.moveTo(tStartCenter, pos); + context.lineTo(tStartCenter - 3 * opts.pix, pos); + gapwidth += 3 * opts.pix; + } + //画文字 + switch (textAlign) { + case "left": + context.setTextAlign('left'); + tmpstrat = tStartCenter - yAxisWidth.width + break; + case "right": + context.setTextAlign('right'); + tmpstrat = tStartCenter - gapwidth + break; + default: + context.setTextAlign('center'); + tmpstrat = tStartCenter - yAxisWidth.width / 2 + } + context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix); + } + context.closePath(); + context.stroke(); + context.setTextAlign('left'); + }); + //画Y轴轴线 + if (yData.axisLine !== false) { + context.beginPath(); + context.setStrokeStyle(yData.axisLineColor || '#cccccc'); + context.setLineWidth(1 * opts.pix); + if (yAxisWidth.position == 'left') { + context.moveTo(tStartLeft, opts.height - opts.area[2]); + context.lineTo(tStartLeft, opts.area[0]); + } else if (yAxisWidth.position == 'right') { + context.moveTo(tStartRight, opts.height - opts.area[2]); + context.lineTo(tStartRight, opts.area[0]); + } else if (yAxisWidth.position == 'center') { + context.moveTo(tStartCenter, opts.height - opts.area[2]); + context.lineTo(tStartCenter, opts.area[0]); + } + context.stroke(); + } + //画Y轴标题 + if (opts.yAxis.showTitle) { + let titleFontSize = yData.titleFontSize * opts.pix || config.fontSize; + let title = yData.title; + context.beginPath(); + context.setFontSize(titleFontSize); + context.setFillStyle(yData.titleFontColor || opts.fontColor); + if (yAxisWidth.position == 'left') { + context.fillText(title, tStartLeft - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix); + } else if (yAxisWidth.position == 'right') { + context.fillText(title, tStartRight - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix); + } else if (yAxisWidth.position == 'center') { + context.fillText(title, tStartCenter - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix); + } + context.closePath(); + context.stroke(); + } + if (yAxisWidth.position == 'left') { + tStartLeft -= (yAxisWidth.width + opts.yAxis.padding * opts.pix); + } else { + tStartRight += yAxisWidth.width + opts.yAxis.padding * opts.pix; + } + } + } + } + +} + +function drawLegend(series, opts, config, context, chartData) { + if (opts.legend.show === false) { + return; + } + let legendData = chartData.legendData; + let legendList = legendData.points; + let legendArea = legendData.area; + let padding = opts.legend.padding * opts.pix; + let fontSize = opts.legend.fontSize * opts.pix; + let shapeWidth = 15 * opts.pix; + let shapeRight = 5 * opts.pix; + let itemGap = opts.legend.itemGap * opts.pix; + let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize); + //画背景及边框 + context.beginPath(); + context.setLineWidth(opts.legend.borderWidth * opts.pix); + context.setStrokeStyle(opts.legend.borderColor); + context.setFillStyle(opts.legend.backgroundColor); + context.moveTo(legendArea.start.x, legendArea.start.y); + context.rect(legendArea.start.x, legendArea.start.y, legendArea.width, legendArea.height); + context.closePath(); + context.fill(); + context.stroke(); + legendList.forEach(function(itemList, listIndex) { + let width = 0; + let height = 0; + width = legendData.widthArr[listIndex]; + height = legendData.heightArr[listIndex]; + let startX = 0; + let startY = 0; + if (opts.legend.position == 'top' || opts.legend.position == 'bottom') { + switch (opts.legend.float) { + case 'left': + startX = legendArea.start.x + padding; + break; + case 'right': + startX = legendArea.start.x + legendArea.width - width; + break; + default: + startX = legendArea.start.x + (legendArea.width - width) / 2; + } + startY = legendArea.start.y + padding + listIndex * lineHeight; + } else { + if (listIndex == 0) { + width = 0; + } else { + width = legendData.widthArr[listIndex - 1]; + } + startX = legendArea.start.x + padding + width; + startY = legendArea.start.y + padding + (legendArea.height - height) / 2; + } + context.setFontSize(config.fontSize); + for (let i = 0; i < itemList.length; i++) { + let item = itemList[i]; + item.area = [0, 0, 0, 0]; + item.area[0] = startX; + item.area[1] = startY; + item.area[3] = startY + lineHeight; + context.beginPath(); + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(item.show ? item.color : opts.legend.hiddenColor); + context.setFillStyle(item.show ? item.color : opts.legend.hiddenColor); + switch (item.legendShape) { + case 'line': + context.moveTo(startX, startY + 0.5 * lineHeight - 2 * opts.pix); + context.fillRect(startX, startY + 0.5 * lineHeight - 2 * opts.pix, 15 * opts.pix, 4 * opts.pix); + break; + case 'triangle': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix); + context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix); + context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix); + break; + case 'diamond': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix); + context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix); + context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight); + context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix); + break; + case 'circle': + context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight); + context.arc(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight, 5 * opts.pix, 0, 2 * Math.PI); + break; + case 'rect': + context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix); + context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); + break; + case 'square': + context.moveTo(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix); + context.fillRect(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix); + break; + case 'none': + break; + default: + context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix); + context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); + } + context.closePath(); + context.fill(); + context.stroke(); + startX += shapeWidth + shapeRight; + let fontTrans = 0.5 * lineHeight + 0.5 * fontSize - 2; + const legendText = item.legendText ? item.legendText : item.name; + context.beginPath(); + context.setFontSize(fontSize); + context.setFillStyle(item.show ? opts.legend.fontColor : opts.legend.hiddenColor); + context.fillText(legendText, startX, startY + fontTrans); + context.closePath(); + context.stroke(); + if (opts.legend.position == 'top' || opts.legend.position == 'bottom') { + startX += measureText(legendText, fontSize, context) + itemGap; + item.area[2] = startX; + } else { + item.area[2] = startX + measureText(legendText, fontSize, context) + itemGap;; + startX -= shapeWidth + shapeRight; + startY += lineHeight; + } + } + }); +} + +function drawPieDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var pieOption = assign({}, { + activeOpacity: 0.5, + activeRadius: 10, + offsetAngle: 0, + labelWidth: 15, + ringWidth: 30, + customRadius: 0, + border: false, + borderWidth: 2, + borderColor: '#FFFFFF', + centerColor: '#FFFFFF', + linearType: 'none', + customColor: [], + }, opts.type == "pie" ? opts.extra.pie : opts.extra.ring); + var centerPosition = { + x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2, + y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2 + }; + if (config.pieChartLinePadding == 0) { + config.pieChartLinePadding = pieOption.activeRadius * opts.pix; + } + + var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding); + radius = radius < 10 ? 10 : radius; + if (pieOption.customRadius > 0) { + radius = pieOption.customRadius * opts.pix; + } + series = getPieDataPoints(series, radius, process); + var activeRadius = pieOption.activeRadius * opts.pix; + pieOption.customColor = fillCustomColor(pieOption.linearType, pieOption.customColor, series, config); + series = series.map(function(eachSeries) { + eachSeries._start_ += (pieOption.offsetAngle) * Math.PI / 180; + return eachSeries; + }); + series.forEach(function(eachSeries, seriesIndex) { + if (opts.tooltip) { + if (opts.tooltip.index == seriesIndex) { + context.beginPath(); + context.setFillStyle(hexToRgb(eachSeries.color, pieOption.activeOpacity || 0.5)); + context.moveTo(centerPosition.x, centerPosition.y); + context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_ + activeRadius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI); + context.closePath(); + context.fill(); + } + } + context.beginPath(); + context.setLineWidth(pieOption.borderWidth * opts.pix); + context.lineJoin = "round"; + context.setStrokeStyle(pieOption.borderColor); + var fillcolor = eachSeries.color; + if (pieOption.linearType == 'custom') { + var grd; + if(context.createCircularGradient){ + grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_) + }else{ + grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_) + } + grd.addColorStop(0, hexToRgb(pieOption.customColor[eachSeries.linearIndex], 1)) + grd.addColorStop(1, hexToRgb(eachSeries.color, 1)) + fillcolor = grd + } + context.setFillStyle(fillcolor); + context.moveTo(centerPosition.x, centerPosition.y); + context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI); + context.closePath(); + context.fill(); + if (pieOption.border == true) { + context.stroke(); + } + }); + if (opts.type === 'ring') { + var innerPieWidth = radius * 0.6; + if (typeof pieOption.ringWidth === 'number' && pieOption.ringWidth > 0) { + innerPieWidth = Math.max(0, radius - pieOption.ringWidth * opts.pix); + } + context.beginPath(); + context.setFillStyle(pieOption.centerColor); + context.moveTo(centerPosition.x, centerPosition.y); + context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI); + context.closePath(); + context.fill(); + } + if (opts.dataLabel !== false && process === 1) { + drawPieText(series, opts, config, context, radius, centerPosition); + } + if (process === 1 && opts.type === 'ring') { + drawRingTitle(opts, config, context, centerPosition); + } + return { + center: centerPosition, + radius: radius, + series: series + }; +} + +function drawRoseDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var roseOption = assign({}, { + type: 'area', + activeOpacity: 0.5, + activeRadius: 10, + offsetAngle: 0, + labelWidth: 15, + border: false, + borderWidth: 2, + borderColor: '#FFFFFF', + linearType: 'none', + customColor: [], + }, opts.extra.rose); + if (config.pieChartLinePadding == 0) { + config.pieChartLinePadding = roseOption.activeRadius * opts.pix; + } + var centerPosition = { + x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2, + y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2 + }; + var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding); + radius = radius < 10 ? 10 : radius; + var minRadius = roseOption.minRadius || radius * 0.5; + if(radius < minRadius){ + radius = minRadius + 10; + } + series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process); + var activeRadius = roseOption.activeRadius * opts.pix; + roseOption.customColor = fillCustomColor(roseOption.linearType, roseOption.customColor, series, config); + series = series.map(function(eachSeries) { + eachSeries._start_ += (roseOption.offsetAngle || 0) * Math.PI / 180; + return eachSeries; + }); + series.forEach(function(eachSeries, seriesIndex) { + if (opts.tooltip) { + if (opts.tooltip.index == seriesIndex) { + context.beginPath(); + context.setFillStyle(hexToRgb(eachSeries.color, roseOption.activeOpacity || 0.5)); + context.moveTo(centerPosition.x, centerPosition.y); + context.arc(centerPosition.x, centerPosition.y, activeRadius + eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI); + context.closePath(); + context.fill(); + } + } + context.beginPath(); + context.setLineWidth(roseOption.borderWidth * opts.pix); + context.lineJoin = "round"; + context.setStrokeStyle(roseOption.borderColor); + var fillcolor = eachSeries.color; + if (roseOption.linearType == 'custom') { + var grd; + if(context.createCircularGradient){ + grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_) + }else{ + grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_) + } + grd.addColorStop(0, hexToRgb(roseOption.customColor[eachSeries.linearIndex], 1)) + grd.addColorStop(1, hexToRgb(eachSeries.color, 1)) + fillcolor = grd + } + context.setFillStyle(fillcolor); + context.moveTo(centerPosition.x, centerPosition.y); + context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI); + context.closePath(); + context.fill(); + if (roseOption.border == true) { + context.stroke(); + } + }); + + if (opts.dataLabel !== false && process === 1) { + drawPieText(series, opts, config, context, radius, centerPosition); + } + return { + center: centerPosition, + radius: radius, + series: series + }; +} + +function drawArcbarDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var arcbarOption = assign({}, { + startAngle: 0.75, + endAngle: 0.25, + type: 'default', + direction: 'cw', + lineCap: 'round', + width: 12 , + gap: 2 , + linearType: 'none', + customColor: [], + }, opts.extra.arcbar); + series = getArcbarDataPoints(series, arcbarOption, process); + var centerPosition; + if (arcbarOption.centerX || arcbarOption.centerY) { + centerPosition = { + x: arcbarOption.centerX ? arcbarOption.centerX : opts.width / 2, + y: arcbarOption.centerY ? arcbarOption.centerY : opts.height / 2 + }; + } else { + centerPosition = { + x: opts.width / 2, + y: opts.height / 2 + }; + } + var radius; + if (arcbarOption.radius) { + radius = arcbarOption.radius; + } else { + radius = Math.min(centerPosition.x, centerPosition.y); + radius -= 5 * opts.pix; + radius -= arcbarOption.width / 2; + } + radius = radius < 10 ? 10 : radius; + arcbarOption.customColor = fillCustomColor(arcbarOption.linearType, arcbarOption.customColor, series, config); + + for (let i = 0; i < series.length; i++) { + let eachSeries = series[i]; + //背景颜色 + context.setLineWidth(arcbarOption.width * opts.pix); + context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9'); + context.setLineCap(arcbarOption.lineCap); + context.beginPath(); + if (arcbarOption.type == 'default') { + context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, arcbarOption.direction == 'ccw'); + } else { + context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, 0, 2 * Math.PI, arcbarOption.direction == 'ccw'); + } + context.stroke(); + //进度条 + var fillColor = eachSeries.color + if(arcbarOption.linearType == 'custom'){ + var grd = context.createLinearGradient(centerPosition.x - radius, centerPosition.y, centerPosition.x + radius, centerPosition.y); + grd.addColorStop(1, hexToRgb(arcbarOption.customColor[eachSeries.linearIndex], 1)) + grd.addColorStop(0, hexToRgb(eachSeries.color, 1)) + fillColor = grd; + } + context.setLineWidth(arcbarOption.width * opts.pix); + context.setStrokeStyle(fillColor); + context.setLineCap(arcbarOption.lineCap); + context.beginPath(); + context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, arcbarOption.direction == 'ccw'); + context.stroke(); + } + drawRingTitle(opts, config, context, centerPosition); + return { + center: centerPosition, + radius: radius, + series: series + }; +} + +function drawGaugeDataPoints(categories, series, opts, config, context) { + var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1; + var gaugeOption = assign({}, { + type: 'default', + startAngle: 0.75, + endAngle: 0.25, + width: 15, + labelOffset:13, + splitLine: { + fixRadius: 0, + splitNumber: 10, + width: 15, + color: '#FFFFFF', + childNumber: 5, + childWidth: 5 + }, + pointer: { + width: 15, + color: 'auto' + } + }, opts.extra.gauge); + if (gaugeOption.oldAngle == undefined) { + gaugeOption.oldAngle = gaugeOption.startAngle; + } + if (gaugeOption.oldData == undefined) { + gaugeOption.oldData = 0; + } + categories = getGaugeAxisPoints(categories, gaugeOption.startAngle, gaugeOption.endAngle); + var centerPosition = { + x: opts.width / 2, + y: opts.height / 2 + }; + var radius = Math.min(centerPosition.x, centerPosition.y); + radius -= 5 * opts.pix; + radius -= gaugeOption.width / 2; + radius = radius < 10 ? 10 : radius; + var innerRadius = radius - gaugeOption.width; + var totalAngle = 0; + //判断仪表盘的样式:default百度样式,progress新样式 + if (gaugeOption.type == 'progress') { + //## 第一步画中心圆形背景和进度条背景 + //中心圆形背景 + var pieRadius = radius - gaugeOption.width * 3; + context.beginPath(); + let gradient = context.createLinearGradient(centerPosition.x, centerPosition.y - pieRadius, centerPosition.x, centerPosition.y + pieRadius); + //配置渐变填充(起点:中心点向上减半径;结束点中心点向下加半径) + gradient.addColorStop('0', hexToRgb(series[0].color, 0.3)); + gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1)); + context.setFillStyle(gradient); + context.arc(centerPosition.x, centerPosition.y, pieRadius, 0, 2 * Math.PI, false); + context.fill(); + //画进度条背景 + context.setLineWidth(gaugeOption.width); + context.setStrokeStyle(hexToRgb(series[0].color, 0.3)); + context.setLineCap('round'); + context.beginPath(); + context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, gaugeOption.endAngle * Math.PI, false); + context.stroke(); + //## 第二步画刻度线 + if (gaugeOption.endAngle < gaugeOption.startAngle) { + totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; + } else { + totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; + } + let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; + let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber; + let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius; + let endX = -radius - gaugeOption.width - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width; + context.save(); + context.translate(centerPosition.x, centerPosition.y); + context.rotate((gaugeOption.startAngle - 1) * Math.PI); + let len = gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; + let proc = series[0].data * process; + for (let i = 0; i < len; i++) { + context.beginPath(); + //刻度线随进度变色 + if (proc > (i / len)) { + context.setStrokeStyle(hexToRgb(series[0].color, 1)); + } else { + context.setStrokeStyle(hexToRgb(series[0].color, 0.3)); + } + context.setLineWidth(3 * opts.pix); + context.moveTo(startX, 0); + context.lineTo(endX, 0); + context.stroke(); + context.rotate(childAngle * Math.PI); + } + context.restore(); + //## 第三步画进度条 + series = getGaugeArcbarDataPoints(series, gaugeOption, process); + context.setLineWidth(gaugeOption.width); + context.setStrokeStyle(series[0].color); + context.setLineCap('round'); + context.beginPath(); + context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, series[0]._proportion_ * Math.PI, false); + context.stroke(); + //## 第四步画指针 + let pointerRadius = radius - gaugeOption.width * 2.5; + context.save(); + context.translate(centerPosition.x, centerPosition.y); + context.rotate((series[0]._proportion_ - 1) * Math.PI); + context.beginPath(); + context.setLineWidth(gaugeOption.width / 3); + let gradient3 = context.createLinearGradient(0, -pointerRadius * 0.6, 0, pointerRadius * 0.6); + gradient3.addColorStop('0', hexToRgb('#FFFFFF', 0)); + gradient3.addColorStop('0.5', hexToRgb(series[0].color, 1)); + gradient3.addColorStop('1.0', hexToRgb('#FFFFFF', 0)); + context.setStrokeStyle(gradient3); + context.arc(0, 0, pointerRadius, 0.85 * Math.PI, 1.15 * Math.PI, false); + context.stroke(); + context.beginPath(); + context.setLineWidth(1); + context.setStrokeStyle(series[0].color); + context.setFillStyle(series[0].color); + context.moveTo(-pointerRadius - gaugeOption.width / 3 / 2, -4); + context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2 - 4, 0); + context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, 4); + context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, -4); + context.stroke(); + context.fill(); + context.restore(); + //default百度样式 + } else { + //画背景 + context.setLineWidth(gaugeOption.width); + context.setLineCap('butt'); + for (let i = 0; i < categories.length; i++) { + let eachCategories = categories[i]; + context.beginPath(); + context.setStrokeStyle(eachCategories.color); + context.arc(centerPosition.x, centerPosition.y, radius, eachCategories._startAngle_ * Math.PI, eachCategories._endAngle_ * Math.PI, false); + context.stroke(); + } + context.save(); + //画刻度线 + if (gaugeOption.endAngle < gaugeOption.startAngle) { + totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; + } else { + totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; + } + let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; + let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber; + let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius; + let endX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width; + let childendX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.childWidth; + context.translate(centerPosition.x, centerPosition.y); + context.rotate((gaugeOption.startAngle - 1) * Math.PI); + for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) { + context.beginPath(); + context.setStrokeStyle(gaugeOption.splitLine.color); + context.setLineWidth(2 * opts.pix); + context.moveTo(startX, 0); + context.lineTo(endX, 0); + context.stroke(); + context.rotate(splitAngle * Math.PI); + } + context.restore(); + context.save(); + context.translate(centerPosition.x, centerPosition.y); + context.rotate((gaugeOption.startAngle - 1) * Math.PI); + for (let i = 0; i < gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; i++) { + context.beginPath(); + context.setStrokeStyle(gaugeOption.splitLine.color); + context.setLineWidth(1 * opts.pix); + context.moveTo(startX, 0); + context.lineTo(childendX, 0); + context.stroke(); + context.rotate(childAngle * Math.PI); + } + context.restore(); + //画指针 + series = getGaugeDataPoints(series, categories, gaugeOption, process); + for (let i = 0; i < series.length; i++) { + let eachSeries = series[i]; + context.save(); + context.translate(centerPosition.x, centerPosition.y); + context.rotate((eachSeries._proportion_ - 1) * Math.PI); + context.beginPath(); + context.setFillStyle(eachSeries.color); + context.moveTo(gaugeOption.pointer.width, 0); + context.lineTo(0, -gaugeOption.pointer.width / 2); + context.lineTo(-innerRadius, 0); + context.lineTo(0, gaugeOption.pointer.width / 2); + context.lineTo(gaugeOption.pointer.width, 0); + context.closePath(); + context.fill(); + context.beginPath(); + context.setFillStyle('#FFFFFF'); + context.arc(0, 0, gaugeOption.pointer.width / 6, 0, 2 * Math.PI, false); + context.fill(); + context.restore(); + } + if (opts.dataLabel !== false) { + drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context); + } + } + //画仪表盘标题,副标题 + drawRingTitle(opts, config, context, centerPosition); + if (process === 1 && opts.type === 'gauge') { + opts.extra.gauge.oldAngle = series[0]._proportion_; + opts.extra.gauge.oldData = series[0].data; + } + return { + center: centerPosition, + radius: radius, + innerRadius: innerRadius, + categories: categories, + totalAngle: totalAngle + }; +} + +function drawRadarDataPoints(series, opts, config, context) { + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + var radarOption = assign({}, { + gridColor: '#cccccc', + gridType: 'radar', + gridEval:1, + axisLabel:false, + axisLabelTofix:0, + labelShow:true, + labelColor:'#666666', + labelPointShow:false, + labelPointRadius:3, + labelPointColor:'#cccccc', + opacity: 0.2, + gridCount: 3, + border:false, + borderWidth:2, + linearType: 'none', + customColor: [], + }, opts.extra.radar); + var coordinateAngle = getRadarCoordinateSeries(opts.categories.length); + var centerPosition = { + x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2, + y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2 + }; + var xr = (opts.width - opts.area[1] - opts.area[3]) / 2 + var yr = (opts.height - opts.area[0] - opts.area[2]) / 2 + var radius = Math.min(xr - (getMaxTextListLength(opts.categories, config.fontSize, context) + config.radarLabelTextMargin), yr - config.radarLabelTextMargin); + radius -= config.radarLabelTextMargin * opts.pix; + radius = radius < 10 ? 10 : radius; + radius = radarOption.radius ? radarOption.radius : radius; + // 画分割线 + context.beginPath(); + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(radarOption.gridColor); + coordinateAngle.forEach(function(angle,index) { + var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition); + context.moveTo(centerPosition.x, centerPosition.y); + if (index % radarOption.gridEval == 0) { + context.lineTo(pos.x, pos.y); + } + }); + context.stroke(); + context.closePath(); + + // 画背景网格 + var _loop = function _loop(i) { + var startPos = {}; + context.beginPath(); + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(radarOption.gridColor); + if (radarOption.gridType == 'radar') { + coordinateAngle.forEach(function(angle, index) { + var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(angle), radius / + radarOption.gridCount * i * Math.sin(angle), centerPosition); + if (index === 0) { + startPos = pos; + context.moveTo(pos.x, pos.y); + } else { + context.lineTo(pos.x, pos.y); + } + }); + context.lineTo(startPos.x, startPos.y); + } else { + var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(1.5), radius / radarOption.gridCount * i * Math.sin(1.5), centerPosition); + context.arc(centerPosition.x, centerPosition.y, centerPosition.y - pos.y, 0, 2 * Math.PI, false); + } + context.stroke(); + context.closePath(); + }; + for (var i = 1; i <= radarOption.gridCount; i++) { + _loop(i); + } + radarOption.customColor = fillCustomColor(radarOption.linearType, radarOption.customColor, series, config); + var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process); + radarDataPoints.forEach(function(eachSeries, seriesIndex) { + // 绘制区域数据 + context.beginPath(); + context.setLineWidth(radarOption.borderWidth * opts.pix); + context.setStrokeStyle(eachSeries.color); + + var fillcolor = hexToRgb(eachSeries.color, radarOption.opacity); + if (radarOption.linearType == 'custom') { + var grd; + if(context.createCircularGradient){ + grd = context.createCircularGradient(centerPosition.x, centerPosition.y, radius) + }else{ + grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, radius) + } + grd.addColorStop(0, hexToRgb(radarOption.customColor[series[seriesIndex].linearIndex], radarOption.opacity)) + grd.addColorStop(1, hexToRgb(eachSeries.color, radarOption.opacity)) + fillcolor = grd + } + + context.setFillStyle(fillcolor); + eachSeries.data.forEach(function(item, index) { + if (index === 0) { + context.moveTo(item.position.x, item.position.y); + } else { + context.lineTo(item.position.x, item.position.y); + } + }); + context.closePath(); + context.fill(); + if(radarOption.border === true){ + context.stroke(); + } + context.closePath(); + if (opts.dataPointShape !== false) { + var points = eachSeries.data.map(function(item) { + return item.position; + }); + drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); + } + }); + // 画刻度值 + if(radarOption.axisLabel === true){ + const maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series))); + const stepLength = radius / radarOption.gridCount; + const fontSize = opts.fontSize * opts.pix; + context.setFontSize(fontSize); + context.setFillStyle(opts.fontColor); + context.setTextAlign('left'); + for (var i = 0; i < radarOption.gridCount + 1; i++) { + let label = i * maxData / radarOption.gridCount; + label = label.toFixed(radarOption.axisLabelTofix); + context.fillText(String(label), centerPosition.x + 3 * opts.pix, centerPosition.y - i * stepLength + fontSize / 2); + } + } + + // draw label text + drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context); + + // draw dataLabel + if (opts.dataLabel !== false && process === 1) { + radarDataPoints.forEach(function(eachSeries, seriesIndex) { + context.beginPath(); + var fontSize = eachSeries.textSize * opts.pix || config.fontSize; + context.setFontSize(fontSize); + context.setFillStyle(eachSeries.textColor || opts.fontColor); + eachSeries.data.forEach(function(item, index) { + //如果是中心点垂直的上下点位 + if(Math.abs(item.position.x - centerPosition.x)<2){ + //如果在上面 + if(item.position.y < centerPosition.y){ + context.setTextAlign('center'); + context.fillText(item.value, item.position.x, item.position.y - 4); + }else{ + context.setTextAlign('center'); + context.fillText(item.value, item.position.x, item.position.y + fontSize + 2); + } + }else{ + //如果在左侧 + if(item.position.x < centerPosition.x){ + context.setTextAlign('right'); + context.fillText(item.value, item.position.x - 4, item.position.y + fontSize / 2 - 2); + }else{ + context.setTextAlign('left'); + context.fillText(item.value, item.position.x + 4, item.position.y + fontSize / 2 - 2); + } + } + }); + context.closePath(); + context.stroke(); + }); + context.setTextAlign('left'); + } + + return { + center: centerPosition, + radius: radius, + angleList: coordinateAngle + }; +} + +// 经纬度转墨卡托 +function lonlat2mercator(longitude, latitude) { + var mercator = Array(2); + var x = longitude * 20037508.34 / 180; + var y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180); + y = y * 20037508.34 / 180; + mercator[0] = x; + mercator[1] = y; + return mercator; +} + +// 墨卡托转经纬度 +function mercator2lonlat(longitude, latitude) { + var lonlat = Array(2) + var x = longitude / 20037508.34 * 180; + var y = latitude / 20037508.34 * 180; + y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2); + lonlat[0] = x; + lonlat[1] = y; + return lonlat; +} + +function getBoundingBox(data) { + var bounds = {},coords; + bounds.xMin = 180; + bounds.xMax = 0; + bounds.yMin = 90; + bounds.yMax = 0 + for (var i = 0; i < data.length; i++) { + var coorda = data[i].geometry.coordinates + for (var k = 0; k < coorda.length; k++) { + coords = coorda[k]; + if (coords.length == 1) { + coords = coords[0] + } + for (var j = 0; j < coords.length; j++) { + var longitude = coords[j][0]; + var latitude = coords[j][1]; + var point = { + x: longitude, + y: latitude + } + bounds.xMin = bounds.xMin < point.x ? bounds.xMin : point.x; + bounds.xMax = bounds.xMax > point.x ? bounds.xMax : point.x; + bounds.yMin = bounds.yMin < point.y ? bounds.yMin : point.y; + bounds.yMax = bounds.yMax > point.y ? bounds.yMax : point.y; + } + } + } + return bounds; +} + +function coordinateToPoint(latitude, longitude, bounds, scale, xoffset, yoffset) { + return { + x: (longitude - bounds.xMin) * scale + xoffset, + y: (bounds.yMax - latitude) * scale + yoffset + }; +} + +function pointToCoordinate(pointY, pointX, bounds, scale, xoffset, yoffset) { + return { + x: (pointX - xoffset) / scale + bounds.xMin, + y: bounds.yMax - (pointY - yoffset) / scale + }; +} + +function isRayIntersectsSegment(poi, s_poi, e_poi) { + if (s_poi[1] == e_poi[1]) { + return false; + } + if (s_poi[1] > poi[1] && e_poi[1] > poi[1]) { + return false; + } + if (s_poi[1] < poi[1] && e_poi[1] < poi[1]) { + return false; + } + if (s_poi[1] == poi[1] && e_poi[1] > poi[1]) { + return false; + } + if (e_poi[1] == poi[1] && s_poi[1] > poi[1]) { + return false; + } + if (s_poi[0] < poi[0] && e_poi[1] < poi[1]) { + return false; + } + let xseg = e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]); + if (xseg < poi[0]) { + return false; + } else { + return true; + } +} + +function isPoiWithinPoly(poi, poly, mercator) { + let sinsc = 0; + for (let i = 0; i < poly.length; i++) { + let epoly = poly[i][0]; + if (poly.length == 1) { + epoly = poly[i][0] + } + for (let j = 0; j < epoly.length - 1; j++) { + let s_poi = epoly[j]; + let e_poi = epoly[j + 1]; + if (mercator) { + s_poi = lonlat2mercator(epoly[j][0], epoly[j][1]); + e_poi = lonlat2mercator(epoly[j + 1][0], epoly[j + 1][1]); + } + if (isRayIntersectsSegment(poi, s_poi, e_poi)) { + sinsc += 1; + } + } + } + if (sinsc % 2 == 1) { + return true; + } else { + return false; + } +} + +function drawMapDataPoints(series, opts, config, context) { + var mapOption = assign({}, { + border: true, + mercator: false, + borderWidth: 1, + active:true, + borderColor: '#666666', + fillOpacity: 0.6, + activeBorderColor: '#f04864', + activeFillColor: '#facc14', + activeFillOpacity: 1 + }, opts.extra.map); + var coords, point; + var data = series; + var bounds = getBoundingBox(data); + if (mapOption.mercator) { + var max = lonlat2mercator(bounds.xMax, bounds.yMax) + var min = lonlat2mercator(bounds.xMin, bounds.yMin) + bounds.xMax = max[0] + bounds.yMax = max[1] + bounds.xMin = min[0] + bounds.yMin = min[1] + } + var xScale = opts.width / Math.abs(bounds.xMax - bounds.xMin); + var yScale = opts.height / Math.abs(bounds.yMax - bounds.yMin); + var scale = xScale < yScale ? xScale : yScale; + var xoffset = opts.width / 2 - Math.abs(bounds.xMax - bounds.xMin) / 2 * scale; + var yoffset = opts.height / 2 - Math.abs(bounds.yMax - bounds.yMin) / 2 * scale; + for (var i = 0; i < data.length; i++) { + context.beginPath(); + context.setLineWidth(mapOption.borderWidth * opts.pix); + context.setStrokeStyle(mapOption.borderColor); + context.setFillStyle(hexToRgb(series[i].color, series[i].fillOpacity||mapOption.fillOpacity)); + if (mapOption.active == true && opts.tooltip) { + if (opts.tooltip.index == i) { + context.setStrokeStyle(mapOption.activeBorderColor); + context.setFillStyle(hexToRgb(mapOption.activeFillColor, mapOption.activeFillOpacity)); + } + } + var coorda = data[i].geometry.coordinates + for (var k = 0; k < coorda.length; k++) { + coords = coorda[k]; + if (coords.length == 1) { + coords = coords[0] + } + for (var j = 0; j < coords.length; j++) { + var gaosi = Array(2); + if (mapOption.mercator) { + gaosi = lonlat2mercator(coords[j][0], coords[j][1]) + } else { + gaosi = coords[j] + } + point = coordinateToPoint(gaosi[1], gaosi[0], bounds, scale, xoffset, yoffset) + if (j === 0) { + context.beginPath(); + context.moveTo(point.x, point.y); + } else { + context.lineTo(point.x, point.y); + } + } + context.fill(); + if (mapOption.border == true) { + context.stroke(); + } + } + } + if (opts.dataLabel == true) { + for (var i = 0; i < data.length; i++) { + var centerPoint = data[i].properties.centroid; + if (centerPoint) { + if (mapOption.mercator) { + centerPoint = lonlat2mercator(data[i].properties.centroid[0], data[i].properties.centroid[1]) + } + point = coordinateToPoint(centerPoint[1], centerPoint[0], bounds, scale, xoffset, yoffset); + let fontSize = data[i].textSize * opts.pix || config.fontSize; + let fontColor = data[i].textColor || opts.fontColor; + if(mapOption.active && mapOption.activeTextColor && opts.tooltip && opts.tooltip.index == i){ + fontColor = mapOption.activeTextColor; + } + let text = data[i].properties.name; + context.beginPath(); + context.setFontSize(fontSize) + context.setFillStyle(fontColor) + context.fillText(text, point.x - measureText(text, fontSize, context) / 2, point.y + fontSize / 2); + context.closePath(); + context.stroke(); + } + } + } + opts.chartData.mapData = { + bounds: bounds, + scale: scale, + xoffset: xoffset, + yoffset: yoffset, + mercator: mapOption.mercator + } + drawToolTipBridge(opts, config, context, 1); + context.draw(); +} + +function normalInt(min, max, iter) { + iter = iter == 0 ? 1 : iter; + var arr = []; + for (var i = 0; i < iter; i++) { + arr[i] = Math.random(); + }; + return Math.floor(arr.reduce(function(i, j) { + return i + j + }) / iter * (max - min)) + min; +}; + +function collisionNew(area, points, width, height) { + var isIn = false; + for (let i = 0; i < points.length; i++) { + if (points[i].area) { + if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i].area[0]) { + if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) { + isIn = true; + break; + } else { + isIn = false; + } + } else { + isIn = true; + break; + } + } + } + return isIn; +}; + +function getWordCloudPoint(opts, type, context) { + let points = opts.series; + switch (type) { + case 'normal': + for (let i = 0; i < points.length; i++) { + let text = points[i].name; + let tHeight = points[i].textSize * opts.pix; + let tWidth = measureText(text, tHeight, context); + let x, y; + let area; + let breaknum = 0; + while (true) { + breaknum++; + x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2; + y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2; + area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + + opts.height / 2 + ]; + let isCollision = collisionNew(area, points, opts.width, opts.height); + if (!isCollision) break; + if (breaknum == 1000) { + area = [-100, -100, -100, -100]; + break; + } + }; + points[i].area = area; + } + break; + case 'vertical': + function Spin() { + //获取均匀随机值,是否旋转,旋转的概率为(1-0.5) + if (Math.random() > 0.7) { + return true; + } else { + return false + }; + }; + for (let i = 0; i < points.length; i++) { + let text = points[i].name; + let tHeight = points[i].textSize * opts.pix; + let tWidth = measureText(text, tHeight, context); + let isSpin = Spin(); + let x, y, area, areav; + let breaknum = 0; + while (true) { + breaknum++; + let isCollision; + if (isSpin) { + x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2; + y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2; + area = [y - 5 - tWidth + opts.width / 2, (-x - 5 + opts.height / 2), y + 5 + opts.width / 2, (-x + tHeight + 5 + opts.height / 2)]; + areav = [opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) - 5, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) - 5, opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) + tHeight, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) + tWidth + 5]; + isCollision = collisionNew(areav, points, opts.height, opts.width); + } else { + x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2; + y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2; + area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + opts.height / 2]; + isCollision = collisionNew(area, points, opts.width, opts.height); + } + if (!isCollision) break; + if (breaknum == 1000) { + area = [-1000, -1000, -1000, -1000]; + break; + } + }; + if (isSpin) { + points[i].area = areav; + points[i].areav = area; + } else { + points[i].area = area; + } + points[i].rotate = isSpin; + }; + break; + } + return points; +} + +function drawWordCloudDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let wordOption = assign({}, { + type: 'normal', + autoColors: true + }, opts.extra.word); + if (!opts.chartData.wordCloudData) { + opts.chartData.wordCloudData = getWordCloudPoint(opts, wordOption.type, context); + } + context.beginPath(); + context.setFillStyle(opts.background); + context.rect(0, 0, opts.width, opts.height); + context.fill(); + context.save(); + let points = opts.chartData.wordCloudData; + context.translate(opts.width / 2, opts.height / 2); + for (let i = 0; i < points.length; i++) { + context.save(); + if (points[i].rotate) { + context.rotate(90 * Math.PI / 180); + } + let text = points[i].name; + let tHeight = points[i].textSize * opts.pix; + let tWidth = measureText(text, tHeight, context); + context.beginPath(); + context.setStrokeStyle(points[i].color); + context.setFillStyle(points[i].color); + context.setFontSize(tHeight); + if (points[i].rotate) { + if (points[i].areav[0] > 0) { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.strokeText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process); + } else { + context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process); + } + } else { + context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process); + } + } + } else { + if (points[i].area[0] > 0) { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.strokeText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process); + } else { + context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process); + } + } else { + context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process); + } + } + } + context.stroke(); + context.restore(); + } + context.restore(); +} + +function drawFunnelDataPoints(series, opts, config, context) { + let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; + let funnelOption = assign({}, { + type:'funnel', + activeWidth: 10, + activeOpacity: 0.3, + border: false, + borderWidth: 2, + borderColor: '#FFFFFF', + fillOpacity: 1, + minSize: 0, + labelAlign: 'right', + linearType: 'none', + customColor: [], + }, opts.extra.funnel); + let eachSpacing = (opts.height - opts.area[0] - opts.area[2]) / series.length; + let centerPosition = { + x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2, + y: opts.height - opts.area[2] + }; + let activeWidth = funnelOption.activeWidth * opts.pix; + let radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - activeWidth, (opts.height - opts.area[0] - opts.area[2]) / 2 - activeWidth); + let seriesNew = getFunnelDataPoints(series, radius, funnelOption, eachSpacing, process); + context.save(); + context.translate(centerPosition.x, centerPosition.y); + funnelOption.customColor = fillCustomColor(funnelOption.linearType, funnelOption.customColor, series, config); + if(funnelOption.type == 'pyramid'){ + for (let i = 0; i < seriesNew.length; i++) { + if (i == seriesNew.length -1) { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.beginPath(); + context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); + context.moveTo(-activeWidth, -eachSpacing); + context.lineTo(-seriesNew[i].radius - activeWidth, 0); + context.lineTo(seriesNew[i].radius + activeWidth, 0); + context.lineTo(activeWidth, -eachSpacing); + context.lineTo(-activeWidth, -eachSpacing); + context.closePath(); + context.fill(); + } + } + seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i]; + context.beginPath(); + context.setLineWidth(funnelOption.borderWidth * opts.pix); + context.setStrokeStyle(funnelOption.borderColor); + var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); + if (funnelOption.linearType == 'custom') { + var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); + grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); + grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + fillColor = grd + } + context.setFillStyle(fillColor); + context.moveTo(0, -eachSpacing); + context.lineTo(-seriesNew[i].radius, 0); + context.lineTo(seriesNew[i].radius, 0); + context.lineTo(0, -eachSpacing); + context.closePath(); + context.fill(); + if (funnelOption.border == true) { + context.stroke(); + } + } else { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.beginPath(); + context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); + context.moveTo(0, 0); + context.lineTo(-seriesNew[i].radius - activeWidth, 0); + context.lineTo(-seriesNew[i + 1].radius - activeWidth, -eachSpacing); + context.lineTo(seriesNew[i + 1].radius + activeWidth, -eachSpacing); + context.lineTo(seriesNew[i].radius + activeWidth, 0); + context.lineTo(0, 0); + context.closePath(); + context.fill(); + } + } + seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i]; + context.beginPath(); + context.setLineWidth(funnelOption.borderWidth * opts.pix); + context.setStrokeStyle(funnelOption.borderColor); + var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); + if (funnelOption.linearType == 'custom') { + var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); + grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); + grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + fillColor = grd + } + context.setFillStyle(fillColor); + context.moveTo(0, 0); + context.lineTo(-seriesNew[i].radius, 0); + context.lineTo(-seriesNew[i + 1].radius, -eachSpacing); + context.lineTo(seriesNew[i + 1].radius, -eachSpacing); + context.lineTo(seriesNew[i].radius, 0); + context.lineTo(0, 0); + context.closePath(); + context.fill(); + if (funnelOption.border == true) { + context.stroke(); + } + } + context.translate(0, -eachSpacing) + } + }else{ + context.translate(0, - (seriesNew.length - 1) * eachSpacing); + for (let i = 0; i < seriesNew.length; i++) { + if (i == seriesNew.length - 1) { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.beginPath(); + context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); + context.moveTo(-activeWidth - funnelOption.minSize/2, 0); + context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing); + context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing); + context.lineTo(activeWidth + funnelOption.minSize/2, 0); + context.lineTo(-activeWidth - funnelOption.minSize/2, 0); + context.closePath(); + context.fill(); + } + } + seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing, centerPosition.x + seriesNew[i].radius, centerPosition.y ]; + context.beginPath(); + context.setLineWidth(funnelOption.borderWidth * opts.pix); + context.setStrokeStyle(funnelOption.borderColor); + var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); + if (funnelOption.linearType == 'custom') { + var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); + grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); + grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + fillColor = grd + } + context.setFillStyle(fillColor); + context.moveTo(0, 0); + context.lineTo(-funnelOption.minSize/2, 0); + context.lineTo(-seriesNew[i].radius, -eachSpacing); + context.lineTo(seriesNew[i].radius, -eachSpacing); + context.lineTo(funnelOption.minSize/2, 0); + context.lineTo(0, 0); + context.closePath(); + context.fill(); + if (funnelOption.border == true) { + context.stroke(); + } + } else { + if (opts.tooltip) { + if (opts.tooltip.index == i) { + context.beginPath(); + context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); + context.moveTo(0, 0); + context.lineTo(-seriesNew[i + 1].radius - activeWidth, 0); + context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing); + context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing); + context.lineTo(seriesNew[i + 1].radius + activeWidth, 0); + context.lineTo(0, 0); + context.closePath(); + context.fill(); + } + } + seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i - 1)]; + context.beginPath(); + context.setLineWidth(funnelOption.borderWidth * opts.pix); + context.setStrokeStyle(funnelOption.borderColor); + var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); + if (funnelOption.linearType == 'custom') { + var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); + grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); + grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); + fillColor = grd + } + context.setFillStyle(fillColor); + context.moveTo(0, 0); + context.lineTo(-seriesNew[i + 1].radius, 0); + context.lineTo(-seriesNew[i].radius, -eachSpacing); + context.lineTo(seriesNew[i].radius, -eachSpacing); + context.lineTo(seriesNew[i + 1].radius, 0); + context.lineTo(0, 0); + context.closePath(); + context.fill(); + if (funnelOption.border == true) { + context.stroke(); + } + } + context.translate(0, eachSpacing) + } + } + + context.restore(); + if (opts.dataLabel !== false && process === 1) { + drawFunnelText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition); + } + if (process === 1) { + drawFunnelCenterText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition); + } + return { + center: centerPosition, + radius: radius, + series: seriesNew + }; +} + +function drawFunnelText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) { + for (let i = 0; i < series.length; i++) { + let item = series[i]; + if(item.labelShow === false){ + continue; + } + let startX, endX, startY, fontSize; + let text = item.formatter ? item.formatter(item,i,series,opts) : util.toFixed(item._proportion_ * 100) + '%'; + text = item.labelText ? item.labelText : text; + if (labelAlign == 'right') { + if (i == series.length -1) { + startX = (item.funnelArea[2] + centerPosition.x) / 2; + } else { + startX = (item.funnelArea[2] + series[i + 1].funnelArea[2]) / 2; + } + endX = startX + activeWidth * 2; + startY = item.funnelArea[1] + eachSpacing / 2; + fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix; + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(item.color); + context.setFillStyle(item.color); + context.beginPath(); + context.moveTo(startX, startY); + context.lineTo(endX, startY); + context.stroke(); + context.closePath(); + context.beginPath(); + context.moveTo(endX, startY); + context.arc(endX, startY, 2 * opts.pix, 0, 2 * Math.PI); + context.closePath(); + context.fill(); + context.beginPath(); + context.setFontSize(fontSize); + context.setFillStyle(item.textColor || opts.fontColor); + context.fillText(text, endX + 5, startY + fontSize / 2 - 2); + context.closePath(); + context.stroke(); + context.closePath(); + } + if (labelAlign == 'left') { + if (i == series.length -1) { + startX = (item.funnelArea[0] + centerPosition.x) / 2; + } else { + startX = (item.funnelArea[0] + series[i + 1].funnelArea[0]) / 2; + } + endX = startX - activeWidth * 2; + startY = item.funnelArea[1] + eachSpacing / 2; + fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix; + context.setLineWidth(1 * opts.pix); + context.setStrokeStyle(item.color); + context.setFillStyle(item.color); + context.beginPath(); + context.moveTo(startX, startY); + context.lineTo(endX, startY); + context.stroke(); + context.closePath(); + context.beginPath(); + context.moveTo(endX, startY); + context.arc(endX, startY, 2, 0, 2 * Math.PI); + context.closePath(); + context.fill(); + context.beginPath(); + context.setFontSize(fontSize); + context.setFillStyle(item.textColor || opts.fontColor); + context.fillText(text, endX - 5 - measureText(text, fontSize, context), startY + fontSize / 2 - 2); + context.closePath(); + context.stroke(); + context.closePath(); + } + } +} + +function drawFunnelCenterText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) { + for (let i = 0; i < series.length; i++) { + let item = series[i]; + let startY, fontSize; + if (item.centerText) { + startY = item.funnelArea[1] + eachSpacing / 2; + fontSize = item.centerTextSize * opts.pix || opts.fontSize * opts.pix; + context.beginPath(); + context.setFontSize(fontSize); + context.setFillStyle(item.centerTextColor || "#FFFFFF"); + context.fillText(item.centerText, centerPosition.x - measureText(item.centerText, fontSize, context) / 2, startY + fontSize / 2 - 2); + context.closePath(); + context.stroke(); + context.closePath(); + } + } +} + + +function drawCanvas(opts, context) { + context.save(); + context.translate(0, 0.5); + context.restore(); + context.draw(); +} + +var Timing = { + easeIn: function easeIn(pos) { + return Math.pow(pos, 3); + }, + easeOut: function easeOut(pos) { + return Math.pow(pos - 1, 3) + 1; + }, + easeInOut: function easeInOut(pos) { + if ((pos /= 0.5) < 1) { + return 0.5 * Math.pow(pos, 3); + } else { + return 0.5 * (Math.pow(pos - 2, 3) + 2); + } + }, + linear: function linear(pos) { + return pos; + } +}; + +function Animation(opts) { + this.isStop = false; + opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration; + opts.timing = opts.timing || 'easeInOut'; + var delay = 17; + function createAnimationFrame() { + if (typeof setTimeout !== 'undefined') { + return function(step, delay) { + setTimeout(function() { + var timeStamp = +new Date(); + step(timeStamp); + }, delay); + }; + } else if (typeof requestAnimationFrame !== 'undefined') { + return requestAnimationFrame; + } else { + return function(step) { + step(null); + }; + } + }; + var animationFrame = createAnimationFrame(); + var startTimeStamp = null; + var _step = function step(timestamp) { + if (timestamp === null || this.isStop === true) { + opts.onProcess && opts.onProcess(1); + opts.onAnimationFinish && opts.onAnimationFinish(); + return; + } + if (startTimeStamp === null) { + startTimeStamp = timestamp; + } + if (timestamp - startTimeStamp < opts.duration) { + var process = (timestamp - startTimeStamp) / opts.duration; + var timingFunction = Timing[opts.timing]; + process = timingFunction(process); + opts.onProcess && opts.onProcess(process); + animationFrame(_step, delay); + } else { + opts.onProcess && opts.onProcess(1); + opts.onAnimationFinish && opts.onAnimationFinish(); + } + }; + _step = _step.bind(this); + animationFrame(_step, delay); +} + +Animation.prototype.stop = function() { + this.isStop = true; +}; + +function drawCharts(type, opts, config, context) { + var _this = this; + var series = opts.series; + //兼容ECharts饼图类数据格式 + if (type === 'pie' || type === 'ring' || type === 'mount' || type === 'rose' || type === 'funnel') { + series = fixPieSeries(series, opts, config); + } + var categories = opts.categories; + if (type === 'mount') { + categories = []; + for (let j = 0; j < series.length; j++) { + if(series[j].show !== false) categories.push(series[j].name) + } + opts.categories = categories; + } + series = fillSeries(series, opts, config); + var duration = opts.animation ? opts.duration : 0; + _this.animationInstance && _this.animationInstance.stop(); + var seriesMA = null; + if (type == 'candle') { + let average = assign({}, opts.extra.candle.average); + if (average.show) { + seriesMA = calCandleMA(average.day, average.name, average.color, series[0].data); + seriesMA = fillSeries(seriesMA, opts, config); + opts.seriesMA = seriesMA; + } else if (opts.seriesMA) { + seriesMA = opts.seriesMA = fillSeries(opts.seriesMA, opts, config); + } else { + seriesMA = series; + } + } else { + seriesMA = series; + } + /* 过滤掉show=false的series */ + opts._series_ = series = filterSeries(series); + //重新计算图表区域 + opts.area = new Array(4); + //复位绘图区域 + for (let j = 0; j < 4; j++) { + opts.area[j] = opts.padding[j] * opts.pix; + } + //通过计算三大区域:图例、X轴、Y轴的大小,确定绘图区域 + var _calLegendData = calLegendData(seriesMA, opts, config, opts.chartData, context), + legendHeight = _calLegendData.area.wholeHeight, + legendWidth = _calLegendData.area.wholeWidth; + + switch (opts.legend.position) { + case 'top': + opts.area[0] += legendHeight; + break; + case 'bottom': + opts.area[2] += legendHeight; + break; + case 'left': + opts.area[3] += legendWidth; + break; + case 'right': + opts.area[1] += legendWidth; + break; + } + + let _calYAxisData = {}, + yAxisWidth = 0; + if (opts.type === 'line' || opts.type === 'column'|| opts.type === 'mount' || opts.type === 'area' || opts.type === 'mix' || opts.type === 'candle' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') { + _calYAxisData = calYAxisData(series, opts, config, context); + yAxisWidth = _calYAxisData.yAxisWidth; + //如果显示Y轴标题 + if (opts.yAxis.showTitle) { + let maxTitleHeight = 0; + for (let i = 0; i < opts.yAxis.data.length; i++) { + maxTitleHeight = Math.max(maxTitleHeight, opts.yAxis.data[i].titleFontSize ? opts.yAxis.data[i].titleFontSize * opts.pix : config.fontSize) + } + opts.area[0] += maxTitleHeight; + } + let rightIndex = 0, + leftIndex = 0; + //计算主绘图区域左右位置 + for (let i = 0; i < yAxisWidth.length; i++) { + if (yAxisWidth[i].position == 'left') { + if (leftIndex > 0) { + opts.area[3] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix; + } else { + opts.area[3] += yAxisWidth[i].width; + } + leftIndex += 1; + } else if (yAxisWidth[i].position == 'right') { + if (rightIndex > 0) { + opts.area[1] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix; + } else { + opts.area[1] += yAxisWidth[i].width; + } + rightIndex += 1; + } + } + } else { + config.yAxisWidth = yAxisWidth; + } + opts.chartData.yAxisData = _calYAxisData; + + if (opts.categories && opts.categories.length && opts.type !== 'radar' && opts.type !== 'gauge' && opts.type !== 'bar') { + opts.chartData.xAxisData = getXAxisPoints(opts.categories, opts, config); + let _calCategoriesData = calCategoriesData(opts.categories, opts, config, opts.chartData.xAxisData.eachSpacing, context), + xAxisHeight = _calCategoriesData.xAxisHeight, + angle = _calCategoriesData.angle; + config.xAxisHeight = xAxisHeight; + config._xAxisTextAngle_ = angle; + opts.area[2] += xAxisHeight; + opts.chartData.categoriesData = _calCategoriesData; + } else { + if (opts.type === 'line' || opts.type === 'area' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') { + opts.chartData.xAxisData = calXAxisData(series, opts, config, context); + categories = opts.chartData.xAxisData.rangesFormat; + let _calCategoriesData = calCategoriesData(categories, opts, config, opts.chartData.xAxisData.eachSpacing, context), + xAxisHeight = _calCategoriesData.xAxisHeight, + angle = _calCategoriesData.angle; + config.xAxisHeight = xAxisHeight; + config._xAxisTextAngle_ = angle; + opts.area[2] += xAxisHeight; + opts.chartData.categoriesData = _calCategoriesData; + } else { + opts.chartData.xAxisData = { + xAxisPoints: [] + }; + } + } + + //计算右对齐偏移距离 + if (opts.enableScroll && opts.xAxis.scrollAlign == 'right' && opts._scrollDistance_ === undefined) { + let offsetLeft = 0, + xAxisPoints = opts.chartData.xAxisData.xAxisPoints, + startX = opts.chartData.xAxisData.startX, + endX = opts.chartData.xAxisData.endX, + eachSpacing = opts.chartData.xAxisData.eachSpacing; + let totalWidth = eachSpacing * (xAxisPoints.length - 1); + let screenWidth = endX - startX; + offsetLeft = screenWidth - totalWidth; + _this.scrollOption.currentOffset = offsetLeft; + _this.scrollOption.startTouchX = offsetLeft; + _this.scrollOption.distance = 0; + _this.scrollOption.lastMoveTime = 0; + opts._scrollDistance_ = offsetLeft; + } + + if (type === 'pie' || type === 'ring' || type === 'rose') { + config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(seriesMA, config, context, opts); + } + + switch (type) { + case 'word': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawWordCloudDataPoints(series, opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'map': + context.clearRect(0, 0, opts.width, opts.height); + drawMapDataPoints(series, opts, config, context); + setTimeout(()=>{ + this.uevent.trigger('renderComplete'); + },50) + break; + case 'funnel': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.funnelData = drawFunnelDataPoints(series, opts, config, context, process); + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'line': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process), + xAxisPoints = _drawLineDataPoints.xAxisPoints, + calPoints = _drawLineDataPoints.calPoints, + eachSpacing = _drawLineDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'scatter': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawScatterDataPoints = drawScatterDataPoints(series, opts, config, context, process), + xAxisPoints = _drawScatterDataPoints.xAxisPoints, + calPoints = _drawScatterDataPoints.calPoints, + eachSpacing = _drawScatterDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'bubble': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawBubbleDataPoints = drawBubbleDataPoints(series, opts, config, context, process), + xAxisPoints = _drawBubbleDataPoints.xAxisPoints, + calPoints = _drawBubbleDataPoints.calPoints, + eachSpacing = _drawBubbleDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'mix': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawMixDataPoints = drawMixDataPoints(series, opts, config, context, process), + xAxisPoints = _drawMixDataPoints.xAxisPoints, + calPoints = _drawMixDataPoints.calPoints, + eachSpacing = _drawMixDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'column': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process), + xAxisPoints = _drawColumnDataPoints.xAxisPoints, + calPoints = _drawColumnDataPoints.calPoints, + eachSpacing = _drawColumnDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'mount': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawMountDataPoints = drawMountDataPoints(series, opts, config, context, process), + xAxisPoints = _drawMountDataPoints.xAxisPoints, + calPoints = _drawMountDataPoints.calPoints, + eachSpacing = _drawMountDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'bar': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawXAxis(categories, opts, config, context); + var _drawBarDataPoints = drawBarDataPoints(series, opts, config, context, process), + yAxisPoints = _drawBarDataPoints.yAxisPoints, + calPoints = _drawBarDataPoints.calPoints, + eachSpacing = _drawBarDataPoints.eachSpacing; + opts.chartData.yAxisPoints = yAxisPoints; + opts.chartData.xAxisPoints = opts.chartData.xAxisData.xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, yAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'area': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process), + xAxisPoints = _drawAreaDataPoints.xAxisPoints, + calPoints = _drawAreaDataPoints.calPoints, + eachSpacing = _drawAreaDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'ring': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process); + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'pie': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process); + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'rose': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.pieData = drawRoseDataPoints(series, opts, config, context, process); + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'radar': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process); + drawLegend(opts.series, opts, config, context, opts.chartData); + drawToolTipBridge(opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'arcbar': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.arcbarData = drawArcbarDataPoints(series, opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'gauge': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + opts.chartData.gaugeData = drawGaugeDataPoints(categories, series, opts, config, context, process); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + case 'candle': + this.animationInstance = new Animation({ + timing: opts.timing, + duration: duration, + onProcess: function onProcess(process) { + context.clearRect(0, 0, opts.width, opts.height); + if (opts.rotate) { + contextRotate(context, opts); + } + drawYAxisGrid(categories, opts, config, context); + drawXAxis(categories, opts, config, context); + var _drawCandleDataPoints = drawCandleDataPoints(series, seriesMA, opts, config, context, process), + xAxisPoints = _drawCandleDataPoints.xAxisPoints, + calPoints = _drawCandleDataPoints.calPoints, + eachSpacing = _drawCandleDataPoints.eachSpacing; + opts.chartData.xAxisPoints = xAxisPoints; + opts.chartData.calPoints = calPoints; + opts.chartData.eachSpacing = eachSpacing; + drawYAxis(series, opts, config, context); + if (opts.enableMarkLine !== false && process === 1) { + drawMarkLine(opts, config, context); + } + if (seriesMA) { + drawLegend(seriesMA, opts, config, context, opts.chartData); + } else { + drawLegend(opts.series, opts, config, context, opts.chartData); + } + drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); + drawCanvas(opts, context); + }, + onAnimationFinish: function onAnimationFinish() { + _this.uevent.trigger('renderComplete'); + } + }); + break; + } +} + +function uChartsEvent() { + this.events = {}; +} + +uChartsEvent.prototype.addEventListener = function(type, listener) { + this.events[type] = this.events[type] || []; + this.events[type].push(listener); +}; + +uChartsEvent.prototype.delEventListener = function(type) { + this.events[type] = []; +}; + +uChartsEvent.prototype.trigger = function() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + var type = args[0]; + var params = args.slice(1); + if (!!this.events[type]) { + this.events[type].forEach(function(listener) { + try { + listener.apply(null, params); + } catch (e) { + //console.log('[uCharts] '+e); + } + }); + } +}; + +var uCharts = function uCharts(opts) { + opts.pix = opts.pixelRatio ? opts.pixelRatio : 1; + opts.fontSize = opts.fontSize ? opts.fontSize : 13; + opts.fontColor = opts.fontColor ? opts.fontColor : config.fontColor; + if (opts.background == "" || opts.background == "none") { + opts.background = "#FFFFFF" + } + opts.title = assign({}, opts.title); + opts.subtitle = assign({}, opts.subtitle); + opts.duration = opts.duration ? opts.duration : 1000; + opts.yAxis = assign({}, { + data: [], + showTitle: false, + disabled: false, + disableGrid: false, + gridSet: 'number', + splitNumber: 5, + gridType: 'solid', + dashLength: 4 * opts.pix, + gridColor: '#cccccc', + padding: 10, + fontColor: '#666666' + }, opts.yAxis); + opts.xAxis = assign({}, { + rotateLabel: false, + rotateAngle:45, + disabled: false, + disableGrid: false, + splitNumber: 5, + calibration:false, + fontColor: '#666666', + fontSize: 13, + lineHeight: 20, + marginTop: 0, + gridType: 'solid', + dashLength: 4, + scrollAlign: 'left', + boundaryGap: 'center', + axisLine: true, + axisLineColor: '#cccccc', + titleFontSize: 13, + titleOffsetY: 0, + titleOffsetX: 0, + titleFontColor: '#666666' + }, opts.xAxis); + opts.xAxis.scrollPosition = opts.xAxis.scrollAlign; + opts.legend = assign({}, { + show: true, + position: 'bottom', + float: 'center', + backgroundColor: 'rgba(0,0,0,0)', + borderColor: 'rgba(0,0,0,0)', + borderWidth: 0, + padding: 5, + margin: 5, + itemGap: 10, + fontSize: opts.fontSize, + lineHeight: opts.fontSize, + fontColor: opts.fontColor, + formatter: {}, + hiddenColor: '#CECECE' + }, opts.legend); + opts.extra = assign({ + tooltip:{ + legendShape: 'auto' + } + }, opts.extra); + opts.rotate = opts.rotate ? true : false; + opts.animation = opts.animation ? true : false; + opts.rotate = opts.rotate ? true : false; + opts.canvas2d = opts.canvas2d ? true : false; + + let config$$1 = assign({}, config); + config$$1.color = opts.color ? opts.color : config$$1.color; + if (opts.type == 'pie') { + config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix; + } + if (opts.type == 'ring') { + config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.ring.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix; + } + if (opts.type == 'rose') { + config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix; + } + config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pix; + + //屏幕旋转 + config$$1.rotate = opts.rotate; + if (opts.rotate) { + let tempWidth = opts.width; + let tempHeight = opts.height; + opts.width = tempHeight; + opts.height = tempWidth; + } + + //适配高分屏 + opts.padding = opts.padding ? opts.padding : config$$1.padding; + config$$1.yAxisWidth = config.yAxisWidth * opts.pix; + config$$1.fontSize = opts.fontSize * opts.pix; + config$$1.titleFontSize = config.titleFontSize * opts.pix; + config$$1.subtitleFontSize = config.subtitleFontSize * opts.pix; + if(!opts.context){ + throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!'); + } + this.context = opts.context; + if (!this.context.setTextAlign) { + this.context.setStrokeStyle = function(e) { + return this.strokeStyle = e; + } + this.context.setLineWidth = function(e) { + return this.lineWidth = e; + } + this.context.setLineCap = function(e) { + return this.lineCap = e; + } + this.context.setFontSize = function(e) { + return this.font = e + "px sans-serif"; + } + this.context.setFillStyle = function(e) { + return this.fillStyle = e; + } + this.context.setTextAlign = function(e) { + return this.textAlign = e; + } + this.context.setTextBaseline = function(e) { + return this.textBaseline = e; + } + this.context.setShadow = function(offsetX,offsetY,blur,color) { + this.shadowColor = color; + this.shadowOffsetX = offsetX; + this.shadowOffsetY = offsetY; + this.shadowBlur = blur; + } + this.context.draw = function() {} + } + //兼容NVUEsetLineDash + if(!this.context.setLineDash){ + this.context.setLineDash = function(e) {} + } + opts.chartData = {}; + this.uevent = new uChartsEvent(); + this.scrollOption = { + currentOffset: 0, + startTouchX: 0, + distance: 0, + lastMoveTime: 0 + }; + this.opts = opts; + this.config = config$$1; + drawCharts.call(this, opts.type, opts, config$$1, this.context); +}; + +uCharts.prototype.updateData = function() { + let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.opts = assign({}, this.opts, data); + this.opts.updateData = true; + let scrollPosition = data.scrollPosition || 'current'; + switch (scrollPosition) { + case 'current': + this.opts._scrollDistance_ = this.scrollOption.currentOffset; + break; + case 'left': + this.opts._scrollDistance_ = 0; + this.scrollOption = { + currentOffset: 0, + startTouchX: 0, + distance: 0, + lastMoveTime: 0 + }; + break; + case 'right': + let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context), yAxisWidth = _calYAxisData.yAxisWidth; + this.config.yAxisWidth = yAxisWidth; + let offsetLeft = 0; + let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config), xAxisPoints = _getXAxisPoints0.xAxisPoints, + startX = _getXAxisPoints0.startX, + endX = _getXAxisPoints0.endX, + eachSpacing = _getXAxisPoints0.eachSpacing; + let totalWidth = eachSpacing * (xAxisPoints.length - 1); + let screenWidth = endX - startX; + offsetLeft = screenWidth - totalWidth; + this.scrollOption = { + currentOffset: offsetLeft, + startTouchX: offsetLeft, + distance: 0, + lastMoveTime: 0 + }; + this.opts._scrollDistance_ = offsetLeft; + break; + } + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context); +}; + +uCharts.prototype.zoom = function() { + var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.opts.xAxis.itemCount; + if (this.opts.enableScroll !== true) { + console.log('[uCharts] 请启用滚动条后使用') + return; + } + //当前屏幕中间点 + let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.opts.chartData.eachSpacing) + Math.round(this.opts.xAxis.itemCount / 2); + this.opts.animation = false; + this.opts.xAxis.itemCount = val.itemCount; + //重新计算x轴偏移距离 + let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context), + yAxisWidth = _calYAxisData.yAxisWidth; + this.config.yAxisWidth = yAxisWidth; + let offsetLeft = 0; + let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config), + xAxisPoints = _getXAxisPoints0.xAxisPoints, + startX = _getXAxisPoints0.startX, + endX = _getXAxisPoints0.endX, + eachSpacing = _getXAxisPoints0.eachSpacing; + let centerLeft = eachSpacing * centerPoint; + let screenWidth = endX - startX; + let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1); + offsetLeft = screenWidth / 2 - centerLeft; + if (offsetLeft > 0) { + offsetLeft = 0; + } + if (offsetLeft < MaxLeft) { + offsetLeft = MaxLeft; + } + this.scrollOption = { + currentOffset: offsetLeft, + startTouchX: 0, + distance: 0, + lastMoveTime: 0 + }; + calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts); + this.opts._scrollDistance_ = offsetLeft; + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context); +}; + +uCharts.prototype.dobuleZoom = function(e) { + if (this.opts.enableScroll !== true) { + console.log('[uCharts] 请启用滚动条后使用') + return; + } + const tcs = e.changedTouches; + if (tcs.length < 2) { + return; + } + for (var i = 0; i < tcs.length; i++) { + tcs[i].x = tcs[i].x ? tcs[i].x : tcs[i].clientX; + tcs[i].y = tcs[i].y ? tcs[i].y : tcs[i].clientY; + } + const ntcs = [getTouches(tcs[0], this.opts, e),getTouches(tcs[1], this.opts, e)]; + const xlength = Math.abs(ntcs[0].x - ntcs[1].x); + // 记录初始的两指之间的数据 + if(!this.scrollOption.moveCount){ + let cts0 = {changedTouches:[{x:tcs[0].x,y:this.opts.area[0] / this.opts.pix + 2}]}; + let cts1 = {changedTouches:[{x:tcs[1].x,y:this.opts.area[0] / this.opts.pix + 2}]}; + if(this.opts.rotate){ + cts0 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[0].y}]}; + cts1 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[1].y}]}; + } + const moveCurrent1 = this.getCurrentDataIndex(cts0).index; + const moveCurrent2 = this.getCurrentDataIndex(cts1).index; + const moveCount = Math.abs(moveCurrent1 - moveCurrent2); + this.scrollOption.moveCount = moveCount; + this.scrollOption.moveCurrent1 = Math.min(moveCurrent1, moveCurrent2); + this.scrollOption.moveCurrent2 = Math.max(moveCurrent1, moveCurrent2); + return; + } + + let currentEachSpacing = xlength / this.scrollOption.moveCount; + let itemCount = (this.opts.width - this.opts.area[1] - this.opts.area[3]) / currentEachSpacing; + itemCount = itemCount <= 2 ? 2 : itemCount; + itemCount = itemCount >= this.opts.categories.length ? this.opts.categories.length : itemCount; + this.opts.animation = false; + this.opts.xAxis.itemCount = itemCount; + // 重新计算滚动条偏移距离 + let offsetLeft = 0; + let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config), + xAxisPoints = _getXAxisPoints0.xAxisPoints, + startX = _getXAxisPoints0.startX, + endX = _getXAxisPoints0.endX, + eachSpacing = _getXAxisPoints0.eachSpacing; + let currentLeft = eachSpacing * this.scrollOption.moveCurrent1; + let screenWidth = endX - startX; + let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1); + offsetLeft = -currentLeft+Math.min(ntcs[0].x,ntcs[1].x)-this.opts.area[3]-eachSpacing; + if (offsetLeft > 0) { + offsetLeft = 0; + } + if (offsetLeft < MaxLeft) { + offsetLeft = MaxLeft; + } + this.scrollOption.currentOffset= offsetLeft; + this.scrollOption.startTouchX= 0; + this.scrollOption.distance=0; + calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts); + this.opts._scrollDistance_ = offsetLeft; + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context); +} + +uCharts.prototype.stopAnimation = function() { + this.animationInstance && this.animationInstance.stop(); +}; + +uCharts.prototype.addEventListener = function(type, listener) { + this.uevent.addEventListener(type, listener); +}; + +uCharts.prototype.delEventListener = function(type) { + this.uevent.delEventListener(type); +}; + +uCharts.prototype.getCurrentDataIndex = function(e) { + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + if (touches) { + let _touches$ = getTouches(touches, this.opts, e); + if (this.opts.type === 'pie' || this.opts.type === 'ring') { + return findPieChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.pieData, this.opts); + } else if (this.opts.type === 'rose') { + return findRoseChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.pieData, this.opts); + } else if (this.opts.type === 'radar') { + return findRadarChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.radarData, this.opts.categories.length); + } else if (this.opts.type === 'funnel') { + return findFunnelChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.funnelData); + } else if (this.opts.type === 'map') { + return findMapChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts); + } else if (this.opts.type === 'word') { + return findWordChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.wordCloudData); + } else if (this.opts.type === 'bar') { + return findBarChartCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset)); + } else { + return findCurrentIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset)); + } + } + return -1; +}; + +uCharts.prototype.getLegendDataIndex = function(e) { + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + if (touches) { + let _touches$ = getTouches(touches, this.opts, e); + return findLegendIndex({ + x: _touches$.x, + y: _touches$.y + }, this.opts.chartData.legendData); + } + return -1; +}; + +uCharts.prototype.touchLegend = function(e) { + var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + if (touches) { + var _touches$ = getTouches(touches, this.opts, e); + var index = this.getLegendDataIndex(e); + if (index >= 0) { + if (this.opts.type == 'candle') { + this.opts.seriesMA[index].show = !this.opts.seriesMA[index].show; + } else { + this.opts.series[index].show = !this.opts.series[index].show; + } + this.opts.animation = option.animation ? true : false; + this.opts._scrollDistance_ = this.scrollOption.currentOffset; + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context); + } + } + +}; + +uCharts.prototype.showToolTip = function(e) { + var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + if (!touches) { + console.log("[uCharts] 未获取到event坐标信息"); + } + var _touches$ = getTouches(touches, this.opts, e); + var currentOffset = this.scrollOption.currentOffset; + var opts = assign({}, this.opts, { + _scrollDistance_: currentOffset, + animation: false + }); + if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column' || this.opts.type === 'scatter' || this.opts.type === 'bubble') { + var current = this.getCurrentDataIndex(e); + var index = option.index == undefined ? current.index : option.index; + if (index > -1 || index.length>0) { + var seriesData = getSeriesDataItem(this.opts.series, index, current.group); + if (seriesData.length !== 0) { + var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option), + textList = _getToolTipData.textList, + offset = _getToolTipData.offset; + offset.y = _touches$.y; + opts.tooltip = { + textList: option.textList !== undefined ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index, + group: current.group + }; + } + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'mount') { + var index = option.index == undefined ? this.getCurrentDataIndex(e).index : option.index; + if (index > -1) { + var opts = assign({}, this.opts, {animation: false}); + var seriesData = assign({}, opts._series_[index]); + var textList = [{ + text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data, + color: seriesData.color, + legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape + }]; + var offset = { + x: opts.chartData.calPoints[index].x, + y: _touches$.y + }; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'bar') { + var current = this.getCurrentDataIndex(e); + var index = option.index == undefined ? current.index : option.index; + if (index > -1 || index.length>0) { + var seriesData = getSeriesDataItem(this.opts.series, index, current.group); + if (seriesData.length !== 0) { + var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option), + textList = _getToolTipData.textList, + offset = _getToolTipData.offset; + offset.x = _touches$.x; + opts.tooltip = { + textList: option.textList !== undefined ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'mix') { + var current = this.getCurrentDataIndex(e); + var index = option.index == undefined ? current.index : option.index; + if (index > -1) { + var currentOffset = this.scrollOption.currentOffset; + var opts = assign({}, this.opts, { + _scrollDistance_: currentOffset, + animation: false + }); + var seriesData = getSeriesDataItem(this.opts.series, index); + if (seriesData.length !== 0) { + var _getMixToolTipData = getMixToolTipData(seriesData, this.opts, index, this.opts.categories, option), + textList = _getMixToolTipData.textList, + offset = _getMixToolTipData.offset; + offset.y = _touches$.y; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'candle') { + var current = this.getCurrentDataIndex(e); + var index = option.index == undefined ? current.index : option.index; + if (index > -1) { + var currentOffset = this.scrollOption.currentOffset; + var opts = assign({}, this.opts, { + _scrollDistance_: currentOffset, + animation: false + }); + var seriesData = getSeriesDataItem(this.opts.series, index); + if (seriesData.length !== 0) { + var _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.opts, index, this.opts.categories, this.opts.extra.candle, option), + textList = _getToolTipData.textList, + offset = _getToolTipData.offset; + offset.y = _touches$.y; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose' || this.opts.type === 'funnel') { + var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index; + if (index > -1) { + var opts = assign({}, this.opts, {animation: false}); + var seriesData = assign({}, opts._series_[index]); + var textList = [{ + text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data, + color: seriesData.color, + legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape + }]; + var offset = { + x: _touches$.x, + y: _touches$.y + }; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'map') { + var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index; + if (index > -1) { + var opts = assign({}, this.opts, {animation: false}); + var seriesData = assign({}, this.opts.series[index]); + seriesData.name = seriesData.properties.name + var textList = [{ + text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name, + color: seriesData.color, + legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape + }]; + var offset = { + x: _touches$.x, + y: _touches$.y + }; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + opts.updateData = false; + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'word') { + var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index; + if (index > -1) { + var opts = assign({}, this.opts, {animation: false}); + var seriesData = assign({}, this.opts.series[index]); + var textList = [{ + text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name, + color: seriesData.color, + legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape + }]; + var offset = { + x: _touches$.x, + y: _touches$.y + }; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + opts.updateData = false; + drawCharts.call(this, opts.type, opts, this.config, this.context); + } + if (this.opts.type === 'radar') { + var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index; + if (index > -1) { + var opts = assign({}, this.opts, {animation: false}); + var seriesData = getSeriesDataItem(this.opts.series, index); + if (seriesData.length !== 0) { + var textList = seriesData.map((item) => { + return { + text: option.formatter ? option.formatter(item, this.opts.categories[index], index, this.opts) : item.name + ': ' + item.data, + color: item.color, + legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? item.legendShape : this.opts.extra.tooltip.legendShape + }; + }); + var offset = { + x: _touches$.x, + y: _touches$.y + }; + opts.tooltip = { + textList: option.textList ? option.textList : textList, + offset: option.offset !== undefined ? option.offset : offset, + option: option, + index: index + }; + } + } + drawCharts.call(this, opts.type, opts, this.config, this.context); + } +}; + +uCharts.prototype.translate = function(distance) { + this.scrollOption = { + currentOffset: distance, + startTouchX: distance, + distance: 0, + lastMoveTime: 0 + }; + let opts = assign({}, this.opts, { + _scrollDistance_: distance, + animation: false + }); + drawCharts.call(this, this.opts.type, opts, this.config, this.context); +}; + +uCharts.prototype.scrollStart = function(e) { + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + var _touches$ = getTouches(touches, this.opts, e); + if (touches && this.opts.enableScroll === true) { + this.scrollOption.startTouchX = _touches$.x; + } +}; + +uCharts.prototype.scroll = function(e) { + if (this.scrollOption.lastMoveTime === 0) { + this.scrollOption.lastMoveTime = Date.now(); + } + let Limit = this.opts.touchMoveLimit || 60; + let currMoveTime = Date.now(); + let duration = currMoveTime - this.scrollOption.lastMoveTime; + if (duration < Math.floor(1000 / Limit)) return; + if (this.scrollOption.startTouchX == 0) return; + this.scrollOption.lastMoveTime = currMoveTime; + var touches = null; + if (e.changedTouches) { + touches = e.changedTouches[0]; + } else { + touches = e.mp.changedTouches[0]; + } + if (touches && this.opts.enableScroll === true) { + var _touches$ = getTouches(touches, this.opts, e); + var _distance; + _distance = _touches$.x - this.scrollOption.startTouchX; + var currentOffset = this.scrollOption.currentOffset; + var validDistance = calValidDistance(this, currentOffset + _distance, this.opts.chartData, this.config, this.opts); + this.scrollOption.distance = _distance = validDistance - currentOffset; + var opts = assign({}, this.opts, { + _scrollDistance_: currentOffset + _distance, + animation: false + }); + this.opts = opts; + drawCharts.call(this, opts.type, opts, this.config, this.context); + return currentOffset + _distance; + } +}; + +uCharts.prototype.scrollEnd = function(e) { + if (this.opts.enableScroll === true) { + var _scrollOption = this.scrollOption, + currentOffset = _scrollOption.currentOffset, + distance = _scrollOption.distance; + this.scrollOption.currentOffset = currentOffset + distance; + this.scrollOption.distance = 0; + this.scrollOption.moveCount = 0; + } +}; + +export default uCharts; \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js new file mode 100644 index 0000000..0902ecd --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js @@ -0,0 +1,18 @@ +/* + * uCharts (R) + * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台 + * Copyright (C) 2021 QIUN (R) 秋云 https://www.ucharts.cn All rights reserved. + * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) + * 复制使用请保留本段注释,感谢支持开源! + * + * uCharts (R) 官方网站 + * https://www.uCharts.cn + * + * 开源地址: + * https://gitee.com/uCharts/uCharts + * + * uni-app插件市场地址: + * http://ext.dcloud.net.cn/plugin?id=271 + * + */ +"use strict";var config={version:"v2.5.0-20230101",yAxisWidth:15,xAxisHeight:22,padding:[10,10,10,10],rotate:false,fontSize:13,fontColor:"#666666",dataPointShape:["circle","circle","circle","circle"],color:["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],linearColor:["#0EE2F8","#2BDCA8","#FA7D8D","#EB88E2","#2AE3A0","#0EE2F8","#EB88E2","#6773E3","#F78A85"],pieChartLinePadding:15,pieChartTextPadding:5,titleFontSize:20,subtitleFontSize:15,radarLabelTextMargin:13};var assign=function(e,...t){if(e==null){throw new TypeError("[uCharts] Cannot convert undefined or null to object")}if(!t||t.length<=0){return e}function i(e,a){for(let t in a){e[t]=e[t]&&e[t].toString()==="[object Object]"?i(e[t],a[t]):e[t]=a[t]}return e}t.forEach(t=>{e=i(e,t)});return e};var util={toFixed:function t(e,a){a=a||2;if(this.isFloat(e)){e=e.toFixed(a)}return e},isFloat:function t(e){return e%1!==0},approximatelyEqual:function t(e,a){return Math.abs(e-a)<1e-10},isSameSign:function t(e,a){return Math.abs(e)===e&&Math.abs(a)===a||Math.abs(e)!==e&&Math.abs(a)!==a},isSameXCoordinateArea:function t(e,a){return this.isSameSign(e.x,a.x)},isCollision:function t(e,a){e.end={};e.end.x=e.start.x+e.width;e.end.y=e.start.y-e.height;a.end={};a.end.x=a.start.x+a.width;a.end.y=a.start.y-a.height;var i=a.start.x>e.end.x||a.end.xe.start.y||a.start.y1){if(r.extra.mount.widthRatio>2)r.extra.mount.widthRatio=2;n+=(r.extra.mount.widthRatio-1)*a.eachSpacing}var l=e;if(e>=0){l=0;t.uevent.trigger("scrollLeft");t.scrollOption.position="left";r.xAxis.scrollPosition="left"}else if(Math.abs(e)>=n-o){l=o-n;t.uevent.trigger("scrollRight");t.scrollOption.position="right";r.xAxis.scrollPosition="right"}else{t.scrollOption.position=e;r.xAxis.scrollPosition=e}return l}function isInAngleRange(t,e,a){function i(t){while(t<0){t+=2*Math.PI}while(t>2*Math.PI){t-=2*Math.PI}return t}t=i(t);e=i(e);a=i(a);if(e>a){a+=2*Math.PI;if(t=e&&t<=a}function createCurveControlPoints(t,e){function a(t,e){if(t[e-1]&&t[e+1]){return t[e].y>=Math.max(t[e-1].y,t[e+1].y)||t[e].y<=Math.min(t[e-1].y,t[e+1].y)}else{return false}}function c(t,e){if(t[e-1]&&t[e+1]){return t[e].x>=Math.max(t[e-1].x,t[e+1].x)||t[e].x<=Math.min(t[e-1].x,t[e+1].x)}else{return false}}var i=.2;var r=.2;var o=null;var n=null;var l=null;var s=null;if(e<1){o=t[0].x+(t[1].x-t[0].x)*i;n=t[0].y+(t[1].y-t[0].y)*i}else{o=t[e].x+(t[e+1].x-t[e-1].x)*i;n=t[e].y+(t[e+1].y-t[e-1].y)*i}if(e>t.length-3){var h=t.length-1;l=t[h].x-(t[h].x-t[h-1].x)*r;s=t[h].y-(t[h].y-t[h-1].y)*r}else{l=t[e+1].x-(t[e+2].x-t[e].x)*r;s=t[e+1].y-(t[e+2].y-t[e].y)*r}if(a(t,e+1)){s=t[e+1].y}if(a(t,e)){n=t[e].y}if(c(t,e+1)){l=t[e+1].x}if(c(t,e)){o=t[e].x}if(n>=Math.max(t[e].y,t[e+1].y)||n<=Math.min(t[e].y,t[e+1].y)){n=t[e].y}if(s>=Math.max(t[e].y,t[e+1].y)||s<=Math.min(t[e].y,t[e+1].y)){s=t[e+1].y}if(o>=Math.max(t[e].x,t[e+1].x)||o<=Math.min(t[e].x,t[e+1].x)){o=t[e].x}if(l>=Math.max(t[e].x,t[e+1].x)||l<=Math.min(t[e].x,t[e+1].x)){l=t[e+1].x}return{ctrA:{x:o,y:n},ctrB:{x:l,y:s}}}function convertCoordinateOrigin(t,e,a){return{x:a.x+t,y:a.y-e}}function avoidCollision(t,e){if(e){while(util.isCollision(t,e)){if(t.start.x>0){t.start.y--}else if(t.start.x<0){t.start.y++}else{if(t.start.y>0){t.start.y++}else{t.start.y--}}}}return t}function fixPieSeries(e,a,t){let i=[];if(e.length>0&&e[0].data.constructor.toString().indexOf("Array")>-1){a._pieSeries_=e;let t=e[0].data;for(var r=0;r=1e4){a=1e3}else if(i>=1e3){a=100}else if(i>=100){a=10}else if(i>=10){a=5}else if(i>=1){a=1}else if(i>=.1){a=.1}else if(i>=.01){a=.01}else if(i>=.001){a=.001}else if(i>=1e-4){a=1e-4}else if(i>=1e-5){a=1e-5}else{a=1e-6}return{minRange:findRange(t,"lower",a),maxRange:findRange(e,"upper",a)}}function measureText(a,t,e){var i=0;a=String(a);e=false;if(e!==false&&e!==undefined&&e.setFontSize&&e.measureText){e.setFontSize(t);return e.measureText(a).width}else{var a=a.split("");for(let e=0;e-1;if(n){let t=filterSeries(e);for(var l=0;l5&&arguments[5]!==undefined?arguments[5]:{};var l=a.chartData.calPoints?a.chartData.calPoints:[];let s={};if(r.length>0){let e=[];for(let t=0;t0){e=o[i]}return{text:n.formatter?n.formatter(t,e,i,a):t.name+": "+t.data,color:t.color,legendShape:a.extra.tooltip.legendShape=="auto"?t.legendShape:a.extra.tooltip.legendShape}});var h={x:Math.round(s.x),y:Math.round(s.y)};return{textList:e,offset:h}}function getMixToolTipData(t,e,a,i){var r=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};var o=e.chartData.xAxisPoints[a]+e.chartData.eachSpacing/2;var n=t.map(function(t){return{text:r.formatter?r.formatter(t,i[a],a,e):t.name+": "+t.data,color:t.color,disableLegend:t.disableLegend?true:false,legendShape:e.extra.tooltip.legendShape=="auto"?t.legendShape:e.extra.tooltip.legendShape}});n=n.filter(function(t){if(t.disableLegend!==true){return t}});var l={x:Math.round(o),y:0};return{textList:n,offset:l}}function getCandleToolTipData(o,e,n,l,i,t){var r=arguments.length>6&&arguments[6]!==undefined?arguments[6]:{};var a=n.chartData.calPoints;let s=t.color.upFill;let h=t.color.downFill;let c=[s,s,h,s];var d=[];e.map(function(t){if(l==0){if(t.data[1]-t.data[0]<0){c[1]=h}else{c[1]=s}}else{if(t.data[0]o[l-1][1]){c[2]=s}if(t.data[3]4&&arguments[4]!==undefined?arguments[4]:0;var l={index:-1,group:[]};var i=e.chartData.eachSpacing/2;let r=[];if(n&&n.length>0){if(!e.categories){i=0}else{for(let t=1;tt){l.index=e}})}}}return l}function findBarChartCurrentIndex(a,t,e,i){var r=arguments.length>4&&arguments[4]!==undefined?arguments[4]:0;var o={index:-1,group:[]};var n=e.chartData.eachSpacing/2;let l=e.chartData.yAxisPoints;if(t&&t.length>0){if(isInExactChartArea(a,e,i)){l.forEach(function(t,e){if(a.y+r+n>t){o.index=e}})}}return o}function findLegendIndex(o,t,e){let n=-1;let l=0;if(isInExactLegendArea(o,t.area)){let i=t.points;let r=-1;for(let t=0,e=i.length;tt[0]-l&&o.xt[1]-l&&o.ye.start.x&&t.xe.start.y&&t.y=e.area[3]-10&&t.y>=e.area[0]&&t.y<=e.height-e.area[2]}function findRadarChartCurrentIndex(t,e,a){var r=2*Math.PI/a;var o=-1;if(isInExactPieChartArea(t,e.center,e.radius)){var n=function t(e){if(e<0){e+=2*Math.PI}if(e>2*Math.PI){e-=2*Math.PI}return e};var l=Math.atan2(e.center.y-t.y,t.x-e.center.x);l=-1*l;if(l<0){l+=2*Math.PI}var i=e.angleList.map(function(t){t=n(-1*t);return t});i.forEach(function(t,e){var a=n(t-r/2);var i=n(t+r/2);if(i=a&&l<=i||l+2*Math.PI>=a&&l+2*Math.PI<=i){o=e}})}return o}function findFunnelChartCurrentIndex(t,e){var a=-1;for(var i=0,r=e.series.length;io.funnelArea[0]&&t.xo.funnelArea[1]&&t.yo.area[0]&&t.xo.area[1]&&t.ys.width-s.area[1]-s.area[3]){i.push(n);o.push(r-s.legend.itemGap*s.pix);r=e;n=[t]}else{r+=e;n.push(t)}}if(n.length){i.push(n);o.push(r-s.legend.itemGap*s.pix);c.widthArr=o;let t=Math.max.apply(null,o);switch(s.legend.float){case"left":c.area.start.x=s.area[3];c.area.end.x=s.area[3]+t+2*d;break;case"right":c.area.start.x=s.width-s.area[1]-t-2*d;c.area.end.x=s.width-s.area[1];break;default:c.area.start.x=(s.width-t)/2-d;c.area.end.x=(s.width+t)/2+d}c.area.width=t+2*d;c.area.wholeWidth=t+2*d;c.area.height=i.length*u+2*d;c.area.wholeHeight=i.length*u+2*d+2*x;c.points=i}}else{let t=l.length;let e=s.height-s.area[0]-s.area[2]-2*x-2*d;let a=Math.min(Math.floor(e/u),t);c.area.height=a*u+d*2;c.area.wholeHeight=a*u+d*2;switch(s.legend.float){case"top":c.area.start.y=s.area[0]+x;c.area.end.y=s.area[0]+x+c.area.height;break;case"bottom":c.area.start.y=s.height-s.area[2]-x-c.area.height;c.area.end.y=s.height-s.area[2]-x;break;default:c.area.start.y=(s.height-c.area.height)/2;c.area.end.y=(s.height+c.area.height)/2}let i=t%a===0?t/a:Math.floor(t/a+1);let r=[];for(let e=0;ei){i=t}}c.widthArr.push(i);c.heightArr.push(a.length*u+d*2)}let e=0;for(let t=0;t4&&arguments[4]!==undefined?arguments[4]:-1;var i;if(c=="stack"){i=dataCombineStack(t,e.categories.length)}else{i=dataCombine(t)}var r=[];i=i.filter(function(t){if(typeof t==="object"&&t!==null){if(t.constructor.toString().indexOf("Array")>-1){return t!==null}else{return t.value!==null}}else{return t!==null}});i.map(function(t){if(typeof t==="object"){if(t.constructor.toString().indexOf("Array")>-1){if(e.type=="candle"){t.map(function(t){r.push(t)})}else{r.push(t[0])}}else{r.push(t.value)}}else{r.push(t)}});var o=0;var n=0;if(r.length>0){o=Math.min.apply(this,r);n=Math.max.apply(this,r)}if(a>-1){if(typeof e.xAxis.data[a].min==="number"){o=Math.min(e.xAxis.data[a].min,o)}if(typeof e.xAxis.data[a].max==="number"){n=Math.max(e.xAxis.data[a].max,n)}}else{if(typeof e.xAxis.min==="number"){o=Math.min(e.xAxis.min,o)}if(typeof e.xAxis.max==="number"){n=Math.max(e.xAxis.max,n)}}if(o===n){var d=n||10;n+=d}var l=o;var x=n;var f=[];var p=(x-l)/e.xAxis.splitNumber;for(var s=0;s<=e.xAxis.splitNumber;s++){f.push(l+p*s)}return f}function calXAxisData(t,e,a,i){var r=assign({},{type:""},e.extra.bar);var o={angle:0,xAxisHeight:e.xAxis.lineHeight*e.pix+e.xAxis.marginTop*e.pix};o.ranges=getXAxisTextList(t,e,a,r.type);o.rangesFormat=o.ranges.map(function(t){t=util.toFixed(t,2);return t});var n=o.ranges.map(function(t){t=util.toFixed(t,2);return t});o=Object.assign(o,getXAxisPoints(n,e,a));var l=o.eachSpacing;var s=n.map(function(t){return measureText(t,e.xAxis.fontSize*e.pix,i)});if(e.xAxis.disabled===true){o.xAxisHeight=0}return o}function getRadarDataPoints(r,o,n,a,t){var l=arguments.length>5&&arguments[5]!==undefined?arguments[5]:1;var e=t.extra.radar||{};e.max=e.max||0;var s=Math.max(e.max,Math.max.apply(null,dataCombine(a)));var h=[];for(let e=0;e2&&arguments[2]!==undefined?arguments[2]:1;var o=0;var n=0;for(let e=0;e4&&arguments[4]!==undefined?arguments[4]:1;for(let t=0;t4&&arguments[4]!==undefined?arguments[4]:1;var l=0;var s=0;var h=[];for(let e=0;e2&&arguments[2]!==undefined?arguments[2]:1;if(o==1){o=.999999}for(let a=0;a=2){t._proportion_=t._proportion_%2}}return i}function getGaugeArcbarDataPoints(i,r){var o=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;if(o==1){o=.999999}for(let a=0;a=2){t._proportion_=t._proportion_%2}}return i}function getGaugeAxisPoints(e,a,t){let i;if(t=2){e[t]._endAngle_=e[t]._endAngle_%2}r=e[t]._endAngle_}return e}function getGaugeDataPoints(i,r,o){let n=arguments.length>3&&arguments[3]!==undefined?arguments[3]:1;for(let a=0;a=o.oldData){e._proportion_=(e._endAngle_-e._oldAngle_)*n+o.oldAngle}else{e._proportion_=e._oldAngle_-(e._oldAngle_-e._endAngle_)*n}if(e._proportion_>=2){e._proportion_=e._proportion_%2}}return i}function getPieTextMaxLength(i,r,o,n){i=getPieDataPoints(i);let l=0;for(let a=0;a0){t.width=Math.min(t.width,+n.extra.mix.column.width*n.pix)}if(n.extra.column&&n.extra.column.width&&+n.extra.column.width>0){t.width=Math.min(t.width,+n.extra.column.width*n.pix)}if(t.width<=0){t.width=1}t.x+=(o+.5-r/2)*(t.width+e);return t})}function fixBarData(t,i,r,o,e,n){return t.map(function(t){if(t===null){return null}var e=0;var a=0;e=n.extra.bar.seriesGap*n.pix||0;a=n.extra.bar.categoryGap*n.pix||0;e=Math.min(e,i/r);a=Math.min(a,i/r);t.width=Math.ceil((i-2*a-e*(r-1))/r);if(n.extra.bar&&n.extra.bar.width&&+n.extra.bar.width>0){t.width=Math.min(t.width,+n.extra.bar.width*n.pix)}if(t.width<=0){t.width=1}t.y+=(o+.5-r/2)*(t.width+e);return t})}function fixColumeMeterData(t,e,a,i,r,o,n){var l=o.extra.column.categoryGap*o.pix||0;return t.map(function(t){if(t===null){return null}t.width=e-2*l;if(o.extra.column&&o.extra.column.width&&+o.extra.column.width>0){t.width=Math.min(t.width,+o.extra.column.width*o.pix)}if(i>0){t.width-=n}return t})}function fixColumeStackData(t,a,e,i,r,o,n){var l=o.extra.column.categoryGap*o.pix||0;return t.map(function(t,e){if(t===null){return null}t.width=Math.ceil(a-2*l);if(o.extra.column&&o.extra.column.width&&+o.extra.column.width>0){t.width=Math.min(t.width,+o.extra.column.width*o.pix)}if(t.width<=0){t.width=1}return t})}function fixBarStackData(t,a,e,i,r,o,n){var l=o.extra.bar.categoryGap*o.pix||0;return t.map(function(t,e){if(t===null){return null}t.width=Math.ceil(a-2*l);if(o.extra.bar&&o.extra.bar.width&&+o.extra.bar.width>0){t.width=Math.min(t.width,+o.extra.bar.width*o.pix)}if(t.width<=0){t.width=1}return t})}function getXAxisPoints(t,e,h){var a=e.width-e.area[1]-e.area[3];var i=e.enableScroll?Math.min(e.xAxis.itemCount,t.length):t.length;if((e.type=="line"||e.type=="area"||e.type=="scatter"||e.type=="bubble"||e.type=="bar")&&i>1&&e.xAxis.boundaryGap=="justify"){i-=1}var r=0;if(e.type=="mount"&&e.extra&&e.extra.mount&&e.extra.mount.widthRatio&&e.extra.mount.widthRatio>1){if(e.extra.mount.widthRatio>2)e.extra.mount.widthRatio=2;r=e.extra.mount.widthRatio-1;i+=r}var o=a/i;var n=[];var l=e.area[3];var s=e.width-e.area[1];t.forEach(function(t,e){n.push(l+r/2*o+e*o)});if(e.xAxis.boundaryGap!=="justify"){if(e.enableScroll===true){n.push(l+r*o+t.length*o)}else{n.push(s)}}return{xAxisPoints:n,startX:l,endX:s,eachSpacing:o}}function getCandleDataPoints(t,l,s,h,c,d,a){var x=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var e=[];var f=d.height-d.area[0]-d.area[2];t.forEach(function(t,o){if(t===null){e.push(null)}else{var n=[];t.forEach(function(t,e){var a={};a.x=h[o]+Math.round(c/2);var i=t.value||t;var r=f*(i-l)/(s-l);r*=x;a.y=d.height-Math.round(r)-d.area[2];n.push(a)});e.push(n)}});return e}function getDataPoints(t,a,n,l,s,h,e){var c=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var d="center";if(h.type=="line"||h.type=="area"||h.type=="scatter"||h.type=="bubble"){d=h.xAxis.boundaryGap}var x=[];var f=h.height-h.area[0]-h.area[2];var p=h.width-h.area[1]-h.area[3];t.forEach(function(i,t){if(i===null){x.push(null)}else{var r={};r.color=i.color;r.x=l[t];var o=i;if(typeof i==="object"&&i!==null){if(i.constructor.toString().indexOf("Array")>-1){let t,e,a;t=[].concat(h.chartData.xAxisData.ranges);e=t.shift();a=t.pop();o=i[1];r.x=h.area[3]+p*(i[0]-e)/(a-e);if(h.type=="bubble"){r.r=i[2];r.t=i[3]}}else{o=i.value}}if(d=="center"){r.x+=s/2}var e=f*(o-a)/(n-a);e*=c;r.y=h.height-e-h.area[2];x.push(r)}});return x}function getLineDataPoints(t,a,n,l,s,h,e,p,c){var c=arguments.length>8&&arguments[8]!==undefined?arguments[8]:1;var d=h.xAxis.boundaryGap;var x=[];var f=h.height-h.area[0]-h.area[2];var u=h.width-h.area[1]-h.area[3];t.forEach(function(i,t){if(i===null){x.push(null)}else{var r={};r.color=i.color;if(p.animation=="vertical"){r.x=l[t];var o=i;if(typeof i==="object"&&i!==null){if(i.constructor.toString().indexOf("Array")>-1){let t,e,a;t=[].concat(h.chartData.xAxisData.ranges);e=t.shift();a=t.pop();o=i[1];r.x=h.area[3]+u*(i[0]-e)/(a-e)}else{o=i.value}}if(d=="center"){r.x+=s/2}var e=f*(o-a)/(n-a);e*=c;r.y=h.height-e-h.area[2];x.push(r)}else{r.x=l[0]+s*t*c;var o=i;if(d=="center"){r.x+=s/2}var e=f*(o-a)/(n-a);r.y=h.height-e-h.area[2];x.push(r)}}});return x}function getColumnDataPoints(t,a,n,l,s,h,e,i,c){var c=arguments.length>8&&arguments[8]!==undefined?arguments[8]:1;var d=[];var x=h.height-h.area[0]-h.area[2];var f=h.width-h.area[1]-h.area[3];t.forEach(function(i,t){if(i===null){d.push(null)}else{var r={};r.color=i.color;r.x=l[t];var o=i;if(typeof i==="object"&&i!==null){if(i.constructor.toString().indexOf("Array")>-1){let t,e,a;t=[].concat(h.chartData.xAxisData.ranges);e=t.shift();a=t.pop();o=i[1];r.x=h.area[3]+f*(i[0]-e)/(a-e)}else{o=i.value}}r.x+=s/2;var e=x*(o*c-a)/(n-a);r.y=h.height-e-h.area[2];d.push(r)}});return d}function getMountDataPoints(t,o,n,l,s,h,e,a){var c=arguments.length>8&&arguments[8]!==undefined?arguments[8]:1;var d=[];var x=h.height-h.area[0]-h.area[2];var i=h.width-h.area[1]-h.area[3];var f=s*e.widthRatio;t.forEach(function(t,e){if(t===null){d.push(null)}else{var a={};a.color=t.color;a.x=l[e];a.x+=s/2;var i=t.data;var r=x*(i*c-o)/(n-o);a.y=h.height-r-h.area[2];a.value=i;a.width=f;d.push(a)}});return d}function getBarDataPoints(t,o,n,l,e,s,a){var h=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var c=[];var i=s.height-s.area[0]-s.area[2];var d=s.width-s.area[1]-s.area[3];t.forEach(function(t,e){if(t===null){c.push(null)}else{var a={};a.color=t.color;a.y=l[e];var i=t;if(typeof t==="object"&&t!==null){i=t.value}var r=d*(i-o)/(n-o);r*=h;a.height=r;a.value=i;a.x=r+s.area[3];c.push(a)}});return c}function getStackDataPoints(t,s,h,c,g,d,e,x,y){var f=arguments.length>9&&arguments[9]!==undefined?arguments[9]:1;var p=[];var u=d.height-d.area[0]-d.area[2];t.forEach(function(t,e){if(t===null){p.push(null)}else{var a={};a.color=t.color;a.x=c[e]+Math.round(g/2);if(x>0){var i=0;for(let t=0;t<=x;t++){i+=y[t].data[e]}var r=i-t;var o=u*(i-s)/(h-s);var n=u*(r-s)/(h-s)}else{var i=t;if(typeof t==="object"&&t!==null){i=t.value}var o=u*(i-s)/(h-s);var n=0}var l=n;o*=f;l*=f;a.y=d.height-Math.round(o)-d.area[2];a.y0=d.height-Math.round(l)-d.area[2];p.push(a)}});return p}function getBarStackDataPoints(t,s,h,c,e,d,a,x,g){var f=arguments.length>9&&arguments[9]!==undefined?arguments[9]:1;var p=[];var u=d.width-d.area[1]-d.area[3];t.forEach(function(t,e){if(t===null){p.push(null)}else{var a={};a.color=t.color;a.y=c[e];if(x>0){var i=0;for(let t=0;t<=x;t++){i+=g[t].data[e]}var r=i-t;var o=u*(i-s)/(h-s);var n=u*(r-s)/(h-s)}else{var i=t;if(typeof t==="object"&&t!==null){i=t.value}var o=u*(i-s)/(h-s);var n=0}var l=n;o*=f;l*=f;a.height=o-l;a.x=d.area[3]+o;a.x0=d.area[3]+l;p.push(a)}});return p}function getYAxisTextList(t,e,h,c,a){var d=arguments.length>5&&arguments[5]!==undefined?arguments[5]:-1;var i;if(c=="stack"){i=dataCombineStack(t,e.categories.length)}else{i=dataCombine(t)}var r=[];i=i.filter(function(t){if(typeof t==="object"&&t!==null){if(t.constructor.toString().indexOf("Array")>-1){return t!==null}else{return t.value!==null}}else{return t!==null}});i.map(function(t){if(typeof t==="object"){if(t.constructor.toString().indexOf("Array")>-1){if(e.type=="candle"){t.map(function(t){r.push(t)})}else{r.push(t[1])}}else{r.push(t.value)}}else{r.push(t)}});var o=a.min||0;var n=a.max||0;if(r.length>0){o=Math.min.apply(this,r);n=Math.max.apply(this,r)}if(o===n){if(n==0){n=10}else{o=0}}var l=getDataRange(o,n);var x=a.min===undefined||a.min===null?l.minRange:a.min;var f=a.max===undefined||a.max===null?l.maxRange:a.max;var p=(f-x)/e.yAxis.splitNumber;var u=[];for(var s=0;s<=e.yAxis.splitNumber;s++){u.push(x+p*s)}return u.reverse()}function calYAxisData(a,o,e,n){var l=assign({},{type:""},o.extra.column);var t=o.yAxis.data.length;var s=new Array(t);if(t>0){for(let e=0;e{return t+(i.unit||"")}}i.categories=i.categories||o.categories;h[r]=i.categories}else{if(!i.formatter){i.formatter=(t,e,a)=>{return util.toFixed(t,i.tofix||0)+(i.unit||"")}}h[r]=getYAxisTextList(s[r],o,e,l.type,i,r)}let a=i.fontSize*o.pix||e.fontSize;d[r]={position:i.position?i.position:"left",width:0};c[r]=h[r].map(function(t,e){t=i.formatter(t,e,o);d[r].width=Math.max(d[r].width,measureText(t,a,n)+5);return t});let t=i.calibration?4*o.pix:0;d[r].width+=t+3*o.pix;if(i.disabled===true){d[r].width=0}}}else{var h=new Array(1);var c=new Array(1);var d=new Array(1);if(o.type==="bar"){h[0]=o.categories;if(!o.yAxis.formatter){o.yAxis.formatter=(t,e,a)=>{return t+(a.yAxis.unit||"")}}}else{if(!o.yAxis.formatter){o.yAxis.formatter=(t,e,a)=>{return t.toFixed(a.yAxis.tofix)+(a.yAxis.unit||"")}}h[0]=getYAxisTextList(a,o,e,l.type,{})}d[0]={position:"left",width:0};var i=o.yAxis.fontSize*o.pix||e.fontSize;c[0]=h[0].map(function(t,e){t=o.yAxis.formatter(t,e,o);d[0].width=Math.max(d[0].width,measureText(t,i,n)+5);return t});d[0].width+=3*o.pix;if(o.yAxis.disabled===true){d[0]={position:"left",width:0};o.yAxis.data[0]={disabled:true}}else{o.yAxis.data[0]={disabled:false,position:"left",max:o.yAxis.max,min:o.yAxis.min,formatter:o.yAxis.formatter};if(o.type==="bar"){o.yAxis.data[0].categories=o.categories;o.yAxis.data[0].type="categories"}}}return{rangesFormat:c,ranges:h,yAxisWidth:d}}function calTooltipYAxisData(r,t,o,e,a){let n=[].concat(o.chartData.yAxisData.ranges);let l=o.height-o.area[0]-o.area[2];let s=o.area[0];let h=[];for(let i=0;i0&&r.tooltip.group.includes(n)==false){return}var l=typeof r.tooltip.index==="number"?r.tooltip.index:r.tooltip.index[r.tooltip.group.indexOf(n)];i.beginPath();if(o.activeType=="hollow"){i.setStrokeStyle(e);i.setFillStyle(r.background);i.setLineWidth(2*r.pix)}else{i.setStrokeStyle("#ffffff");i.setFillStyle(e);i.setLineWidth(1*r.pix)}if(a==="diamond"){t.forEach(function(t,e){if(t!==null&&l==e){i.moveTo(t.x,t.y-4.5);i.lineTo(t.x-4.5,t.y);i.lineTo(t.x,t.y+4.5);i.lineTo(t.x+4.5,t.y);i.lineTo(t.x,t.y-4.5)}})}else if(a==="circle"){t.forEach(function(t,e){if(t!==null&&l==e){i.moveTo(t.x+2.5*r.pix,t.y);i.arc(t.x,t.y,3*r.pix,0,2*Math.PI,false)}})}else if(a==="square"){t.forEach(function(t,e){if(t!==null&&l==e){i.moveTo(t.x-3.5,t.y-3.5);i.rect(t.x-3.5,t.y-3.5,7,7)}})}else if(a==="triangle"){t.forEach(function(t,e){if(t!==null&&l==e){i.moveTo(t.x,t.y-4.5);i.lineTo(t.x-4.5,t.y+4.5);i.lineTo(t.x+4.5,t.y+4.5);i.lineTo(t.x,t.y-4.5)}})}else if(a==="none"){return}i.closePath();i.fill();i.stroke()}function drawRingTitle(t,e,a,i){var r=t.title.fontSize||e.titleFontSize;var o=t.subtitle.fontSize||e.subtitleFontSize;var n=t.title.name||"";var l=t.subtitle.name||"";var c=t.title.color||t.fontColor;var d=t.subtitle.color||t.fontColor;var x=n?r:0;var f=l?o:0;var s=5;if(l){var p=measureText(l,o*t.pix,a);var u=i.x-p/2+(t.subtitle.offsetX||0)*t.pix;var h=i.y+o*t.pix/2+(t.subtitle.offsetY||0)*t.pix;if(n){h+=(x*t.pix+s)/2}a.beginPath();a.setFontSize(o*t.pix);a.setFillStyle(d);a.fillText(l,u,h);a.closePath();a.stroke()}if(n){var g=measureText(n,r*t.pix,a);var y=i.x-g/2+(t.title.offsetX||0);var v=i.y+r*t.pix/2+(t.title.offsetY||0)*t.pix;if(l){v-=(f*t.pix+s)/2}a.beginPath();a.setFontSize(r*t.pix);a.setFillStyle(c);a.fillText(n,y,v);a.closePath();a.stroke()}}function drawPointText(t,o,n,l,s){var h=o.data;var c=o.textOffset?o.textOffset:0;t.forEach(function(t,e){if(t!==null){l.beginPath();var a=o.textSize?o.textSize*s.pix:n.fontSize;l.setFontSize(a);l.setFillStyle(o.textColor||s.fontColor);var i=h[e];if(typeof h[e]==="object"&&h[e]!==null){if(h[e].constructor.toString().indexOf("Array")>-1){i=h[e][1]}else{i=h[e].value}}var r=o.formatter?o.formatter(i,e,o,s):i;l.setTextAlign("center");l.fillText(String(r),t.x,t.y-4+c*s.pix);l.closePath();l.stroke();l.setTextAlign("left")}})}function drawColumePointText(t,n,l,s,h){var c=n.data;var d=n.textOffset?n.textOffset:0;var x=h.extra.column.labelPosition;t.forEach(function(t,e){if(t!==null){s.beginPath();var a=n.textSize?n.textSize*h.pix:l.fontSize;s.setFontSize(a);s.setFillStyle(n.textColor||h.fontColor);var i=c[e];if(typeof c[e]==="object"&&c[e]!==null){if(c[e].constructor.toString().indexOf("Array")>-1){i=c[e][1]}else{i=c[e].value}}var r=n.formatter?n.formatter(i,e,n,h):i;s.setTextAlign("center");var o=t.y-4*h.pix+d*h.pix;if(t.y>n.zeroPoints){o=t.y+d*h.pix+a}if(x=="insideTop"){o=t.y+a+d*h.pix;if(t.y>n.zeroPoints){o=t.y-d*h.pix-4*h.pix}}if(x=="center"){o=t.y+d*h.pix+(h.height-h.area[2]-t.y+a)/2;if(n.zeroPointsn.zeroPoints){o=t.y-d*h.pix-(t.y-n.zeroPoints-a)/2}if(h.extra.column.type=="stack"){o=t.y+d*h.pix+(t.y0-t.y+a)/2}}if(x=="bottom"){o=h.height-h.area[2]+d*h.pix-4*h.pix;if(n.zeroPointsn.zeroPoints){o=n.zeroPoints-d*h.pix+a+2*h.pix}if(h.extra.column.type=="stack"){o=t.y0+d*h.pix-4*h.pix}}s.fillText(String(r),t.x,o);s.closePath();s.stroke();s.setTextAlign("left")}})}function drawMountPointText(t,n,l,s,h,c){var e=n.data;var d=n.textOffset?n.textOffset:0;var a=h.extra.mount.labelPosition;t.forEach(function(t,e){if(t!==null){s.beginPath();var a=n[e].textSize?n[e].textSize*h.pix:l.fontSize;s.setFontSize(a);s.setFillStyle(n[e].textColor||h.fontColor);var i=t.value;var r=n[e].formatter?n[e].formatter(i,e,n,h):i;s.setTextAlign("center");var o=t.y-4*h.pix+d*h.pix;if(t.y>c){o=t.y+d*h.pix+a}s.fillText(String(r),t.x,o);s.closePath();s.stroke();s.setTextAlign("left")}})}function drawBarPointText(t,o,n,l,s){var h=o.data;var e=o.textOffset?o.textOffset:0;t.forEach(function(t,e){if(t!==null){l.beginPath();var a=o.textSize?o.textSize*s.pix:n.fontSize;l.setFontSize(a);l.setFillStyle(o.textColor||s.fontColor);var i=h[e];if(typeof h[e]==="object"&&h[e]!==null){i=h[e].value}var r=o.formatter?o.formatter(i,e,o,s):i;l.setTextAlign("left");l.fillText(String(r),t.x+4*s.pix,t.y+a/2-3);l.closePath();l.stroke()}})}function drawGaugeLabel(e,a,i,r,o,n){a-=e.width/2+e.labelOffset*r.pix;a=a<10?10:a;let t;if(e.endAngle=2){l=l%2}s+=x}}function drawRadarLabel(t,s,h,c,d,x){var f=c.extra.radar||{};t.forEach(function(t,e){if(f.labelPointShow===true&&c.categories[e]!==""){var a={x:s*Math.cos(t),y:s*Math.sin(t)};var i=convertCoordinateOrigin(a.x,a.y,h);x.setFillStyle(f.labelPointColor);x.beginPath();x.arc(i.x,i.y,f.labelPointRadius*c.pix,0,2*Math.PI,false);x.closePath();x.fill()}if(f.labelShow===true){var r={x:(s+d.radarLabelTextMargin*c.pix)*Math.cos(t),y:(s+d.radarLabelTextMargin*c.pix)*Math.sin(t)};var o=convertCoordinateOrigin(r.x,r.y,h);var n=o.x;var l=o.y;if(util.approximatelyEqual(r.x,0)){n-=measureText(c.categories[e]||"",d.fontSize,x)/2}else if(r.x<0){n-=measureText(c.categories[e]||"",d.fontSize,x)}x.beginPath();x.setFontSize(d.fontSize);x.setFillStyle(f.labelColor||c.fontColor);x.fillText(c.categories[e]||"",n,l+d.fontSize/2);x.closePath();x.stroke()}})}function drawPieText(n,d,x,f,t,l){var p=x.pieChartLinePadding;var u=[];var g=null;var y=n.map(function(t,e){var a=t.formatter?t.formatter(t,e,n,d):util.toFixed(t._proportion_.toFixed(4)*100)+"%";a=t.labelText?t.labelText:a;var i=2*Math.PI-(t._start_+2*Math.PI*t._proportion_/2);if(t._rose_proportion_){i=2*Math.PI-(t._start_+2*Math.PI*t._rose_proportion_/2)}var r=t.color;var o=t._radius_;return{arc:i,text:a,color:r,radius:o,textColor:t.textColor,textSize:t.textSize,labelShow:t.labelShow}});for(let c=0;c=0?e+x.pieChartTextPadding:e-x.pieChartTextPadding;let n=a;let l=measureText(t.text,t.textSize*d.pix||x.fontSize,f);let s=n;if(g&&util.isSameXCoordinateArea(g.start,{x:o})){if(o>0){s=Math.min(n,g.start.y)}else if(e<0){s=Math.max(n,g.start.y)}else{if(n>0){s=Math.max(n,g.start.y)}else{s=Math.min(n,g.start.y)}}}if(o<0){o-=l}let h={lineStart:{x:i,y:r},lineEnd:{x:e,y:a},start:{x:o,y:s},width:l,height:x.fontSize,text:t.text,color:t.color,textColor:t.textColor,textSize:t.textSize};g=avoidCollision(h,g);u.push(g)}for(let n=0;nr?r:o.activeWidth;var n=e.area[0];var l=e.height-e.area[2];i.beginPath();i.setFillStyle(hexToRgb(o.activeBgColor,o.activeBgOpacity));i.rect(t-o.activeWidth/2,n,o.activeWidth,l-n);i.closePath();i.fill();i.setFillStyle("#FFFFFF")}function drawBarToolTipSplitArea(t,e,a,i,r){var o=assign({},{activeBgColor:"#000000",activeBgOpacity:.08},e.extra.bar);var n=e.area[3];var l=e.width-e.area[1];i.beginPath();i.setFillStyle(hexToRgb(o.activeBgColor,o.activeBgOpacity));i.rect(n,t-r/2,l-n,r);i.closePath();i.fill();i.setFillStyle("#FFFFFF")}function drawToolTip(e,r,o,a,n,i,f){var l=assign({},{showBox:true,showArrow:true,showCategory:false,bgColor:"#000000",bgOpacity:.7,borderColor:"#000000",borderWidth:0,borderRadius:0,borderOpacity:.7,boxPadding:3,fontColor:"#FFFFFF",fontSize:13,lineHeight:20,legendShow:true,legendShape:"auto",splitLine:true},o.extra.tooltip);if(l.showCategory==true&&o.categories){e.unshift({text:o.categories[o.tooltip.index],color:null})}var s=l.fontSize*o.pix;var p=l.lineHeight*o.pix;var h=l.boxPadding*o.pix;var c=s;var u=5*o.pix;if(l.legendShow==false){c=0;u=0}var d=l.showArrow?8*o.pix:0;var g=false;if(o.type=="line"||o.type=="mount"||o.type=="area"||o.type=="candle"||o.type=="mix"){if(l.splitLine==true){drawToolTipSplitLine(o.tooltip.offset.x,o,a,n)}}r=assign({x:0,y:0},r);r.y-=8*o.pix;var y=e.map(function(t){return measureText(t.text,s,n)});var x=c+u+4*h+Math.max.apply(null,y);var v=2*h+e.length*p;if(l.showBox==false){return}if(r.x-Math.abs(o._scrollDistance_||0)+d+x>o.width){g=true}if(v+r.y>o.height){r.y=o.height-v}n.beginPath();n.setFillStyle(hexToRgb(l.bgColor,l.bgOpacity));n.setLineWidth(l.borderWidth*o.pix);n.setStrokeStyle(hexToRgb(l.borderColor,l.borderOpacity));var t=l.borderRadius;if(g){if(x+d>o.width){r.x=o.width+Math.abs(o._scrollDistance_||0)+d+(x-o.width)}if(x>r.x){r.x=o.width+Math.abs(o._scrollDistance_||0)+d+(x-o.width)}if(l.showArrow){n.moveTo(r.x,r.y+10*o.pix);n.lineTo(r.x-d,r.y+10*o.pix+5*o.pix)}n.arc(r.x-d-t,r.y+v-t,t,0,Math.PI/2,false);n.arc(r.x-d-Math.round(x)+t,r.y+v-t,t,Math.PI/2,Math.PI,false);n.arc(r.x-d-Math.round(x)+t,r.y+t,t,-Math.PI,-Math.PI/2,false);n.arc(r.x-d-t,r.y+t,t,-Math.PI/2,0,false);if(l.showArrow){n.lineTo(r.x-d,r.y+10*o.pix-5*o.pix);n.lineTo(r.x,r.y+10*o.pix)}}else{if(l.showArrow){n.moveTo(r.x,r.y+10*o.pix);n.lineTo(r.x+d,r.y+10*o.pix-5*o.pix)}n.arc(r.x+d+t,r.y+t,t,-Math.PI,-Math.PI/2,false);n.arc(r.x+d+Math.round(x)-t,r.y+t,t,-Math.PI/2,0,false);n.arc(r.x+d+Math.round(x)-t,r.y+v-t,t,0,Math.PI/2,false);n.arc(r.x+d+t,r.y+v-t,t,Math.PI/2,Math.PI,false);if(l.showArrow){n.lineTo(r.x+d,r.y+10*o.pix+5*o.pix);n.lineTo(r.x,r.y+10*o.pix)}}n.closePath();n.fill();if(l.borderWidth>0){n.stroke()}if(l.legendShow){e.forEach(function(t,e){if(t.color!==null){n.beginPath();n.setFillStyle(t.color);var a=r.x+d+2*h;var i=r.y+(p-s)/2+p*e+h+1;if(g){a=r.x-x-d+2*h}switch(t.legendShape){case"line":n.moveTo(a,i+.5*c-2*o.pix);n.fillRect(a,i+.5*c-2*o.pix,c,4*o.pix);break;case"triangle":n.moveTo(a+7.5*o.pix,i+.5*c-5*o.pix);n.lineTo(a+2.5*o.pix,i+.5*c+5*o.pix);n.lineTo(a+12.5*o.pix,i+.5*c+5*o.pix);n.lineTo(a+7.5*o.pix,i+.5*c-5*o.pix);break;case"diamond":n.moveTo(a+7.5*o.pix,i+.5*c-5*o.pix);n.lineTo(a+2.5*o.pix,i+.5*c);n.lineTo(a+7.5*o.pix,i+.5*c+5*o.pix);n.lineTo(a+12.5*o.pix,i+.5*c);n.lineTo(a+7.5*o.pix,i+.5*c-5*o.pix);break;case"circle":n.moveTo(a+7.5*o.pix,i+.5*c);n.arc(a+7.5*o.pix,i+.5*c,5*o.pix,0,2*Math.PI);break;case"rect":n.moveTo(a,i+.5*c-5*o.pix);n.fillRect(a,i+.5*c-5*o.pix,15*o.pix,10*o.pix);break;case"square":n.moveTo(a+2*o.pix,i+.5*c-5*o.pix);n.fillRect(a+2*o.pix,i+.5*c-5*o.pix,10*o.pix,10*o.pix);break;default:n.moveTo(a,i+.5*c-5*o.pix);n.fillRect(a,i+.5*c-5*o.pix,15*o.pix,10*o.pix)}n.closePath();n.fill()}})}e.forEach(function(t,e){var a=r.x+d+2*h+c+u;if(g){a=r.x-x-d+2*h+c+u}var i=r.y+p*e+(p-s)/2-1+h+s;n.beginPath();n.setFontSize(s);n.setTextBaseline("normal");n.setFillStyle(l.fontColor);n.fillText(t.text,a,i);n.closePath();n.stroke()})}function drawColumnDataPoints(T,b,S,w){let A=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let t=b.chartData.xAxisData,P=t.xAxisPoints,C=t.eachSpacing;let D=assign({},{type:"group",width:C/2,meterBorder:4,meterFillColor:"#FFFFFF",barBorderCircle:false,barBorderRadius:[],seriesGap:2,linearType:"none",linearOpacity:1,customColor:[],colorStop:0,labelPosition:"outside"},b.extra.column);let M=[];w.save();let L=-2;let F=P.length+2;if(b._scrollDistance_&&b._scrollDistance_!==0&&b.enableScroll===true){w.translate(b._scrollDistance_,0);L=Math.floor(-b._scrollDistance_/C)-2;F=L+b.xAxis.itemCount+4}if(b.tooltip&&b.tooltip.textList&&b.tooltip.textList.length&&A===1){drawToolTipSplitArea(b.tooltip.offset.x,b,S,w,C)}D.customColor=fillCustomColor(D.linearType,D.customColor,T,S);T.forEach(function(a,i){let e,t,o;e=[].concat(b.chartData.yAxisData.ranges[a.index]);t=e.pop();o=e.shift();let x=b.height-b.area[0]-b.area[2];let f=x*(0-t)/(o-t);let n=b.height-Math.round(f)-b.area[2];a.zeroPoints=n;var p=a.data;switch(D.type){case"group":var r=getColumnDataPoints(p,t,o,P,C,b,S,n,A);var u=getStackDataPoints(p,t,o,P,C,b,S,i,T,A);M.push(u);r=fixColumeData(r,C,T.length,i,S,b);for(let t=0;tL&&tn?n:o.y;const d=o.width;const s=Math.abs(n-o.y);if(D.barBorderCircle){D.barBorderRadius=[d/2,d/2,0,0]}if(o.y>n){D.barBorderRadius=[0,0,d/2,d/2]}let[t,e,a,i]=D.barBorderRadius;let r=Math.min(d/2,s/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;w.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);w.arc(h+d-e,c+e,e,-Math.PI/2,0);w.arc(h+d-a,c+s-a,a,0,Math.PI/2);w.arc(h+i,c+s-i,i,Math.PI/2,Math.PI)}else{w.moveTo(l,o.y);w.lineTo(l+o.width,o.y);w.lineTo(l+o.width,n);w.lineTo(l,n);w.lineTo(l,o.y);w.setLineWidth(1);w.setStrokeStyle(y)}w.setFillStyle(g);w.closePath();w.fill()}};break;case"stack":var r=getStackDataPoints(p,t,o,P,C,b,S,i,T,A);M.push(r);r=fixColumeStackData(r,C,T.length,i,S,b,T);for(let e=0;eL&&e0){s-=m}w.setFillStyle(g);w.moveTo(l,t.y);w.fillRect(l,t.y,t.width,s);w.closePath();w.fill()}};break;case"meter":var r=getDataPoints(p,t,o,P,C,b,S,A);M.push(r);r=fixColumeMeterData(r,C,T.length,i,S,b,D.meterBorder);for(let t=0;tL&&t0){w.setStrokeStyle(a.color);w.setLineWidth(D.meterBorder*b.pix)}if(i==0){w.setFillStyle(D.meterFillColor)}else{w.setFillStyle(o.color||a.color)}var l=o.x-o.width/2;var s=b.height-o.y-b.area[2];if(D.barBorderRadius&&D.barBorderRadius.length===4||D.barBorderCircle===true){const h=l;const c=o.y;const d=o.width;const s=n-o.y;if(D.barBorderCircle){D.barBorderRadius=[d/2,d/2,0,0]}let[t,e,a,i]=D.barBorderRadius;let r=Math.min(d/2,s/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;w.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);w.arc(h+d-e,c+e,e,-Math.PI/2,0);w.arc(h+d-a,c+s-a,a,0,Math.PI/2);w.arc(h+i,c+s-i,i,Math.PI/2,Math.PI);w.fill()}else{w.moveTo(l,o.y);w.lineTo(l+o.width,o.y);w.lineTo(l+o.width,n);w.lineTo(l,n);w.lineTo(l,o.y);w.fill()}if(i==0&&D.meterBorder>0){w.closePath();w.stroke()}}}break}});if(b.dataLabel!==false&&A===1){T.forEach(function(t,e){let a,i,r;a=[].concat(b.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;switch(D.type){case"group":var n=getColumnDataPoints(o,i,r,P,C,b,S,A);n=fixColumeData(n,C,T.length,e,S,b);drawColumePointText(n,t,S,w,b);break;case"stack":var n=getStackDataPoints(o,i,r,P,C,b,S,e,T,A);drawColumePointText(n,t,S,w,b);break;case"meter":var n=getDataPoints(o,i,r,P,C,b,S,A);drawColumePointText(n,t,S,w,b);break}})}w.restore();return{xAxisPoints:P,calPoints:M,eachSpacing:C}}function drawMountDataPoints(i,r,o,n){let f=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let t=r.chartData.xAxisData,p=t.xAxisPoints,l=t.eachSpacing;let s=assign({},{type:"mount",widthRatio:1,borderWidth:1,barBorderCircle:false,barBorderRadius:[],linearType:"none",linearOpacity:1,customColor:[],colorStop:0},r.extra.mount);s.widthRatio=s.widthRatio<=0?0:s.widthRatio;s.widthRatio=s.widthRatio>=2?2:s.widthRatio;let e=[];n.save();let u=-2;let g=p.length+2;if(r._scrollDistance_&&r._scrollDistance_!==0&&r.enableScroll===true){n.translate(r._scrollDistance_,0);u=Math.floor(-r._scrollDistance_/l)-2;g=u+r.xAxis.itemCount+4}s.customColor=fillCustomColor(s.linearType,s.customColor,i,o);let y,v,m;y=[].concat(r.chartData.yAxisData.ranges[0]);v=y.pop();m=y.shift();let T=r.height-r.area[0]-r.area[2];let b=T*(0-v)/(m-v);let h=r.height-Math.round(b)-r.area[2];var c=getMountDataPoints(i,v,m,p,l,r,s,h,f);switch(s.type){case"bar":for(let t=0;tu&&th?h:o.y;const C=o.width;const S=Math.abs(h-o.y);if(s.barBorderCircle){s.barBorderRadius=[C/2,C/2,0,0]}if(o.y>h){s.barBorderRadius=[0,0,C/2,C/2]}let[t,e,a,i]=s.barBorderRadius;let r=Math.min(C/2,S/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;n.arc(A+t,P+t,t,-Math.PI,-Math.PI/2);n.arc(A+C-e,P+e,e,-Math.PI/2,0);n.arc(A+C-a,P+S-a,a,0,Math.PI/2);n.arc(A+i,P+S-i,i,Math.PI/2,Math.PI)}else{n.moveTo(d,o.y);n.lineTo(d+o.width,o.y);n.lineTo(d+o.width,h);n.lineTo(d,h);n.lineTo(d,o.y)}n.setStrokeStyle(w);n.setFillStyle(a);if(s.borderWidth>0){n.setLineWidth(s.borderWidth*r.pix);n.closePath();n.stroke()}n.fill()}};break;case"triangle":for(let e=0;eu&&e0){n.setLineWidth(s.borderWidth*r.pix);n.stroke()}n.fill()}};break;case"mount":for(let e=0;eu&&e0){n.setLineWidth(s.borderWidth*r.pix);n.stroke()}n.fill()}};break;case"sharp":for(let e=0;eu&&e0){n.setLineWidth(s.borderWidth*r.pix);n.stroke()}n.fill()}};break}if(r.dataLabel!==false&&f===1){let t,e,a;t=[].concat(r.chartData.yAxisData.ranges[0]);e=t.pop();a=t.shift();var c=getMountDataPoints(i,e,a,p,l,r,s,h,f);drawMountPointText(c,i,o,n,r,h)}n.restore();return{xAxisPoints:p,calPoints:c,eachSpacing:l}}function drawBarDataPoints(y,v,m,T){let b=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let S=[];let w=(v.height-v.area[0]-v.area[2])/v.categories.length;for(let t=0;tC&&tr?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(g+i,c+i,i,-Math.PI,-Math.PI/2);T.arc(o.x-t,c+t,t,-Math.PI/2,0);T.arc(o.x-e,c+h-e,e,0,Math.PI/2);T.arc(g+a,c+h-a,a,Math.PI/2,Math.PI)}else{T.moveTo(n,r);T.lineTo(o.x,r);T.lineTo(o.x,r+o.width);T.lineTo(n,r+o.width);T.lineTo(n,r);T.setLineWidth(1);T.setStrokeStyle(u)}T.setFillStyle(l);T.closePath();T.fill()}};break;case"stack":var i=getBarStackDataPoints(x,e,d,S,w,v,m,t,y,b);P.push(i);i=fixBarStackData(i,w,y.length,t,m,v,y);for(let e=0;eC&&e5&&arguments[5]!==undefined?arguments[5]:1;var s=assign({},{color:{},average:{}},h.extra.candle);s.color=assign({},{upLine:"#f04864",upFill:"#f04864",downLine:"#2fc25b",downFill:"#2fc25b"},s.color);s.average=assign({},{show:false,name:[],day:[],color:c.color},s.average);h.extra.candle=s;let a=h.chartData.xAxisData,x=a.xAxisPoints,f=a.eachSpacing;let y=[];d.save();let p=-2;let v=x.length+2;let u=0;let m=h.width+f;if(h._scrollDistance_&&h._scrollDistance_!==0&&h.enableScroll===true){d.translate(h._scrollDistance_,0);p=Math.floor(-h._scrollDistance_/f)-2;v=p+h.xAxis.itemCount+4;u=-h._scrollDistance_-f*2+h.area[3];m=u+(h.xAxis.itemCount+4)*f}if(s.average.show||t){t.forEach(function(e,t){let a,i,r;a=[].concat(h.chartData.yAxisData.ranges[e.index]);i=a.pop();r=a.shift();var o=e.data;var n=getDataPoints(o,i,r,x,f,h,c,g);var l=splitPoints(n,e);for(let t=0;tu){d.moveTo(t.x,t.y);a=1}if(e>0&&t.x>u&&t.xp&&e0){d.setStrokeStyle(s.color.upLine);d.setFillStyle(s.color.upFill);d.setLineWidth(1*h.pix);d.moveTo(t[3].x,t[3].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[1].x-f/4,t[1].y);d.lineTo(t[0].x-f/4,t[0].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[2].x,t[2].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[0].x+f/4,t[0].y);d.lineTo(t[1].x+f/4,t[1].y);d.lineTo(t[1].x,t[1].y);d.moveTo(t[3].x,t[3].y)}else{d.setStrokeStyle(s.color.downLine);d.setFillStyle(s.color.downFill);d.setLineWidth(1*h.pix);d.moveTo(t[3].x,t[3].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[0].x-f/4,t[0].y);d.lineTo(t[1].x-f/4,t[1].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[2].x,t[2].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[1].x+f/4,t[1].y);d.lineTo(t[0].x+f/4,t[0].y);d.lineTo(t[0].x,t[0].y);d.moveTo(t[3].x,t[3].y)}d.closePath();d.fill();d.stroke()}}});d.restore();return{xAxisPoints:x,calPoints:y,eachSpacing:f}}function drawAreaDataPoints(t,s,h,c){var d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var x=assign({},{type:"straight",opacity:.2,addLine:false,width:2,gradient:false,activeType:"none"},s.extra.area);let e=s.chartData.xAxisData,f=e.xAxisPoints,p=e.eachSpacing;let y=s.height-s.area[2];let v=[];c.save();let u=0;let g=s.width+p;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);u=-s._scrollDistance_-p*2+s.area[3];g=u+(s.xAxis.itemCount+4)*p}t.forEach(function(e,t){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[e.index]);i=a.pop();r=a.shift();let o=e.data;let n=getDataPoints(o,i,r,f,p,s,h,d);v.push(n);let l=splitPoints(n,e);for(let t=0;t1){let t=r[0];let e=r[r.length-1];c.moveTo(t.x,t.y);let i=0;if(x.type==="curve"){for(let a=0;au){c.moveTo(e.x,e.y);i=1}if(a>0&&e.x>u&&e.xu){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>u&&t.xu){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>u&&t.xu){c.moveTo(e.x,e.y);i=1}if(a>0&&e.x>u&&e.xu){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>u&&t.xu){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>u&&t.x4&&arguments[4]!==undefined?arguments[4]:1;var i=assign({},{type:"circle"},s.extra.scatter);let e=s.chartData.xAxisData,x=e.xAxisPoints,f=e.eachSpacing;var r=[];c.save();let a=0;let o=s.width+f;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);a=-s._scrollDistance_-f*2+s.area[3];o=a+(s.xAxis.itemCount+4)*f}t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,x,f,s,h,d);c.beginPath();c.setStrokeStyle(t.color);c.setFillStyle(t.color);c.setLineWidth(1*s.pix);var l=t.pointShape;if(l==="diamond"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x,t.y-4.5);c.lineTo(t.x-4.5,t.y);c.lineTo(t.x,t.y+4.5);c.lineTo(t.x+4.5,t.y);c.lineTo(t.x,t.y-4.5)}})}else if(l==="circle"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x+2.5*s.pix,t.y);c.arc(t.x,t.y,3*s.pix,0,2*Math.PI,false)}})}else if(l==="square"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x-3.5,t.y-3.5);c.rect(t.x-3.5,t.y-3.5,7,7)}})}else if(l==="triangle"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x,t.y-4.5);c.lineTo(t.x-4.5,t.y+4.5);c.lineTo(t.x+4.5,t.y+4.5);c.lineTo(t.x,t.y-4.5)}})}else if(l==="triangle"){return}c.closePath();c.fill();c.stroke()});if(s.dataLabel!==false&&d===1){t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,x,f,s,h,d);drawPointText(n,t,h,c,s)})}c.restore();return{xAxisPoints:x,calPoints:r,eachSpacing:f}}function drawBubbleDataPoints(a,l,s,h){var c=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var d=assign({},{opacity:1,border:2},l.extra.bubble);let t=l.chartData.xAxisData,x=t.xAxisPoints,f=t.eachSpacing;var i=[];h.save();let e=0;let r=l.width+f;if(l._scrollDistance_&&l._scrollDistance_!==0&&l.enableScroll===true){h.translate(l._scrollDistance_,0);e=-l._scrollDistance_-f*2+l.area[3];r=e+(l.xAxis.itemCount+4)*f}a.forEach(function(i,t){let e,a,r;e=[].concat(l.chartData.yAxisData.ranges[i.index]);a=e.pop();r=e.shift();var o=i.data;var n=getDataPoints(o,a,r,x,f,l,s,c);h.beginPath();h.setStrokeStyle(i.color);h.setLineWidth(d.border*l.pix);h.setFillStyle(hexToRgb(i.color,d.opacity));n.forEach(function(t,e){h.moveTo(t.x+t.r,t.y);h.arc(t.x,t.y,t.r*l.pix,0,2*Math.PI,false)});h.closePath();h.fill();h.stroke();if(l.dataLabel!==false&&c===1){n.forEach(function(t,e){h.beginPath();var a=i.textSize*l.pix||s.fontSize;h.setFontSize(a);h.setFillStyle(i.textColor||"#FFFFFF");h.setTextAlign("center");h.fillText(String(t.t),t.x,t.y+a/2);h.closePath();h.stroke();h.setTextAlign("left")})}});h.restore();return{xAxisPoints:x,calPoints:i,eachSpacing:f}}function drawLineDataPoints(t,d,x,f){var p=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var u=assign({},{type:"straight",width:2,activeType:"none",linearType:"none",onShadow:false,animation:"vertical"},d.extra.line);u.width*=d.pix;let e=d.chartData.xAxisData,g=e.xAxisPoints,y=e.eachSpacing;var T=[];f.save();let v=0;let m=d.width+y;if(d._scrollDistance_&&d._scrollDistance_!==0&&d.enableScroll===true){f.translate(d._scrollDistance_,0);v=-d._scrollDistance_-y*2+d.area[3];m=v+(d.xAxis.itemCount+4)*y}t.forEach(function(e,c){f.beginPath();f.setStrokeStyle(e.color);f.moveTo(-1e4,-1e4);f.lineTo(-10001,-10001);f.stroke();let t,a,i;t=[].concat(d.chartData.yAxisData.ranges[e.index]);a=t.pop();i=t.shift();var r=e.data;var o=getLineDataPoints(r,a,i,g,y,d,x,u,p);T.push(o);var n=splitPoints(o,e);if(e.lineType=="dash"){let t=e.dashLength?e.dashLength:8;t*=d.pix;f.setLineDash([t,t])}f.beginPath();var l=e.color;if(u.linearType!=="none"&&e.linearColor&&e.linearColor.length>0){var s=f.createLinearGradient(d.chartData.xAxisData.startX,d.height/2,d.chartData.xAxisData.endX,d.height/2);for(var h=0;h0){f.setShadow(e.setShadow[0],e.setShadow[1],e.setShadow[2],e.setShadow[3])}else{f.setShadow(0,0,0,"rgba(0,0,0,0)")}f.setLineWidth(u.width);n.forEach(function(i,t){if(i.length===1){f.moveTo(i[0].x,i[0].y)}else{f.moveTo(i[0].x,i[0].y);let a=0;if(u.type==="curve"){for(let e=0;ev){f.moveTo(t.x,t.y);a=1}if(e>0&&t.x>v&&t.xv){f.moveTo(t.x,t.y);a=1}if(e>0&&t.x>v&&t.xv){f.moveTo(t.x,t.y);a=1}if(e>0&&t.x>v&&t.x4&&arguments[4]!==undefined?arguments[4]:1;let e=v.chartData.xAxisData,b=e.xAxisPoints,S=e.eachSpacing;let w=assign({},{width:S/2,barBorderCircle:false,barBorderRadius:[],seriesGap:2,linearType:"none",linearOpacity:1,customColor:[],colorStop:0},v.extra.mix.column);let A=assign({},{opacity:.2,gradient:false},v.extra.mix.area);let M=assign({},{width:2},v.extra.mix.line);let L=v.height-v.area[2];let F=[];var _=0;var k=0;t.forEach(function(t,e){if(t.type=="column"){k+=1}});T.save();let R=-2;let I=b.length+2;let P=0;let C=v.width+S;if(v._scrollDistance_&&v._scrollDistance_!==0&&v.enableScroll===true){T.translate(v._scrollDistance_,0);R=Math.floor(-v._scrollDistance_/S)-2;I=R+v.xAxis.itemCount+4;P=-v._scrollDistance_-S*2+v.area[3];C=P+(v.xAxis.itemCount+4)*S}w.customColor=fillCustomColor(w.linearType,w.customColor,t,m);t.forEach(function(n,t){let o,x,f;o=[].concat(v.chartData.yAxisData.ranges[n.index]);x=o.pop();f=o.shift();var p=n.data;var a=getDataPoints(p,x,f,b,S,v,m,D);F.push(a);if(n.type=="column"){a=fixColumeData(a,S,k,_,m,v);for(let t=0;tR&&tr?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);T.arc(h+d-e,c+e,e,-Math.PI/2,0);T.arc(h+d-a,c+s-a,a,0,Math.PI/2);T.arc(h+i,c+s-i,i,Math.PI/2,Math.PI)}else{T.moveTo(l,o.y);T.lineTo(l+o.width,o.y);T.lineTo(l+o.width,v.height-v.area[2]);T.lineTo(l,v.height-v.area[2]);T.lineTo(l,o.y);T.setLineWidth(1);T.setStrokeStyle(u)}T.setFillStyle(e);T.closePath();T.fill()}}_+=1}if(n.type=="area"){let e=splitPoints(a,n);for(let t=0;t1){var r=i[0];let t=i[i.length-1];T.moveTo(r.x,r.y);let a=0;if(n.style==="curve"){for(let e=0;eP){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>P&&t.xP){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>P&&t.xP){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>P&&t.xP){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>P&&t.x1){if(h.extra.mount.widthRatio>2)h.extra.mount.widthRatio=2;l+=(h.extra.mount.widthRatio-1)*f}var s=n*n/l;var y=0;if(h._scrollDistance_){y=-h._scrollDistance_*n/l}d.beginPath();d.setLineCap("round");d.setLineWidth(6*h.pix);d.setStrokeStyle(h.xAxis.scrollBackgroundColor||"#EFEBEF");d.moveTo(t,o);d.lineTo(a,o);d.stroke();d.closePath();d.beginPath();d.setLineCap("round");d.setLineWidth(6*h.pix);d.setStrokeStyle(h.xAxis.scrollColor||"#A6A6A6");d.moveTo(t+y,o);d.lineTo(t+y+s,o);d.stroke();d.closePath();d.setLineCap("butt")}d.save();if(h._scrollDistance_&&h._scrollDistance_!==0){d.translate(h._scrollDistance_,0)}if(h.xAxis.calibration===true){d.setStrokeStyle(h.xAxis.gridColor||"#cccccc");d.setLineCap("butt");d.setLineWidth(1*h.pix);x.forEach(function(t,e){if(e>0){d.beginPath();d.moveTo(t-f/2,u);d.lineTo(t-f/2,u+3*h.pix);d.closePath();d.stroke()}})}if(h.xAxis.disableGrid!==true){d.setStrokeStyle(h.xAxis.gridColor||"#cccccc");d.setLineCap("butt");d.setLineWidth(1*h.pix);if(h.xAxis.gridType=="dash"){d.setLineDash([h.xAxis.dashLength*h.pix,h.xAxis.dashLength*h.pix])}h.xAxis.gridEval=h.xAxis.gridEval||1;x.forEach(function(t,e){if(e%h.xAxis.gridEval==0){d.beginPath();d.moveTo(t,u);d.lineTo(t,i);d.stroke()}});d.setLineDash([])}if(h.xAxis.disabled!==true){let t=r.length;if(h.xAxis.labelCount){if(h.xAxis.itemCount){t=Math.ceil(r.length/h.xAxis.itemCount*h.xAxis.labelCount)}else{t=h.xAxis.labelCount}t-=1}let e=Math.ceil(r.length/t);let a=[];let i=r.length;for(let t=0;t=h.area[3]-1&&n-Math.abs(o)<=h.width-h.area[1]+1){d.beginPath();d.setFontSize(g);d.setFillStyle(h.xAxis.fontColor||h.fontColor);d.fillText(String(a),x[e]+i,u+h.xAxis.marginTop*h.pix+(h.xAxis.lineHeight-h.xAxis.fontSize)*h.pix/2+h.xAxis.fontSize*h.pix);d.closePath();d.stroke()}})}else{a.forEach(function(t,e){var a=h.xAxis.formatter?h.xAxis.formatter(t):t;var i=h._scrollDistance_||0;var r=p=="center"?x[e]+f/2:x[e];if(r-Math.abs(i)>=h.area[3]-1&&r-Math.abs(i)<=h.width-h.area[1]+1){d.save();d.beginPath();d.setFontSize(g);d.setFillStyle(h.xAxis.fontColor||h.fontColor);var o=measureText(String(a),g,d);var n=x[e];if(p=="center"){n=x[e]+f/2}var l=0;if(h.xAxis.scrollShow){l=6*h.pix}var s=u+h.xAxis.marginTop*h.pix+g-g*Math.abs(Math.sin(c._xAxisTextAngle_));if(h.xAxis.rotateAngle<0){n-=g/2;o=0}else{n+=g/2;o=-o}d.translate(n,s);d.rotate(-1*c._xAxisTextAngle_);d.fillText(String(a),o,0);d.closePath();d.stroke();d.restore()}})}}d.restore();if(h.xAxis.title){d.beginPath();d.setFontSize(h.xAxis.titleFontSize*h.pix);d.setFillStyle(h.xAxis.titleFontColor);d.fillText(String(h.xAxis.title),h.width-h.area[1]+h.xAxis.titleOffsetX*h.pix,h.height-h.area[2]+h.xAxis.marginTop*h.pix+(h.xAxis.lineHeight-h.xAxis.titleFontSize)*h.pix/2+(h.xAxis.titleFontSize+h.xAxis.titleOffsetY)*h.pix);d.closePath();d.stroke()}if(h.xAxis.axisLine){d.beginPath();d.setStrokeStyle(h.xAxis.axisLineColor);d.setLineWidth(1*h.pix);d.moveTo(t,h.height-h.area[2]);d.lineTo(a,h.height-h.area[2]);d.stroke()}}function drawYAxisGrid(c,e,d,a){if(e.yAxis.disableGrid===true){return}let t=e.height-e.area[0]-e.area[2];let i=t/e.yAxis.splitNumber;let r=e.area[3];let o=e.chartData.xAxisData.xAxisPoints,n=e.chartData.xAxisData.eachSpacing;let l=n*(o.length-1);if(e.type=="mount"&&e.extra&&e.extra.mount&&e.extra.mount.widthRatio&&e.extra.mount.widthRatio>1){if(e.extra.mount.widthRatio>2)e.extra.mount.widthRatio=2;l+=(e.extra.mount.widthRatio-1)*n}let x=r+l;let s=[];let h=1;if(e.xAxis.axisLine===false){h=0}for(let t=h;t4&&arguments[4]!==undefined?arguments[4]:1;var n=assign({},{activeOpacity:.5,activeRadius:10,offsetAngle:0,labelWidth:15,ringWidth:30,customRadius:0,border:false,borderWidth:2,borderColor:"#FFFFFF",centerColor:"#FFFFFF",linearType:"none",customColor:[]},r.type=="pie"?r.extra.pie:r.extra.ring);var l={x:r.area[3]+(r.width-r.area[1]-r.area[3])/2,y:r.area[0]+(r.height-r.area[0]-r.area[2])/2};if(e.pieChartLinePadding==0){e.pieChartLinePadding=n.activeRadius*r.pix}var i=Math.min((r.width-r.area[1]-r.area[3])/2-e.pieChartLinePadding-e.pieChartTextPadding-e._pieTextMaxLength_,(r.height-r.area[0]-r.area[2])/2-e.pieChartLinePadding-e.pieChartTextPadding);i=i<10?10:i;if(n.customRadius>0){i=n.customRadius*r.pix}t=getPieDataPoints(t,i,a);var h=n.activeRadius*r.pix;n.customColor=fillCustomColor(n.linearType,n.customColor,t,e);t=t.map(function(t){t._start_+=n.offsetAngle*Math.PI/180;return t});t.forEach(function(t,e){if(r.tooltip){if(r.tooltip.index==e){o.beginPath();o.setFillStyle(hexToRgb(t.color,n.activeOpacity||.5));o.moveTo(l.x,l.y);o.arc(l.x,l.y,t._radius_+h,t._start_,t._start_+2*t._proportion_*Math.PI);o.closePath();o.fill()}}o.beginPath();o.setLineWidth(n.borderWidth*r.pix);o.lineJoin="round";o.setStrokeStyle(n.borderColor);var a=t.color;if(n.linearType=="custom"){var i;if(o.createCircularGradient){i=o.createCircularGradient(l.x,l.y,t._radius_)}else{i=o.createRadialGradient(l.x,l.y,0,l.x,l.y,t._radius_)}i.addColorStop(0,hexToRgb(n.customColor[t.linearIndex],1));i.addColorStop(1,hexToRgb(t.color,1));a=i}o.setFillStyle(a);o.moveTo(l.x,l.y);o.arc(l.x,l.y,t._radius_,t._start_,t._start_+2*t._proportion_*Math.PI);o.closePath();o.fill();if(n.border==true){o.stroke()}});if(r.type==="ring"){var s=i*.6;if(typeof n.ringWidth==="number"&&n.ringWidth>0){s=Math.max(0,i-n.ringWidth*r.pix)}o.beginPath();o.setFillStyle(n.centerColor);o.moveTo(l.x,l.y);o.arc(l.x,l.y,s,0,2*Math.PI);o.closePath();o.fill()}if(r.dataLabel!==false&&a===1){drawPieText(t,r,e,o,i,l)}if(a===1&&r.type==="ring"){drawRingTitle(r,e,o,l)}return{center:l,radius:i,series:t}}function drawRoseDataPoints(t,r,e,o){var a=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var n=assign({},{type:"area",activeOpacity:.5,activeRadius:10,offsetAngle:0,labelWidth:15,border:false,borderWidth:2,borderColor:"#FFFFFF",linearType:"none",customColor:[]},r.extra.rose);if(e.pieChartLinePadding==0){e.pieChartLinePadding=n.activeRadius*r.pix}var l={x:r.area[3]+(r.width-r.area[1]-r.area[3])/2,y:r.area[0]+(r.height-r.area[0]-r.area[2])/2};var i=Math.min((r.width-r.area[1]-r.area[3])/2-e.pieChartLinePadding-e.pieChartTextPadding-e._pieTextMaxLength_,(r.height-r.area[0]-r.area[2])/2-e.pieChartLinePadding-e.pieChartTextPadding);i=i<10?10:i;var s=n.minRadius||i*.5;if(i4&&arguments[4]!==undefined?arguments[4]:1;var o=assign({},{startAngle:.75,endAngle:.25,type:"default",direction:"cw",lineCap:"round",width:12,gap:2,linearType:"none",customColor:[]},i.extra.arcbar);a=getArcbarDataPoints(a,o,e);var n;if(o.centerX||o.centerY){n={x:o.centerX?o.centerX:i.width/2,y:o.centerY?o.centerY:i.height/2}}else{n={x:i.width/2,y:i.height/2}}var l;if(o.radius){l=o.radius}else{l=Math.min(n.x,n.y);l-=5*i.pix;l-=o.width/2}l=l<10?10:l;o.customColor=fillCustomColor(o.linearType,o.customColor,a,t);for(let e=0;e5&&arguments[5]!==undefined?arguments[5]:1;var f=assign({},{type:"default",startAngle:.75,endAngle:.25,width:15,labelOffset:13,splitLine:{fixRadius:0,splitNumber:10,width:15,color:"#FFFFFF",childNumber:5,childWidth:5},pointer:{width:15,color:"auto"}},c.extra.gauge);if(f.oldAngle==undefined){f.oldAngle=f.startAngle}if(f.oldData==undefined){f.oldData=0}n=getGaugeAxisPoints(n,f.startAngle,f.endAngle);var p={x:c.width/2,y:c.height/2};var u=Math.min(p.x,p.y);u-=5*c.pix;u-=f.width/2;u=u<10?10:u;var g=u-f.width;var y=0;if(f.type=="progress"){var v=u-f.width*3;d.beginPath();let t=d.createLinearGradient(p.x,p.y-v,p.x,p.y+v);t.addColorStop("0",hexToRgb(h[0].color,.3));t.addColorStop("1.0",hexToRgb("#FFFFFF",.1));d.setFillStyle(t);d.arc(p.x,p.y,v,0,2*Math.PI,false);d.fill();d.setLineWidth(f.width);d.setStrokeStyle(hexToRgb(h[0].color,.3));d.setLineCap("round");d.beginPath();d.arc(p.x,p.y,g,f.startAngle*Math.PI,f.endAngle*Math.PI,false);d.stroke();if(f.endAnglet/o){d.setStrokeStyle(hexToRgb(h[0].color,1))}else{d.setStrokeStyle(hexToRgb(h[0].color,.3))}d.setLineWidth(3*c.pix);d.moveTo(i,0);d.lineTo(r,0);d.stroke();d.rotate(a*Math.PI)}d.restore();h=getGaugeArcbarDataPoints(h,f,x);d.setLineWidth(f.width);d.setStrokeStyle(h[0].color);d.setLineCap("round");d.beginPath();d.arc(p.x,p.y,g,f.startAngle*Math.PI,h[0]._proportion_*Math.PI,false);d.stroke();let l=u-f.width*2.5;d.save();d.translate(p.x,p.y);d.rotate((h[0]._proportion_-1)*Math.PI);d.beginPath();d.setLineWidth(f.width/3);let s=d.createLinearGradient(0,-l*.6,0,l*.6);s.addColorStop("0",hexToRgb("#FFFFFF",0));s.addColorStop("0.5",hexToRgb(h[0].color,1));s.addColorStop("1.0",hexToRgb("#FFFFFF",0));d.setStrokeStyle(s);d.arc(0,0,l,.85*Math.PI,1.15*Math.PI,false);d.stroke();d.beginPath();d.setLineWidth(1);d.setStrokeStyle(h[0].color);d.setFillStyle(h[0].color);d.moveTo(-l-f.width/3/2,-4);d.lineTo(-l-f.width/3/2-4,0);d.lineTo(-l-f.width/3/2,4);d.lineTo(-l-f.width/3/2,-4);d.stroke();d.fill();d.restore()}else{d.setLineWidth(f.width);d.setLineCap("butt");for(let e=0;e4&&arguments[4]!==undefined?arguments[4]:1;var s=assign({},{gridColor:"#cccccc",gridType:"radar",gridEval:1,axisLabel:false,axisLabelTofix:0,labelShow:true,labelColor:"#666666",labelPointShow:false,labelPointRadius:3,labelPointColor:"#cccccc",opacity:.2,gridCount:3,border:false,borderWidth:2,linearType:"none",customColor:[]},n.extra.radar);var a=getRadarCoordinateSeries(n.categories.length);var h={x:n.area[3]+(n.width-n.area[1]-n.area[3])/2,y:n.area[0]+(n.height-n.area[0]-n.area[2])/2};var r=(n.width-n.area[1]-n.area[3])/2;var d=(n.height-n.area[0]-n.area[2])/2;var c=Math.min(r-(getMaxTextListLength(n.categories,i.fontSize,l)+i.radarLabelTextMargin),d-i.radarLabelTextMargin);c-=i.radarLabelTextMargin*n.pix;c=c<10?10:c;c=s.radius?s.radius:c;l.beginPath();l.setLineWidth(1*n.pix);l.setStrokeStyle(s.gridColor);a.forEach(function(t,e){var a=convertCoordinateOrigin(c*Math.cos(t),c*Math.sin(t),h);l.moveTo(h.x,h.y);if(e%s.gridEval==0){l.lineTo(a.x,a.y)}});l.stroke();l.closePath();var x=function t(i){var r={};l.beginPath();l.setLineWidth(1*n.pix);l.setStrokeStyle(s.gridColor);if(s.gridType=="radar"){a.forEach(function(t,e){var a=convertCoordinateOrigin(c/s.gridCount*i*Math.cos(t),c/s.gridCount*i*Math.sin(t),h);if(e===0){r=a;l.moveTo(a.x,a.y)}else{l.lineTo(a.x,a.y)}});l.lineTo(r.x,r.y)}else{var e=convertCoordinateOrigin(c/s.gridCount*i*Math.cos(1.5),c/s.gridCount*i*Math.sin(1.5),h);l.arc(h.x,h.y,h.y-e.y,0,2*Math.PI,false)}l.stroke();l.closePath()};for(var e=1;e<=s.gridCount;e++){x(e)}s.customColor=fillCustomColor(s.linearType,s.customColor,o,i);var f=getRadarDataPoints(a,h,c,o,n,t);f.forEach(function(t,e){l.beginPath();l.setLineWidth(s.borderWidth*n.pix);l.setStrokeStyle(t.color);var a=hexToRgb(t.color,s.opacity);if(s.linearType=="custom"){var i;if(l.createCircularGradient){i=l.createCircularGradient(h.x,h.y,c)}else{i=l.createRadialGradient(h.x,h.y,0,h.x,h.y,c)}i.addColorStop(0,hexToRgb(s.customColor[o[e].linearIndex],s.opacity));i.addColorStop(1,hexToRgb(t.color,s.opacity));a=i}l.setFillStyle(a);t.data.forEach(function(t,e){if(e===0){l.moveTo(t.position.x,t.position.y)}else{l.lineTo(t.position.x,t.position.y)}});l.closePath();l.fill();if(s.border===true){l.stroke()}l.closePath();if(n.dataPointShape!==false){var r=t.data.map(function(t){return t.position});drawPointShape(r,t.color,t.pointShape,l,n)}});if(s.axisLabel===true){const p=Math.max(s.max,Math.max.apply(null,dataCombine(o)));const u=c/s.gridCount;const g=n.fontSize*n.pix;l.setFontSize(g);l.setFillStyle(n.fontColor);l.setTextAlign("left");for(var e=0;eh.x?e.xMax:h.x;e.yMin=e.yMinh.y?e.yMax:h.y}}}return e}function coordinateToPoint(t,e,a,i,r,o){return{x:(e-a.xMin)*i+r,y:(a.yMax-t)*i+o}}function pointToCoordinate(t,e,a,i,r,o){return{x:(e-r)/i+a.xMin,y:a.yMax-(t-o)/i}}function isRayIntersectsSegment(t,e,a){if(e[1]==a[1]){return false}if(e[1]>t[1]&&a[1]>t[1]){return false}if(e[1]t[1]){return false}if(a[1]==t[1]&&e[1]>t[1]){return false}if(e[0]a[t].area[2]||e[1]>a[t].area[3]||e[2]i||e[3]>r){o=true;break}else{o=false}}else{o=true;break}}}return o}function getWordCloudPoint(c,t,d){let x=c.series;switch(t){case"normal":for(let l=0;l.7){return true}else{return false}};for(let h=0;h4&&arguments[4]!==undefined?arguments[4]:1;let a=assign({},{type:"normal",autoColors:true},r.extra.word);if(!r.chartData.wordCloudData){r.chartData.wordCloudData=getWordCloudPoint(r,a.type,o)}o.beginPath();o.setFillStyle(r.background);o.rect(0,0,r.width,r.height);o.fill();o.save();let l=r.chartData.wordCloudData;o.translate(r.width/2,r.height/2);for(let i=0;i0){if(r.tooltip){if(r.tooltip.index==i){o.strokeText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}else{o.fillText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}}else{o.fillText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}}}else{if(l[i].area[0]>0){if(r.tooltip){if(r.tooltip.index==i){o.strokeText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}else{o.fillText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}}else{o.fillText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}}}o.stroke();o.restore()}o.restore()}function drawFunnelDataPoints(t,e,c,a){let d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let i=assign({},{type:"funnel",activeWidth:10,activeOpacity:.3,border:false,borderWidth:2,borderColor:"#FFFFFF",fillOpacity:1,minSize:0,labelAlign:"right",linearType:"none",customColor:[]},e.extra.funnel);let r=(e.height-e.area[0]-e.area[2])/t.length;let o={x:e.area[3]+(e.width-e.area[1]-e.area[3])/2,y:e.height-e.area[2]};let n=i.activeWidth*e.pix;let x=Math.min((e.width-e.area[1]-e.area[3])/2-n,(e.height-e.area[0]-e.area[2])/2-n);let l=getFunnelDataPoints(t,x,i,r,d);a.save();a.translate(o.x,o.y);i.customColor=fillCustomColor(i.linearType,i.customColor,t,c);if(i.type=="pyramid"){for(let t=0;t0){l.area[3]+=i[t].width+l.yAxis.padding*l.pix}else{l.area[3]+=i[t].width}a+=1}else if(i[t].position=="right"){if(e>0){l.area[1]+=i[t].width+l.yAxis.padding*l.pix}else{l.area[1]+=i[t].width}e+=1}}}else{n.yAxisWidth=i}l.chartData.yAxisData=f;if(l.categories&&l.categories.length&&l.type!=="radar"&&l.type!=="gauge"&&l.type!=="bar"){l.chartData.xAxisData=getXAxisPoints(l.categories,l,n);let t=calCategoriesData(l.categories,l,n,l.chartData.xAxisData.eachSpacing,s),e=t.xAxisHeight,a=t.angle;n.xAxisHeight=e;n._xAxisTextAngle_=a;l.area[2]+=e;l.chartData.categoriesData=t}else{if(l.type==="line"||l.type==="area"||l.type==="scatter"||l.type==="bubble"||l.type==="bar"){l.chartData.xAxisData=calXAxisData(c,l,n,s);d=l.chartData.xAxisData.rangesFormat;let t=calCategoriesData(d,l,n,l.chartData.xAxisData.eachSpacing,s),e=t.xAxisHeight,a=t.angle;n.xAxisHeight=e;n._xAxisTextAngle_=a;l.area[2]+=e;l.chartData.categoriesData=t}else{l.chartData.xAxisData={xAxisPoints:[]}}}if(l.enableScroll&&l.xAxis.scrollAlign=="right"&&l._scrollDistance_===undefined){let t=0,e=l.chartData.xAxisData.xAxisPoints,a=l.chartData.xAxisData.startX,i=l.chartData.xAxisData.endX,r=l.chartData.xAxisData.eachSpacing;let o=r*(e.length-1);let n=i-a;t=n-o;h.scrollOption.currentOffset=t;h.scrollOption.startTouchX=t;h.scrollOption.distance=0;h.scrollOption.lastMoveTime=0;l._scrollDistance_=t}if(t==="pie"||t==="ring"||t==="rose"){n._pieTextMaxLength_=l.dataLabel===false?0:getPieTextMaxLength(x,n,s,l)}switch(t){case"word":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function(t){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawWordCloudDataPoints(c,l,n,s,t);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"map":s.clearRect(0,0,l.width,l.height);drawMapDataPoints(c,l,n,s);setTimeout(()=>{this.uevent.trigger("renderComplete")},50);break;case"funnel":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function(t){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.funnelData=drawFunnelDataPoints(c,l,n,s,t);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,t);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"line":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawLineDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"scatter":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawScatterDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"bubble":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawBubbleDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"mix":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawMixDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"column":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawColumnDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"mount":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawMountDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"bar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawXAxis(d,l,n,s);var a=drawBarDataPoints(c,l,n,s,e),i=a.yAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.yAxisPoints=i;l.chartData.xAxisPoints=l.chartData.xAxisData.xAxisPoints;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"area":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawAreaDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"ring":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawPieDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"pie":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawPieDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"rose":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawRoseDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"radar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.radarData=drawRadarDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"arcbar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.arcbarData=drawArcbarDataPoints(c,l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"gauge":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.gaugeData=drawGaugeDataPoints(d,c,l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"candle":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawCandleDataPoints(c,x,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}if(x){drawLegend(x,l,n,s,l.chartData)}else{drawLegend(l.series,l,n,s,l.chartData)}drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break}}function uChartsEvent(){this.events={}}uChartsEvent.prototype.addEventListener=function(t,e){this.events[t]=this.events[t]||[];this.events[t].push(e)};uChartsEvent.prototype.delEventListener=function(t){this.events[t]=[]};uChartsEvent.prototype.trigger=function(){for(var t=arguments.length,e=Array(t),a=0;a0&&arguments[0]!==undefined?arguments[0]:{};this.opts=assign({},this.opts,t);this.opts.updateData=true;let c=t.scrollPosition||"current";switch(c){case"current":this.opts._scrollDistance_=this.scrollOption.currentOffset;break;case"left":this.opts._scrollDistance_=0;this.scrollOption={currentOffset:0,startTouchX:0,distance:0,lastMoveTime:0};break;case"right":let t=calYAxisData(this.opts.series,this.opts,this.config,this.context),e=t.yAxisWidth;this.config.yAxisWidth=e;let a=0;let i=getXAxisPoints(this.opts.categories,this.opts,this.config),r=i.xAxisPoints,o=i.startX,n=i.endX,l=i.eachSpacing;let s=l*(r.length-1);let h=n-o;a=h-s;this.scrollOption={currentOffset:a,startTouchX:a,distance:0,lastMoveTime:0};this.opts._scrollDistance_=a;break}drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)};uCharts.prototype.zoom=function(){var t=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.opts.xAxis.itemCount;if(this.opts.enableScroll!==true){console.log("[uCharts] 请启用滚动条后使用");return}let e=Math.round(Math.abs(this.scrollOption.currentOffset)/this.opts.chartData.eachSpacing)+Math.round(this.opts.xAxis.itemCount/2);this.opts.animation=false;this.opts.xAxis.itemCount=t.itemCount;let a=calYAxisData(this.opts.series,this.opts,this.config,this.context),i=a.yAxisWidth;this.config.yAxisWidth=i;let r=0;let o=getXAxisPoints(this.opts.categories,this.opts,this.config),h=o.xAxisPoints,c=o.startX,d=o.endX,n=o.eachSpacing;let x=n*e;let l=d-c;let s=l-n*(h.length-1);r=l/2-x;if(r>0){r=0}if(r=this.opts.categories.length?this.opts.categories.length:r;this.opts.animation=false;this.opts.xAxis.itemCount=r;let o=0;let n=getXAxisPoints(this.opts.categories,this.opts,this.config),x=n.xAxisPoints,f=n.startX,p=n.endX,l=n.eachSpacing;let u=l*this.scrollOption.moveCurrent1;let g=p-f;let y=g-l*(x.length-1);o=-u+Math.min(i[0].x,i[1].x)-this.opts.area[3]-l;if(o>0){o=0}if(o1&&arguments[1]!==undefined?arguments[1]:{};var a=null;if(t.changedTouches){a=t.changedTouches[0]}else{a=t.mp.changedTouches[0]}if(a){var i=getTouches(a,this.opts,t);var r=this.getLegendDataIndex(t);if(r>=0){if(this.opts.type=="candle"){this.opts.seriesMA[r].show=!this.opts.seriesMA[r].show}else{this.opts.series[r].show=!this.opts.series[r].show}this.opts.animation=e.animation?true:false;this.opts._scrollDistance_=this.scrollOption.currentOffset;drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)}}};uCharts.prototype.showToolTip=function(t){var e=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var c=null;if(t.changedTouches){c=t.changedTouches[0]}else{c=t.mp.changedTouches[0]}if(!c){console.log("[uCharts] 未获取到event坐标信息")}var a=getTouches(c,this.opts,t);var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});if(this.opts.type==="line"||this.opts.type==="area"||this.opts.type==="column"||this.opts.type==="scatter"||this.opts.type==="bubble"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1||o.length>0){var n=getSeriesDataItem(this.opts.series,o,r.group);if(n.length!==0){var l=getToolTipData(n,this.opts,o,r.group,this.opts.categories,e),s=l.textList,h=l.offset;h.y=a.y;i.tooltip={textList:e.textList!==undefined?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o,group:r.group}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="mount"){var o=e.index==undefined?this.getCurrentDataIndex(t).index:e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},i._series_[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,i):n.name+": "+n.data,color:n.color,legendShape:this.opts.extra.tooltip.legendShape=="auto"?n.legendShape:this.opts.extra.tooltip.legendShape}];var h={x:i.chartData.calPoints[o].x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="bar"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1||o.length>0){var n=getSeriesDataItem(this.opts.series,o,r.group);if(n.length!==0){var l=getToolTipData(n,this.opts,o,r.group,this.opts.categories,e),s=l.textList,h=l.offset;h.x=a.x;i.tooltip={textList:e.textList!==undefined?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="mix"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1){var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var x=getMixToolTipData(n,this.opts,o,this.opts.categories,e),s=x.textList,h=x.offset;h.y=a.y;i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="candle"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1){var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var l=getCandleToolTipData(this.opts.series[0].data,n,this.opts,o,this.opts.categories,this.opts.extra.candle,e),s=l.textList,h=l.offset;h.y=a.y;i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="pie"||this.opts.type==="ring"||this.opts.type==="rose"||this.opts.type==="funnel"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},i._series_[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,i):n.name+": "+n.data,color:n.color,legendShape:this.opts.extra.tooltip.legendShape=="auto"?n.legendShape:this.opts.extra.tooltip.legendShape}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="map"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},this.opts.series[o]);n.name=n.properties.name;var s=[{text:e.formatter?e.formatter(n,undefined,o,this.opts):n.name,color:n.color,legendShape:this.opts.extra.tooltip.legendShape=="auto"?n.legendShape:this.opts.extra.tooltip.legendShape}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}i.updateData=false;drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="word"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},this.opts.series[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,this.opts):n.name,color:n.color,legendShape:this.opts.extra.tooltip.legendShape=="auto"?n.legendShape:this.opts.extra.tooltip.legendShape}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}i.updateData=false;drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="radar"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var s=n.map(t=>{return{text:e.formatter?e.formatter(t,this.opts.categories[o],o,this.opts):t.name+": "+t.data,color:t.color,legendShape:this.opts.extra.tooltip.legendShape=="auto"?t.legendShape:this.opts.extra.tooltip.legendShape}});var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}};uCharts.prototype.translate=function(t){this.scrollOption={currentOffset:t,startTouchX:t,distance:0,lastMoveTime:0};let e=assign({},this.opts,{_scrollDistance_:t,animation:false});drawCharts.call(this,this.opts.type,e,this.config,this.context)};uCharts.prototype.scrollStart=function(t){var e=null;if(t.changedTouches){e=t.changedTouches[0]}else{e=t.mp.changedTouches[0]}var a=getTouches(e,this.opts,t);if(e&&this.opts.enableScroll===true){this.scrollOption.startTouchX=a.x}};uCharts.prototype.scroll=function(t){if(this.scrollOption.lastMoveTime===0){this.scrollOption.lastMoveTime=Date.now()}let e=this.opts.touchMoveLimit||60;let a=Date.now();let i=a-this.scrollOption.lastMoveTime;if(i=0){var o="touchend"!==n?e.targetTouches[0]:e.changedTouches[0];o&&st(t,o,e,i)}else st(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;var a=e.button;return null==e.which&&void 0!==a&&gw.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ht(t,e,i){pw?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function ct(t,e,i){pw?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}function dt(t){return 2===t.which||3===t.which}function ft(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function pt(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function gt(t,e,i){return{type:t,event:i,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:i.zrX,offsetY:i.zrY,gestureEvent:i.gestureEvent,pinchX:i.pinchX,pinchY:i.pinchY,pinchScale:i.pinchScale,wheelDelta:i.zrDelta,zrByTouch:i.zrByTouch,which:i.which,stop:mt}}function mt(t){mw(this.event)}function vt(){}function yt(t,e,i){if(t[t.rectHover?"rectContain":"contain"](e,i)){for(var n,o=t;o;){if(o.clipPath&&!o.clipPath.contain(e,i))return!1;o.silent&&(n=!0),o=o.parent}return!n||xw}return!1}function xt(){var t=new bw(6);return _t(t),t}function _t(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function wt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function bt(t,e,i){var n=e[0]*i[0]+e[2]*i[1],o=e[1]*i[0]+e[3]*i[1],a=e[0]*i[2]+e[2]*i[3],r=e[1]*i[2]+e[3]*i[3],s=e[0]*i[4]+e[2]*i[5]+e[4],l=e[1]*i[4]+e[3]*i[5]+e[5];return t[0]=n,t[1]=o,t[2]=a,t[3]=r,t[4]=s,t[5]=l,t}function St(t,e,i){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+i[0],t[5]=e[5]+i[1],t}function Mt(t,e,i){var n=e[0],o=e[2],a=e[4],r=e[1],s=e[3],l=e[5],u=Math.sin(i),h=Math.cos(i);return t[0]=n*h+r*u,t[1]=-n*u+r*h,t[2]=o*h+s*u,t[3]=-o*u+h*s,t[4]=h*a+u*l,t[5]=h*l-u*a,t}function It(t,e,i){var n=i[0],o=i[1];return t[0]=e[0]*n,t[1]=e[1]*o,t[2]=e[2]*n,t[3]=e[3]*o,t[4]=e[4]*n,t[5]=e[5]*o,t}function Tt(t,e){var i=e[0],n=e[2],o=e[4],a=e[1],r=e[3],s=e[5],l=i*r-a*n;return l?(l=1/l,t[0]=r*l,t[1]=-a*l,t[2]=-n*l,t[3]=i*l,t[4]=(n*s-r*o)*l,t[5]=(a*o-i*s)*l,t):null}function At(t){var e=xt();return wt(e,t),e}function Dt(t){return t>Iw||t<-Iw}function Ct(t){this._target=t.target,this._life=t.life||1e3,this._delay=t.delay||0,this._initialized=!1,this.loop=null!=t.loop&&t.loop,this.gap=t.gap||0,this.easing=t.easing||"Linear",this.onframe=t.onframe,this.ondestroy=t.ondestroy,this.onrestart=t.onrestart,this._pausedTime=0,this._paused=!1}function Lt(t){return(t=Math.round(t))<0?0:t>255?255:t}function kt(t){return(t=Math.round(t))<0?0:t>360?360:t}function Pt(t){return t<0?0:t>1?1:t}function Nt(t){return Lt(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function Ot(t){return Pt(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function Et(t,e,i){return i<0?i+=1:i>1&&(i-=1),6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function Rt(t,e,i){return t+(e-t)*i}function zt(t,e,i,n,o){return t[0]=e,t[1]=i,t[2]=n,t[3]=o,t}function Bt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function Vt(t,e){Vw&&Bt(Vw,e),Vw=Bw.put(t,Vw||e.slice())}function Gt(t,e){if(t){e=e||[];var i=Bw.get(t);if(i)return Bt(e,i);var n=(t+="").replace(/ /g,"").toLowerCase();if(n in zw)return Bt(e,zw[n]),Vt(t,e),e;if("#"!==n.charAt(0)){var o=n.indexOf("("),a=n.indexOf(")");if(-1!==o&&a+1===n.length){var r=n.substr(0,o),s=n.substr(o+1,a-(o+1)).split(","),l=1;switch(r){case"rgba":if(4!==s.length)return void zt(e,0,0,0,1);l=Ot(s.pop());case"rgb":return 3!==s.length?void zt(e,0,0,0,1):(zt(e,Nt(s[0]),Nt(s[1]),Nt(s[2]),l),Vt(t,e),e);case"hsla":return 4!==s.length?void zt(e,0,0,0,1):(s[3]=Ot(s[3]),Ft(s,e),Vt(t,e),e);case"hsl":return 3!==s.length?void zt(e,0,0,0,1):(Ft(s,e),Vt(t,e),e);default:return}}zt(e,0,0,0,1)}else{if(4===n.length)return(u=parseInt(n.substr(1),16))>=0&&u<=4095?(zt(e,(3840&u)>>4|(3840&u)>>8,240&u|(240&u)>>4,15&u|(15&u)<<4,1),Vt(t,e),e):void zt(e,0,0,0,1);if(7===n.length){var u=parseInt(n.substr(1),16);return u>=0&&u<=16777215?(zt(e,(16711680&u)>>16,(65280&u)>>8,255&u,1),Vt(t,e),e):void zt(e,0,0,0,1)}}}}function Ft(t,e){var i=(parseFloat(t[0])%360+360)%360/360,n=Ot(t[1]),o=Ot(t[2]),a=o<=.5?o*(n+1):o+n-o*n,r=2*o-a;return e=e||[],zt(e,Lt(255*Et(r,a,i+1/3)),Lt(255*Et(r,a,i)),Lt(255*Et(r,a,i-1/3)),1),4===t.length&&(e[3]=t[3]),e}function Wt(t){if(t){var e,i,n=t[0]/255,o=t[1]/255,a=t[2]/255,r=Math.min(n,o,a),s=Math.max(n,o,a),l=s-r,u=(s+r)/2;if(0===l)e=0,i=0;else{i=u<.5?l/(s+r):l/(2-s-r);var h=((s-n)/6+l/2)/l,c=((s-o)/6+l/2)/l,d=((s-a)/6+l/2)/l;n===s?e=d-c:o===s?e=1/3+h-d:a===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,u];return null!=t[3]&&f.push(t[3]),f}}function Ht(t,e){var i=Gt(t);if(i){for(var n=0;n<3;n++)i[n]=e<0?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0,i[n]>255?i[n]=255:t[n]<0&&(i[n]=0);return qt(i,4===i.length?"rgba":"rgb")}}function Zt(t){var e=Gt(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)}function Ut(t,e,i){if(e&&e.length&&t>=0&&t<=1){i=i||[];var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=e[o],s=e[a],l=n-o;return i[0]=Lt(Rt(r[0],s[0],l)),i[1]=Lt(Rt(r[1],s[1],l)),i[2]=Lt(Rt(r[2],s[2],l)),i[3]=Pt(Rt(r[3],s[3],l)),i}}function Xt(t,e,i){if(e&&e.length&&t>=0&&t<=1){var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=Gt(e[o]),s=Gt(e[a]),l=n-o,u=qt([Lt(Rt(r[0],s[0],l)),Lt(Rt(r[1],s[1],l)),Lt(Rt(r[2],s[2],l)),Pt(Rt(r[3],s[3],l))],"rgba");return i?{color:u,leftIndex:o,rightIndex:a,value:n}:u}}function jt(t,e,i,n){if(t=Gt(t))return t=Wt(t),null!=e&&(t[0]=kt(e)),null!=i&&(t[1]=Ot(i)),null!=n&&(t[2]=Ot(n)),qt(Ft(t),"rgba")}function Yt(t,e){if((t=Gt(t))&&null!=e)return t[3]=Pt(e),qt(t,"rgba")}function qt(t,e){if(t&&t.length){var i=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(i+=","+t[3]),e+"("+i+")"}}function Kt(t,e){return t[e]}function $t(t,e,i){t[e]=i}function Jt(t,e,i){return(e-t)*i+t}function Qt(t,e,i){return i>.5?e:t}function te(t,e,i,n,o){var a=t.length;if(1===o)for(s=0;so)t.length=o;else for(r=n;r=0&&!(m[i]<=e);i--);i=Math.min(i,u-2)}else{for(i=L;ie);i++);i=Math.min(i-1,u-2)}L=i,k=e;var n=m[i+1]-m[i];if(0!==n)if(I=(e-m[i])/n,l)if(A=v[i],T=v[0===i?i:i-1],D=v[i>u-2?u-1:i+1],C=v[i>u-3?u-1:i+2],d)ne(T,A,D,C,I,I*I,I*I*I,r(t,o),g);else{if(f)a=ne(T,A,D,C,I,I*I,I*I*I,P,1),a=re(P);else{if(p)return Qt(A,D,I);a=oe(T,A,D,C,I,I*I,I*I*I)}s(t,o,a)}else if(d)te(v[i],v[i+1],I,r(t,o),g);else{var a;if(f)te(v[i],v[i+1],I,P,1),a=re(P);else{if(p)return Qt(v[i],v[i+1],I);a=Jt(v[i],v[i+1],I)}s(t,o,a)}},ondestroy:i});return e&&"spline"!==e&&(N.easing=e),N}}}function ue(t,e,i,n,o,a,r,s){_(n)?(a=o,o=n,n=0):x(o)?(a=o,o="linear",n=0):x(n)?(a=n,n=0):x(i)?(a=i,i=500):i||(i=500),t.stopAnimation(),he(t,"",t,e,i,n,s);var l=t.animators.slice(),u=l.length;u||a&&a();for(var h=0;h0&&t.animate(e,!1).when(null==o?500:o,s).delay(a||0)}function ce(t,e,i,n){if(e){var o={};o[e]={},o[e][i]=n,t.attr(o)}else t.attr(i,n)}function de(t,e,i,n){i<0&&(t+=i,i=-i),n<0&&(e+=n,n=-n),this.x=t,this.y=e,this.width=i,this.height=n}function fe(t){for(var e=0;t>=eb;)e|=1&t,t>>=1;return t+e}function pe(t,e,i,n){var o=e+1;if(o===i)return 1;if(n(t[o++],t[e])<0){for(;o=0;)o++;return o-e}function ge(t,e,i){for(i--;e>>1])<0?l=a:s=a+1;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=r}}function ve(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])>0){for(s=n-o;l0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}else{for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}for(r++;r>>1);a(t,e[i+h])>0?r=h+1:l=h}return l}function ye(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])<0){for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}else{for(s=n-o;l=0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}for(r++;r>>1);a(t,e[i+h])<0?l=h:r=h+1}return l}function xe(t,e){function i(i){var s=a[i],u=r[i],h=a[i+1],c=r[i+1];r[i]=u+c,i===l-3&&(a[i+1]=a[i+2],r[i+1]=r[i+2]),l--;var d=ye(t[h],t,s,u,0,e);s+=d,0!==(u-=d)&&0!==(c=ve(t[s+u-1],t,h,c,c-1,e))&&(u<=c?n(s,u,h,c):o(s,u,h,c))}function n(i,n,o,a){var r=0;for(r=0;r=ib||f>=ib);if(p)break;g<0&&(g=0),g+=2}if((s=g)<1&&(s=1),1===n){for(r=0;r=0;r--)t[f+r]=t[d+r];if(0===n){v=!0;break}}if(t[c--]=u[h--],1==--a){v=!0;break}if(0!=(m=a-ve(t[l],u,0,a,a-1,e))){for(a-=m,f=(c-=m)+1,d=(h-=m)+1,r=0;r=ib||m>=ib);if(v)break;p<0&&(p=0),p+=2}if((s=p)<1&&(s=1),1===a){for(f=(c-=n)+1,d=(l-=n)+1,r=n-1;r>=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else{if(0===a)throw new Error;for(d=c-(a-1),r=0;r=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else for(d=c-(a-1),r=0;r1;){var t=l-2;if(t>=1&&r[t-1]<=r[t]+r[t+1]||t>=2&&r[t-2]<=r[t]+r[t-1])r[t-1]r[t+1])break;i(t)}},this.forceMergeRuns=function(){for(;l>1;){var t=l-2;t>0&&r[t-1]s&&(l=s),me(t,i,i+l,i+a,e),a=l}r.pushRun(i,a),r.mergeRuns(),o-=a,i+=a}while(0!==o);r.forceMergeRuns()}}function we(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}function be(t,e,i){var n=null==e.x?0:e.x,o=null==e.x2?1:e.x2,a=null==e.y?0:e.y,r=null==e.y2?0:e.y2;return e.global||(n=n*i.width+i.x,o=o*i.width+i.x,a=a*i.height+i.y,r=r*i.height+i.y),n=isNaN(n)?0:n,o=isNaN(o)?1:o,a=isNaN(a)?0:a,r=isNaN(r)?0:r,t.createLinearGradient(n,a,o,r)}function Se(t,e,i){var n=i.width,o=i.height,a=Math.min(n,o),r=null==e.x?.5:e.x,s=null==e.y?.5:e.y,l=null==e.r?.5:e.r;return e.global||(r=r*n+i.x,s=s*o+i.y,l*=a),t.createRadialGradient(r,s,0,r,s,l)}function Me(){return!1}function Ie(t,e,i){var n=iw(),o=e.getWidth(),a=e.getHeight(),r=n.style;return r&&(r.position="absolute",r.left=0,r.top=0,r.width=o+"px",r.height=a+"px",n.setAttribute("data-zr-dom-id",t)),n.width=o*i,n.height=a*i,n}function Te(t){if("string"==typeof t){var e=mb.get(t);return e&&e.image}return t}function Ae(t,e,i,n,o){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!i)return e;var a=mb.get(t),r={hostEl:i,cb:n,cbPayload:o};return a?!Ce(e=a.image)&&a.pending.push(r):((e=new Image).onload=e.onerror=De,mb.put(t,e.__cachedImgObj={image:e,pending:[r]}),e.src=e.__zrImageSrc=t),e}return t}return e}function De(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;exb&&(yb=0,vb={}),yb++,vb[i]=o,o}function ke(t,e,i,n,o,a,r,s){return r?Ne(t,e,i,n,o,a,r,s):Pe(t,e,i,n,o,a,s)}function Pe(t,e,i,n,o,a,r){var s=He(t,e,o,a,r),l=Le(t,e);o&&(l+=o[1]+o[3]);var u=s.outerHeight,h=new de(Oe(0,l,i),Ee(0,u,n),l,u);return h.lineHeight=s.lineHeight,h}function Ne(t,e,i,n,o,a,r,s){var l=Ze(t,{rich:r,truncate:s,font:e,textAlign:i,textPadding:o,textLineHeight:a}),u=l.outerWidth,h=l.outerHeight;return new de(Oe(0,u,i),Ee(0,h,n),u,h)}function Oe(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function Ee(t,e,i){return"middle"===i?t-=e/2:"bottom"===i&&(t-=e),t}function Re(t,e,i){var n=e.x,o=e.y,a=e.height,r=e.width,s=a/2,l="left",u="top";switch(t){case"left":n-=i,o+=s,l="right",u="middle";break;case"right":n+=i+r,o+=s,u="middle";break;case"top":n+=r/2,o-=i,l="center",u="bottom";break;case"bottom":n+=r/2,o+=a+i,l="center";break;case"inside":n+=r/2,o+=s,l="center",u="middle";break;case"insideLeft":n+=i,o+=s,u="middle";break;case"insideRight":n+=r-i,o+=s,l="right",u="middle";break;case"insideTop":n+=r/2,o+=i,l="center";break;case"insideBottom":n+=r/2,o+=a-i,l="center",u="bottom";break;case"insideTopLeft":n+=i,o+=i;break;case"insideTopRight":n+=r-i,o+=i,l="right";break;case"insideBottomLeft":n+=i,o+=a-i,u="bottom";break;case"insideBottomRight":n+=r-i,o+=a-i,l="right",u="bottom"}return{x:n,y:o,textAlign:l,textVerticalAlign:u}}function ze(t,e,i,n,o){if(!e)return"";var a=(t+"").split("\n");o=Be(e,i,n,o);for(var r=0,s=a.length;r=r;l++)s-=r;var u=Le(i,e);return u>s&&(i="",u=0),s=t-u,n.ellipsis=i,n.ellipsisWidth=u,n.contentWidth=s,n.containerWidth=t,n}function Ve(t,e){var i=e.containerWidth,n=e.font,o=e.contentWidth;if(!i)return"";var a=Le(t,n);if(a<=i)return t;for(var r=0;;r++){if(a<=o||r>=e.maxIterations){t+=e.ellipsis;break}var s=0===r?Ge(t,o,e.ascCharWidth,e.cnCharWidth):a>0?Math.floor(t.length*o/a):0;a=Le(t=t.substr(0,s),n)}return""===t&&(t=e.placeholder),t}function Ge(t,e,i,n){for(var o=0,a=0,r=t.length;au)t="",r=[];else if(null!=h)for(var c=Be(h-(i?i[1]+i[3]:0),e,o.ellipsis,{minChar:o.minChar,placeholder:o.placeholder}),d=0,f=r.length;do&&Ue(i,t.substring(o,a)),Ue(i,n[2],n[1]),o=_b.lastIndex}of)return{lines:[],width:0,height:0};k.textWidth=Le(k.text,_);var b=y.textWidth,S=null==b||"auto"===b;if("string"==typeof b&&"%"===b.charAt(b.length-1))k.percentWidth=b,u.push(k),b=0;else{if(S){b=k.textWidth;var M=y.textBackgroundColor,I=M&&M.image;I&&Ce(I=Te(I))&&(b=Math.max(b,I.width*w/I.height))}var T=x?x[1]+x[3]:0;b+=T;var C=null!=d?d-m:null;null!=C&&Cl&&(i*=l/(c=i+n),n*=l/c),o+a>l&&(o*=l/(c=o+a),a*=l/c),n+o>u&&(n*=u/(c=n+o),o*=u/c),i+a>u&&(i*=u/(c=i+a),a*=u/c),t.moveTo(r+i,s),t.lineTo(r+l-n,s),0!==n&&t.arc(r+l-n,s+n,n,-Math.PI/2,0),t.lineTo(r+l,s+u-o),0!==o&&t.arc(r+l-o,s+u-o,o,0,Math.PI/2),t.lineTo(r+a,s+u),0!==a&&t.arc(r+a,s+u-a,a,Math.PI/2,Math.PI),t.lineTo(r,s+i),0!==i&&t.arc(r+i,s+i,i,Math.PI,1.5*Math.PI)}function Ye(t){return qe(t),d(t.rich,qe),t}function qe(t){if(t){t.font=Xe(t);var e=t.textAlign;"middle"===e&&(e="center"),t.textAlign=null==e||Mb[e]?e:"left";var i=t.textVerticalAlign||t.textBaseline;"center"===i&&(i="middle"),t.textVerticalAlign=null==i||Ib[i]?i:"top",t.textPadding&&(t.textPadding=L(t.textPadding))}}function Ke(t,e,i,n,o,a){n.rich?Je(t,e,i,n,o,a):$e(t,e,i,n,o,a)}function $e(t,e,i,n,o,a){var r,s=ii(n),l=!1,u=e.__attrCachedBy===rb.PLAIN_TEXT;a!==sb?(a&&(r=a.style,l=!s&&u&&r),e.__attrCachedBy=s?rb.NONE:rb.PLAIN_TEXT):u&&(e.__attrCachedBy=rb.NONE);var h=n.font||Sb;l&&h===(r.font||Sb)||(e.font=h);var c=t.__computedFont;t.__styleFont!==h&&(t.__styleFont=h,c=t.__computedFont=e.font);var d=n.textPadding,f=n.textLineHeight,p=t.__textCotentBlock;p&&!t.__dirtyText||(p=t.__textCotentBlock=He(i,c,d,f,n.truncate));var g=p.outerHeight,m=p.lines,v=p.lineHeight,y=ai(g,n,o),x=y.baseX,_=y.baseY,w=y.textAlign||"left",b=y.textVerticalAlign;ti(e,n,o,x,_);var S=Ee(_,g,b),M=x,I=S;if(s||d){var T=Le(i,c);d&&(T+=d[1]+d[3]);var A=Oe(x,T,w);s&&ni(t,e,n,A,S,T,g),d&&(M=hi(x,w,d),I+=d[0])}e.textAlign=w,e.textBaseline="middle",e.globalAlpha=n.opacity||1;for(B=0;B=0&&"right"===(_=b[C]).textAlign;)ei(t,e,_,n,M,v,D,"right"),I-=_.width,D-=_.width,C--;for(A+=(a-(A-m)-(y-D)-I)/2;T<=C;)ei(t,e,_=b[T],n,M,v,A+_.width/2,"center"),A+=_.width,T++;v+=M}}function ti(t,e,i,n,o){if(i&&e.textRotation){var a=e.textOrigin;"center"===a?(n=i.width/2+i.x,o=i.height/2+i.y):a&&(n=a[0]+i.x,o=a[1]+i.y),t.translate(n,o),t.rotate(-e.textRotation),t.translate(-n,-o)}}function ei(t,e,i,n,o,a,r,s){var l=n.rich[i.styleName]||{};l.text=i.text;var u=i.textVerticalAlign,h=a+o/2;"top"===u?h=a+i.height/2:"bottom"===u&&(h=a+o-i.height/2),!i.isLineHolder&&ii(l)&&ni(t,e,l,"right"===s?r-i.width:"center"===s?r-i.width/2:r,h-i.height/2,i.width,i.height);var c=i.textPadding;c&&(r=hi(r,s,c),h-=i.height/2-c[2]-i.textHeight/2),ri(e,"shadowBlur",D(l.textShadowBlur,n.textShadowBlur,0)),ri(e,"shadowColor",l.textShadowColor||n.textShadowColor||"transparent"),ri(e,"shadowOffsetX",D(l.textShadowOffsetX,n.textShadowOffsetX,0)),ri(e,"shadowOffsetY",D(l.textShadowOffsetY,n.textShadowOffsetY,0)),ri(e,"textAlign",s),ri(e,"textBaseline","middle"),ri(e,"font",i.font||Sb);var d=si(l.textStroke||n.textStroke,p),f=li(l.textFill||n.textFill),p=A(l.textStrokeWidth,n.textStrokeWidth);d&&(ri(e,"lineWidth",p),ri(e,"strokeStyle",d),e.strokeText(i.text,r,h)),f&&(ri(e,"fillStyle",f),e.fillText(i.text,r,h))}function ii(t){return!!(t.textBackgroundColor||t.textBorderWidth&&t.textBorderColor)}function ni(t,e,i,n,o,a,r){var s=i.textBackgroundColor,l=i.textBorderWidth,u=i.textBorderColor,h=_(s);if(ri(e,"shadowBlur",i.textBoxShadowBlur||0),ri(e,"shadowColor",i.textBoxShadowColor||"transparent"),ri(e,"shadowOffsetX",i.textBoxShadowOffsetX||0),ri(e,"shadowOffsetY",i.textBoxShadowOffsetY||0),h||l&&u){e.beginPath();var c=i.textBorderRadius;c?je(e,{x:n,y:o,width:a,height:r,r:c}):e.rect(n,o,a,r),e.closePath()}if(h)if(ri(e,"fillStyle",s),null!=i.fillOpacity){f=e.globalAlpha;e.globalAlpha=i.fillOpacity*i.opacity,e.fill(),e.globalAlpha=f}else e.fill();else if(w(s)){var d=s.image;(d=Ae(d,null,t,oi,s))&&Ce(d)&&e.drawImage(d,n,o,a,r)}if(l&&u)if(ri(e,"lineWidth",l),ri(e,"strokeStyle",u),null!=i.strokeOpacity){var f=e.globalAlpha;e.globalAlpha=i.strokeOpacity*i.opacity,e.stroke(),e.globalAlpha=f}else e.stroke()}function oi(t,e){e.image=t}function ai(t,e,i){var n=e.x||0,o=e.y||0,a=e.textAlign,r=e.textVerticalAlign;if(i){var s=e.textPosition;if(s instanceof Array)n=i.x+ui(s[0],i.width),o=i.y+ui(s[1],i.height);else{var l=Re(s,i,e.textDistance);n=l.x,o=l.y,a=a||l.textAlign,r=r||l.textVerticalAlign}var u=e.textOffset;u&&(n+=u[0],o+=u[1])}return{baseX:n,baseY:o,textAlign:a,textVerticalAlign:r}}function ri(t,e,i){return t[e]=ab(t,e,i),t[e]}function si(t,e){return null==t||e<=0||"transparent"===t||"none"===t?null:t.image||t.colorStops?"#000":t}function li(t){return null==t||"none"===t?null:t.image||t.colorStops?"#000":t}function ui(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t}function hi(t,e,i){return"right"===e?t-i[1]:"center"===e?t+i[3]/2-i[1]/2:t+i[3]}function ci(t,e){return null!=t&&(t||e.textBackgroundColor||e.textBorderWidth&&e.textBorderColor||e.textPadding)}function di(t){t=t||{},Kw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&"style"!==e&&(this[e]=t[e]);this.style=new ub(t.style,this),this._rect=null,this.__clipPaths=[]}function fi(t){di.call(this,t)}function pi(t){return parseInt(t,10)}function gi(t){return!!t&&(!!t.__builtin__||"function"==typeof t.resize&&"function"==typeof t.refresh)}function mi(t,e,i){return Cb.copy(t.getBoundingRect()),t.transform&&Cb.applyTransform(t.transform),Lb.width=e,Lb.height=i,!Cb.intersect(Lb)}function vi(t,e){if(t===e)return!1;if(!t||!e||t.length!==e.length)return!0;for(var i=0;i=i.length&&i.push({option:t})}}),i}function Ni(t){var e=R();Zb(t,function(t,i){var n=t.exist;n&&e.set(n.id,t)}),Zb(t,function(t,i){var n=t.option;k(!n||null==n.id||!e.get(n.id)||e.get(n.id)===t,"id duplicates: "+(n&&n.id)),n&&null!=n.id&&e.set(n.id,t),!t.keyInfo&&(t.keyInfo={})}),Zb(t,function(t,i){var n=t.exist,o=t.option,a=t.keyInfo;if(Ub(o)){if(a.name=null!=o.name?o.name+"":n?n.name:jb+i,n)a.id=n.id;else if(null!=o.id)a.id=o.id+"";else{var r=0;do{a.id="\0"+a.name+"\0"+r++}while(e.get(a.id))}e.set(a.id,t)}})}function Oi(t){var e=t.name;return!(!e||!e.indexOf(jb))}function Ei(t){return Ub(t)&&t.id&&0===(t.id+"").indexOf("\0_ec_\0")}function Ri(t,e){function i(t,e,i){for(var n=0,o=t.length;n-rS&&trS||t<-rS}function tn(t,e,i,n,o){var a=1-o;return a*a*(a*t+3*o*e)+o*o*(o*n+3*a*i)}function en(t,e,i,n,o){var a=1-o;return 3*(((e-t)*a+2*(i-e)*o)*a+(n-i)*o*o)}function nn(t,e,i,n,o,a){var r=n+3*(e-i)-t,s=3*(i-2*e+t),l=3*(e-t),u=t-o,h=s*s-3*r*l,c=s*l-9*r*u,d=l*l-3*s*u,f=0;if(Ji(h)&&Ji(c))Ji(s)?a[0]=0:(M=-l/s)>=0&&M<=1&&(a[f++]=M);else{var p=c*c-4*h*d;if(Ji(p)){var g=c/h,m=-g/2;(M=-s/r+g)>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m)}else if(p>0){var v=aS(p),y=h*s+1.5*r*(-c+v),x=h*s+1.5*r*(-c-v);(M=(-s-((y=y<0?-oS(-y,uS):oS(y,uS))+(x=x<0?-oS(-x,uS):oS(x,uS))))/(3*r))>=0&&M<=1&&(a[f++]=M)}else{var _=(2*h*s-3*r*c)/(2*aS(h*h*h)),w=Math.acos(_)/3,b=aS(h),S=Math.cos(w),M=(-s-2*b*S)/(3*r),m=(-s+b*(S+lS*Math.sin(w)))/(3*r),I=(-s+b*(S-lS*Math.sin(w)))/(3*r);M>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m),I>=0&&I<=1&&(a[f++]=I)}}return f}function on(t,e,i,n,o){var a=6*i-12*e+6*t,r=9*e+3*n-3*t-9*i,s=3*e-3*t,l=0;if(Ji(r))Qi(a)&&(c=-s/a)>=0&&c<=1&&(o[l++]=c);else{var u=a*a-4*r*s;if(Ji(u))o[0]=-a/(2*r);else if(u>0){var h=aS(u),c=(-a+h)/(2*r),d=(-a-h)/(2*r);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function an(t,e,i,n,o,a){var r=(e-t)*o+t,s=(i-e)*o+e,l=(n-i)*o+i,u=(s-r)*o+r,h=(l-s)*o+s,c=(h-u)*o+u;a[0]=t,a[1]=r,a[2]=u,a[3]=c,a[4]=c,a[5]=h,a[6]=l,a[7]=n}function rn(t,e,i,n,o,a,r,s,l,u,h){var c,d,f,p,g,m=.005,v=1/0;hS[0]=l,hS[1]=u;for(var y=0;y<1;y+=.05)cS[0]=tn(t,i,o,r,y),cS[1]=tn(e,n,a,s,y),(p=hw(hS,cS))=0&&p=0&&c<=1&&(o[l++]=c);else{var u=r*r-4*a*s;if(Ji(u))(c=-r/(2*a))>=0&&c<=1&&(o[l++]=c);else if(u>0){var h=aS(u),c=(-r+h)/(2*a),d=(-r-h)/(2*a);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function hn(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function cn(t,e,i,n,o){var a=(e-t)*n+t,r=(i-e)*n+e,s=(r-a)*n+a;o[0]=t,o[1]=a,o[2]=s,o[3]=s,o[4]=r,o[5]=i}function dn(t,e,i,n,o,a,r,s,l){var u,h=.005,c=1/0;hS[0]=r,hS[1]=s;for(var d=0;d<1;d+=.05)cS[0]=sn(t,i,o,d),cS[1]=sn(e,n,a,d),(m=hw(hS,cS))=0&&m1e-4)return s[0]=t-i,s[1]=e-n,l[0]=t+i,void(l[1]=e+n);if(yS[0]=mS(o)*i+t,yS[1]=gS(o)*n+e,xS[0]=mS(a)*i+t,xS[1]=gS(a)*n+e,u(s,yS,xS),h(l,yS,xS),(o%=vS)<0&&(o+=vS),(a%=vS)<0&&(a+=vS),o>a&&!r?a+=vS:oo&&(_S[0]=mS(f)*i+t,_S[1]=gS(f)*n+e,u(s,_S,s),h(l,_S,l))}function yn(t,e,i,n,o,a,r){if(0===o)return!1;var s=o,l=0,u=t;if(r>e+s&&r>n+s||rt+s&&a>i+s||ae+c&&h>n+c&&h>a+c&&h>s+c||ht+c&&u>i+c&&u>o+c&&u>r+c||ue+u&&l>n+u&&l>a+u||lt+u&&s>i+u&&s>o+u||si||h+uo&&(o+=zS);var d=Math.atan2(l,s);return d<0&&(d+=zS),d>=n&&d<=o||d+zS>=n&&d+zS<=o}function Sn(t,e,i,n,o,a){if(a>e&&a>n||ao?r:0}function Mn(t,e){return Math.abs(t-e)e&&u>n&&u>a&&u>s||u1&&In(),c=tn(e,n,a,s,WS[0]),p>1&&(d=tn(e,n,a,s,WS[1]))),2===p?me&&s>n&&s>a||s=0&&u<=1){for(var h=0,c=sn(e,n,a,u),d=0;di||s<-i)return 0;u=Math.sqrt(i*i-s*s);FS[0]=-u,FS[1]=u;var l=Math.abs(n-o);if(l<1e-4)return 0;if(l%VS<1e-4){n=0,o=VS;p=a?1:-1;return r>=FS[0]+t&&r<=FS[1]+t?p:0}if(a){var u=n;n=wn(o),o=wn(u)}else n=wn(n),o=wn(o);n>o&&(o+=VS);for(var h=0,c=0;c<2;c++){var d=FS[c];if(d+t>r){var f=Math.atan2(s,d),p=a?1:-1;f<0&&(f=VS+f),(f>=n&&f<=o||f+VS>=n&&f+VS<=o)&&(f>Math.PI/2&&f<1.5*Math.PI&&(p=-p),h+=p)}}return h}function Cn(t,e,i,n,o){for(var a=0,r=0,s=0,l=0,u=0,h=0;h1&&(i||(a+=Sn(r,s,l,u,n,o))),1===h&&(l=r=t[h],u=s=t[h+1]),c){case BS.M:r=l=t[h++],s=u=t[h++];break;case BS.L:if(i){if(yn(r,s,t[h],t[h+1],e,n,o))return!0}else a+=Sn(r,s,t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.C:if(i){if(xn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=Tn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.Q:if(i){if(_n(r,s,t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=An(r,s,t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.A:var d=t[h++],f=t[h++],p=t[h++],g=t[h++],m=t[h++],v=t[h++];h+=1;var y=1-t[h++],x=Math.cos(m)*p+d,_=Math.sin(m)*g+f;h>1?a+=Sn(r,s,x,_,n,o):(l=x,u=_);var w=(n-d)*g/p+d;if(i){if(bn(d,f,g,m,m+v,y,e,w,o))return!0}else a+=Dn(d,f,g,m,m+v,y,w,o);r=Math.cos(m+v)*p+d,s=Math.sin(m+v)*g+f;break;case BS.R:l=r=t[h++],u=s=t[h++];var x=l+t[h++],_=u+t[h++];if(i){if(yn(l,u,x,u,e,n,o)||yn(x,u,x,_,e,n,o)||yn(x,_,l,_,e,n,o)||yn(l,_,l,u,e,n,o))return!0}else a+=Sn(x,u,x,_,n,o),a+=Sn(l,_,l,u,n,o);break;case BS.Z:if(i){if(yn(r,s,l,u,e,n,o))return!0}else a+=Sn(r,s,l,u,n,o);r=l,s=u}}return i||Mn(s,u)||(a+=Sn(r,s,l,u,n,o)||0),0!==a}function Ln(t,e,i){return Cn(t,0,!1,e,i)}function kn(t,e,i,n){return Cn(t,e,!0,i,n)}function Pn(t){di.call(this,t),this.path=null}function Nn(t,e,i,n,o,a,r,s,l,u,h){var c=l*(tM/180),d=QS(c)*(t-i)/2+JS(c)*(e-n)/2,f=-1*JS(c)*(t-i)/2+QS(c)*(e-n)/2,p=d*d/(r*r)+f*f/(s*s);p>1&&(r*=$S(p),s*=$S(p));var g=(o===a?-1:1)*$S((r*r*(s*s)-r*r*(f*f)-s*s*(d*d))/(r*r*(f*f)+s*s*(d*d)))||0,m=g*r*f/s,v=g*-s*d/r,y=(t+i)/2+QS(c)*m-JS(c)*v,x=(e+n)/2+JS(c)*m+QS(c)*v,_=nM([1,0],[(d-m)/r,(f-v)/s]),w=[(d-m)/r,(f-v)/s],b=[(-1*d-m)/r,(-1*f-v)/s],S=nM(w,b);iM(w,b)<=-1&&(S=tM),iM(w,b)>=1&&(S=0),0===a&&S>0&&(S-=2*tM),1===a&&S<0&&(S+=2*tM),h.addData(u,y,x,r,s,_,S,c,a)}function On(t){if(!t)return new ES;for(var e,i=0,n=0,o=i,a=n,r=new ES,s=ES.CMD,l=t.match(oM),u=0;u=2){if(o&&"spline"!==o){var a=fM(n,o,i,e.smoothConstraint);t.moveTo(n[0][0],n[0][1]);for(var r=n.length,s=0;s<(i?r:r-1);s++){var l=a[2*s],u=a[2*s+1],h=n[(s+1)%r];t.bezierCurveTo(l[0],l[1],u[0],u[1],h[0],h[1])}}else{"spline"===o&&(n=dM(n,i)),t.moveTo(n[0][0],n[0][1]);for(var s=1,c=n.length;s=0)?(i={textFill:null,textStroke:t.textStroke,textStrokeWidth:t.textStrokeWidth},t.textFill="#fff",null==t.textStroke&&(t.textStroke=a,null==t.textStrokeWidth&&(t.textStrokeWidth=2))):null!=a&&(i={textFill:null},t.textFill=a),i&&(t.insideRollback=i)}}function bo(t){var e=t.insideRollback;e&&(t.textFill=e.textFill,t.textStroke=e.textStroke,t.textStrokeWidth=e.textStrokeWidth,t.insideRollback=null)}function So(t,e){var i=e||e.getModel("textStyle");return P([t.fontStyle||i&&i.getShallow("fontStyle")||"",t.fontWeight||i&&i.getShallow("fontWeight")||"",(t.fontSize||i&&i.getShallow("fontSize")||12)+"px",t.fontFamily||i&&i.getShallow("fontFamily")||"sans-serif"].join(" "))}function Mo(t,e,i,n,o,a){if("function"==typeof o&&(a=o,o=null),n&&n.isAnimationEnabled()){var r=t?"Update":"",s=n.getShallow("animationDuration"+r),l=n.getShallow("animationEasing"+r),u=n.getShallow("animationDelay"+r);"function"==typeof u&&(u=u(o,n.getAnimationDelayParams?n.getAnimationDelayParams(e,o):null)),"function"==typeof s&&(s=s(o)),s>0?e.animateTo(i,s,u||0,l,a,!!a):(e.stopAnimation(),e.attr(i),a&&a())}else e.stopAnimation(),e.attr(i),a&&a()}function Io(t,e,i,n,o){Mo(!0,t,e,i,n,o)}function To(t,e,i,n,o){Mo(!1,t,e,i,n,o)}function Ao(t,e){for(var i=_t([]);t&&t!==e;)bt(i,t.getLocalTransform(),i),t=t.parent;return i}function Do(t,e,i){return e&&!c(e)&&(e=Tw.getLocalTransform(e)),i&&(e=Tt([],e)),Q([],t,e)}function Co(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),o=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-o:"bottom"===t?o:0];return a=Do(a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?"bottom":"top"}function Lo(t,e,i,n){function o(t){var e={position:F(t.position),rotation:t.rotation};return t.shape&&(e.shape=a({},t.shape)),e}if(t&&e){var r=function(t){var e={};return t.traverse(function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}(t);e.traverse(function(t){if(!t.isGroup&&t.anid){var e=r[t.anid];if(e){var n=o(t);t.attr(o(e)),Io(t,n,i,t.dataIndex)}}})}}function ko(t,e){return f(t,function(t){var i=t[0];i=LM(i,e.x),i=kM(i,e.x+e.width);var n=t[1];return n=LM(n,e.y),n=kM(n,e.y+e.height),[i,n]})}function Po(t,e,i){var n=(e=a({rectHover:!0},e)).style={strokeNoScale:!0};if(i=i||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(n.image=t.slice(8),r(n,i),new fi(e)):Xn(t.replace("path://",""),e,i,"center")}function No(t,e,i){this.parentModel=e,this.ecModel=i,this.option=t}function Oo(t,e,i){for(var n=0;n0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/o*a+i[0]}function Vo(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?zo(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t}function Go(t,e,i){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),i?t:+t}function Fo(t){return t.sort(function(t,e){return t-e}),t}function Wo(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Ho(t){var e=t.toString(),i=e.indexOf("e");if(i>0){var n=+e.slice(i+1);return n<0?-n:0}var o=e.indexOf(".");return o<0?0:e.length-1-o}function Zo(t,e){var i=Math.log,n=Math.LN10,o=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n),r=Math.min(Math.max(-o+a,0),20);return isFinite(r)?r:20}function Uo(t,e,i){if(!t[e])return 0;var n=p(t,function(t,e){return t+(isNaN(e)?0:e)},0);if(0===n)return 0;for(var o=Math.pow(10,i),a=f(t,function(t){return(isNaN(t)?0:t)/n*o*100}),r=100*o,s=f(a,function(t){return Math.floor(t)}),l=p(s,function(t,e){return t+e},0),u=f(a,function(t,e){return t-s[e]});lh&&(h=u[d],c=d);++s[c],u[c]=0,++l}return s[e]/o}function Xo(t){var e=2*Math.PI;return(t%e+e)%e}function jo(t){return t>-UM&&t=-20?+t.toFixed(n<0?-n:0):t}function Jo(t){function e(t,i,n){return t.interval[n]=0}function ta(t){return isNaN(t)?"-":(t=(t+"").split("."))[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t.length>1?"."+t[1]:"")}function ea(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}function ia(t){return null==t?"":(t+"").replace(KM,function(t,e){return $M[e]})}function na(t,e,i){y(e)||(e=[e]);var n=e.length;if(!n)return"";for(var o=e[0].$vars||[],a=0;a':'':{renderMode:o,content:"{marker"+a+"|} ",style:{color:i}}:""}function ra(t,e){return t+="","0000".substr(0,e-t.length)+t}function sa(t,e,i){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var n=Yo(e),o=i?"UTC":"",a=n["get"+o+"FullYear"](),r=n["get"+o+"Month"]()+1,s=n["get"+o+"Date"](),l=n["get"+o+"Hours"](),u=n["get"+o+"Minutes"](),h=n["get"+o+"Seconds"](),c=n["get"+o+"Milliseconds"]();return t=t.replace("MM",ra(r,2)).replace("M",r).replace("yyyy",a).replace("yy",a%100).replace("dd",ra(s,2)).replace("d",s).replace("hh",ra(l,2)).replace("h",l).replace("mm",ra(u,2)).replace("m",u).replace("ss",ra(h,2)).replace("s",h).replace("SSS",ra(c,3))}function la(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t}function ua(t,e,i,n,o){var a=0,r=0;null==n&&(n=1/0),null==o&&(o=1/0);var s=0;e.eachChild(function(l,u){var h,c,d=l.position,f=l.getBoundingRect(),p=e.childAt(u+1),g=p&&p.getBoundingRect();if("horizontal"===t){var m=f.width+(g?-g.x+f.x:0);(h=a+m)>n||l.newline?(a=0,h=m,r+=s+i,s=f.height):s=Math.max(s,f.height)}else{var v=f.height+(g?-g.y+f.y:0);(c=r+v)>o||l.newline?(a+=s+i,r=0,c=v,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=a,d[1]=r,"horizontal"===t?a=h+i:r=c+i)})}function ha(t,e,i){var n=e.width,o=e.height,a=Vo(t.x,n),r=Vo(t.y,o),s=Vo(t.x2,n),l=Vo(t.y2,o);return(isNaN(a)||isNaN(parseFloat(t.x)))&&(a=0),(isNaN(s)||isNaN(parseFloat(t.x2)))&&(s=n),(isNaN(r)||isNaN(parseFloat(t.y)))&&(r=0),(isNaN(l)||isNaN(parseFloat(t.y2)))&&(l=o),i=qM(i||0),{width:Math.max(s-a-i[1]-i[3],0),height:Math.max(l-r-i[0]-i[2],0)}}function ca(t,e,i){i=qM(i||0);var n=e.width,o=e.height,a=Vo(t.left,n),r=Vo(t.top,o),s=Vo(t.right,n),l=Vo(t.bottom,o),u=Vo(t.width,n),h=Vo(t.height,o),c=i[2]+i[0],d=i[1]+i[3],f=t.aspect;switch(isNaN(u)&&(u=n-s-d-a),isNaN(h)&&(h=o-l-c-r),null!=f&&(isNaN(u)&&isNaN(h)&&(f>n/o?u=.8*n:h=.8*o),isNaN(u)&&(u=f*h),isNaN(h)&&(h=u/f)),isNaN(a)&&(a=n-s-u-d),isNaN(r)&&(r=o-l-h-c),t.left||t.right){case"center":a=n/2-u/2-i[3];break;case"right":a=n-u-d}switch(t.top||t.bottom){case"middle":case"center":r=o/2-h/2-i[0];break;case"bottom":r=o-h-c}a=a||0,r=r||0,isNaN(u)&&(u=n-d-a-(s||0)),isNaN(h)&&(h=o-c-r-(l||0));var p=new de(a+i[3],r+i[0],u,h);return p.margin=i,p}function da(t,e,i,n,o){var a=!o||!o.hv||o.hv[0],s=!o||!o.hv||o.hv[1],l=o&&o.boundingMode||"all";if(a||s){var u;if("raw"===l)u="group"===t.type?new de(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(u=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(u=u.clone()).applyTransform(h)}e=ca(r({width:u.width,height:u.height},e),i,n);var c=t.position,d=a?e.x-u.x:0,f=s?e.y-u.y:0;t.attr("position","raw"===l?[d,f]:[c[0]+d,c[1]+f])}}function fa(t,e){return null!=t[oI[e][0]]||null!=t[oI[e][1]]&&null!=t[oI[e][2]]}function pa(t,e,i){function n(i,n){var r={},l=0,u={},h=0;if(iI(i,function(e){u[e]=t[e]}),iI(i,function(t){o(e,t)&&(r[t]=u[t]=e[t]),a(r,t)&&l++,a(u,t)&&h++}),s[n])return a(e,i[1])?u[i[2]]=null:a(e,i[2])&&(u[i[1]]=null),u;if(2!==h&&l){if(l>=2)return r;for(var c=0;ce)return t[n];return t[i-1]}function ya(t){var e=t.get("coordinateSystem"),i={coordSysName:e,coordSysDims:[],axisMap:R(),categoryAxisMap:R()},n=fI[e];if(n)return n(t,i,i.axisMap,i.categoryAxisMap),i}function xa(t){return"category"===t.get("type")}function _a(t){this.fromDataset=t.fromDataset,this.data=t.data||(t.sourceFormat===vI?{}:[]),this.sourceFormat=t.sourceFormat||yI,this.seriesLayoutBy=t.seriesLayoutBy||_I,this.dimensionsDefine=t.dimensionsDefine,this.encodeDefine=t.encodeDefine&&R(t.encodeDefine),this.startIndex=t.startIndex||0,this.dimensionsDetectCount=t.dimensionsDetectCount}function wa(t){var e=t.option.source,i=yI;if(S(e))i=xI;else if(y(e)){0===e.length&&(i=gI);for(var n=0,o=e.length;n=e:"max"===i?t<=e:t===e}function Xa(t,e){return t.join(",")===e.join(",")}function ja(t,e){AI(e=e||{},function(e,i){if(null!=e){var n=t[i];if(lI.hasClass(i)){e=Di(e);var o=Pi(n=Di(n),e);t[i]=CI(o,function(t){return t.option&&t.exist?LI(t.exist,t.option,!0):t.exist||t.option})}else t[i]=LI(n,e,!0)}})}function Ya(t){var e=t&&t.itemStyle;if(e)for(var i=0,o=OI.length;i=0;p--){var g=t[p];if(s||(d=g.data.rawIndexOf(g.stackedByDimension,c)),d>=0){var m=g.data.getByRawIndex(g.stackResultDimension,d);if(h>=0&&m>0||h<=0&&m<0){h+=m,f=m;break}}}return n[0]=h,n[1]=f,n});r.hostModel.setData(l),e.data=l})}function rr(t,e){_a.isInstance(t)||(t=_a.seriesDataToSource(t)),this._source=t;var i=this._data=t.data,n=t.sourceFormat;n===xI&&(this._offset=0,this._dimSize=e,this._data=i),a(this,GI[n===gI?n+"_"+t.seriesLayoutBy:n])}function sr(){return this._data.length}function lr(t){return this._data[t]}function ur(t){for(var e=0;ee.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function Mr(t,e){d(t.CHANGABLE_METHODS,function(i){t.wrapMethod(i,v(Ir,e))})}function Ir(t){var e=Tr(t);e&&e.setOutputEnd(this.count())}function Tr(t){var e=(t.ecModel||{}).scheduler,i=e&&e.getPipeline(t.uid);if(i){var n=i.currentTask;if(n){var o=n.agentStubMap;o&&(n=o.get(t.uid))}return n}}function Ar(){this.group=new tb,this.uid=Ro("viewChart"),this.renderTask=gr({plan:Lr,reset:kr}),this.renderTask.context={view:this}}function Dr(t,e){if(t&&(t.trigger(e),"group"===t.type))for(var i=0;i=0?n():c=setTimeout(n,-a),u=o};return d.clear=function(){c&&(clearTimeout(c),c=null)},d.debounceNextCall=function(t){l=t},d}function Nr(t,e,i,n){var o=t[e];if(o){var a=o[iT]||o,r=o[oT];if(o[nT]!==i||r!==n){if(null==i||!n)return t[e]=a;(o=t[e]=Pr(a,i,"debounce"===n))[iT]=a,o[oT]=n,o[nT]=i}return o}}function Or(t,e){var i=t[e];i&&i[iT]&&(t[e]=i[iT])}function Er(t,e,i,n){this.ecInstance=t,this.api=e,this.unfinished;var i=this._dataProcessorHandlers=i.slice(),n=this._visualHandlers=n.slice();this._allHandlers=i.concat(n),this._stageTaskMap=R()}function Rr(t,e,i,n,o){function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}o=o||{};var r;d(e,function(e,s){if(!o.visualType||o.visualType===e.visualType){var l=t._stageTaskMap.get(e.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,d=h.agentStubMap;d.each(function(t){a(o,t)&&(t.dirty(),c=!0)}),c&&h.dirty(),hT(h,n);var f=t.getPerformArgs(h,o.block);d.each(function(t){t.perform(f)}),r|=h.perform(f)}else u&&u.each(function(s,l){a(o,s)&&s.dirty();var u=t.getPerformArgs(s,o.block);u.skip=!e.performRawSeries&&i.isSeriesFiltered(s.context.model),hT(s,n),r|=s.perform(u)})}}),t.unfinished|=r}function zr(t,e,i,n,o){function a(i){var a=i.uid,s=r.get(a)||r.set(a,gr({plan:Hr,reset:Zr,count:Xr}));s.context={model:i,ecModel:n,api:o,useClearVisual:e.isVisual&&!e.isLayout,plan:e.plan,reset:e.reset,scheduler:t},jr(t,i,s)}var r=i.seriesTaskMap||(i.seriesTaskMap=R()),s=e.seriesType,l=e.getTargetSeries;e.createOnAllSeries?n.eachRawSeries(a):s?n.eachRawSeriesByType(s,a):l&&l(n,o).each(a);var u=t._pipelineMap;r.each(function(t,e){u.get(e)||(t.dispose(),r.removeKey(e))})}function Br(t,e,i,n,o){function a(e){var i=e.uid,n=s.get(i);n||(n=s.set(i,gr({reset:Gr,onDirty:Wr})),r.dirty()),n.context={model:e,overallProgress:h,modifyOutputEnd:c},n.agent=r,n.__block=h,jr(t,e,n)}var r=i.overallTask=i.overallTask||gr({reset:Vr});r.context={ecModel:n,api:o,overallReset:e.overallReset,scheduler:t};var s=r.agentStubMap=r.agentStubMap||R(),l=e.seriesType,u=e.getTargetSeries,h=!0,c=e.modifyOutputEnd;l?n.eachRawSeriesByType(l,a):u?u(n,o).each(a):(h=!1,d(n.getSeries(),a));var f=t._pipelineMap;s.each(function(t,e){f.get(e)||(t.dispose(),r.dirty(),s.removeKey(e))})}function Vr(t){t.overallReset(t.ecModel,t.api,t.payload)}function Gr(t,e){return t.overallProgress&&Fr}function Fr(){this.agent.dirty(),this.getDownstream().dirty()}function Wr(){this.agent&&this.agent.dirty()}function Hr(t){return t.plan&&t.plan(t.model,t.ecModel,t.api,t.payload)}function Zr(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=Di(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?f(e,function(t,e){return Ur(e)}):cT}function Ur(t){return function(e,i){var n=i.data,o=i.resetDefines[t];if(o&&o.dataEach)for(var a=e.start;a0?parseInt(n,10)/100:n?parseFloat(n):0;var o=i.getAttribute("stop-color")||"#000000";e.addColorStop(n,o)}i=i.nextSibling}}function Qr(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),r(e.__inheritedStyle,t.__inheritedStyle))}function ts(t){for(var e=P(t).split(_T),i=[],n=0;n0;a-=2){var r=o[a],s=o[a-1];switch(n=n||xt(),s){case"translate":r=P(r).split(_T),St(n,n,[parseFloat(r[0]),parseFloat(r[1]||0)]);break;case"scale":r=P(r).split(_T),It(n,n,[parseFloat(r[0]),parseFloat(r[1]||r[0])]);break;case"rotate":r=P(r).split(_T),Mt(n,n,parseFloat(r[0]));break;case"skew":r=P(r).split(_T),console.warn("Skew transform is not supported yet");break;case"matrix":r=P(r).split(_T);n[0]=parseFloat(r[0]),n[1]=parseFloat(r[1]),n[2]=parseFloat(r[2]),n[3]=parseFloat(r[3]),n[4]=parseFloat(r[4]),n[5]=parseFloat(r[5])}}e.setLocalTransform(n)}}function os(t){var e=t.getAttribute("style"),i={};if(!e)return i;var n={};TT.lastIndex=0;for(var o;null!=(o=TT.exec(e));)n[o[1]]=o[2];for(var a in ST)ST.hasOwnProperty(a)&&null!=n[a]&&(i[ST[a]]=n[a]);return i}function as(t,e,i){var n=e/t.width,o=i/t.height,a=Math.min(n,o);return{scale:[a,a],position:[-(t.x+t.width/2)*a+e/2,-(t.y+t.height/2)*a+i/2]}}function rs(t,e){return(new $r).parse(t,e)}function ss(t){return function(e,i,n){e=e&&e.toLowerCase(),fw.prototype[t].call(this,e,i,n)}}function ls(){fw.call(this)}function us(t,e,n){function o(t,e){return t.__prio-e.__prio}n=n||{},"string"==typeof e&&(e=JT[e]),this.id,this.group,this._dom=t;var a=this._zr=Ii(t,{renderer:n.renderer||"canvas",devicePixelRatio:n.devicePixelRatio,width:n.width,height:n.height});this._throttledZrFlush=Pr(m(a.flush,a),17),(e=i(e))&&BI(e,!0),this._theme=e,this._chartsViews=[],this._chartsMap={},this._componentsViews=[],this._componentsMap={},this._coordSysMgr=new Fa;var r=this._api=As(this);_e($T,o),_e(YT,o),this._scheduler=new Er(this,r,YT,$T),fw.call(this,this._ecEventProcessor=new Ds),this._messageCenter=new ls,this._initEvents(),this.resize=m(this.resize,this),this._pendingActions=[],a.animation.on("frame",this._onframe,this),vs(a,this),N(this)}function hs(t,e,i){var n,o=this._model,a=this._coordSysMgr.getCoordinateSystems();e=Vi(o,e);for(var r=0;re.get("hoverLayerThreshold")&&!U_.node&&i.traverse(function(t){t.isGroup||(t.useHoverLayer=!0)})}function Is(t,e){var i=t.get("blendMode")||null;e.group.traverse(function(t){t.isGroup||t.style.blend!==i&&t.setStyle("blend",i),t.eachPendingDisplayable&&t.eachPendingDisplayable(function(t){t.setStyle("blend",i)})})}function Ts(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function As(t){var e=t._coordSysMgr;return a(new Ga(t),{getCoordinateSystems:m(e.getCoordinateSystems,e),getComponentByElement:function(e){for(;e;){var i=e.__ecComponentInfo;if(null!=i)return t._model.getComponent(i.mainType,i.index);e=e.parent}}})}function Ds(){this.eventInfo}function Cs(t){function e(t,e){for(var n=0;n65535?dA:pA}function Js(t){var e=t.constructor;return e===Array?t.slice():new e(t)}function Qs(t,e){d(gA.concat(e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods,d(mA,function(n){t[n]=i(e[n])}),t._calculationInfo=a(e._calculationInfo)}function tl(t,e,i,n,o){var a=cA[e.type],r=n-1,s=e.name,l=t[s][r];if(l&&l.length=0?this._indices[t]:-1}function al(t,e){var i=t._idList[e];return null==i&&(i=il(t,t._idDimIdx,e)),null==i&&(i=hA+e),i}function rl(t){return y(t)||(t=[t]),t}function sl(t,e){var i=t.dimensions,n=new vA(f(i,t.getDimensionInfo,t),t.hostModel);Qs(n,t);for(var o=n._storage={},a=t._storage,r=0;r=0?(o[s]=ll(a[s]),n._rawExtent[s]=ul(),n._extent[s]=null):o[s]=a[s])}return n}function ll(t){for(var e=new Array(t.length),i=0;in&&(r=o.interval=n);var s=o.intervalPrecision=Ml(r);return Tl(o.niceTickExtent=[MA(Math.ceil(t[0]/r)*r,s),MA(Math.floor(t[1]/r)*r,s)],t),o}function Ml(t){return Ho(t)+2}function Il(t,e,i){t[e]=Math.max(Math.min(t[e],i[1]),i[0])}function Tl(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),Il(t,0,e),Il(t,1,e),t[0]>t[1]&&(t[0]=t[1])}function Al(t,e,i,n){var o=[];if(!t)return o;e[0]1e4)return[];return e[1]>(o.length?o[o.length-1]:i[1])&&o.push(e[1]),o}function Dl(t){return t.get("stack")||AA+t.seriesIndex}function Cl(t){return t.dim+t.index}function Ll(t){var e=[],i=t.axis;if("category"===i.type){for(var n=i.getBandWidth(),o=0;o=0?"p":"n",b=m;p&&(o[r][_]||(o[r][_]={p:m,n:m}),b=o[r][_][w]);var S,M,I,T;if(g)S=b,M=(A=i.dataToPoint([x,_]))[1]+l,I=A[0]-m,T=u,Math.abs(I)a[1]?(n=a[1],o=a[0]):(n=a[0],o=a[1]);var r=e.toGlobalCoord(e.dataToCoord(0));return ro&&(r=o),r}function Vl(t,e){return VA(t,BA(e))}function Gl(t,e){var i,n,o,a=t.type,r=e.getMin(),s=e.getMax(),l=null!=r,u=null!=s,h=t.getExtent();"ordinal"===a?i=e.getCategories().length:(y(n=e.get("boundaryGap"))||(n=[n||0,n||0]),"boolean"==typeof n[0]&&(n=[0,0]),n[0]=Vo(n[0],1),n[1]=Vo(n[1],1),o=h[1]-h[0]||Math.abs(h[0])),null==r&&(r="ordinal"===a?i?0:NaN:h[0]-n[0]*o),null==s&&(s="ordinal"===a?i?i-1:NaN:h[1]+n[1]*o),"dataMin"===r?r=h[0]:"function"==typeof r&&(r=r({min:h[0],max:h[1]})),"dataMax"===s?s=h[1]:"function"==typeof s&&(s=s({min:h[0],max:h[1]})),(null==r||!isFinite(r))&&(r=NaN),(null==s||!isFinite(s))&&(s=NaN),t.setBlank(I(r)||I(s)||"ordinal"===a&&!t.getOrdinalMeta().categories.length),e.getNeedCrossZero()&&(r>0&&s>0&&!l&&(r=0),r<0&&s<0&&!u&&(s=0));var c=e.ecModel;if(c&&"time"===a){var f,p=kl("bar",c);if(d(p,function(t){f|=t.getBaseAxis()===e.axis}),f){var g=Pl(p),m=Fl(r,s,e,g);r=m.min,s=m.max}}return[r,s]}function Fl(t,e,i,n){var o=i.axis.getExtent(),a=o[1]-o[0],r=Ol(n,i.axis);if(void 0===r)return{min:t,max:e};var s=1/0;d(r,function(t){s=Math.min(t.offset,s)});var l=-1/0;d(r,function(t){l=Math.max(t.offset+t.width,l)}),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/a)-h;return e+=c*(l/u),t-=c*(s/u),{min:t,max:e}}function Wl(t,e){var i=Gl(t,e),n=null!=e.getMin(),o=null!=e.getMax(),a=e.get("splitNumber");"log"===t.type&&(t.base=e.get("logBase"));var r=t.type;t.setExtent(i[0],i[1]),t.niceExtent({splitNumber:a,fixMin:n,fixMax:o,minInterval:"interval"===r||"time"===r?e.get("minInterval"):null,maxInterval:"interval"===r||"time"===r?e.get("maxInterval"):null});var s=e.get("interval");null!=s&&t.setInterval&&t.setInterval(s)}function Hl(t,e){if(e=e||t.get("type"))switch(e){case"category":return new SA(t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),[1/0,-1/0]);case"value":return new TA;default:return(xl.getClass(e)||TA).create(t)}}function Zl(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(i>0&&n>0||i<0&&n<0)}function Ul(t){var e=t.getLabelModel().get("formatter"),i="category"===t.type?t.scale.getExtent()[0]:null;return"string"==typeof e?e=function(e){return function(i){return i=t.scale.getLabel(i),e.replace("{value}",null!=i?i:"")}}(e):"function"==typeof e?function(n,o){return null!=i&&(o=n-i),e(Xl(t,n),o)}:function(e){return t.scale.getLabel(e)}}function Xl(t,e){return"category"===t.type?t.scale.getLabel(e):e}function jl(t){var e=t.model,i=t.scale;if(e.get("axisLabel.show")&&!i.isBlank()){var n,o,a="category"===t.type,r=i.getExtent();o=a?i.count():(n=i.getTicks()).length;var s,l=t.getLabelModel(),u=Ul(t),h=1;o>40&&(h=Math.ceil(o/40));for(var c=0;c>1^-(1&s),l=l>>1^-(1&l),o=s+=o,a=l+=a,n.push([s/i,l/i])}return n}function ou(t){return"category"===t.type?ru(t):uu(t)}function au(t,e){return"category"===t.type?lu(t,e):{ticks:t.scale.getTicks()}}function ru(t){var e=t.getLabelModel(),i=su(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:i.labelCategoryInterval}:i}function su(t,e){var i=hu(t,"labels"),n=ql(e),o=cu(i,n);if(o)return o;var a,r;return a=x(n)?vu(t,n):mu(t,r="auto"===n?fu(t):n),du(i,n,{labels:a,labelCategoryInterval:r})}function lu(t,e){var i=hu(t,"ticks"),n=ql(e),o=cu(i,n);if(o)return o;var a,r;if(e.get("show")&&!t.scale.isBlank()||(a=[]),x(n))a=vu(t,n,!0);else if("auto"===n){var s=su(t,t.getLabelModel());r=s.labelCategoryInterval,a=f(s.labels,function(t){return t.tickValue})}else a=mu(t,r=n,!0);return du(i,n,{ticks:a,tickCategoryInterval:r})}function uu(t){var e=t.scale.getTicks(),i=Ul(t);return{labels:f(e,function(e,n){return{formattedLabel:i(e,n),rawLabel:t.scale.getLabel(e),tickValue:e}})}}function hu(t,e){return nD(t)[e]||(nD(t)[e]=[])}function cu(t,e){for(var i=0;i40&&(s=Math.max(1,Math.floor(r/40)));for(var l=a[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(n)),c=Math.abs(u*Math.sin(n)),d=0,f=0;l<=a[1];l+=s){var p=0,g=0,m=ke(i(l),e.font,"center","top");p=1.3*m.width,g=1.3*m.height,d=Math.max(d,p,7),f=Math.max(f,g,7)}var v=d/h,y=f/c;isNaN(v)&&(v=1/0),isNaN(y)&&(y=1/0);var x=Math.max(0,Math.floor(Math.min(v,y))),_=nD(t.model),w=_.lastAutoInterval,b=_.lastTickCount;return null!=w&&null!=b&&Math.abs(w-x)<=1&&Math.abs(b-r)<=1&&w>x?x=w:(_.lastTickCount=r,_.lastAutoInterval=x),x}function gu(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}function mu(t,e,i){function n(t){l.push(i?t:{formattedLabel:o(t),rawLabel:a.getLabel(t),tickValue:t})}var o=Ul(t),a=t.scale,r=a.getExtent(),s=t.getLabelModel(),l=[],u=Math.max((e||0)+1,1),h=r[0],c=a.count();0!==h&&u>1&&c/u>2&&(h=Math.round(Math.ceil(h/u)*u));var d=Kl(t),f=s.get("showMinLabel")||d,p=s.get("showMaxLabel")||d;f&&h!==r[0]&&n(r[0]);for(var g=h;g<=r[1];g+=u)n(g);return p&&g!==r[1]&&n(r[1]),l}function vu(t,e,i){var n=t.scale,o=Ul(t),a=[];return d(n.getTicks(),function(t){var r=n.getLabel(t);e(t,r)&&a.push(i?t:{formattedLabel:o(t),rawLabel:r,tickValue:t})}),a}function yu(t,e){var i=(t[1]-t[0])/e/2;t[0]+=i,t[1]-=i}function xu(t,e,i,n,o){function a(t,e){return h?t>e:t0&&(t.coord-=u/(2*(e+1)))}),s={coord:e[r-1].coord+u},e.push(s)}var h=l[0]>l[1];a(e[0].coord,l[0])&&(o?e[0].coord=l[0]:e.shift()),o&&a(l[0],e[0].coord)&&e.unshift({coord:l[0]}),a(l[1],s.coord)&&(o?s.coord=l[1]:e.pop()),o&&a(s.coord,l[1])&&e.push({coord:l[1]})}}function _u(t,e){var i=t.mapDimension("defaultedLabel",!0),n=i.length;if(1===n)return fr(t,e,i[0]);if(n){for(var o=[],a=0;a0?i=n[0]:n[1]<0&&(i=n[1]),i}function Ou(t,e,i,n){var o=NaN;t.stacked&&(o=i.get(i.getCalculationInfo("stackedOverDimension"),n)),isNaN(o)&&(o=t.valueStart);var a=t.baseDataOffset,r=[];return r[a]=i.get(t.baseDim,n),r[1-a]=o,e.dataToPoint(r)}function Eu(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}function Ru(t){return isNaN(t[0])||isNaN(t[1])}function zu(t,e,i,n,o,a,r,s,l,u,h){return"none"!==u&&u?Bu.apply(this,arguments):Vu.apply(this,arguments)}function Bu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(Ru(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]);else if(l>0){var g=e[c],m="y"===u?1:0,v=(p[m]-g[m])*l;_D(bD,g),bD[m]=g[m]+v,_D(SD,p),SD[m]=p[m]-v,t.bezierCurveTo(bD[0],bD[1],SD[0],SD[1],p[0],p[1])}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function Vu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(Ru(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]),_D(bD,p);else if(l>0){var g=d+a,m=e[g];if(h)for(;m&&Ru(e[g]);)m=e[g+=a];var v=.5,y=e[c];if(!(m=e[g])||Ru(m))_D(SD,p);else{Ru(m)&&!h&&(m=p),U(wD,m,y);var x,_;if("x"===u||"y"===u){var w="x"===u?0:1;x=Math.abs(p[w]-y[w]),_=Math.abs(p[w]-m[w])}else x=uw(p,y),_=uw(p,m);xD(SD,p,wD,-l*(1-(v=_/(_+x))))}vD(bD,bD,s),yD(bD,bD,r),vD(SD,SD,s),yD(SD,SD,r),t.bezierCurveTo(bD[0],bD[1],SD[0],SD[1],p[0],p[1]),xD(bD,p,wD,l*v)}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function Gu(t,e){var i=[1/0,1/0],n=[-1/0,-1/0];if(e)for(var o=0;on[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}function Fu(t,e){if(t.length===e.length){for(var i=0;ie[0]?1:-1;e[0]+=n*i,e[1]-=n*i}return e}function Zu(t,e,i){if(!i.valueDim)return[];for(var n=[],o=0,a=e.count();oa[1]&&a.reverse();var r=o.getExtent(),s=Math.PI/180;i&&(a[0]-=.5,a[1]+=.5);var l=new hM({shape:{cx:Go(t.cx,1),cy:Go(t.cy,1),r0:Go(a[0],1),r:Go(a[1],1),startAngle:-r[0]*s,endAngle:-r[1]*s,clockwise:o.inverse}});return e&&(l.shape.endAngle=-r[0]*s,To(l,{shape:{endAngle:-r[1]*s}},n)),l}function ju(t,e,i,n){return"polar"===t.type?Xu(t,e,i,n):Uu(t,e,i,n)}function Yu(t,e,i){for(var n=e.getBaseAxis(),o="x"===n.dim||"radius"===n.dim?0:1,a=[],r=0;r=0;a--){var r=i[a].dimension,s=t.dimensions[r],l=t.getDimensionInfo(s);if("x"===(n=l&&l.coordDim)||"y"===n){o=i[a];break}}if(o){var u=e.getAxis(n),h=f(o.stops,function(t){return{coord:u.toGlobalCoord(u.dataToCoord(t.value)),color:t.color}}),c=h.length,p=o.outerColors.slice();c&&h[0].coord>h[c-1].coord&&(h.reverse(),p.reverse());var g=h[0].coord-10,m=h[c-1].coord+10,v=m-g;if(v<.001)return"transparent";d(h,function(t){t.offset=(t.coord-g)/v}),h.push({offset:c?h[c-1].offset:.5,color:p[1]||"transparent"}),h.unshift({offset:c?h[0].offset:.5,color:p[0]||"transparent"});var y=new TM(0,0,0,0,h,!0);return y[n]=g,y[n+"2"]=m,y}}}function Ku(t,e,i){var n=t.get("showAllSymbol"),o="auto"===n;if(!n||o){var a=i.getAxesByScale("ordinal")[0];if(a&&(!o||!$u(a,e))){var r=e.mapDimension(a.dim),s={};return d(a.getViewLabels(),function(t){s[t.tickValue]=1}),function(t){return!s.hasOwnProperty(e.get(r,t))}}}}function $u(t,e){var i=t.getExtent(),n=Math.abs(i[1]-i[0])/t.scale.count();isNaN(n)&&(n=0);for(var o=e.count(),a=Math.max(1,Math.round(o/5)),r=0;rn)return!1;return!0}function Ju(t){return this._axes[t]}function Qu(t){LD.call(this,t)}function th(t,e){return e.type||(e.data?"category":"value")}function eh(t,e,i){return t.getCoordSysModel()===e}function ih(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this.model=t}function nh(t,e,i,n){function o(t){return t.dim+"_"+t.index}i.getAxesOnZeroOf=function(){return a?[a]:[]};var a,r=t[e],s=i.model,l=s.get("axisLine.onZero"),u=s.get("axisLine.onZeroAxisIndex");if(l){if(null!=u)oh(r[u])&&(a=r[u]);else for(var h in r)if(r.hasOwnProperty(h)&&oh(r[h])&&!n[o(r[h])]){a=r[h];break}a&&(n[o(a)]=!0)}}function oh(t){return t&&"category"!==t.type&&"time"!==t.type&&Zl(t)}function ah(t,e){var i=t.getExtent(),n=i[0]+i[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return n-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return n-t+e}}function rh(t,e){return f(VD,function(e){return t.getReferringComponents(e)[0]})}function sh(t){return"cartesian2d"===t.get("coordinateSystem")}function lh(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e}function uh(t,e,i,n){var o,a,r=Xo(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return jo(r-GD/2)?(a=l?"bottom":"top",o="center"):jo(r-1.5*GD)?(a=l?"top":"bottom",o="center"):(a="middle",o=r<1.5*GD&&r>GD/2?l?"left":"right":l?"right":"left"),{rotation:r,textAlign:o,textVerticalAlign:a}}function hh(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)}function ch(t,e,i){if(!Kl(t.axis)){var n=t.get("axisLabel.showMinLabel"),o=t.get("axisLabel.showMaxLabel");e=e||[],i=i||[];var a=e[0],r=e[1],s=e[e.length-1],l=e[e.length-2],u=i[0],h=i[1],c=i[i.length-1],d=i[i.length-2];!1===n?(dh(a),dh(u)):fh(a,r)&&(n?(dh(r),dh(h)):(dh(a),dh(u))),!1===o?(dh(s),dh(c)):fh(l,s)&&(o?(dh(l),dh(d)):(dh(s),dh(c)))}}function dh(t){t&&(t.ignore=!0)}function fh(t,e,i){var n=t&&t.getBoundingRect().clone(),o=e&&e.getBoundingRect().clone();if(n&&o){var a=_t([]);return Mt(a,a,-t.rotation),n.applyTransform(bt([],a,t.getLocalTransform())),o.applyTransform(bt([],a,e.getLocalTransform())),n.intersect(o)}}function ph(t){return"middle"===t||"center"===t}function gh(t,e,i){var n=e.axis;if(e.get("axisTick.show")&&!n.scale.isBlank()){for(var o=e.getModel("axisTick"),a=o.getModel("lineStyle"),s=o.get("length"),l=n.getTicksCoords(),u=[],h=[],c=t._transform,d=[],f=0;f=0||t===e}function Sh(t){var e=Mh(t);if(e){var i=e.axisPointerModel,n=e.axis.scale,o=i.option,a=i.get("status"),r=i.get("value");null!=r&&(r=n.parse(r));var s=Th(i);null==a&&(o.status=s?"show":"hide");var l=n.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==r||r>l[1])&&(r=l[1]),r0?"bottom":"top":o.width>0?"left":"right";l||kh(t.style,d,n,u,a,i,p),fo(t,d)}function Rh(t,e){var i=t.get(tC)||0;return Math.min(i,Math.abs(e.width),Math.abs(e.height))}function zh(t,e,i){var n=t.getData(),o=[],a=n.getLayout("valueAxisHorizontal")?1:0;o[1-a]=n.getLayout("valueAxisStart");var r=new nC({shape:{points:n.getLayout("largePoints")},incremental:!!i,__startPoint:o,__valueIdx:a});e.add(r),Bh(r,t,n)}function Bh(t,e,i){var n=i.getVisual("borderColor")||i.getVisual("color"),o=e.getModel("itemStyle").getItemStyle(["color","borderColor"]);t.useStyle(o),t.style.fill=null,t.style.stroke=n,t.style.lineWidth=i.getLayout("barWidth")}function Vh(t,e,i,n){var o=e.getData(),a=this.dataIndex,r=o.getName(a),s=e.get("selectedOffset");n.dispatchAction({type:"pieToggleSelect",from:t,name:r,seriesId:e.id}),o.each(function(t){Gh(o.getItemGraphicEl(t),o.getItemLayout(t),e.isSelected(o.getName(t)),s,i)})}function Gh(t,e,i,n,o){var a=(e.startAngle+e.endAngle)/2,r=Math.cos(a),s=Math.sin(a),l=i?n:0,u=[r*l,s*l];o?t.animate().when(200,{position:u}).start("bounceOut"):t.attr("position",u)}function Fh(t,e){function i(){a.ignore=a.hoverIgnore,r.ignore=r.hoverIgnore}function n(){a.ignore=a.normalIgnore,r.ignore=r.normalIgnore}tb.call(this);var o=new hM({z2:2}),a=new gM,r=new rM;this.add(o),this.add(a),this.add(r),this.updateData(t,e,!0),this.on("emphasis",i).on("normal",n).on("mouseover",i).on("mouseout",n)}function Wh(t,e,i,n,o,a,r){function s(e,i){for(var n=e;n>=0&&(t[n].y-=i,!(n>0&&t[n].y>t[n-1].y+t[n-1].height));n--);}function l(t,e,i,n,o,a){for(var r=e?Number.MAX_VALUE:0,s=0,l=t.length;s=r&&(d=r-10),!e&&d<=r&&(d=r+10),t[s].x=i+d*a,r=d}}t.sort(function(t,e){return t.y-e.y});for(var u,h=0,c=t.length,d=[],f=[],p=0;pe&&a+1t[a].y+t[a].height)return void s(a,n/2);s(i-1,n/2)}(p,c,-u),h=t[p].y+t[p].height;r-h<0&&s(c-1,h-r);for(p=0;p=i?f.push(t[p]):d.push(t[p]);l(d,!1,e,i,n,o),l(f,!0,e,i,n,o)}function Hh(t,e,i,n,o,a){for(var r=[],s=[],l=0;l3?1.4:o>1?1.2:1.1;hc(this,"zoom","zoomOnMouseWheel",t,{scale:n>0?s:1/s,originX:a,originY:r})}if(i){var l=Math.abs(n);hc(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:(n>0?1:-1)*(l>3?.4:l>1?.15:.05),originX:a,originY:r})}}}function uc(t){ic(this._zr,"globalPan")||hc(this,"zoom",null,t,{scale:t.pinchScale>1?1.1:1/1.1,originX:t.pinchX,originY:t.pinchY})}function hc(t,e,i,n,o){t.pointerChecker&&t.pointerChecker(n,o.originX,o.originY)&&(mw(n.event),cc(t,e,i,n,o))}function cc(t,e,i,n,o){o.isAvailableBehavior=m(dc,null,i,n),t.trigger(e,o)}function dc(t,e,i){var n=i[t];return!t||n&&(!_(n)||e.event[n+"Key"])}function fc(t,e,i){var n=t.target,o=n.position;o[0]+=e,o[1]+=i,n.dirty()}function pc(t,e,i,n){var o=t.target,a=t.zoomLimit,r=o.position,s=o.scale,l=t.zoom=t.zoom||1;if(l*=e,a){var u=a.min||0,h=a.max||1/0;l=Math.max(Math.min(h,l),u)}var c=l/t.zoom;t.zoom=l,r[0]-=(i-r[0])*(c-1),r[1]-=(n-r[1])*(c-1),s[0]*=c,s[1]*=c,o.dirty()}function gc(t,e,i){var n=e.getComponentByElement(t.topTarget),o=n&&n.coordinateSystem;return n&&n!==i&&!RC[n.mainType]&&o&&o.model!==i}function mc(t,e){var i=t.getItemStyle(),n=t.get("areaColor");return null!=n&&(i.fill=n),i}function vc(t,e,i,n,o){i.off("click"),i.off("mousedown"),e.get("selectedMode")&&(i.on("mousedown",function(){t._mouseDownFlag=!0}),i.on("click",function(a){if(t._mouseDownFlag){t._mouseDownFlag=!1;for(var r=a.target;!r.__regions;)r=r.parent;if(r){var s={type:("geo"===e.mainType?"geo":"map")+"ToggleSelect",batch:f(r.__regions,function(t){return{name:t.name,from:o.uid}})};s[e.mainType+"Id"]=e.id,n.dispatchAction(s),yc(e,i)}}}))}function yc(t,e){e.eachChild(function(e){d(e.__regions,function(i){e.trigger(t.isSelected(i.name)?"emphasis":"normal")})})}function xc(t,e){var i=new tb;this.uid=Ro("ec_map_draw"),this._controller=new oc(t.getZr()),this._controllerHost={target:e?i:null},this.group=i,this._updateGroup=e,this._mouseDownFlag,this._mapName,this._initialized,i.add(this._regionsGroup=new tb),i.add(this._backgroundGroup=new tb)}function _c(t){var e=this[zC];e&&e.recordVersion===this[BC]&&wc(e,t)}function wc(t,e){var i=t.circle,n=t.labelModel,o=t.hoverLabelModel,a=t.emphasisText,r=t.normalText;e?(i.style.extendFrom(mo({},o,{text:o.get("show")?a:null},{isRectText:!0,useInsideStyle:!1},!0)),i.__mapOriginalZ2=i.z2,i.z2+=NM):(mo(i.style,n,{text:n.get("show")?r:null,textPosition:n.getShallow("position")||"bottom"},{isRectText:!0,useInsideStyle:!1}),i.dirty(!1),null!=i.__mapOriginalZ2&&(i.z2=i.__mapOriginalZ2,i.__mapOriginalZ2=null))}function bc(t,e,i){var n=t.getZoom(),o=t.getCenter(),a=e.zoom,r=t.dataToPoint(o);if(null!=e.dx&&null!=e.dy){r[0]-=e.dx,r[1]-=e.dy;o=t.pointToData(r);t.setCenter(o)}if(null!=a){if(i){var s=i.min||0,l=i.max||1/0;a=Math.max(Math.min(n*a,l),s)/n}t.scale[0]*=a,t.scale[1]*=a;var u=t.position,h=(e.originX-u[0])*(a-1),c=(e.originY-u[1])*(a-1);u[0]-=h,u[1]-=c,t.updateTransform();o=t.pointToData(r);t.setCenter(o),t.setZoom(a*n)}return{center:t.getCenter(),zoom:t.getZoom()}}function Sc(){Tw.call(this)}function Mc(t){this.name=t,this.zoomLimit,Tw.call(this),this._roamTransformable=new Sc,this._rawTransformable=new Sc,this._center,this._zoom}function Ic(t,e,i,n){var o=i.seriesModel,a=o?o.coordinateSystem:null;return a===this?a[t](n):null}function Tc(t,e,i,n){Mc.call(this,t),this.map=e;var o=OC.load(e,i);this._nameCoordMap=o.nameCoordMap,this._regionsMap=o.regionsMap,this._invertLongitute=null==n||n,this.regions=o.regions,this._rect=o.boundingRect}function Ac(t,e,i,n){var o=i.geoModel,a=i.seriesModel,r=o?o.coordinateSystem:a?a.coordinateSystem||(a.getReferringComponents("geo")[0]||{}).coordinateSystem:null;return r===this?r[t](n):null}function Dc(t,e){var i=t.get("boundingCoords");if(null!=i){var n=i[0],o=i[1];isNaN(n[0])||isNaN(n[1])||isNaN(o[0])||isNaN(o[1])||this.setBoundingRect(n[0],n[1],o[0]-n[0],o[1]-n[1])}var a,r=this.getBoundingRect(),s=t.get("layoutCenter"),l=t.get("layoutSize"),u=e.getWidth(),h=e.getHeight(),c=r.width/r.height*this.aspectScale,d=!1;s&&l&&(s=[Vo(s[0],u),Vo(s[1],h)],l=Vo(l,Math.min(u,h)),isNaN(s[0])||isNaN(s[1])||isNaN(l)||(d=!0));if(d){var f={};c>1?(f.width=l,f.height=l/c):(f.height=l,f.width=l*c),f.y=s[1]-f.height/2,f.x=s[0]-f.width/2}else(a=t.getBoxLayoutParams()).aspect=c,f=ca(a,{width:u,height:h});this.setViewRect(f.x,f.y,f.width,f.height),this.setCenter(t.get("center")),this.setZoom(t.get("zoom"))}function Cc(t,e){d(e.get("geoCoord"),function(e,i){t.addGeoCoord(i,e)})}function Lc(t,e){var i={};return d(t,function(t){t.each(t.mapDimension("value"),function(e,n){var o="ec-"+t.getName(n);i[o]=i[o]||[],isNaN(e)||i[o].push(e)})}),t[0].map(t[0].mapDimension("value"),function(n,o){for(var a="ec-"+t[0].getName(o),r=0,s=1/0,l=-1/0,u=i[a].length,h=0;h=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},n.push(a)}}function Wc(t,e){var i=t.isExpand?t.children:[],n=t.parentNode.children,o=t.hierNode.i?n[t.hierNode.i-1]:null;if(i.length){jc(t);var a=(i[0].hierNode.prelim+i[i.length-1].hierNode.prelim)/2;o?(t.hierNode.prelim=o.hierNode.prelim+e(t,o),t.hierNode.modifier=t.hierNode.prelim-a):t.hierNode.prelim=a}else o&&(t.hierNode.prelim=o.hierNode.prelim+e(t,o));t.parentNode.hierNode.defaultAncestor=Yc(t,o,t.parentNode.hierNode.defaultAncestor||n[0],e)}function Hc(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function Zc(t){return arguments.length?t:Qc}function Uc(t,e){var i={};return t-=Math.PI/2,i.x=e*Math.cos(t),i.y=e*Math.sin(t),i}function Xc(t,e){return ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function jc(t){for(var e=t.children,i=e.length,n=0,o=0;--i>=0;){var a=e[i];a.hierNode.prelim+=n,a.hierNode.modifier+=n,o+=a.hierNode.change,n+=a.hierNode.shift+o}}function Yc(t,e,i,n){if(e){for(var o=t,a=t,r=a.parentNode.children[0],s=e,l=o.hierNode.modifier,u=a.hierNode.modifier,h=r.hierNode.modifier,c=s.hierNode.modifier;s=qc(s),a=Kc(a),s&&a;){o=qc(o),r=Kc(r),o.hierNode.ancestor=t;var d=s.hierNode.prelim+c-a.hierNode.prelim-u+n(s,a);d>0&&(Jc($c(s,t,i),t,d),u+=d,l+=d),c+=s.hierNode.modifier,u+=a.hierNode.modifier,l+=o.hierNode.modifier,h+=r.hierNode.modifier}s&&!qc(o)&&(o.hierNode.thread=s,o.hierNode.modifier+=c-l),a&&!Kc(r)&&(r.hierNode.thread=a,r.hierNode.modifier+=u-h,i=t)}return i}function qc(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function Kc(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function $c(t,e,i){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:i}function Jc(t,e,i){var n=i/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=n,e.hierNode.shift+=i,e.hierNode.modifier+=i,e.hierNode.prelim+=i,t.hierNode.change+=n}function Qc(t,e){return t.parentNode===e.parentNode?1:2}function td(t,e){var i=t.getItemLayout(e);return i&&!isNaN(i.x)&&!isNaN(i.y)&&"none"!==t.getItemVisual(e,"symbol")}function ed(t,e,i){return i.itemModel=e,i.itemStyle=e.getModel("itemStyle").getItemStyle(),i.hoverItemStyle=e.getModel("emphasis.itemStyle").getItemStyle(),i.lineStyle=e.getModel("lineStyle").getLineStyle(),i.labelModel=e.getModel("label"),i.hoverLabelModel=e.getModel("emphasis.label"),!1===t.isExpand&&0!==t.children.length?i.symbolInnerColor=i.itemStyle.fill:i.symbolInnerColor="#fff",i}function id(t,e,i,n,o,a){var s=!i,l=t.tree.getNodeByDataIndex(e),a=ed(l,l.getModel(),a),u=t.tree.root,h=l.parentNode===u?l:l.parentNode||l,c=t.getItemGraphicEl(h.dataIndex),d=h.getLayout(),f=c?{x:c.position[0],y:c.position[1],rawX:c.__radialOldRawX,rawY:c.__radialOldRawY}:d,p=l.getLayout();s?(i=new wu(t,e,a)).attr("position",[f.x,f.y]):i.updateData(t,e,a),i.__radialOldRawX=i.__radialRawX,i.__radialOldRawY=i.__radialRawY,i.__radialRawX=p.rawX,i.__radialRawY=p.rawY,n.add(i),t.setItemGraphicEl(e,i),Io(i,{position:[p.x,p.y]},o);var g=i.getSymbolPath();if("radial"===a.layout){var m,v,y=u.children[0],x=y.getLayout(),_=y.children.length;if(p.x===x.x&&!0===l.isExpand){var w={};w.x=(y.children[0].getLayout().x+y.children[_-1].getLayout().x)/2,w.y=(y.children[0].getLayout().y+y.children[_-1].getLayout().y)/2,(m=Math.atan2(w.y-x.y,w.x-x.x))<0&&(m=2*Math.PI+m),(v=w.xx.x)||(m-=Math.PI);var b=v?"left":"right";g.setStyle({textPosition:b,textRotation:-m,textOrigin:"center",verticalAlign:"middle"})}if(l.parentNode&&l.parentNode!==u){var S=i.__edge;S||(S=i.__edge=new bM({shape:od(a,f,f),style:r({opacity:0,strokeNoScale:!0},a.lineStyle)})),Io(S,{shape:od(a,d,p),style:{opacity:1}},o),n.add(S)}}function nd(t,e,i,n,o,a){for(var r,s=t.tree.getNodeByDataIndex(e),l=t.tree.root,a=ed(s,s.getModel(),a),u=s.parentNode===l?s:s.parentNode||s;null==(r=u.getLayout());)u=u.parentNode===l?u:u.parentNode||u;Io(i,{position:[r.x+1,r.y+1]},o,function(){n.remove(i),t.setItemGraphicEl(e,null)}),i.fadeOut(null,{keepLabel:!0});var h=i.__edge;h&&Io(h,{shape:od(a,r,r),style:{opacity:0}},o,function(){n.remove(h)})}function od(t,e,i){var n,o,a,r,s,l,u,h,c=t.orient;if("radial"===t.layout){s=e.rawX,u=e.rawY,l=i.rawX,h=i.rawY;var d=Uc(s,u),f=Uc(s,u+(h-u)*t.curvature),p=Uc(l,h+(u-h)*t.curvature),g=Uc(l,h);return{x1:d.x,y1:d.y,x2:g.x,y2:g.y,cpx1:f.x,cpy1:f.y,cpx2:p.x,cpy2:p.y}}return s=e.x,u=e.y,l=i.x,h=i.y,"LR"!==c&&"RL"!==c||(n=s+(l-s)*t.curvature,o=u,a=l+(s-l)*t.curvature,r=h),"TB"!==c&&"BT"!==c||(n=s,o=u+(h-u)*t.curvature,a=l,r=h+(u-h)*t.curvature),{x1:s,y1:u,x2:l,y2:h,cpx1:n,cpy1:o,cpx2:a,cpy2:r}}function ad(t,e,i){for(var n,o=[t],a=[];n=o.pop();)if(a.push(n),n.isExpand){var r=n.children;if(r.length)for(var s=0;s=0;a--)n.push(o[a])}}function sd(t,e){var i=Xc(t,e);t.layoutInfo=i;var n=t.get("layout"),o=0,a=0,r=null;"radial"===n?(o=2*Math.PI,a=Math.min(i.height,i.width)/2,r=Zc(function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth})):(o=i.width,a=i.height,r=Zc());var s=t.getData().tree.root,l=s.children[0];if(l){Fc(s),ad(l,Wc,r),s.hierNode.modifier=-l.hierNode.prelim,rd(l,Hc);var u=l,h=l,c=l;rd(l,function(t){var e=t.getLayout().x;eh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)});var d=u===h?1:r(u,h)/2,f=d-u.getLayout().x,p=0,g=0,m=0,v=0;if("radial"===n)p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),rd(l,function(t){m=(t.getLayout().x+f)*p,v=(t.depth-1)*g;var e=Uc(m,v);t.setLayout({x:e.x,y:e.y,rawX:m,rawY:v},!0)});else{var y=t.getOrient();"RL"===y||"LR"===y?(g=a/(h.getLayout().x+d+f),p=o/(c.depth-1||1),rd(l,function(t){v=(t.getLayout().x+f)*g,m="LR"===y?(t.depth-1)*p:o-(t.depth-1)*p,t.setLayout({x:m,y:v},!0)})):"TB"!==y&&"BT"!==y||(p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),rd(l,function(t){m=(t.getLayout().x+f)*p,v="TB"===y?(t.depth-1)*g:a-(t.depth-1)*g,t.setLayout({x:m,y:v},!0)}))}}}function ld(t,e,i){if(t&&l(e,t.type)>=0){var n=i.getData().tree.root,o=t.targetNode;if("string"==typeof o&&(o=n.getNodeById(o)),o&&n.contains(o))return{node:o};var a=t.targetNodeId;if(null!=a&&(o=n.getNodeById(a)))return{node:o}}}function ud(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function hd(t,e){return l(ud(t),e)>=0}function cd(t,e){for(var i=[];t;){var n=t.dataIndex;i.push({name:t.name,dataIndex:n,value:e.getRawValue(n)}),t=t.parentNode}return i.reverse(),i}function dd(t){var e=0;d(t.children,function(t){dd(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function fd(t,e){var i=e.get("color");if(i){var n;return d(t=t||[],function(t){var e=new No(t),i=e.get("color");(e.get("itemStyle.color")||i&&"none"!==i)&&(n=!0)}),n||((t[0]||(t[0]={})).color=i.slice()),t}}function pd(t){this.group=new tb,t.add(this.group)}function gd(t,e,i,n,o,a){var r=[[o?t:t-UC,e],[t+i,e],[t+i,e+n],[o?t:t-UC,e+n]];return!a&&r.splice(2,0,[t+i+UC,e+n/2]),!o&&r.push([t,e+n/2]),r}function md(t,e,i){t.eventData={componentType:"series",componentSubType:"treemap",componentIndex:e.componentIndex,seriesIndex:e.componentIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:i&&i.dataIndex,name:i&&i.name},treePathInfo:i&&cd(i,e)}}function vd(){var t,e=[],i={};return{add:function(t,n,o,a,r){return _(a)&&(r=a,a=0),!i[t.id]&&(i[t.id]=1,e.push({el:t,target:n,time:o,delay:a,easing:r}),!0)},done:function(e){return t=e,this},start:function(){for(var n=e.length,o=0,a=e.length;o=0;a--)null==i[a]&&(delete n[e[a]],e.pop())}function bd(t,e){var i=t.visual,n=[];w(i)?sL(i,function(t){n.push(t)}):null!=i&&n.push(i);var o={color:1,symbol:1};e||1!==n.length||o.hasOwnProperty(t.type)||(n[1]=n[0]),Ld(t,n)}function Sd(t){return{applyVisual:function(e,i,n){e=this.mapValueToVisual(e),n("color",t(i("color"),e))},_doMap:Dd([0,1])}}function Md(t){var e=this.option.visual;return e[Math.round(Bo(t,[0,1],[0,e.length-1],!0))]||{}}function Id(t){return function(e,i,n){n(t,this.mapValueToVisual(e))}}function Td(t){var e=this.option.visual;return e[this.option.loop&&t!==uL?t%e.length:t]}function Ad(){return this.option.visual[0]}function Dd(t){return{linear:function(e){return Bo(e,t,this.option.visual,!0)},category:Td,piecewise:function(e,i){var n=Cd.call(this,i);return null==n&&(n=Bo(e,t,this.option.visual,!0)),n},fixed:Ad}}function Cd(t){var e=this.option,i=e.pieceList;if(e.hasSpecialVisual){var n=i[hL.findPieceIndex(t,i)];if(n&&n.visual)return n.visual[this.type]}}function Ld(t,e){return t.visual=e,"color"===t.type&&(t.parsedVisual=f(e,function(t){return Gt(t)})),e}function kd(t,e,i){return t?e<=i:e=o.length||t===o[t.depth])&&Pd(t,Vd(r,h,t,e,g,a),i,n,o,a)})}else l=Od(h),t.setVisual("color",l)}}function Nd(t,e,i,n){var o=a({},e);return d(["color","colorAlpha","colorSaturation"],function(a){var r=t.get(a,!0);null==r&&i&&(r=i[a]),null==r&&(r=e[a]),null==r&&(r=n.get(a)),null!=r&&(o[a]=r)}),o}function Od(t){var e=Rd(t,"color");if(e){var i=Rd(t,"colorAlpha"),n=Rd(t,"colorSaturation");return n&&(e=jt(e,null,null,n)),i&&(e=Yt(e,i)),e}}function Ed(t,e){return null!=e?jt(e,null,null,t):null}function Rd(t,e){var i=t[e];if(null!=i&&"none"!==i)return i}function zd(t,e,i,n,o,a){if(a&&a.length){var r=Bd(e,"color")||null!=o.color&&"none"!==o.color&&(Bd(e,"colorAlpha")||Bd(e,"colorSaturation"));if(r){var s=e.get("visualMin"),l=e.get("visualMax"),u=i.dataExtent.slice();null!=s&&su[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:r.name,dataExtent:u,visual:r.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var d=new hL(c);return d.__drColorMappingBy=h,d}}}function Bd(t,e){var i=t.get(e);return fL(i)&&i.length?{name:e,range:i}:null}function Vd(t,e,i,n,o,r){var s=a({},e);if(o){var l=o.type,u="color"===l&&o.__drColorMappingBy,h="index"===u?n:"id"===u?r.mapIdToIndex(i.getId()):i.getValue(t.get("visualDimension"));s[l]=o.mapValueToVisual(h)}return s}function Gd(t,e,i,n){var o,a;if(!t.isRemoved()){var r=t.getLayout();o=r.width,a=r.height;var s=(f=t.getModel()).get(_L),l=f.get(wL)/2,u=Kd(f),h=Math.max(s,u),c=s-l,d=h-l,f=t.getModel();t.setLayout({borderWidth:s,upperHeight:h,upperLabelHeight:u},!0);var p=(o=mL(o-2*c,0))*(a=mL(a-c-d,0)),g=Fd(t,f,p,e,i,n);if(g.length){var m={x:c,y:d,width:o,height:a},v=vL(o,a),y=1/0,x=[];x.area=0;for(var _=0,w=g.length;_=0;l--){var u=o["asc"===n?r-l-1:l].getValue();u/i*es[1]&&(s[1]=e)})}else s=[NaN,NaN];return{sum:n,dataExtent:s}}function Ud(t,e,i){for(var n,o=0,a=1/0,r=0,s=t.length;ro&&(o=n));var l=t.area*t.area,u=e*e*i;return l?mL(u*o/l,l/(u*a)):1/0}function Xd(t,e,i,n,o){var a=e===i.width?0:1,r=1-a,s=["x","y"],l=["width","height"],u=i[s[a]],h=e?t.area/e:0;(o||h>i[l[r]])&&(h=i[l[r]]);for(var c=0,d=t.length;cXM&&(u=XM),a=s}u=0?n+=u:n-=u:p>=0?n-=u:n+=u}return n}function pf(t,e){return t.getVisual("opacity")||t.getModel().get(e)}function gf(t,e,i){var n=t.getGraphicEl(),o=pf(t,e);null!=i&&(null==o&&(o=1),o*=i),n.downplay&&n.downplay(),n.traverse(function(t){if("group"!==t.type){var e=t.lineLabelOriginalOpacity;null!=e&&null==i||(e=o),t.setStyle("opacity",e)}})}function mf(t,e){var i=pf(t,e),n=t.getGraphicEl();n.highlight&&n.highlight(),n.traverse(function(t){"group"!==t.type&&t.setStyle("opacity",i)})}function vf(t){return t instanceof Array||(t=[t,t]),t}function yf(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=t.getGraph();i.eachNode(function(t){var e=t.getModel();t.setLayout([+e.get("x"),+e.get("y")])}),xf(i)}}function xf(t){t.eachEdge(function(t){var e=t.getModel().get("lineStyle.curveness")||0,i=F(t.node1.getLayout()),n=F(t.node2.getLayout()),o=[i,n];+e&&o.push([(i[0]+n[0])/2-(i[1]-n[1])*e,(i[1]+n[1])/2-(n[0]-i[0])*e]),t.setLayout(o)})}function _f(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=e.getBoundingRect(),n=t.getData(),o=n.graph,a=0,r=n.getSum("value"),s=2*Math.PI/(r||n.count()),l=i.width/2+i.x,u=i.height/2+i.y,h=Math.min(i.width,i.height)/2;o.eachNode(function(t){var e=t.getValue("value");a+=s*(r?e:1)/2,t.setLayout([h*Math.cos(a)+l,h*Math.sin(a)+u]),a+=s*(r?e:1)/2}),n.setLayout({cx:l,cy:u}),o.eachEdge(function(t){var e,i=t.getModel().get("lineStyle.curveness")||0,n=F(t.node1.getLayout()),o=F(t.node2.getLayout()),a=(n[0]+o[0])/2,r=(n[1]+o[1])/2;+i&&(e=[l*(i*=3)+a*(1-i),u*i+r*(1-i)]),t.setLayout([n,o,e])})}}function wf(t,e,i){for(var n=i.rect,o=n.width,a=n.height,r=[n.x+o/2,n.y+a/2],s=null==i.gravity?.1:i.gravity,l=0;l0?-1:i<0?1:e?-1:1}}function Pf(t,e){return Math.min(e[1],Math.max(e[0],t))}function Nf(t,e,i){this._axesMap=R(),this._axesLayout={},this.dimensions=t.dimensions,this._rect,this._model=t,this._init(t,e,i)}function Of(t,e){return ek(ik(t,e[0]),e[1])}function Ef(t,e){var i=e.layoutLength/(e.axisCount-1);return{position:i*t,axisNameAvailableWidth:i,axisLabelShow:!0}}function Rf(t,e){var i,n,o=e.layoutLength,a=e.axisExpandWidth,r=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return tmk}function $f(t){var e=t.length-1;return e<0&&(e=0),[t[0],t[e]]}function Jf(t,e,i,n){var o=new tb;return o.add(new yM({name:"main",style:ip(i),silent:!0,draggable:!0,cursor:"move",drift:uk(t,e,o,"nswe"),ondragend:uk(qf,e,{isEnd:!0})})),hk(n,function(i){o.add(new yM({name:i,style:{opacity:0},draggable:!0,silent:!0,invisible:!0,drift:uk(t,e,o,i),ondragend:uk(qf,e,{isEnd:!0})}))}),o}function Qf(t,e,i,n){var o=n.brushStyle.lineWidth||0,a=fk(o,vk),r=i[0][0],s=i[1][0],l=r-o/2,u=s-o/2,h=i[0][1],c=i[1][1],d=h-a+o/2,f=c-a+o/2,p=h-r,g=c-s,m=p+o,v=g+o;ep(t,e,"main",r,s,p,g),n.transformable&&(ep(t,e,"w",l,u,a,v),ep(t,e,"e",d,u,a,v),ep(t,e,"n",l,u,m,a),ep(t,e,"s",l,f,m,a),ep(t,e,"nw",l,u,a,a),ep(t,e,"ne",d,u,a,a),ep(t,e,"sw",l,f,a,a),ep(t,e,"se",d,f,a,a))}function tp(t,e){var i=e.__brushOption,n=i.transformable,o=e.childAt(0);o.useStyle(ip(i)),o.attr({silent:!n,cursor:n?"move":"default"}),hk(["w","e","n","s","se","sw","ne","nw"],function(i){var o=e.childOfName(i),a=ap(t,i);o&&o.attr({silent:!n,invisible:!n,cursor:n?_k[a]+"-resize":null})})}function ep(t,e,i,n,o,a,r){var s=e.childOfName(i);s&&s.setShape(hp(up(t,e,[[n,o],[n+a,o+r]])))}function ip(t){return r({strokeNoScale:!0},t.brushStyle)}function np(t,e,i,n){var o=[dk(t,i),dk(e,n)],a=[fk(t,i),fk(e,n)];return[[o[0],a[0]],[o[1],a[1]]]}function op(t){return Ao(t.group)}function ap(t,e){if(e.length>1)return("e"===(n=[ap(t,(e=e.split(""))[0]),ap(t,e[1])])[0]||"w"===n[0])&&n.reverse(),n.join("");var i={left:"w",right:"e",top:"n",bottom:"s"},n=Co({w:"left",e:"right",n:"top",s:"bottom"}[e],op(t));return i[n]}function rp(t,e,i,n,o,a,r,s){var l=n.__brushOption,u=t(l.range),h=lp(i,a,r);hk(o.split(""),function(t){var e=xk[t];u[e[0]][e[1]]+=h[e[0]]}),l.range=e(np(u[0][0],u[1][0],u[0][1],u[1][1])),Zf(i,n),qf(i,{isEnd:!1})}function sp(t,e,i,n,o){var a=e.__brushOption.range,r=lp(t,i,n);hk(a,function(t){t[0]+=r[0],t[1]+=r[1]}),Zf(t,e),qf(t,{isEnd:!1})}function lp(t,e,i){var n=t.group,o=n.transformCoordToLocal(e,i),a=n.transformCoordToLocal(0,0);return[o[0]-a[0],o[1]-a[1]]}function up(t,e,n){var o=jf(t,e);return o&&!0!==o?o.clipPath(n,t._transform):i(n)}function hp(t){var e=dk(t[0][0],t[1][0]),i=dk(t[0][1],t[1][1]);return{x:e,y:i,width:fk(t[0][0],t[1][0])-e,height:fk(t[0][1],t[1][1])-i}}function cp(t,e,i){if(t._brushType){var n=t._zr,o=t._covers,a=Xf(t,e,i);if(!t._dragging)for(var r=0;r0;a--)Yp(s,l*=.99,r),jp(s,o,i,n,r),tg(s,l,r),jp(s,o,i,n,r)}function Up(t,e){var i=[],n="vertical"===e?"y":"x",o=Zi(t,function(t){return t.getLayout()[n]});return o.keys.sort(function(t,e){return t-e}),d(o.keys,function(t){i.push(o.buckets.get(t))}),i}function Xp(t,e,i,n,o,a,r){var s=[];d(e,function(t){var e=t.length,i=0,l=0;d(t,function(t){i+=t.getLayout().value}),l="vertical"===r?(o-(e-1)*a)/i:(n-(e-1)*a)/i,s.push(l)}),s.sort(function(t,e){return t-e});var l=s[0];d(e,function(t){d(t,function(t,e){var i=t.getLayout().value*l;"vertical"===r?(t.setLayout({x:e},!0),t.setLayout({dx:i},!0)):(t.setLayout({y:e},!0),t.setLayout({dy:i},!0))})}),d(i,function(t){var e=+t.getValue()*l;t.setLayout({dy:e},!0)})}function jp(t,e,i,n,o){d(t,function(t){var a,r,s,l=0,u=t.length;if("vertical"===o){var h;for(t.sort(function(t,e){return t.getLayout().x-e.getLayout().x}),s=0;s0&&(h=a.getLayout().x+r,a.setLayout({x:h},!0)),l=a.getLayout().x+a.getLayout().dx+e;if((r=l-e-n)>0)for(h=a.getLayout().x-r,a.setLayout({x:h},!0),l=h,s=u-2;s>=0;--s)(r=(a=t[s]).getLayout().x+a.getLayout().dx+e-l)>0&&(h=a.getLayout().x-r,a.setLayout({x:h},!0)),l=a.getLayout().x}else{var c;for(t.sort(function(t,e){return t.getLayout().y-e.getLayout().y}),s=0;s0&&(c=a.getLayout().y+r,a.setLayout({y:c},!0)),l=a.getLayout().y+a.getLayout().dy+e;if((r=l-e-i)>0)for(c=a.getLayout().y-r,a.setLayout({y:c},!0),l=c,s=u-2;s>=0;--s)(r=(a=t[s]).getLayout().y+a.getLayout().dy+e-l)>0&&(c=a.getLayout().y-r,a.setLayout({y:c},!0)),l=a.getLayout().y}})}function Yp(t,e,i){d(t.slice().reverse(),function(t){d(t,function(t){if(t.outEdges.length){var n=Qp(t.outEdges,qp,i)/Qp(t.outEdges,Jp,i);if("vertical"===i){var o=t.getLayout().x+(n-$p(t,i))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(n-$p(t,i))*e;t.setLayout({y:a},!0)}}})})}function qp(t,e){return $p(t.node2,e)*t.getValue()}function Kp(t,e){return $p(t.node1,e)*t.getValue()}function $p(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function Jp(t){return t.getValue()}function Qp(t,e,i){for(var n=0,o=t.length,a=-1;++a0?"P":"N",a=n.getVisual("borderColor"+o)||n.getVisual("color"+o),r=i.getModel(Gk).getItemStyle(Wk);e.useStyle(r),e.style.fill=null,e.style.stroke=a}function fg(t,e,i,n,o){return i>n?-1:i0?t.get(o,e-1)<=n?1:-1:1}function pg(t,e){var i,n=t.getBaseAxis(),o="category"===n.type?n.getBandWidth():(i=n.getExtent(),Math.abs(i[1]-i[0])/e.count()),a=Vo(A(t.get("barMaxWidth"),o),o),r=Vo(A(t.get("barMinWidth"),1),o),s=t.get("barWidth");return null!=s?Vo(s,o):Math.max(Math.min(o/2,a),r)}function gg(t){return y(t)||(t=[+t,+t]),t}function mg(t,e){t.eachChild(function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?e.color:null,fill:"fill"===e.brushType?e.color:null}})})}function vg(t,e){tb.call(this);var i=new wu(t,e),n=new tb;this.add(i),this.add(n),n.beforeUpdate=function(){this.attr(i.getScale())},this.updateData(t,e)}function yg(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=f(e,function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),o([e,t[0],t[1]])}))}function xg(t,e,i){tb.call(this),this.add(this.createLine(t,e,i)),this._updateEffectSymbol(t,e)}function _g(t,e,i){tb.call(this),this._createPolyline(t,e,i)}function wg(t,e,i){xg.call(this,t,e,i),this._lastFrame=0,this._lastFramePercent=0}function bg(){this.group=new tb}function Sg(t){return t instanceof Array||(t=[t,t]),t}function Mg(){var t=iw();this.canvas=t,this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={}}function Ig(t,e,i){var n=t[1]-t[0],o=(e=f(e,function(e){return{interval:[(e.interval[0]-t[0])/n,(e.interval[1]-t[0])/n]}})).length,a=0;return function(t){for(n=a;n=0;n--){var r=e[n].interval;if(r[0]<=t&&t<=r[1]){a=n;break}}return n>=0&&n=e[0]&&t<=e[1]}}function Ag(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}function Dg(t,e,i,n){var o=t.getItemLayout(e),a=i.get("symbolRepeat"),r=i.get("symbolClip"),s=i.get("symbolPosition")||"start",l=(i.get("symbolRotate")||0)*Math.PI/180||0,u=i.get("symbolPatternSize")||2,h=i.isAnimationEnabled(),c={dataIndex:e,layout:o,itemModel:i,symbolType:t.getItemVisual(e,"symbol")||"circle",color:t.getItemVisual(e,"color"),symbolClip:r,symbolRepeat:a,symbolRepeatDirection:i.get("symbolRepeatDirection"),symbolPatternSize:u,rotation:l,animationModel:h?i:null,hoverAnimation:h&&i.get("hoverAnimation"),z2:i.getShallow("z",!0)||0};Cg(i,a,o,n,c),kg(t,e,o,a,r,c.boundingLength,c.pxSign,u,n,c),Pg(i,c.symbolScale,l,n,c);var d=c.symbolSize,f=i.get("symbolOffset");return y(f)&&(f=[Vo(f[0],d[0]),Vo(f[1],d[1])]),Ng(i,d,o,a,r,f,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,n,c),c}function Cg(t,e,i,n,o){var a,r=n.valueDim,s=t.get("symbolBoundingData"),l=n.coordSys.getOtherAxis(n.coordSys.getBaseAxis()),u=l.toGlobalCoord(l.dataToCoord(0)),h=1-+(i[r.wh]<=0);if(y(s)){var c=[Lg(l,s[0])-u,Lg(l,s[1])-u];c[1]0?1:a<0?-1:0}function Lg(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function kg(t,e,i,n,o,a,r,s,l,u){var h=l.valueDim,c=l.categoryDim,d=Math.abs(i[c.wh]),f=t.getItemVisual(e,"symbolSize");y(f)?f=f.slice():(null==f&&(f="100%"),f=[f,f]),f[c.index]=Vo(f[c.index],d),f[h.index]=Vo(f[h.index],n?d:Math.abs(a)),u.symbolSize=f,(u.symbolScale=[f[0]/s,f[1]/s])[h.index]*=(l.isHorizontal?-1:1)*r}function Pg(t,e,i,n,o){var a=t.get(cP)||0;a&&(fP.attr({scale:e.slice(),rotation:i}),fP.updateTransform(),a/=fP.getLineScale(),a*=e[n.valueDim.index]),o.valueLineWidth=a}function Ng(t,e,i,n,o,r,s,l,u,h,c,d){var f=c.categoryDim,p=c.valueDim,g=d.pxSign,m=Math.max(e[p.index]+l,0),v=m;if(n){var y=Math.abs(u),x=T(t.get("symbolMargin"),"15%")+"",_=!1;x.lastIndexOf("!")===x.length-1&&(_=!0,x=x.slice(0,x.length-1)),x=Vo(x,e[p.index]);var w=Math.max(m+2*x,0),b=_?0:2*x,S=Qo(n),M=S?n:Kg((y+b)/w);w=m+2*(x=(y-M*m)/2/(_?M:M-1)),b=_?0:2*x,S||"fixed"===n||(M=h?Kg((Math.abs(h)+b)/w):0),v=M*w-b,d.repeatTimes=M,d.symbolMargin=x}var I=g*(v/2),A=d.pathPosition=[];A[f.index]=i[f.wh]/2,A[p.index]="start"===s?I:"end"===s?u-I:u/2,r&&(A[0]+=r[0],A[1]+=r[1]);var D=d.bundlePosition=[];D[f.index]=i[f.xy],D[p.index]=i[p.xy];var C=d.barRectShape=a({},i);C[p.wh]=g*Math.max(Math.abs(i[p.wh]),Math.abs(A[p.index]+I)),C[f.wh]=i[f.wh];var L=d.clipShape={};L[f.xy]=-i[f.xy],L[f.wh]=c.ecSize[f.wh],L[p.xy]=0,L[p.wh]=i[p.wh]}function Og(t){var e=t.symbolPatternSize,i=Jl(t.symbolType,-e/2,-e/2,e,e,t.color);return i.attr({culling:!0}),"image"!==i.type&&i.setStyle({strokeNoScale:!0}),i}function Eg(t,e,i,n){function o(t){var e=l.slice(),n=i.pxSign,o=t;return("start"===i.symbolRepeatDirection?n>0:n<0)&&(o=h-1-t),e[u.index]=d*(o-h/2+.5)+l[u.index],{position:e,scale:i.symbolScale.slice(),rotation:i.rotation}}var a=t.__pictorialBundle,r=i.symbolSize,s=i.valueLineWidth,l=i.pathPosition,u=e.valueDim,h=i.repeatTimes||0,c=0,d=r[e.valueDim.index]+s+2*i.symbolMargin;for(jg(t,function(t){t.__pictorialAnimationIndex=c,t.__pictorialRepeatTimes=h,c0)],d=t.__pictorialBarRect;kh(d.style,h,a,n,e.seriesModel,o,c),fo(d,h)}function Kg(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}function $g(t,e,i){this.dimension="single",this.dimensions=["single"],this._axis=null,this._rect,this._init(t,e,i),this.model=t}function Jg(t,e){e=e||{};var i=t.coordinateSystem,n=t.axis,o={},a=n.position,r=n.orient,s=i.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};o.position=["vertical"===r?u.vertical[a]:l[0],"horizontal"===r?u.horizontal[a]:l[3]];var h={horizontal:0,vertical:1};o.rotation=Math.PI/2*h[r];var c={top:-1,bottom:1,right:1,left:-1};o.labelDirection=o.tickDirection=o.nameDirection=c[a],t.get("axisTick.inside")&&(o.tickDirection=-o.tickDirection),T(e.labelInside,t.get("axisLabel.inside"))&&(o.labelDirection=-o.labelDirection);var d=e.rotate;return null==d&&(d=t.get("axisLabel.rotate")),o.labelRotation="top"===a?-d:d,o.z2=1,o}function Qg(t,e,i,n,o){var r=t.axis;if(!r.scale.isBlank()&&r.containData(e))if(t.involveSeries){var s=tm(e,t),l=s.payloadBatch,u=s.snapToValue;l[0]&&null==o.seriesIndex&&a(o,l[0]),!n&&t.snap&&r.containData(u)&&null!=u&&(e=u),i.showPointer(t,e,l,o),i.showTooltip(t,s,u)}else i.showPointer(t,e)}function tm(t,e){var i=e.axis,n=i.dim,o=t,a=[],r=Number.MAX_VALUE,s=-1;return _P(e.seriesModels,function(e,l){var u,h,c=e.getData().mapDimension(n,!0);if(e.getAxisTooltipData){var d=e.getAxisTooltipData(c,t,i);h=d.dataIndices,u=d.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===i.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var f=t-u,p=Math.abs(f);p<=r&&((p=0&&s<0)&&(r=p,s=f,o=u,a.length=0),_P(h,function(t){a.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})}))}}),{payloadBatch:a,snapToValue:o}}function em(t,e,i,n){t[e.key]={value:i,payloadBatch:n}}function im(t,e,i,n){var o=i.payloadBatch,a=e.axis,r=a.model,s=e.axisPointerModel;if(e.triggerTooltip&&o.length){var l=e.coordSys.model,u=Ah(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:a.dim,axisIndex:r.componentIndex,axisType:r.type,axisId:r.id,value:n,valueLabelOpt:{precision:s.get("label.precision"),formatter:s.get("label.formatter")},seriesDataIndices:o.slice()})}}function nm(t,e,i){var n=i.axesInfo=[];_P(e,function(e,i){var o=e.axisPointerModel.option,a=t[i];a?(!e.useHandle&&(o.status="show"),o.value=a.value,o.seriesDataIndices=(a.payloadBatch||[]).slice()):!e.useHandle&&(o.status="hide"),"show"===o.status&&n.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:o.value})})}function om(t,e,i,n){if(!lm(e)&&t.list.length){var o=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};n({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:i.tooltipOption,position:i.position,dataIndexInside:o.dataIndexInside,dataIndex:o.dataIndex,seriesIndex:o.seriesIndex,dataByCoordSys:t.list})}else n({type:"hideTip"})}function am(t,e,i){var n=i.getZr(),o=bP(n).axisPointerLastHighlights||{},a=bP(n).axisPointerLastHighlights={};_P(t,function(t,e){var i=t.axisPointerModel.option;"show"===i.status&&_P(i.seriesDataIndices,function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t})});var r=[],s=[];d(o,function(t,e){!a[e]&&s.push(t)}),d(a,function(t,e){!o[e]&&r.push(t)}),s.length&&i.dispatchAction({type:"downplay",escapeConnect:!0,batch:s}),r.length&&i.dispatchAction({type:"highlight",escapeConnect:!0,batch:r})}function rm(t,e){for(var i=0;i<(t||[]).length;i++){var n=t[i];if(e.axis.dim===n.axisDim&&e.axis.model.componentIndex===n.axisIndex)return n}}function sm(t){var e=t.axis.model,i={},n=i.axisDim=t.axis.dim;return i.axisIndex=i[n+"AxisIndex"]=e.componentIndex,i.axisName=i[n+"AxisName"]=e.name,i.axisId=i[n+"AxisId"]=e.id,i}function lm(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function um(t,e,i){if(!U_.node){var n=e.getZr();SP(n).records||(SP(n).records={}),hm(n,e),(SP(n).records[t]||(SP(n).records[t]={})).handler=i}}function hm(t,e){function i(i,n){t.on(i,function(i){var o=pm(e);MP(SP(t).records,function(t){t&&n(t,i,o.dispatchAction)}),cm(o.pendings,e)})}SP(t).initialized||(SP(t).initialized=!0,i("click",v(fm,"click")),i("mousemove",v(fm,"mousemove")),i("globalout",dm))}function cm(t,e){var i,n=t.showTip.length,o=t.hideTip.length;n?i=t.showTip[n-1]:o&&(i=t.hideTip[o-1]),i&&(i.dispatchAction=null,e.dispatchAction(i))}function dm(t,e,i){t.handler("leave",null,i)}function fm(t,e,i,n){e.handler(t,i,n)}function pm(t){var e={showTip:[],hideTip:[]},i=function(n){var o=e[n.type];o?o.push(n):(n.dispatchAction=i,t.dispatchAction(n))};return{dispatchAction:i,pendings:e}}function gm(t,e){if(!U_.node){var i=e.getZr();(SP(i).records||{})[t]&&(SP(i).records[t]=null)}}function mm(){}function vm(t,e,i,n){ym(TP(i).lastProp,n)||(TP(i).lastProp=n,e?Io(i,n,t):(i.stopAnimation(),i.attr(n)))}function ym(t,e){if(w(t)&&w(e)){var i=!0;return d(e,function(e,n){i=i&&ym(t[n],e)}),!!i}return t===e}function xm(t,e){t[e.get("label.show")?"show":"hide"]()}function _m(t){return{position:t.position.slice(),rotation:t.rotation||0}}function wm(t,e,i){var n=e.get("z"),o=e.get("zlevel");t&&t.traverse(function(t){"group"!==t.type&&(null!=n&&(t.z=n),null!=o&&(t.zlevel=o),t.silent=i)})}function bm(t){var e,i=t.get("type"),n=t.getModel(i+"Style");return"line"===i?(e=n.getLineStyle()).fill=null:"shadow"===i&&((e=n.getAreaStyle()).stroke=null),e}function Sm(t,e,i,n,o){var a=Im(i.get("value"),e.axis,e.ecModel,i.get("seriesDataIndices"),{precision:i.get("label.precision"),formatter:i.get("label.formatter")}),r=i.getModel("label"),s=qM(r.get("padding")||0),l=r.getFont(),u=ke(a,l),h=o.position,c=u.width+s[1]+s[3],d=u.height+s[0]+s[2],f=o.align;"right"===f&&(h[0]-=c),"center"===f&&(h[0]-=c/2);var p=o.verticalAlign;"bottom"===p&&(h[1]-=d),"middle"===p&&(h[1]-=d/2),Mm(h,c,d,n);var g=r.get("backgroundColor");g&&"auto"!==g||(g=e.get("axisLine.lineStyle.color")),t.label={shape:{x:0,y:0,width:c,height:d,r:r.get("borderRadius")},position:h.slice(),style:{text:a,textFont:l,textFill:r.getTextColor(),textPosition:"inside",fill:g,stroke:r.get("borderColor")||"transparent",lineWidth:r.get("borderWidth")||0,shadowBlur:r.get("shadowBlur"),shadowColor:r.get("shadowColor"),shadowOffsetX:r.get("shadowOffsetX"),shadowOffsetY:r.get("shadowOffsetY")},z2:10}}function Mm(t,e,i,n){var o=n.getWidth(),a=n.getHeight();t[0]=Math.min(t[0]+e,o)-e,t[1]=Math.min(t[1]+i,a)-i,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}function Im(t,e,i,n,o){t=e.scale.parse(t);var a=e.scale.getLabel(t,{precision:o.precision}),r=o.formatter;if(r){var s={value:Xl(e,t),seriesData:[]};d(n,function(t){var e=i.getSeriesByIndex(t.seriesIndex),n=t.dataIndexInside,o=e&&e.getDataParams(n);o&&s.seriesData.push(o)}),_(r)?a=r.replace("{value}",a):x(r)&&(a=r(s))}return a}function Tm(t,e,i){var n=xt();return Mt(n,n,i.rotation),St(n,n,i.position),Do([t.dataToCoord(e),(i.labelOffset||0)+(i.labelDirection||1)*(i.labelMargin||0)],n)}function Am(t,e,i,n,o,a){var r=FD.innerTextLayout(i.rotation,0,i.labelDirection);i.labelMargin=o.get("label.margin"),Sm(e,n,o,a,{position:Tm(n.axis,t,i),align:r.textAlign,verticalAlign:r.textVerticalAlign})}function Dm(t,e,i){return i=i||0,{x1:t[i],y1:t[1-i],x2:e[i],y2:e[1-i]}}function Cm(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}function Lm(t,e,i,n,o,a){return{cx:t,cy:e,r0:i,r:n,startAngle:o,endAngle:a,clockwise:!0}}function km(t,e){var i={};return i[e.dim+"AxisIndex"]=e.index,t.getCartesian(i)}function Pm(t){return"x"===t.dim?0:1}function Nm(t){return t.isHorizontal()?0:1}function Om(t,e){var i=t.getRect();return[i[kP[e]],i[kP[e]]+i[PP[e]]]}function Em(t,e,i){var n=new yM({shape:{x:t.x-10,y:t.y-10,width:0,height:t.height+20}});return To(n,{shape:{width:t.width+20,height:t.height+20}},e,i),n}function Rm(t,e,i){if(t.count())for(var n,o=e.coordinateSystem,a=e.getLayerSeries(),r=t.mapDimension("single"),s=t.mapDimension("value"),l=f(a,function(e){return f(e.indices,function(e){var i=o.dataToPoint(t.get(r,e));return i[1]=t.get(s,e),i})}),u=zm(l),h=u.y0,c=i/u.max,d=a.length,p=a[0].indices.length,g=0;ga&&(a=u),n.push(u)}for(var h=0;ha&&(a=d)}return r.y0=o,r.max=a,r}function Bm(t){var e=0;d(t.children,function(t){Bm(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function Vm(t,e,i){function n(){r.ignore=r.hoverIgnore}function o(){r.ignore=r.normalIgnore}tb.call(this);var a=new hM({z2:zP});a.seriesIndex=e.seriesIndex;var r=new rM({z2:BP,silent:t.getModel("label").get("silent")});this.add(a),this.add(r),this.updateData(!0,t,"normal",e,i),this.on("emphasis",n).on("normal",o).on("mouseover",n).on("mouseout",o)}function Gm(t,e,i){var n=t.getVisual("color"),o=t.getVisual("visualMeta");o&&0!==o.length||(n=null);var a=t.getModel("itemStyle").get("color");if(a)return a;if(n)return n;if(0===t.depth)return i.option.color[0];var r=i.option.color.length;return a=i.option.color[Fm(t)%r]}function Fm(t){for(var e=t;e.depth>1;)e=e.parentNode;return l(t.getAncestors()[0].children,e)}function Wm(t,e,i){return i!==RP.NONE&&(i===RP.SELF?t===e:i===RP.ANCESTOR?t===e||t.isAncestorOf(e):t===e||t.isDescendantOf(e))}function Hm(t,e,i){e.getData().setItemVisual(t.dataIndex,"color",i)}function Zm(t,e){var i=t.children||[];t.children=Um(i,e),i.length&&d(t.children,function(t){Zm(t,e)})}function Um(t,e){if("function"==typeof e)return t.sort(e);var i="asc"===e;return t.sort(function(t,e){var n=(t.getValue()-e.getValue())*(i?1:-1);return 0===n?(t.dataIndex-e.dataIndex)*(i?-1:1):n})}function Xm(t,e){return e=e||[0,0],f(["x","y"],function(i,n){var o=this.getAxis(i),a=e[n],r=t[n]/2;return"category"===o.type?o.getBandWidth():Math.abs(o.dataToCoord(a-r)-o.dataToCoord(a+r))},this)}function jm(t,e){return e=e||[0,0],f([0,1],function(i){var n=e[i],o=t[i]/2,a=[],r=[];return a[i]=n-o,r[i]=n+o,a[1-i]=r[1-i]=e[1-i],Math.abs(this.dataToPoint(a)[i]-this.dataToPoint(r)[i])},this)}function Ym(t,e){var i=this.getAxis(),n=e instanceof Array?e[0]:e,o=(t instanceof Array?t[0]:t)/2;return"category"===i.type?i.getBandWidth():Math.abs(i.dataToCoord(n-o)-i.dataToCoord(n+o))}function qm(t,e){return f(["Radius","Angle"],function(i,n){var o=this["get"+i+"Axis"](),a=e[n],r=t[n]/2,s="dataTo"+i,l="category"===o.type?o.getBandWidth():Math.abs(o[s](a-r)-o[s](a+r));return"Angle"===i&&(l=l*Math.PI/180),l},this)}function Km(t){var e,i=t.type;if("path"===i){var n=t.shape,o=null!=n.width&&null!=n.height?{x:n.x||0,y:n.y||0,width:n.width,height:n.height}:null,a=lv(n);(e=Xn(a,null,o,n.layout||"center")).__customPathData=a}else"image"===i?(e=new fi({})).__customImagePath=t.style.image:"text"===i?(e=new rM({})).__customText=t.style.text:e=new(0,zM[i.charAt(0).toUpperCase()+i.slice(1)]);return e.__customGraphicType=i,e.name=t.name,e}function $m(t,e,n,o,a,r,s){var l={},u=n.style||{};if(n.shape&&(l.shape=i(n.shape)),n.position&&(l.position=n.position.slice()),n.scale&&(l.scale=n.scale.slice()),n.origin&&(l.origin=n.origin.slice()),n.rotation&&(l.rotation=n.rotation),"image"===t.type&&n.style){h=l.style={};d(["x","y","width","height"],function(e){Jm(e,h,u,t.style,r)})}if("text"===t.type&&n.style){var h=l.style={};d(["x","y"],function(e){Jm(e,h,u,t.style,r)}),!u.hasOwnProperty("textFill")&&u.fill&&(u.textFill=u.fill),!u.hasOwnProperty("textStroke")&&u.stroke&&(u.textStroke=u.stroke)}if("group"!==t.type&&(t.useStyle(u),r)){t.style.opacity=0;var c=u.opacity;null==c&&(c=1),To(t,{style:{opacity:c}},o,e)}r?t.attr(l):Io(t,l,o,e),n.hasOwnProperty("z2")&&t.attr("z2",n.z2||0),n.hasOwnProperty("silent")&&t.attr("silent",n.silent),n.hasOwnProperty("invisible")&&t.attr("invisible",n.invisible),n.hasOwnProperty("ignore")&&t.attr("ignore",n.ignore),n.hasOwnProperty("info")&&t.attr("info",n.info);var f=n.styleEmphasis,p=!1===f;t.__cusHasEmphStl&&null==f||!t.__cusHasEmphStl&&p||(ro(t,f),t.__cusHasEmphStl=!p),s&&po(t,!p)}function Jm(t,e,i,n,o){null==i[t]||o||(e[t]=i[t],i[t]=n[t])}function Qm(t,e,i,n){function o(t){null==t&&(t=h),v&&(c=e.getItemModel(t),d=c.getModel(UP),f=c.getModel(XP),p=e.getItemVisual(t,"color"),v=!1)}var s=t.get("renderItem"),l=t.coordinateSystem,u={};l&&(u=l.prepareCustoms?l.prepareCustoms():YP[l.type](l));var h,c,d,f,p,g=r({getWidth:n.getWidth,getHeight:n.getHeight,getZr:n.getZr,getDevicePixelRatio:n.getDevicePixelRatio,value:function(t,i){return null==i&&(i=h),e.get(e.getDimension(t||0),i)},style:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(HP).getItemStyle();null!=p&&(r.fill=p);var s=e.getItemVisual(n,"opacity");return null!=s&&(r.opacity=s),mo(r,d,null,{autoColor:p,isRectText:!0}),r.text=d.getShallow("show")?A(t.getFormattedLabel(n,"normal"),_u(e,n)):null,i&&a(r,i),r},styleEmphasis:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(ZP).getItemStyle();return mo(r,f,null,{isRectText:!0},!0),r.text=f.getShallow("show")?D(t.getFormattedLabel(n,"emphasis"),t.getFormattedLabel(n,"normal"),_u(e,n)):null,i&&a(r,i),r},visual:function(t,i){return null==i&&(i=h),e.getItemVisual(i,t)},barLayout:function(t){if(l.getBaseAxis)return Ll(r({axis:l.getBaseAxis()},t),n)},currentSeriesIndices:function(){return i.getCurrentSeriesIndices()},font:function(t){return So(t,i)}},u.api||{}),m={context:{},seriesId:t.id,seriesName:t.name,seriesIndex:t.seriesIndex,coordSys:u.coordSys,dataInsideLength:e.count(),encode:tv(t.getData())},v=!0;return function(t,i){return h=t,v=!0,s&&s(r({dataIndexInside:t,dataIndex:e.getRawIndex(t),actionType:i?i.type:null},m),g)}}function tv(t){var e={};return d(t.dimensions,function(i,n){var o=t.getDimensionInfo(i);if(!o.isExtraCoord){var a=o.coordDim;(e[a]=e[a]||[])[o.coordDimIndex]=n}}),e}function ev(t,e,i,n,o,a){return(t=iv(t,e,i,n,o,a,!0))&&a.setItemGraphicEl(e,t),t}function iv(t,e,i,n,o,a,r){var s=!i,l=(i=i||{}).type,u=i.shape,h=i.style;if(t&&(s||null!=l&&l!==t.__customGraphicType||"path"===l&&uv(u)&&lv(u)!==t.__customPathData||"image"===l&&hv(h,"image")&&h.image!==t.__customImagePath||"text"===l&&hv(u,"text")&&h.text!==t.__customText)&&(o.remove(t),t=null),!s){var c=!t;return!t&&(t=Km(i)),$m(t,e,i,n,a,c,r),"group"===l&&nv(t,e,i,n,a),o.add(t),t}}function nv(t,e,i,n,o){var a=i.children,r=a?a.length:0,s=i.$mergeChildren,l="byName"===s||i.diffChildrenByName,u=!1===s;if(r||l||u)if(l)ov({oldChildren:t.children()||[],newChildren:a||[],dataIndex:e,animatableModel:n,group:t,data:o});else{u&&t.removeAll();for(var h=0;hn?t-=l+a:t+=a),null!=r&&(e+u+r>o?e-=u+r:e+=r),[t,e]}function Ov(t,e,i,n,o){var a=i.getOuterSize(),r=a.width,s=a.height;return t=Math.min(t+r,n)-r,e=Math.min(e+s,o)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function Ev(t,e,i){var n=i[0],o=i[1],a=0,r=0,s=e.width,l=e.height;switch(t){case"inside":a=e.x+s/2-n/2,r=e.y+l/2-o/2;break;case"top":a=e.x+s/2-n/2,r=e.y-o-5;break;case"bottom":a=e.x+s/2-n/2,r=e.y+l+5;break;case"left":a=e.x-n-5,r=e.y+l/2-o/2;break;case"right":a=e.x+s+5,r=e.y+l/2-o/2}return[a,r]}function Rv(t){return"center"===t||"middle"===t}function zv(t){return t.get("stack")||"__ec_stack_"+t.seriesIndex}function Bv(t){return t.dim}function Vv(t,e){var i={};d(t,function(t,e){var n=t.getData(),o=t.coordinateSystem.getBaseAxis(),a=o.getExtent(),r="category"===o.type?o.getBandWidth():Math.abs(a[1]-a[0])/n.count(),s=i[Bv(o)]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},l=s.stacks;i[Bv(o)]=s;var u=zv(t);l[u]||s.autoWidthCount++,l[u]=l[u]||{width:0,maxWidth:0};var h=Vo(t.get("barWidth"),r),c=Vo(t.get("barMaxWidth"),r),d=t.get("barGap"),f=t.get("barCategoryGap");h&&!l[u].width&&(h=Math.min(s.remainedWidth,h),l[u].width=h,s.remainedWidth-=h),c&&(l[u].maxWidth=c),null!=d&&(s.gap=d),null!=f&&(s.categoryGap=f)});var n={};return d(i,function(t,e){n[e]={};var i=t.stacks,o=t.bandWidth,a=Vo(t.categoryGap,o),r=Vo(t.gap,1),s=t.remainedWidth,l=t.autoWidthCount,u=(s-a)/(l+(l-1)*r);u=Math.max(u,0),d(i,function(t,e){var i=t.maxWidth;i&&ie[0]&&(e=e.slice().reverse());var n=t.coordToPoint([e[0],i]),o=t.coordToPoint([e[1],i]);return{x1:n[0],y1:n[1],x2:o[0],y2:o[1]}}function jv(t){return t.getRadiusAxis().inverse?0:1}function Yv(t){var e=t[0],i=t[t.length-1];e&&i&&Math.abs(Math.abs(e.coord-i.coord)-360)<1e-4&&t.pop()}function qv(t,e,i){return{position:[t.cx,t.cy],rotation:i/180*Math.PI,labelDirection:-1,tickDirection:-1,nameDirection:1,labelRotate:e.getModel("axisLabel").get("rotate"),z2:1}}function Kv(t,e,i,n,o){var a=e.axis,r=a.dataToCoord(t),s=n.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=n.getRadiusAxis().getExtent();if("radius"===a.dim){var d=xt();Mt(d,d,s),St(d,d,[n.cx,n.cy]),l=Do([r,-o],d);var f=e.getModel("axisLabel").get("rotate")||0,p=FD.innerTextLayout(s,f*Math.PI/180,-1);u=p.textAlign,h=p.textVerticalAlign}else{var g=c[1];l=n.coordToPoint([g+o,r]);var m=n.cx,v=n.cy;u=Math.abs(l[0]-m)/g<.3?"center":l[0]>m?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}function $v(t,e){e.update="updateView",Es(e,function(e,i){var n={};return i.eachComponent({mainType:"geo",query:e},function(i){i[t](e.name),d(i.coordinateSystem.regions,function(t){n[t.name]=i.isSelected(t.name)||!1})}),{selected:n,name:e.name}})}function Jv(t){var e={};d(t,function(t){e[t]=1}),t.length=0,d(e,function(e,i){t.push(i)})}function Qv(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function ty(t,e,n){function o(){var t=function(){};return t.prototype.__hidden=t.prototype,new t}var a={};return MN(e,function(e){var r=a[e]=o();MN(t[e],function(t,o){if(hL.isValidType(o)){var a={type:o,visual:t};n&&n(a,e),r[o]=new hL(a),"opacity"===o&&((a=i(a)).type="colorAlpha",r.__hidden.__alphaForOpacity=new hL(a))}})}),a}function ey(t,e,n){var o;d(n,function(t){e.hasOwnProperty(t)&&Qv(e[t])&&(o=!0)}),o&&d(n,function(n){e.hasOwnProperty(n)&&Qv(e[n])?t[n]=i(e[n]):delete t[n]})}function iy(t,e,i,n,o,a){function r(t){return i.getItemVisual(h,t)}function s(t,e){i.setItemVisual(h,t,e)}function l(t,l){h=null==a?t:l;var c=i.getRawDataItem(h);if(!c||!1!==c.visualMap)for(var d=n.call(o,t),f=e[d],p=u[d],g=0,m=p.length;g1)return!1;var h=uy(i-t,o-t,n-e,a-e)/l;return!(h<0||h>1)}function ly(t){return t<=1e-6&&t>=-1e-6}function uy(t,e,i,n){return t*n-e*i}function hy(t,e,i){var n=this._targetInfoList=[],o={},a=dy(e,t);TN(PN,function(t,e){(!i||!i.include||AN(i.include,e)>=0)&&t(a,n,o)})}function cy(t){return t[0]>t[1]&&t.reverse(),t}function dy(t,e){return Vi(t,e,{includeMainTypes:LN})}function fy(t,e,i,n){var o=i.getAxis(["x","y"][t]),a=cy(f([0,1],function(t){return e?o.coordToData(o.toLocalCoord(n[t])):o.toGlobalCoord(o.dataToCoord(n[t]))})),r=[];return r[t]=a,r[1-t]=[NaN,NaN],{values:a,xyMinMax:r}}function py(t,e,i,n){return[e[0]-n[t]*i[0],e[1]-n[t]*i[1]]}function gy(t,e){var i=my(t),n=my(e),o=[i[0]/n[0],i[1]/n[1]];return isNaN(o[0])&&(o[0]=1),isNaN(o[1])&&(o[1]=1),o}function my(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}function vy(t,e,i,n,o){if(o){var a=t.getZr();a[VN]||(a[BN]||(a[BN]=yy),Nr(a,BN,i,e)(t,n))}}function yy(t,e){if(!t.isDisposed()){var i=t.getZr();i[VN]=!0,t.dispatchAction({type:"brushSelect",batch:e}),i[VN]=!1}}function xy(t,e,i,n){for(var o=0,a=e.length;o=0}function Ny(t,e,i){function n(t,e){return l(e.nodes,t)>=0}function o(t,n){var o=!1;return e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]&&(o=!0)})}),o}function a(t,n){n.nodes.push(t),e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]=!0})})}return function(i){var r={nodes:[],records:{}};if(e(function(t){r.records[t.name]={}}),!i)return r;a(i,r);var s;do{s=!1,t(function(t){!n(t,r)&&o(t,r)&&(a(t,r),s=!0)})}while(s);return r}}function Oy(t,e,i){var n=[1/0,-1/0];return $N(i,function(t){var i=t.getData();i&&$N(i.mapDimension(e,!0),function(t){var e=i.getApproximateExtent(t);e[0]n[1]&&(n[1]=e[1])})}),n[1]0?0:NaN);var r=i.getMax(!0);return null!=r&&"dataMax"!==r&&"function"!=typeof r?e[1]=r:o&&(e[1]=a>0?a-1:NaN),i.get("scale",!0)||(e[0]>0&&(e[0]=0),e[1]<0&&(e[1]=0)),e}function Ry(t,e){var i=t.getAxisModel(),n=t._percentWindow,o=t._valueWindow;if(n){var a=Zo(o,[0,500]);a=Math.min(a,20);var r=e||0===n[0]&&100===n[1];i.setRange(r?null:+o[0].toFixed(a),r?null:+o[1].toFixed(a))}}function zy(t){var e=t._minMaxSpan={},i=t._dataZoomModel;$N(["min","max"],function(n){e[n+"Span"]=i.get(n+"Span");var o=i.get(n+"ValueSpan");if(null!=o&&(e[n+"ValueSpan"]=o,null!=(o=t.getAxisModel().axis.scale.parse(o)))){var a=t._dataExtent;e[n+"Span"]=Bo(a[0]+o,a,[0,100],!0)}})}function By(t){var e={};return tO(["start","end","startValue","endValue","throttle"],function(i){t.hasOwnProperty(i)&&(e[i]=t[i])}),e}function Vy(t,e){var i=t._rangePropMode,n=t.get("rangeMode");tO([["start","startValue"],["end","endValue"]],function(t,o){var a=null!=e[t[0]],r=null!=e[t[1]];a&&!r?i[o]="percent":!a&&r?i[o]="value":n?i[o]=n[o]:a&&(i[o]="percent")})}function Gy(t){return{x:"y",y:"x",radius:"angle",angle:"radius"}[t]}function Fy(t){return"vertical"===t?"ns-resize":"ew-resize"}function Wy(t,e){var i=Uy(t),n=e.dataZoomId,o=e.coordId;d(i,function(t,i){var a=t.dataZoomInfos;a[n]&&l(e.allCoordIds,o)<0&&(delete a[n],t.count--)}),jy(i);var a=i[o];a||((a=i[o]={coordId:o,dataZoomInfos:{},count:0}).controller=Xy(t,a),a.dispatchAction=v(Yy,t)),!a.dataZoomInfos[n]&&a.count++,a.dataZoomInfos[n]=e;var r=qy(a.dataZoomInfos);a.controller.enable(r.controlType,r.opt),a.controller.setPointerChecker(e.containsPoint),Nr(a,"dispatchAction",e.dataZoomModel.get("throttle",!0),"fixRate")}function Hy(t,e){var i=Uy(t);d(i,function(t){t.controller.dispose();var i=t.dataZoomInfos;i[e]&&(delete i[e],t.count--)}),jy(i)}function Zy(t){return t.type+"\0_"+t.id}function Uy(t){var e=t.getZr();return e[fO]||(e[fO]={})}function Xy(t,e){var i=new oc(t.getZr());return d(["pan","zoom","scrollMove"],function(t){i.on(t,function(i){var n=[];d(e.dataZoomInfos,function(o){if(i.isAvailableBehavior(o.dataZoomModel.option)){var a=(o.getRange||{})[t],r=a&&a(e.controller,i);!o.dataZoomModel.get("disabled",!0)&&r&&n.push({dataZoomId:o.dataZoomId,start:r[0],end:r[1]})}}),n.length&&e.dispatchAction(n)})}),i}function jy(t){d(t,function(e,i){e.count||(e.controller.dispose(),delete t[i])})}function Yy(t,e){t.dispatchAction({type:"dataZoom",batch:e})}function qy(t){var e,i={type_true:2,type_move:1,type_false:0,type_undefined:-1},n=!0;return d(t,function(t){var o=t.dataZoomModel,a=!o.get("disabled",!0)&&(!o.get("zoomLock",!0)||"move");i["type_"+a]>i["type_"+e]&&(e=a),n&=o.get("preventDefaultMouseMove",!0)}),{controlType:e,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!n}}}function Ky(t){return function(e,i,n,o){var a=this._range,r=a.slice(),s=e.axisModels[0];if(s){var l=t(r,s,e,i,n,o);return QL(l,r,[0,100],"all"),this._range=r,a[0]!==r[0]||a[1]!==r[1]?r:void 0}}}function $y(t,e){return t&&t.hasOwnProperty&&t.hasOwnProperty(e)}function Jy(t,e,i,n){for(var o=e.targetVisuals[n],a=hL.prepareVisualTypes(o),r={color:t.getData().getVisual("color")},s=0,l=a.length;s=0&&(r[a]=+r[a].toFixed(h)),r}function fx(t,e){var n=t.getData(),o=t.coordinateSystem;if(e&&!cx(e)&&!y(e.coord)&&o){var a=o.dimensions,r=px(e,n,o,t);if((e=i(e)).type&&YO[e.type]&&r.baseAxis&&r.valueAxis){var s=XO(a,r.baseAxis.dim),l=XO(a,r.valueAxis.dim);e.coord=YO[e.type](n,r.baseDataDim,r.valueDataDim,s,l),e.value=e.coord[l]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)YO[u[h]]&&(u[h]=yx(n,n.mapDimension(a[h]),u[h]));e.coord=u}}return e}function px(t,e,i,n){var o={};return null!=t.valueIndex||null!=t.valueDim?(o.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,o.valueAxis=i.getAxis(gx(n,o.valueDataDim)),o.baseAxis=i.getOtherAxis(o.valueAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim)):(o.baseAxis=n.getBaseAxis(),o.valueAxis=i.getOtherAxis(o.baseAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim),o.valueDataDim=e.mapDimension(o.valueAxis.dim)),o}function gx(t,e){var i=t.getData(),n=i.dimensions;e=i.getDimension(e);for(var o=0;o=0)return!0}function Yx(t){for(var e=t.split(/\n+/g),i=[],n=f(Xx(e.shift()).split(pE),function(t){return{name:t,data:[]}}),o=0;o=0&&!i[o][n];o--);if(o<0){var a=t.queryComponents({mainType:"dataZoom",subType:"select",id:n})[0];if(a){var r=a.getPercentRange();i[0][n]={dataZoomId:n,start:r[0],end:r[1]}}}}),i.push(e)}function t_(t){var e=n_(t),i=e[e.length-1];e.length>1&&e.pop();var n={};return gE(i,function(t,i){for(var o=e.length-1;o>=0;o--)if(t=e[o][i]){n[i]=t;break}}),n}function e_(t){t[mE]=null}function i_(t){return n_(t).length}function n_(t){var e=t[mE];return e||(e=t[mE]=[{}]),e}function o_(t,e,i){(this._brushController=new zf(i.getZr())).on("brush",m(this._onBrush,this)).mount(),this._isZoomActive}function a_(t){var e={};return d(["xAxisIndex","yAxisIndex"],function(i){e[i]=t[i],null==e[i]&&(e[i]="all"),(!1===e[i]||"none"===e[i])&&(e[i]=[])}),e}function r_(t,e){t.setIconStatus("back",i_(e)>1?"emphasis":"normal")}function s_(t,e,i,n,o){var a=i._isZoomActive;n&&"takeGlobalCursor"===n.type&&(a="dataZoomSelect"===n.key&&n.dataZoomSelectActive),i._isZoomActive=a,t.setIconStatus("zoom",a?"emphasis":"normal");var r=new hy(a_(t.option),e,{include:["grid"]});i._brushController.setPanels(r.makePanelOpts(o,function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"})).enableBrush(!!a&&{brushType:"auto",brushStyle:{lineWidth:0,fill:"rgba(0,0,0,0.2)"}})}function l_(t){this.model=t}function u_(t){return SE(t)}function h_(){if(!TE&&AE){TE=!0;var t=AE.styleSheets;t.length<31?AE.createStyleSheet().addRule(".zrvml","behavior:url(#default#VML)"):t[0].addRule(".zrvml","behavior:url(#default#VML)")}}function c_(t){return parseInt(t,10)}function d_(t,e){h_(),this.root=t,this.storage=e;var i=document.createElement("div"),n=document.createElement("div");i.style.cssText="display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;",n.style.cssText="position:absolute;left:0;top:0;",t.appendChild(i),this._vmlRoot=n,this._vmlViewport=i,this.resize();var o=e.delFromStorage,a=e.addToStorage;e.delFromStorage=function(t){o.call(e,t),t&&t.onRemove&&t.onRemove(n)},e.addToStorage=function(t){t.onAdd&&t.onAdd(n),a.call(e,t)},this._firstPaint=!0}function f_(t){return function(){Yw('In IE8.0 VML mode painter not support method "'+t+'"')}}function p_(t){return document.createElementNS(sR,t)}function g_(t){return cR(1e4*t)/1e4}function m_(t){return t-vR}function v_(t,e){var i=e?t.textFill:t.fill;return null!=i&&i!==hR}function y_(t,e){var i=e?t.textStroke:t.stroke;return null!=i&&i!==hR}function x_(t,e){e&&__(t,"transform","matrix("+uR.call(e,",")+")")}function __(t,e,i){(!i||"linear"!==i.type&&"radial"!==i.type)&&t.setAttribute(e,i)}function w_(t,e,i){t.setAttributeNS("http://www.w3.org/1999/xlink",e,i)}function b_(t,e,i,n){if(v_(e,i)){var o=i?e.textFill:e.fill;o="transparent"===o?hR:o,"none"!==t.getAttribute("clip-path")&&o===hR&&(o="rgba(0, 0, 0, 0.002)"),__(t,"fill",o),__(t,"fill-opacity",null!=e.fillOpacity?e.fillOpacity*e.opacity:e.opacity)}else __(t,"fill",hR);if(y_(e,i)){var a=i?e.textStroke:e.stroke;__(t,"stroke",a="transparent"===a?hR:a),__(t,"stroke-width",(i?e.textStrokeWidth:e.lineWidth)/(!i&&e.strokeNoScale?n.getLineScale():1)),__(t,"paint-order",i?"stroke":"fill"),__(t,"stroke-opacity",null!=e.strokeOpacity?e.strokeOpacity:e.opacity),e.lineDash?(__(t,"stroke-dasharray",e.lineDash.join(",")),__(t,"stroke-dashoffset",cR(e.lineDashOffset||0))):__(t,"stroke-dasharray",""),e.lineCap&&__(t,"stroke-linecap",e.lineCap),e.lineJoin&&__(t,"stroke-linejoin",e.lineJoin),e.miterLimit&&__(t,"stroke-miterlimit",e.miterLimit)}else __(t,"stroke",hR)}function S_(t){for(var e=[],i=t.data,n=t.len(),o=0;o=gR||!m_(g)&&(d>-pR&&d<0||d>pR)==!!p;var y=g_(s+u*fR(c)),x=g_(l+h*dR(c));m&&(d=p?gR-1e-4:1e-4-gR,v=!0,9===o&&e.push("M",y,x));var _=g_(s+u*fR(c+d)),w=g_(l+h*dR(c+d));e.push("A",g_(u),g_(h),cR(f*mR),+v,+p,_,w);break;case lR.Z:a="Z";break;case lR.R:var _=g_(i[o++]),w=g_(i[o++]),b=g_(i[o++]),S=g_(i[o++]);e.push("M",_,w,"L",_+b,w,"L",_+b,w+S,"L",_,w+S,"L",_,w)}a&&e.push(a);for(var M=0;M=11),domSupported:"undefined"!=typeof document}}(navigator.userAgent),X_={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1,"[object CanvasPattern]":1,"[object Image]":1,"[object Canvas]":1},j_={"[object Int8Array]":1,"[object Uint8Array]":1,"[object Uint8ClampedArray]":1,"[object Int16Array]":1,"[object Uint16Array]":1,"[object Int32Array]":1,"[object Uint32Array]":1,"[object Float32Array]":1,"[object Float64Array]":1},Y_=Object.prototype.toString,q_=Array.prototype,K_=q_.forEach,$_=q_.filter,J_=q_.slice,Q_=q_.map,tw=q_.reduce,ew={},iw=function(){return ew.createCanvas()};ew.createCanvas=function(){return document.createElement("canvas")};var nw,ow="__ec_primitive__";E.prototype={constructor:E,get:function(t){return this.data.hasOwnProperty(t)?this.data[t]:null},set:function(t,e){return this.data[t]=e},each:function(t,e){void 0!==e&&(t=m(t,e));for(var i in this.data)this.data.hasOwnProperty(i)&&t(this.data[i],i)},removeKey:function(t){delete this.data[t]}};var aw=(Object.freeze||Object)({$override:e,clone:i,merge:n,mergeAll:o,extend:a,defaults:r,createCanvas:iw,getContext:s,indexOf:l,inherits:u,mixin:h,isArrayLike:c,each:d,map:f,reduce:p,filter:g,find:function(t,e,i){if(t&&e)for(var n=0,o=t.length;n3&&(n=dw.call(n,1));for(var a=e.length,r=0;r4&&(n=dw.call(n,1,n.length-1));for(var a=n[n.length-1],r=e.length,s=0;s1&&n&&n.length>1){var a=ft(n)/ft(o);!isFinite(a)&&(a=1),e.pinchScale=a;var r=pt(n);return e.pinchX=r[0],e.pinchY=r[1],{type:"pinch",target:t[0].target,event:e}}}}},xw="silent";vt.prototype.dispose=function(){};var _w=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],ww=function(t,e,i,n){fw.call(this),this.storage=t,this.painter=e,this.painterRoot=n,i=i||new vt,this.proxy=null,this._hovered={},this._lastTouchMoment,this._lastX,this._lastY,this._gestureMgr,it.call(this),this.setHandlerProxy(i)};ww.prototype={constructor:ww,setHandlerProxy:function(t){this.proxy&&this.proxy.dispose(),t&&(d(_w,function(e){t.on&&t.on(e,this[e],this)},this),t.handler=this),this.proxy=t},mousemove:function(t){var e=t.zrX,i=t.zrY,n=this._hovered,o=n.target;o&&!o.__zr&&(o=(n=this.findHover(n.x,n.y)).target);var a=this._hovered=this.findHover(e,i),r=a.target,s=this.proxy;s.setCursor&&s.setCursor(r?r.cursor:"default"),o&&r!==o&&this.dispatchToElement(n,"mouseout",t),this.dispatchToElement(a,"mousemove",t),r&&r!==o&&this.dispatchToElement(a,"mouseover",t)},mouseout:function(t){this.dispatchToElement(this._hovered,"mouseout",t);var e,i=t.toElement||t.relatedTarget;do{i=i&&i.parentNode}while(i&&9!==i.nodeType&&!(e=i===this.painterRoot));!e&&this.trigger("globalout",{event:t})},resize:function(t){this._hovered={}},dispatch:function(t,e){var i=this[t];i&&i.call(this,e)},dispose:function(){this.proxy.dispose(),this.storage=this.proxy=this.painter=null},setCursorStyle:function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},dispatchToElement:function(t,e,i){var n=(t=t||{}).target;if(!n||!n.silent){for(var o="on"+e,a=gt(e,t,i);n&&(n[o]&&(a.cancelBubble=n[o].call(n,a)),n.trigger(e,a),n=n.parent,!a.cancelBubble););a.cancelBubble||(this.trigger(e,a),this.painter&&this.painter.eachOtherLayer(function(t){"function"==typeof t[o]&&t[o].call(t,a),t.trigger&&t.trigger(e,a)}))}},findHover:function(t,e,i){for(var n=this.storage.getDisplayList(),o={x:t,y:e},a=n.length-1;a>=0;a--){var r;if(n[a]!==i&&!n[a].ignore&&(r=yt(n[a],t,e))&&(!o.topTarget&&(o.topTarget=n[a]),r!==xw)){o.target=n[a];break}}return o},processGesture:function(t,e){this._gestureMgr||(this._gestureMgr=new vw);var i=this._gestureMgr;"start"===e&&i.clear();var n=i.recognize(t,this.findHover(t.zrX,t.zrY,null).target,this.proxy.dom);if("end"===e&&i.clear(),n){var o=n.type;t.gestureEvent=o,this.dispatchToElement({target:n.target},o,n.event)}}},d(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){ww.prototype[t]=function(e){var i=this.findHover(e.zrX,e.zrY),n=i.target;if("mousedown"===t)this._downEl=n,this._downPoint=[e.zrX,e.zrY],this._upEl=n;else if("mouseup"===t)this._upEl=n;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||uw(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(i,t,e)}}),h(ww,fw),h(ww,it);var bw="undefined"==typeof Float32Array?Array:Float32Array,Sw=(Object.freeze||Object)({create:xt,identity:_t,copy:wt,mul:bt,translate:St,rotate:Mt,scale:It,invert:Tt,clone:At}),Mw=_t,Iw=5e-5,Tw=function(t){(t=t||{}).position||(this.position=[0,0]),null==t.rotation&&(this.rotation=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},Aw=Tw.prototype;Aw.transform=null,Aw.needLocalTransform=function(){return Dt(this.rotation)||Dt(this.position[0])||Dt(this.position[1])||Dt(this.scale[0]-1)||Dt(this.scale[1]-1)};var Dw=[];Aw.updateTransform=function(){var t=this.parent,e=t&&t.transform,i=this.needLocalTransform(),n=this.transform;if(i||e){n=n||xt(),i?this.getLocalTransform(n):Mw(n),e&&(i?bt(n,t.transform,n):wt(n,t.transform)),this.transform=n;var o=this.globalScaleRatio;if(null!=o&&1!==o){this.getGlobalScale(Dw);var a=Dw[0]<0?-1:1,r=Dw[1]<0?-1:1,s=((Dw[0]-a)*o+a)/Dw[0]||0,l=((Dw[1]-r)*o+r)/Dw[1]||0;n[0]*=s,n[1]*=s,n[2]*=l,n[3]*=l}this.invTransform=this.invTransform||xt(),Tt(this.invTransform,n)}else n&&Mw(n)},Aw.getLocalTransform=function(t){return Tw.getLocalTransform(this,t)},Aw.setTransform=function(t){var e=this.transform,i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},Aw.restoreTransform=function(t){var e=t.dpr||1;t.setTransform(e,0,0,e,0,0)};var Cw=[],Lw=xt();Aw.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],i=t[2]*t[2]+t[3]*t[3],n=this.position,o=this.scale;Dt(e-1)&&(e=Math.sqrt(e)),Dt(i-1)&&(i=Math.sqrt(i)),t[0]<0&&(e=-e),t[3]<0&&(i=-i),n[0]=t[4],n[1]=t[5],o[0]=e,o[1]=i,this.rotation=Math.atan2(-t[1]/i,t[0]/e)}},Aw.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(bt(Cw,t.invTransform,e),e=Cw);var i=this.origin;i&&(i[0]||i[1])&&(Lw[4]=i[0],Lw[5]=i[1],bt(Cw,e,Lw),Cw[4]-=i[0],Cw[5]-=i[1],e=Cw),this.setLocalTransform(e)}},Aw.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},Aw.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&Q(i,i,n),i},Aw.transformCoordToGlobal=function(t,e){var i=[t,e],n=this.transform;return n&&Q(i,i,n),i},Tw.getLocalTransform=function(t,e){Mw(e=e||[]);var i=t.origin,n=t.scale||[1,1],o=t.rotation||0,a=t.position||[0,0];return i&&(e[4]-=i[0],e[5]-=i[1]),It(e,e,n),o&&Mt(e,e,o),i&&(e[4]+=i[0],e[5]+=i[1]),e[4]+=a[0],e[5]+=a[1],e};var kw={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-kw.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*kw.bounceIn(2*t):.5*kw.bounceOut(2*t-1)+.5}};Ct.prototype={constructor:Ct,step:function(t,e){if(this._initialized||(this._startTime=t+this._delay,this._initialized=!0),this._paused)this._pausedTime+=e;else{var i=(t-this._startTime-this._pausedTime)/this._life;if(!(i<0)){i=Math.min(i,1);var n=this.easing,o="string"==typeof n?kw[n]:n,a="function"==typeof o?o(i):i;return this.fire("frame",a),1===i?this.loop?(this.restart(t),"restart"):(this._needsRemove=!0,"destroy"):null}}},restart:function(t){var e=(t-this._startTime-this._pausedTime)%this._life;this._startTime=t-e+this.gap,this._pausedTime=0,this._needsRemove=!1},fire:function(t,e){this[t="on"+t]&&this[t](this._target,e)},pause:function(){this._paused=!0},resume:function(){this._paused=!1}};var Pw=function(){this.head=null,this.tail=null,this._len=0},Nw=Pw.prototype;Nw.insert=function(t){var e=new Ow(t);return this.insertEntry(e),e},Nw.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},Nw.remove=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},Nw.len=function(){return this._len},Nw.clear=function(){this.head=this.tail=null,this._len=0};var Ow=function(t){this.value=t,this.next,this.prev},Ew=function(t){this._list=new Pw,this._map={},this._maxSize=t||10,this._lastRemovedEntry=null},Rw=Ew.prototype;Rw.put=function(t,e){var i=this._list,n=this._map,o=null;if(null==n[t]){var a=i.len(),r=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=i.head;i.remove(s),delete n[s.key],o=s.value,this._lastRemovedEntry=s}r?r.value=e:r=new Ow(e),r.key=t,i.insertEntry(r),n[t]=r}return o},Rw.get=function(t){var e=this._map[t],i=this._list;if(null!=e)return e!==i.tail&&(i.remove(e),i.insertEntry(e)),e.value},Rw.clear=function(){this._list.clear(),this._map={}};var zw={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},Bw=new Ew(20),Vw=null,Gw=Ut,Fw=Xt,Ww=(Object.freeze||Object)({parse:Gt,lift:Ht,toHex:Zt,fastLerp:Ut,fastMapToColor:Gw,lerp:Xt,mapToColor:Fw,modifyHSL:jt,modifyAlpha:Yt,stringify:qt}),Hw=Array.prototype.slice,Zw=function(t,e,i,n){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||Kt,this._setter=n||$t,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};Zw.prototype={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var o=this._getter(this._target,n);if(null==o)continue;0!==t&&i[n].push({time:0,value:ae(o)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},pause:function(){for(var t=0;t=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new de(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},de.create=function(t){return new de(t.x,t.y,t.width,t.height)};var tb=function(t){t=t||{},Kw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};tb.prototype={constructor:tb,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i=0&&(i.splice(n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToStorage(t),t instanceof tb&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var e=this.__zr,i=this.__storage,n=this._children,o=l(n,t);return o<0?this:(n.splice(o,1),t.parent=null,i&&(i.delFromStorage(t),t instanceof tb&&t.delChildrenFromStorage(i)),e&&e.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;e=0&&(this.delFromStorage(t),this._roots.splice(o,1),t instanceof tb&&t.delChildrenFromStorage(this))}},addToStorage:function(t){return t&&(t.__storage=this,t.dirty(!1)),this},delFromStorage:function(t){return t&&(t.__storage=null),this},dispose:function(){this._renderList=this._roots=null},displayableSortFunc:we};var ob={shadowBlur:1,shadowOffsetX:1,shadowOffsetY:1,textShadowBlur:1,textShadowOffsetX:1,textShadowOffsetY:1,textBoxShadowBlur:1,textBoxShadowOffsetX:1,textBoxShadowOffsetY:1},ab=function(t,e,i){return ob.hasOwnProperty(e)?i*=t.dpr:i},rb={NONE:0,STYLE_BIND:1,PLAIN_TEXT:2},sb=9,lb=[["shadowBlur",0],["shadowOffsetX",0],["shadowOffsetY",0],["shadowColor","#000"],["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]],ub=function(t){this.extendFrom(t,!1)};ub.prototype={constructor:ub,fill:"#000",stroke:null,opacity:1,fillOpacity:null,strokeOpacity:null,lineDash:null,lineDashOffset:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,lineWidth:1,strokeNoScale:!1,text:null,font:null,textFont:null,fontStyle:null,fontWeight:null,fontSize:null,fontFamily:null,textTag:null,textFill:"#000",textStroke:null,textWidth:null,textHeight:null,textStrokeWidth:0,textLineHeight:null,textPosition:"inside",textRect:null,textOffset:null,textAlign:null,textVerticalAlign:null,textDistance:5,textShadowColor:"transparent",textShadowBlur:0,textShadowOffsetX:0,textShadowOffsetY:0,textBoxShadowColor:"transparent",textBoxShadowBlur:0,textBoxShadowOffsetX:0,textBoxShadowOffsetY:0,transformText:!1,textRotation:0,textOrigin:null,textBackgroundColor:null,textBorderColor:null,textBorderWidth:0,textBorderRadius:0,textPadding:null,rich:null,truncate:null,blend:null,bind:function(t,e,i){var n=this,o=i&&i.style,a=!o||t.__attrCachedBy!==rb.STYLE_BIND;t.__attrCachedBy=rb.STYLE_BIND;for(var r=0;r0},extendFrom:function(t,e){if(t)for(var i in t)!t.hasOwnProperty(i)||!0!==e&&(!1===e?this.hasOwnProperty(i):null==t[i])||(this[i]=t[i])},set:function(t,e){"string"==typeof t?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(t,e,i){for(var n=("radial"===e.type?Se:be)(t,e,i),o=e.colorStops,a=0;a=0&&i.splice(n,1),t.__hoverMir=null},clearHover:function(t){for(var e=this._hoverElements,i=0;i15)break}s.__drawIndex=m,s.__drawIndex0&&t>n[0]){for(r=0;rt);r++);a=i[n[r]]}if(n.splice(r+1,0,t),i[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?s.insertBefore(e.dom,l.nextSibling):s.appendChild(e.dom)}else s.firstChild?s.insertBefore(e.dom,s.firstChild):s.appendChild(e.dom)}else Yw("Layer of zlevel "+t+" is not valid")},eachLayer:function(t,e){var i,n,o=this._zlevelList;for(n=0;n0?.01:0),this._needsManuallyCompositing),a.__builtin__||Yw("ZLevel "+s+" has been used by unkown layer "+a.id),a!==i&&(a.__used=!0,a.__startIndex!==o&&(a.__dirty=!0),a.__startIndex=o,a.incremental?a.__drawIndex=-1:a.__drawIndex=o,e(o),i=a),r.__dirty&&(a.__dirty=!0,a.incremental&&a.__drawIndex<0&&(a.__drawIndex=o))}e(o),this.eachBuiltinLayer(function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)})},clear:function(){return this.eachBuiltinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},setBackgroundColor:function(t){this._backgroundColor=t},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?n(i[t],e,!0):i[t]=e;for(var o=0;o=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;i=0||n&&l(n,r)<0)){var s=e.getShallow(r);null!=s&&(o[t[a][0]]=s)}}return o}},tS=Qb([["lineWidth","width"],["stroke","color"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),eS={getLineStyle:function(t){var e=tS(this,t),i=this.getLineDash(e.lineWidth);return i&&(e.lineDash=i),e},getLineDash:function(t){null==t&&(t=1);var e=this.get("type"),i=Math.max(t,2),n=4*t;return"solid"===e||null==e?null:"dashed"===e?[n,n]:[i,i]}},iS=Qb([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),nS={getAreaStyle:function(t,e){return iS(this,t,e)}},oS=Math.pow,aS=Math.sqrt,rS=1e-8,sS=1e-4,lS=aS(3),uS=1/3,hS=V(),cS=V(),dS=V(),fS=Math.min,pS=Math.max,gS=Math.sin,mS=Math.cos,vS=2*Math.PI,yS=V(),xS=V(),_S=V(),wS=[],bS=[],SS={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},MS=[],IS=[],TS=[],AS=[],DS=Math.min,CS=Math.max,LS=Math.cos,kS=Math.sin,PS=Math.sqrt,NS=Math.abs,OS="undefined"!=typeof Float32Array,ES=function(t){this._saveData=!t,this._saveData&&(this.data=[]),this._ctx=null};ES.prototype={constructor:ES,_xi:0,_yi:0,_x0:0,_y0:0,_ux:0,_uy:0,_len:0,_lineDash:null,_dashOffset:0,_dashIdx:0,_dashSum:0,setScale:function(t,e){this._ux=NS(1/Xw/t)||0,this._uy=NS(1/Xw/e)||0},getContext:function(){return this._ctx},beginPath:function(t){return this._ctx=t,t&&t.beginPath(),t&&(this.dpr=t.dpr),this._saveData&&(this._len=0),this._lineDash&&(this._lineDash=null,this._dashOffset=0),this},moveTo:function(t,e){return this.addData(SS.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},lineTo:function(t,e){var i=NS(t-this._xi)>this._ux||NS(e-this._yi)>this._uy||this._len<5;return this.addData(SS.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,o,a){return this.addData(SS.C,t,e,i,n,o,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,o,a):this._ctx.bezierCurveTo(t,e,i,n,o,a)),this._xi=o,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(SS.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,o,a){return this.addData(SS.A,t,e,i,i,n,o-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,o,a),this._xi=LS(o)*i+t,this._yi=kS(o)*i+e,this},arcTo:function(t,e,i,n,o){return this._ctx&&this._ctx.arcTo(t,e,i,n,o),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(SS.R,t,e,i,n),this},closePath:function(){this.addData(SS.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;ie.length&&(this._expandData(),e=this.data);for(var i=0;i0&&f<=t||h<0&&f>=t||0===h&&(c>0&&p<=e||c<0&&p>=e);)f+=h*(i=r[n=this._dashIdx]),p+=c*i,this._dashIdx=(n+1)%g,h>0&&fl||c>0&&pu||s[n%2?"moveTo":"lineTo"](h>=0?DS(f,t):CS(f,t),c>=0?DS(p,e):CS(p,e));h=f-t,c=p-e,this._dashOffset=-PS(h*h+c*c)},_dashedBezierTo:function(t,e,i,n,o,a){var r,s,l,u,h,c=this._dashSum,d=this._dashOffset,f=this._lineDash,p=this._ctx,g=this._xi,m=this._yi,v=tn,y=0,x=this._dashIdx,_=f.length,w=0;for(d<0&&(d=c+d),d%=c,r=0;r<1;r+=.1)s=v(g,t,i,o,r+.1)-v(g,t,i,o,r),l=v(m,e,n,a,r+.1)-v(m,e,n,a,r),y+=PS(s*s+l*l);for(;x<_&&!((w+=f[x])>d);x++);for(r=(w-d)/y;r<=1;)u=v(g,t,i,o,r),h=v(m,e,n,a,r),x%2?p.moveTo(u,h):p.lineTo(u,h),r+=f[x]/y,x=(x+1)%_;x%2!=0&&p.lineTo(o,a),s=o-u,l=a-h,this._dashOffset=-PS(s*s+l*l)},_dashedQuadraticTo:function(t,e,i,n){var o=i,a=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,o,a)},toStatic:function(){var t=this.data;t instanceof Array&&(t.length=this._len,OS&&(this.data=new Float32Array(t)))},getBoundingRect:function(){MS[0]=MS[1]=TS[0]=TS[1]=Number.MAX_VALUE,IS[0]=IS[1]=AS[0]=AS[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,n=0,o=0,a=0;al||NS(r-o)>u||c===h-1)&&(t.lineTo(a,r),n=a,o=r);break;case SS.C:t.bezierCurveTo(s[c++],s[c++],s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case SS.Q:t.quadraticCurveTo(s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case SS.A:var f=s[c++],p=s[c++],g=s[c++],m=s[c++],v=s[c++],y=s[c++],x=s[c++],_=s[c++],w=g>m?g:m,b=g>m?1:g/m,S=g>m?m/g:1,M=v+y;Math.abs(g-m)>.001?(t.translate(f,p),t.rotate(x),t.scale(b,S),t.arc(0,0,w,v,M,1-_),t.scale(1/b,1/S),t.rotate(-x),t.translate(-f,-p)):t.arc(f,p,w,v,M,1-_),1===c&&(e=LS(v)*g+f,i=kS(v)*m+p),n=LS(M)*g+f,o=kS(M)*m+p;break;case SS.R:e=n=s[c],i=o=s[c+1],t.rect(s[c++],s[c++],s[c++],s[c++]);break;case SS.Z:t.closePath(),n=e,o=i}}}},ES.CMD=SS;var RS=2*Math.PI,zS=2*Math.PI,BS=ES.CMD,VS=2*Math.PI,GS=1e-4,FS=[-1,-1,-1],WS=[-1,-1],HS=fb.prototype.getCanvasPattern,ZS=Math.abs,US=new ES(!0);Pn.prototype={constructor:Pn,type:"path",__dirtyPath:!0,strokeContainThreshold:5,subPixelOptimize:!1,brush:function(t,e){var i=this.style,n=this.path||US,o=i.hasStroke(),a=i.hasFill(),r=i.fill,s=i.stroke,l=a&&!!r.colorStops,u=o&&!!s.colorStops,h=a&&!!r.image,c=o&&!!s.image;if(i.bind(t,this,e),this.setTransform(t),this.__dirty){var d;l&&(d=d||this.getBoundingRect(),this._fillGradient=i.getGradient(t,r,d)),u&&(d=d||this.getBoundingRect(),this._strokeGradient=i.getGradient(t,s,d))}l?t.fillStyle=this._fillGradient:h&&(t.fillStyle=HS.call(r,t)),u?t.strokeStyle=this._strokeGradient:c&&(t.strokeStyle=HS.call(s,t));var f=i.lineDash,p=i.lineDashOffset,g=!!t.setLineDash,m=this.getGlobalScale();if(n.setScale(m[0],m[1]),this.__dirtyPath||f&&!g&&o?(n.beginPath(t),f&&!g&&(n.setLineDash(f),n.setLineDashOffset(p)),this.buildPath(n,this.shape,!1),this.path&&(this.__dirtyPath=!1)):(t.beginPath(),this.path.rebuildPath(t)),a)if(null!=i.fillOpacity){v=t.globalAlpha;t.globalAlpha=i.fillOpacity*i.opacity,n.fill(t),t.globalAlpha=v}else n.fill(t);if(f&&g&&(t.setLineDash(f),t.lineDashOffset=p),o)if(null!=i.strokeOpacity){var v=t.globalAlpha;t.globalAlpha=i.strokeOpacity*i.opacity,n.stroke(t),t.globalAlpha=v}else n.stroke(t);f&&g&&t.setLineDash([]),null!=i.text&&(this.restoreTransform(t),this.drawRectText(t,this.getBoundingRect()))},buildPath:function(t,e,i){},createPathProxy:function(){this.path=new ES},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var n=this.path;n||(n=this.path=new ES),this.__dirtyPath&&(n.beginPath(),this.buildPath(n,this.shape,!1)),t=n.getBoundingRect()}if(this._rect=t,e.hasStroke()){var o=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){o.copy(t);var a=e.lineWidth,r=e.strokeNoScale?this.getLineScale():1;e.hasFill()||(a=Math.max(a,this.strokeContainThreshold||4)),r>1e-10&&(o.width+=a/r,o.height+=a/r,o.x-=a/r/2,o.y-=a/r/2)}return o}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this.getBoundingRect(),o=this.style;if(t=i[0],e=i[1],n.contain(t,e)){var a=this.path.data;if(o.hasStroke()){var r=o.lineWidth,s=o.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(o.hasFill()||(r=Math.max(r,this.strokeContainThreshold)),kn(a,r/s,t,e)))return!0}if(o.hasFill())return Ln(a,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=this.__dirtyText=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):di.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(w(t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&ZS(t[0]-1)>1e-10&&ZS(t[3]-1)>1e-10?Math.sqrt(ZS(t[0]*t[3]-t[2]*t[1])):1}},Pn.extend=function(t){var e=function(e){Pn.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var n=this.shape;for(var o in i)!n.hasOwnProperty(o)&&i.hasOwnProperty(o)&&(n[o]=i[o])}t.init&&t.init.call(this,e)};u(e,Pn);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},u(Pn,di);var XS=ES.CMD,jS=[[],[],[]],YS=Math.sqrt,qS=Math.atan2,KS=function(t,e){var i,n,o,a,r,s,l=t.data,u=XS.M,h=XS.C,c=XS.L,d=XS.R,f=XS.A,p=XS.Q;for(o=0,a=0;o=11?function(){var e,i=this.__clipPaths,n=this.style;if(i)for(var o=0;oi-2?i-1:c+1],u=t[c>i-3?i-1:c+2]);var p=d*d,g=d*p;n.push([Bn(s[0],f[0],l[0],u[0],d,p,g),Bn(s[1],f[1],l[1],u[1],d,p,g)])}return n},fM=function(t,e,i,n){var o,a,r,s,l=[],u=[],h=[],c=[];if(n){r=[1/0,1/0],s=[-1/0,-1/0];for(var d=0,f=t.length;d=i&&a>=o)return{x:i,y:o,width:n-i,height:a-o}},createIcon:Po,Group:tb,Image:fi,Text:rM,Circle:sM,Sector:hM,Ring:cM,Polygon:pM,Polyline:gM,Rect:yM,Line:_M,BezierCurve:bM,Arc:SM,IncrementalDisplayable:Zn,CompoundPath:MM,LinearGradient:TM,RadialGradient:AM,BoundingRect:de}),BM=["textStyle","color"],VM={getTextColor:function(t){var e=this.ecModel;return this.getShallow("color")||(!t&&e?e.get(BM):null)},getFont:function(){return So({fontStyle:this.getShallow("fontStyle"),fontWeight:this.getShallow("fontWeight"),fontSize:this.getShallow("fontSize"),fontFamily:this.getShallow("fontFamily")},this.ecModel)},getTextRect:function(t){return ke(t,this.getFont(),this.getShallow("align"),this.getShallow("verticalAlign")||this.getShallow("baseline"),this.getShallow("padding"),this.getShallow("lineHeight"),this.getShallow("rich"),this.getShallow("truncateText"))}},GM=Qb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"],["textPosition"],["textAlign"]]),FM={getItemStyle:function(t,e){var i=GM(this,t,e),n=this.getBorderLineDash();return n&&(i.lineDash=n),i},getBorderLineDash:function(){var t=this.get("borderType");return"solid"===t||null==t?null:"dashed"===t?[5,5]:[1,1]}},WM=h,HM=Bi();No.prototype={constructor:No,init:null,mergeOption:function(t){n(this.option,t,!0)},get:function(t,e){return null==t?this.option:Oo(this.option,this.parsePath(t),!e&&Eo(this,t))},getShallow:function(t,e){var i=this.option,n=null==i?i:i[t],o=!e&&Eo(this,t);return null==n&&o&&(n=o.getShallow(t)),n},getModel:function(t,e){var i,n=null==t?this.option:Oo(this.option,t=this.parsePath(t));return e=e||(i=Eo(this,t))&&i.getModel(t),new No(n,e,this.ecModel)},isEmpty:function(){return null==this.option},restoreData:function(){},clone:function(){return new(0,this.constructor)(i(this.option))},setReadOnly:function(t){},parsePath:function(t){return"string"==typeof t&&(t=t.split(".")),t},customizeGetParent:function(t){HM(this).getParent=t},isAnimationEnabled:function(){if(!U_.node){if(null!=this.option.animation)return!!this.option.animation;if(this.parentModel)return this.parentModel.isAnimationEnabled()}}},ji(No),Yi(No),WM(No,eS),WM(No,nS),WM(No,VM),WM(No,FM);var ZM=0,UM=1e-4,XM=9007199254740991,jM=/^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/,YM=(Object.freeze||Object)({linearMap:Bo,parsePercent:Vo,round:Go,asc:Fo,getPrecision:Wo,getPrecisionSafe:Ho,getPixelPrecision:Zo,getPercentWithPrecision:Uo,MAX_SAFE_INTEGER:XM,remRadian:Xo,isRadianAroundZero:jo,parseDate:Yo,quantity:qo,nice:$o,quantile:function(t,e){var i=(t.length-1)*e+1,n=Math.floor(i),o=+t[n-1],a=i-n;return a?o+a*(t[n]-o):o},reformIntervals:Jo,isNumeric:Qo}),qM=L,KM=/([&<>"'])/g,$M={"&":"&","<":"<",">":">",'"':""","'":"'"},JM=["a","b","c","d","e","f","g"],QM=function(t,e){return"{"+t+(null==e?"":e)+"}"},tI=ze,eI=(Object.freeze||Object)({addCommas:ta,toCamelCase:ea,normalizeCssArray:qM,encodeHTML:ia,formatTpl:na,formatTplSimple:oa,getTooltipMarker:aa,formatTime:sa,capitalFirst:la,truncateText:tI,getTextBoundingRect:function(t){return ke(t.text,t.font,t.textAlign,t.textVerticalAlign,t.textPadding,t.textLineHeight,t.rich,t.truncate)},getTextRect:function(t,e,i,n,o,a,r,s){return ke(t,e,i,n,o,s,a,r)}}),iI=d,nI=["left","right","top","bottom","width","height"],oI=[["width","left","right"],["height","top","bottom"]],aI=ua,rI=(v(ua,"vertical"),v(ua,"horizontal"),{getBoxLayoutParams:function(){return{left:this.get("left"),top:this.get("top"),right:this.get("right"),bottom:this.get("bottom"),width:this.get("width"),height:this.get("height")}}}),sI=Bi(),lI=No.extend({type:"component",id:"",name:"",mainType:"",subType:"",componentIndex:0,defaultOption:null,ecModel:null,dependentModels:[],uid:null,layoutMode:null,$constructor:function(t,e,i,n){No.call(this,t,e,i,n),this.uid=Ro("ec_cpt_model")},init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i)},mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,o=i?ga(t):{};n(t,e.getTheme().get(this.mainType)),n(t,this.getDefaultOption()),i&&pa(t,o,i)},mergeOption:function(t,e){n(this.option,t,!0);var i=this.layoutMode;i&&pa(this.option,t,i)},optionUpdated:function(t,e){},getDefaultOption:function(){var t=sI(this);if(!t.defaultOption){for(var e=[],i=this.constructor;i;){var o=i.prototype.defaultOption;o&&e.push(o),i=i.superClass}for(var a={},r=e.length-1;r>=0;r--)a=n(a,e[r],!0);t.defaultOption=a}return t.defaultOption},getReferringComponents:function(t){return this.ecModel.queryComponents({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});$i(lI,{registerWhenExtend:!0}),function(t){var e={};t.registerSubTypeDefaulter=function(t,i){t=Ui(t),e[t.main]=i},t.determineSubType=function(i,n){var o=n.type;if(!o){var a=Ui(i).main;t.hasSubTypes(i)&&e[a]&&(o=e[a](n))}return o}}(lI),function(t,e){function i(t){var i={},a=[];return d(t,function(r){var s=n(i,r),u=o(s.originalDeps=e(r),t);s.entryCount=u.length,0===s.entryCount&&a.push(r),d(u,function(t){l(s.predecessor,t)<0&&s.predecessor.push(t);var e=n(i,t);l(e.successor,t)<0&&e.successor.push(r)})}),{graph:i,noEntryList:a}}function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}function o(t,e){var i=[];return d(t,function(t){l(e,t)>=0&&i.push(t)}),i}t.topologicalTravel=function(t,e,n,o){function a(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}if(t.length){var r=i(e),s=r.graph,l=r.noEntryList,u={};for(d(t,function(t){u[t]=!0});l.length;){var h=l.pop(),c=s[h],f=!!u[h];f&&(n.call(o,h,c.originalDeps.slice()),delete u[h]),d(c.successor,f?function(t){u[t]=!0,a(t)}:a)}d(u,function(){throw new Error("Circle dependency may exists")})}}}(lI,function(t){var e=[];return d(lI.getClassesByMainType(t),function(t){e=e.concat(t.prototype.dependencies||[])}),e=f(e,function(t){return Ui(t).main}),"dataset"!==t&&l(e,"dataset")<=0&&e.unshift("dataset"),e}),h(lI,rI);var uI="";"undefined"!=typeof navigator&&(uI=navigator.platform||"");var hI={color:["#c23531","#2f4554","#61a0a8","#d48265","#91c7ae","#749f83","#ca8622","#bda29a","#6e7074","#546570","#c4ccd3"],gradientColor:["#f6efa6","#d88273","#bf444c"],textStyle:{fontFamily:uI.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,animation:"auto",animationDuration:1e3,animationDurationUpdate:300,animationEasing:"exponentialOut",animationEasingUpdate:"cubicOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},cI=Bi(),dI={clearColorPalette:function(){cI(this).colorIdx=0,cI(this).colorNameMap={}},getColorFromPalette:function(t,e,i){var n=cI(e=e||this),o=n.colorIdx||0,a=n.colorNameMap=n.colorNameMap||{};if(a.hasOwnProperty(t))return a[t];var r=Di(this.get("color",!0)),s=this.get("colorLayer",!0),l=null!=i&&s?va(s,i):r;if((l=l||r)&&l.length){var u=l[o];return t&&(a[t]=u),n.colorIdx=(o+1)%l.length,u}}},fI={cartesian2d:function(t,e,i,n){var o=t.getReferringComponents("xAxis")[0],a=t.getReferringComponents("yAxis")[0];e.coordSysDims=["x","y"],i.set("x",o),i.set("y",a),xa(o)&&(n.set("x",o),e.firstCategoryDimIndex=0),xa(a)&&(n.set("y",a),e.firstCategoryDimIndex=1)},singleAxis:function(t,e,i,n){var o=t.getReferringComponents("singleAxis")[0];e.coordSysDims=["single"],i.set("single",o),xa(o)&&(n.set("single",o),e.firstCategoryDimIndex=0)},polar:function(t,e,i,n){var o=t.getReferringComponents("polar")[0],a=o.findAxisModel("radiusAxis"),r=o.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],i.set("radius",a),i.set("angle",r),xa(a)&&(n.set("radius",a),e.firstCategoryDimIndex=0),xa(r)&&(n.set("angle",r),e.firstCategoryDimIndex=1)},geo:function(t,e,i,n){e.coordSysDims=["lng","lat"]},parallel:function(t,e,i,n){var o=t.ecModel,a=o.getComponent("parallel",t.get("parallelIndex")),r=e.coordSysDims=a.dimensions.slice();d(a.parallelAxisIndex,function(t,a){var s=o.getComponent("parallelAxis",t),l=r[a];i.set(l,s),xa(s)&&null==e.firstCategoryDimIndex&&(n.set(l,s),e.firstCategoryDimIndex=a)})}},pI="original",gI="arrayRows",mI="objectRows",vI="keyedColumns",yI="unknown",xI="typedArray",_I="column",wI="row";_a.seriesDataToSource=function(t){return new _a({data:t,sourceFormat:S(t)?xI:pI,fromDataset:!1})},Yi(_a);var bI=Bi(),SI="\0_ec_inner",MI=No.extend({init:function(t,e,i,n){i=i||{},this.option=null,this._theme=new No(i),this._optionManager=n},setOption:function(t,e){k(!(SI in t),"please use chart.getOption()"),this._optionManager.setOption(t,e),this.resetOption(null)},resetOption:function(t){var e=!1,i=this._optionManager;if(!t||"recreate"===t){var n=i.mountOption("recreate"===t);this.option&&"recreate"!==t?(this.restoreData(),this.mergeOption(n)):Ea.call(this,n),e=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(this.mergeOption(o),e=!0)}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this,this._api);a.length&&d(a,function(t){this.mergeOption(t,e=!0)},this)}return e},mergeOption:function(t){var e=this.option,o=this._componentsMap,r=[];Sa(this),d(t,function(t,o){null!=t&&(lI.hasClass(o)?o&&r.push(o):e[o]=null==e[o]?i(t):n(e[o],t,!0))}),lI.topologicalTravel(r,lI.getAllClassMainTypes(),function(i,n){var r=Di(t[i]),s=Pi(o.get(i),r);Ni(s),d(s,function(t,e){var n=t.option;w(n)&&(t.keyInfo.mainType=i,t.keyInfo.subType=za(i,n,t.exist))});var l=Ra(o,n);e[i]=[],o.set(i,[]),d(s,function(t,n){var r=t.exist,s=t.option;if(k(w(s)||r,"Empty component definition"),s){var u=lI.getClass(i,t.keyInfo.subType,!0);if(r&&r instanceof u)r.name=t.keyInfo.name,r.mergeOption(s,this),r.optionUpdated(s,!1);else{var h=a({dependentModels:l,componentIndex:n},t.keyInfo);a(r=new u(s,this,this,h),h),r.init(s,this,this,h),r.optionUpdated(null,!0)}}else r.mergeOption({},this),r.optionUpdated({},!1);o.get(i)[n]=r,e[i][n]=r.option},this),"series"===i&&Ba(this,o.get("series"))},this),this._seriesIndicesMap=R(this._seriesIndices=this._seriesIndices||[])},getOption:function(){var t=i(this.option);return d(t,function(e,i){if(lI.hasClass(i)){for(var n=(e=Di(e)).length-1;n>=0;n--)Ei(e[n])&&e.splice(n,1);t[i]=e}}),delete t[SI],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap.get(t);if(i)return i[e||0]},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,o=t.name,a=this._componentsMap.get(e);if(!a||!a.length)return[];var r;if(null!=i)y(i)||(i=[i]),r=g(f(i,function(t){return a[t]}),function(t){return!!t});else if(null!=n){var s=y(n);r=g(a,function(t){return s&&l(n,t.id)>=0||!s&&t.id===n})}else if(null!=o){var u=y(o);r=g(a,function(t){return u&&l(o,t.name)>=0||!u&&t.name===o})}else r=a.slice();return Va(r,t)},findComponents:function(t){var e=t.query,i=t.mainType,n=function(t){var e=i+"Index",n=i+"Id",o=i+"Name";return!t||null==t[e]&&null==t[n]&&null==t[o]?null:{mainType:i,index:t[e],id:t[n],name:t[o]}}(e);return function(e){return t.filter?g(e,t.filter):e}(Va(n?this.queryComponents(n):this._componentsMap.get(i),t))},eachComponent:function(t,e,i){var n=this._componentsMap;"function"==typeof t?(i=e,e=t,n.each(function(t,n){d(t,function(t,o){e.call(i,n,t,o)})})):_(t)?d(n.get(t),e,i):w(t)&&d(this.findComponents(t),e,i)},getSeriesByName:function(t){return g(this._componentsMap.get("series"),function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap.get("series")[t]},getSeriesByType:function(t){return g(this._componentsMap.get("series"),function(e){return e.subType===t})},getSeries:function(){return this._componentsMap.get("series").slice()},getSeriesCount:function(){return this._componentsMap.get("series").length},eachSeries:function(t,e){d(this._seriesIndices,function(i){var n=this._componentsMap.get("series")[i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){d(this._componentsMap.get("series"),t,e)},eachSeriesByType:function(t,e,i){d(this._seriesIndices,function(n){var o=this._componentsMap.get("series")[n];o.subType===t&&e.call(i,o,n)},this)},eachRawSeriesByType:function(t,e,i){return d(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return null==this._seriesIndicesMap.get(t.componentIndex)},getCurrentSeriesIndices:function(){return(this._seriesIndices||[]).slice()},filterSeries:function(t,e){Ba(this,g(this._componentsMap.get("series"),t,e))},restoreData:function(t){var e=this._componentsMap;Ba(this,e.get("series"));var i=[];e.each(function(t,e){i.push(e)}),lI.topologicalTravel(i,lI.getAllClassMainTypes(),function(i,n){d(e.get(i),function(e){("series"!==i||!Na(e,t))&&e.restoreData()})})}});h(MI,dI);var II=["getDom","getZr","getWidth","getHeight","getDevicePixelRatio","dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL","getModel","getOption","getViewOfComponentModel","getViewOfSeriesModel"],TI={};Fa.prototype={constructor:Fa,create:function(t,e){var i=[];d(TI,function(n,o){var a=n.create(t,e);i=i.concat(a||[])}),this._coordinateSystems=i},update:function(t,e){d(this._coordinateSystems,function(i){i.update&&i.update(t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},Fa.register=function(t,e){TI[t]=e},Fa.get=function(t){return TI[t]};var AI=d,DI=i,CI=f,LI=n,kI=/^(min|max)?(.+)$/;Wa.prototype={constructor:Wa,setOption:function(t,e){t&&d(Di(t.series),function(t){t&&t.data&&S(t.data)&&N(t.data)}),t=DI(t,!0);var i=this._optionBackup,n=Ha.call(this,t,e,!i);this._newBaseOption=n.baseOption,i?(ja(i.baseOption,n.baseOption),n.timelineOptions.length&&(i.timelineOptions=n.timelineOptions),n.mediaList.length&&(i.mediaList=n.mediaList),n.mediaDefault&&(i.mediaDefault=n.mediaDefault)):this._optionBackup=n},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=CI(e.timelineOptions,DI),this._mediaList=CI(e.mediaList,DI),this._mediaDefault=DI(e.mediaDefault),this._currentMediaIndices=[],DI(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i.length){var n=t.getComponent("timeline");n&&(e=DI(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(t){var e=this._api.getWidth(),i=this._api.getHeight(),n=this._mediaList,o=this._mediaDefault,a=[],r=[];if(!n.length&&!o)return r;for(var s=0,l=n.length;s=1)&&(t=1),t}var i=this._upstream,n=t&&t.skip;if(this._dirty&&i){var o=this.context;o.data=o.outputData=i.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this);var a;this._plan&&!n&&(a=this._plan(this.context));var r=e(this._modBy),s=this._modDataCount||0,l=e(t&&t.modBy),u=t&&t.modDataCount||0;r===l&&s===u||(a="reset");var h;(this._dirty||"reset"===a)&&(this._dirty=!1,h=yr(this,n)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=i?i._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var d=this._dueIndex,f=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!n&&(h||d=i?null:t1&&a>0?e:t}};return s}();UI.dirty=function(){this._dirty=!0,this._onDirty&&this._onDirty(this.context)},UI.unfinished=function(){return this._progress&&this._dueIndex":"\n",s="richText"===n,l={},u=0,h=this.getData(),c=h.mapDimension("defaultedTooltip",!0),f=c.length,g=this.getRawValue(t),m=y(g),v=h.getItemVisual(t,"color");w(v)&&v.colorStops&&(v=(v.colorStops[0]||{}).color),v=v||"transparent";var x=(f>1||m&&!f?function(i){function o(t,i){var o=h.getDimensionInfo(i);if(o&&!1!==o.otherDims.tooltip){var c=o.type,d="sub"+a.seriesIndex+"at"+u,p=aa({color:v,type:"subItem",renderMode:n,markerId:d}),g="string"==typeof p?p:p.content,m=(r?g+ia(o.displayName||"-")+": ":"")+ia("ordinal"===c?t+"":"time"===c?e?"":sa("yyyy/MM/dd hh:mm:ss",t):ta(t));m&&f.push(m),s&&(l[d]=v,++u)}}var r=p(i,function(t,e,i){var n=h.getDimensionInfo(i);return t|=n&&!1!==n.tooltip&&null!=n.displayName},0),f=[];c.length?d(c,function(e){o(fr(h,t,e),e)}):d(i,o);var g=r?s?"\n":"
":"",m=g+f.join(g||", ");return{renderMode:n,content:m,style:l}}(g):o(f?fr(h,t,c[0]):m?g[0]:g)).content,_=a.seriesIndex+"at"+u,b=aa({color:v,type:"item",renderMode:n,markerId:_});l[_]=v,++u;var S=h.getName(t),M=this.name;Oi(this)||(M=""),M=M?ia(M)+(e?": ":r):"";var I="string"==typeof b?b:b.content;return{html:e?I+M+x:M+I+(S?ia(S)+": "+x:x),markers:l}},isAnimationEnabled:function(){if(U_.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){this.dataTask.dirty()},getColorFromPalette:function(t,e,i){var n=this.ecModel,o=dI.getColorFromPalette.call(this,t,e,i);return o||(o=n.getColorFromPalette(t,e,i)),o},coordDimToDataDim:function(t){return this.getRawData().mapDimension(t,!0)},getProgressive:function(){return this.get("progressive")},getProgressiveThreshold:function(){return this.get("progressiveThreshold")},getAxisTooltipData:null,getTooltipPosition:null,pipeTask:null,preventIncremental:null,pipelineContext:null});h(YI,ZI),h(YI,dI);var qI=function(){this.group=new tb,this.uid=Ro("viewComponent")};qI.prototype={constructor:qI,init:function(t,e){},render:function(t,e,i,n){},dispose:function(){},filterForExposedEvent:null};var KI=qI.prototype;KI.updateView=KI.updateLayout=KI.updateVisual=function(t,e,i,n){},ji(qI),$i(qI,{registerWhenExtend:!0});var $I=function(){var t=Bi();return function(e){var i=t(e),n=e.pipelineContext,o=i.large,a=i.progressiveRender,r=i.large=n.large,s=i.progressiveRender=n.progressiveRender;return!!(o^r||a^s)&&"reset"}},JI=Bi(),QI=$I();Ar.prototype={type:"chart",init:function(t,e){},render:function(t,e,i,n){},highlight:function(t,e,i,n){Cr(t.getData(),n,"emphasis")},downplay:function(t,e,i,n){Cr(t.getData(),n,"normal")},remove:function(t,e){this.group.removeAll()},dispose:function(){},incrementalPrepareRender:null,incrementalRender:null,updateTransform:null,filterForExposedEvent:null};var tT=Ar.prototype;tT.updateView=tT.updateLayout=tT.updateVisual=function(t,e,i,n){this.render(t,e,i,n)},ji(Ar),$i(Ar,{registerWhenExtend:!0}),Ar.markUpdateMethod=function(t,e){JI(t).updateMethod=e};var eT={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},iT="\0__throttleOriginMethod",nT="\0__throttleRate",oT="\0__throttleType",aT={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var i=t.getData(),n=(t.visualColorAccessPath||"itemStyle.color").split("."),o=t.get(n)||t.getColorFromPalette(t.name,null,e.getSeriesCount());if(i.setVisual("color",o),!e.isSeriesFiltered(t)){"function"!=typeof o||o instanceof IM||i.each(function(e){i.setItemVisual(e,"color",o(t.getDataParams(e)))});return{dataEach:i.hasItemOption?function(t,e){var i=t.getItemModel(e).get(n,!0);null!=i&&t.setItemVisual(e,"color",i)}:null}}}},rT={toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}},sT=function(t,e){function i(t,e){if("string"!=typeof t)return t;var i=t;return d(e,function(t,e){i=i.replace(new RegExp("\\{\\s*"+e+"\\s*\\}","g"),t)}),i}function n(t){var e=a.get(t);if(null==e){for(var i=t.split("."),n=rT.aria,o=0;o1?"series.multiple.prefix":"series.single.prefix"),{seriesCount:r}),e.eachSeries(function(t,e){if(e1?"multiple":"single")+".";a=i(a=n(s?u+"withName":u+"withoutName"),{seriesId:t.seriesIndex,seriesName:t.get("name"),seriesType:o(t.subType)});var c=t.getData();window.data=c,c.count()>l?a+=i(n("data.partialData"),{displayCnt:l}):a+=n("data.allData");for(var d=[],p=0;pi.blockIndex?i.step:null,a=n&&n.modDataCount;return{step:o,modBy:null!=a?Math.ceil(a/o):null,modDataCount:a}}},uT.getPipeline=function(t){return this._pipelineMap.get(t)},uT.updateStreamModes=function(t,e){var i=this._pipelineMap.get(t.uid),n=t.getData().count(),o=i.progressiveEnabled&&e.incrementalPrepareRender&&n>=i.threshold,a=t.get("large")&&n>=t.get("largeThreshold"),r="mod"===t.get("progressiveChunkMode")?n:null;t.pipelineContext=i.context={progressiveRender:o,modDataCount:r,large:a}},uT.restorePipelines=function(t){var e=this,i=e._pipelineMap=R();t.eachSeries(function(t){var n=t.getProgressive(),o=t.uid;i.set(o,{id:o,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:n&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(n||700),count:0}),jr(e,t,t.dataTask)})},uT.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.ecInstance.getModel(),i=this.api;d(this._allHandlers,function(n){var o=t.get(n.uid)||t.set(n.uid,[]);n.reset&&zr(this,n,o,e,i),n.overallReset&&Br(this,n,o,e,i)},this)},uT.prepareView=function(t,e,i,n){var o=t.renderTask,a=o.context;a.model=e,a.ecModel=i,a.api=n,o.__block=!t.incrementalPrepareRender,jr(this,e,o)},uT.performDataProcessorTasks=function(t,e){Rr(this,this._dataProcessorHandlers,t,e,{block:!0})},uT.performVisualTasks=function(t,e,i){Rr(this,this._visualHandlers,t,e,i)},uT.performSeriesTasks=function(t){var e;t.eachSeries(function(t){e|=t.dataTask.perform()}),this.unfinished|=e},uT.plan=function(){this._pipelineMap.each(function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)})};var hT=uT.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},cT=Ur(0);Er.wrapStageHandler=function(t,e){return x(t)&&(t={overallReset:t,seriesType:Yr(t)}),t.uid=Ro("stageHandler"),e&&(t.visualType=e),t};var dT,fT={},pT={};qr(fT,MI),qr(pT,Ga),fT.eachSeriesByType=fT.eachRawSeriesByType=function(t){dT=t},fT.eachComponent=function(t){"series"===t.mainType&&t.subType&&(dT=t.subType)};var gT=["#37A2DA","#32C5E9","#67E0E3","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#E062AE","#E690D1","#e7bcf3","#9d96f5","#8378EA","#96BFFF"],mT={color:gT,colorLayer:[["#37A2DA","#ffd85c","#fd7b5f"],["#37A2DA","#67E0E3","#FFDB5C","#ff9f7f","#E062AE","#9d96f5"],["#37A2DA","#32C5E9","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#e7bcf3","#8378EA","#96BFFF"],gT]},vT=["#dd6b66","#759aa0","#e69d87","#8dc1a9","#ea7e53","#eedd78","#73a373","#73b9bc","#7289ab","#91ca8c","#f49f42"],yT={color:vT,backgroundColor:"#333",tooltip:{axisPointer:{lineStyle:{color:"#eee"},crossStyle:{color:"#eee"}}},legend:{textStyle:{color:"#eee"}},textStyle:{color:"#eee"},title:{textStyle:{color:"#eee"}},toolbox:{iconStyle:{normal:{borderColor:"#eee"}}},dataZoom:{textStyle:{color:"#eee"}},visualMap:{textStyle:{color:"#eee"}},timeline:{lineStyle:{color:"#eee"},itemStyle:{normal:{color:vT[1]}},label:{normal:{textStyle:{color:"#eee"}}},controlStyle:{normal:{color:"#eee",borderColor:"#eee"}}},timeAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},logAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},valueAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},categoryAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},line:{symbol:"circle"},graph:{color:vT},gauge:{title:{textStyle:{color:"#eee"}}},candlestick:{itemStyle:{normal:{color:"#FD1050",color0:"#0CF49B",borderColor:"#FD1050",borderColor0:"#0CF49B"}}}};yT.categoryAxis.splitLine.show=!1,lI.extend({type:"dataset",defaultOption:{seriesLayoutBy:_I,sourceHeader:null,dimensions:null,source:null},optionUpdated:function(){wa(this)}}),qI.extend({type:"dataset"});var xT=Pn.extend({type:"ellipse",shape:{cx:0,cy:0,rx:0,ry:0},buildPath:function(t,e){var i=.5522848,n=e.cx,o=e.cy,a=e.rx,r=e.ry,s=a*i,l=r*i;t.moveTo(n-a,o),t.bezierCurveTo(n-a,o-l,n-s,o-r,n,o-r),t.bezierCurveTo(n+s,o-r,n+a,o-l,n+a,o),t.bezierCurveTo(n+a,o+l,n+s,o+r,n,o+r),t.bezierCurveTo(n-s,o+r,n-a,o+l,n-a,o),t.closePath()}}),_T=/[\s,]+/;$r.prototype.parse=function(t,e){e=e||{};var i=Kr(t);if(!i)throw new Error("Illegal svg");var n=new tb;this._root=n;var o=i.getAttribute("viewBox")||"",a=parseFloat(i.getAttribute("width")||e.width),r=parseFloat(i.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(r)&&(r=null),es(i,n,null,!0);for(var s=i.firstChild;s;)this._parseNode(s,n),s=s.nextSibling;var l,u;if(o){var h=P(o).split(_T);h.length>=4&&(l={x:parseFloat(h[0]||0),y:parseFloat(h[1]||0),width:parseFloat(h[2]),height:parseFloat(h[3])})}if(l&&null!=a&&null!=r&&(u=as(l,a,r),!e.ignoreViewBox)){var c=n;(n=new tb).add(c),c.scale=u.scale.slice(),c.position=u.position.slice()}return e.ignoreRootClip||null==a||null==r||n.setClipPath(new yM({shape:{x:0,y:0,width:a,height:r}})),{root:n,width:a,height:r,viewBoxRect:l,viewBoxTransform:u}},$r.prototype._parseNode=function(t,e){var i=t.nodeName.toLowerCase();"defs"===i?this._isDefine=!0:"text"===i&&(this._isText=!0);var n;if(this._isDefine){if(r=bT[i]){var o=r.call(this,t),a=t.getAttribute("id");a&&(this._defs[a]=o)}}else{var r=wT[i];r&&(n=r.call(this,t,e),e.add(n))}for(var s=t.firstChild;s;)1===s.nodeType&&this._parseNode(s,n),3===s.nodeType&&this._isText&&this._parseText(s,n),s=s.nextSibling;"defs"===i?this._isDefine=!1:"text"===i&&(this._isText=!1)},$r.prototype._parseText=function(t,e){if(1===t.nodeType){var i=t.getAttribute("dx")||0,n=t.getAttribute("dy")||0;this._textX+=parseFloat(i),this._textY+=parseFloat(n)}var o=new rM({style:{text:t.textContent,transformText:!0},position:[this._textX||0,this._textY||0]});Qr(e,o),es(t,o,this._defs);var a=o.style.fontSize;a&&a<9&&(o.style.fontSize=9,o.scale=o.scale||[1,1],o.scale[0]*=a/9,o.scale[1]*=a/9);var r=o.getBoundingRect();return this._textX+=r.width,e.add(o),o};var wT={g:function(t,e){var i=new tb;return Qr(e,i),es(t,i,this._defs),i},rect:function(t,e){var i=new yM;return Qr(e,i),es(t,i,this._defs),i.setShape({x:parseFloat(t.getAttribute("x")||0),y:parseFloat(t.getAttribute("y")||0),width:parseFloat(t.getAttribute("width")||0),height:parseFloat(t.getAttribute("height")||0)}),i},circle:function(t,e){var i=new sM;return Qr(e,i),es(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),r:parseFloat(t.getAttribute("r")||0)}),i},line:function(t,e){var i=new _M;return Qr(e,i),es(t,i,this._defs),i.setShape({x1:parseFloat(t.getAttribute("x1")||0),y1:parseFloat(t.getAttribute("y1")||0),x2:parseFloat(t.getAttribute("x2")||0),y2:parseFloat(t.getAttribute("y2")||0)}),i},ellipse:function(t,e){var i=new xT;return Qr(e,i),es(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),rx:parseFloat(t.getAttribute("rx")||0),ry:parseFloat(t.getAttribute("ry")||0)}),i},polygon:function(t,e){var i=t.getAttribute("points");i&&(i=ts(i));var n=new pM({shape:{points:i||[]}});return Qr(e,n),es(t,n,this._defs),n},polyline:function(t,e){var i=new Pn;Qr(e,i),es(t,i,this._defs);var n=t.getAttribute("points");return n&&(n=ts(n)),new gM({shape:{points:n||[]}})},image:function(t,e){var i=new fi;return Qr(e,i),es(t,i,this._defs),i.setStyle({image:t.getAttribute("xlink:href"),x:t.getAttribute("x"),y:t.getAttribute("y"),width:t.getAttribute("width"),height:t.getAttribute("height")}),i},text:function(t,e){var i=t.getAttribute("x")||0,n=t.getAttribute("y")||0,o=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0;this._textX=parseFloat(i)+parseFloat(o),this._textY=parseFloat(n)+parseFloat(a);var r=new tb;return Qr(e,r),es(t,r,this._defs),r},tspan:function(t,e){var i=t.getAttribute("x"),n=t.getAttribute("y");null!=i&&(this._textX=parseFloat(i)),null!=n&&(this._textY=parseFloat(n));var o=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0,r=new tb;return Qr(e,r),es(t,r,this._defs),this._textX+=o,this._textY+=a,r},path:function(t,e){var i=Rn(t.getAttribute("d")||"");return Qr(e,i),es(t,i,this._defs),i}},bT={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||0,10),i=parseInt(t.getAttribute("y1")||0,10),n=parseInt(t.getAttribute("x2")||10,10),o=parseInt(t.getAttribute("y2")||0,10),a=new TM(e,i,n,o);return Jr(t,a),a},radialgradient:function(t){}},ST={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-align":"textAlign","alignment-baseline":"textBaseline"},MT=/url\(\s*#(.*?)\)/,IT=/(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.e,]*)\)/g,TT=/([^\s:;]+)\s*:\s*([^:;]+)/g,AT=R(),DT={registerMap:function(t,e,i){var n;return y(e)?n=e:e.svg?n=[{type:"svg",source:e.svg,specialAreas:e.specialAreas}]:(e.geoJson&&!e.features&&(i=e.specialAreas,e=e.geoJson),n=[{type:"geoJSON",source:e,specialAreas:i}]),d(n,function(t){var e=t.type;"geoJson"===e&&(e=t.type="geoJSON"),(0,CT[e])(t)}),AT.set(t,n)},retrieveMap:function(t){return AT.get(t)}},CT={geoJSON:function(t){var e=t.source;t.geoJSON=_(e)?"undefined"!=typeof JSON&&JSON.parse?JSON.parse(e):new Function("return ("+e+");")():e},svg:function(t){t.svgXML=Kr(t.source)}},LT=k,kT=d,PT=x,NT=w,OT=lI.parseClassType,ET={zrender:"4.0.6"},RT=1e3,zT=1e3,BT=3e3,VT={PROCESSOR:{FILTER:RT,STATISTIC:5e3},VISUAL:{LAYOUT:zT,GLOBAL:2e3,CHART:BT,COMPONENT:4e3,BRUSH:5e3}},GT="__flagInMainProcess",FT="__optionUpdated",WT=/^[a-zA-Z0-9_]+$/;ls.prototype.on=ss("on"),ls.prototype.off=ss("off"),ls.prototype.one=ss("one"),h(ls,fw);var HT=us.prototype;HT._onframe=function(){if(!this._disposed){var t=this._scheduler;if(this[FT]){var e=this[FT].silent;this[GT]=!0,cs(this),ZT.update.call(this),this[GT]=!1,this[FT]=!1,gs.call(this,e),ms.call(this,e)}else if(t.unfinished){var i=1,n=this._model;this._api;t.unfinished=!1;do{var o=+new Date;t.performSeriesTasks(n),t.performDataProcessorTasks(n),fs(this,n),t.performVisualTasks(n),bs(this,this._model,0,"remain"),i-=+new Date-o}while(i>0&&t.unfinished);t.unfinished||this._zr.flush()}}},HT.getDom=function(){return this._dom},HT.getZr=function(){return this._zr},HT.setOption=function(t,e,i){var n;if(NT(e)&&(i=e.lazyUpdate,n=e.silent,e=e.notMerge),this[GT]=!0,!this._model||e){var o=new Wa(this._api),a=this._theme,r=this._model=new MI(null,null,a,o);r.scheduler=this._scheduler,r.init(null,null,a,o)}this._model.setOption(t,qT),i?(this[FT]={silent:n},this[GT]=!1):(cs(this),ZT.update.call(this),this._zr.flush(),this[FT]=!1,this[GT]=!1,gs.call(this,n),ms.call(this,n))},HT.setTheme=function(){console.error("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},HT.getModel=function(){return this._model},HT.getOption=function(){return this._model&&this._model.getOption()},HT.getWidth=function(){return this._zr.getWidth()},HT.getHeight=function(){return this._zr.getHeight()},HT.getDevicePixelRatio=function(){return this._zr.painter.dpr||window.devicePixelRatio||1},HT.getRenderedCanvas=function(t){if(U_.canvasSupported)return(t=t||{}).pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor"),this._zr.painter.getRenderedCanvas(t)},HT.getSvgDataUrl=function(){if(U_.svgSupported){var t=this._zr;return d(t.storage.getDisplayList(),function(t){t.stopAnimation(!0)}),t.painter.pathToDataUrl()}},HT.getDataURL=function(t){var e=(t=t||{}).excludeComponents,i=this._model,n=[],o=this;kT(e,function(t){i.eachComponent({mainType:t},function(t){var e=o._componentsMap[t.__viewId];e.group.ignore||(n.push(e),e.group.ignore=!0)})});var a="svg"===this._zr.painter.getType()?this.getSvgDataUrl():this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return kT(n,function(t){t.group.ignore=!1}),a},HT.getConnectedDataURL=function(t){if(U_.canvasSupported){var e=this.group,n=Math.min,o=Math.max;if(eA[e]){var a=1/0,r=1/0,s=-1/0,l=-1/0,u=[],h=t&&t.pixelRatio||1;d(tA,function(h,c){if(h.group===e){var d=h.getRenderedCanvas(i(t)),f=h.getDom().getBoundingClientRect();a=n(f.left,a),r=n(f.top,r),s=o(f.right,s),l=o(f.bottom,l),u.push({dom:d,left:f.left,top:f.top})}});var c=(s*=h)-(a*=h),f=(l*=h)-(r*=h),p=iw();p.width=c,p.height=f;var g=Ii(p);return kT(u,function(t){var e=new fi({style:{x:t.left*h-a,y:t.top*h-r,image:t.dom}});g.add(e)}),g.refreshImmediately(),p.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}},HT.convertToPixel=v(hs,"convertToPixel"),HT.convertFromPixel=v(hs,"convertFromPixel"),HT.containPixel=function(t,e){var i;return t=Vi(this._model,t),d(t,function(t,n){n.indexOf("Models")>=0&&d(t,function(t){var o=t.coordinateSystem;if(o&&o.containPoint)i|=!!o.containPoint(e);else if("seriesModels"===n){var a=this._chartsMap[t.__viewId];a&&a.containPoint&&(i|=a.containPoint(e,t))}},this)},this),!!i},HT.getVisual=function(t,e){var i=(t=Vi(this._model,t,{defaultMainType:"series"})).seriesModel.getData(),n=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?i.indexOfRawIndex(t.dataIndex):null;return null!=n?i.getItemVisual(n,e):i.getVisual(e)},HT.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},HT.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]};var ZT={prepareAndUpdate:function(t){cs(this),ZT.update.call(this,t)},update:function(t){var e=this._model,i=this._api,n=this._zr,o=this._coordSysMgr,a=this._scheduler;if(e){a.restoreData(e,t),a.performSeriesTasks(e),o.create(e,i),a.performDataProcessorTasks(e,t),fs(this,e),o.update(e,i),xs(e),a.performVisualTasks(e,t),_s(this,e,i,t);var r=e.get("backgroundColor")||"transparent";if(U_.canvasSupported)n.setBackgroundColor(r);else{var s=Gt(r);r=qt(s,"rgb"),0===s[3]&&(r="transparent")}Ss(e,i)}},updateTransform:function(t){var e=this._model,i=this,n=this._api;if(e){var o=[];e.eachComponent(function(a,r){var s=i.getViewOfComponentModel(r);if(s&&s.__alive)if(s.updateTransform){var l=s.updateTransform(r,e,n,t);l&&l.update&&o.push(s)}else o.push(s)});var a=R();e.eachSeries(function(o){var r=i._chartsMap[o.__viewId];if(r.updateTransform){var s=r.updateTransform(o,e,n,t);s&&s.update&&a.set(o.uid,1)}else a.set(o.uid,1)}),xs(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0,dirtyMap:a}),bs(i,e,0,t,a),Ss(e,this._api)}},updateView:function(t){var e=this._model;e&&(Ar.markUpdateMethod(t,"updateView"),xs(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0}),_s(this,this._model,this._api,t),Ss(e,this._api))},updateVisual:function(t){ZT.update.call(this,t)},updateLayout:function(t){ZT.update.call(this,t)}};HT.resize=function(t){this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var i=e.resetOption("media"),n=t&&t.silent;this[GT]=!0,i&&cs(this),ZT.update.call(this),this[GT]=!1,gs.call(this,n),ms.call(this,n)}},HT.showLoading=function(t,e){if(NT(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),QT[t]){var i=QT[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},HT.hideLoading=function(){this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null},HT.makeActionFromEvent=function(t){var e=a({},t);return e.type=jT[t.type],e},HT.dispatchAction=function(t,e){NT(e)||(e={silent:!!e}),XT[t.type]&&this._model&&(this[GT]?this._pendingActions.push(t):(ps.call(this,t,e.silent),e.flush?this._zr.flush(!0):!1!==e.flush&&U_.browser.weChat&&this._throttledZrFlush(),gs.call(this,e.silent),ms.call(this,e.silent)))},HT.appendData=function(t){var e=t.seriesIndex;this.getModel().getSeriesByIndex(e).appendData(t),this._scheduler.unfinished=!0},HT.on=ss("on"),HT.off=ss("off"),HT.one=ss("one");var UT=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];HT._initEvents=function(){kT(UT,function(t){var e=function(e){var i,n=this.getModel(),o=e.target;if("globalout"===t)i={};else if(o&&null!=o.dataIndex){var r=o.dataModel||n.getSeriesByIndex(o.seriesIndex);i=r&&r.getDataParams(o.dataIndex,o.dataType,o)||{}}else o&&o.eventData&&(i=a({},o.eventData));if(i){var s=i.componentType,l=i.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=i.seriesIndex);var u=s&&null!=l&&n.getComponent(s,l),h=u&&this["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];i.event=e,i.type=t,this._ecEventProcessor.eventInfo={targetEl:o,packedEvent:i,model:u,view:h},this.trigger(t,i)}};e.zrEventfulCallAtLast=!0,this._zr.on(t,e,this)},this),kT(jT,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},HT.isDisposed=function(){return this._disposed},HT.clear=function(){this.setOption({series:[]},!0)},HT.dispose=function(){if(!this._disposed){this._disposed=!0,Fi(this.getDom(),oA,"");var t=this._api,e=this._model;kT(this._componentsViews,function(i){i.dispose(e,t)}),kT(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete tA[this.id]}},h(us,fw),Ds.prototype={constructor:Ds,normalizeQuery:function(t){var e={},i={},n={};if(_(t)){var o=OT(t);e.mainType=o.main||null,e.subType=o.sub||null}else{var a=["Index","Name","Id"],r={name:1,dataIndex:1,dataType:1};d(t,function(t,o){for(var s=!1,l=0;l0&&h===o.length-u.length){var c=o.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}r.hasOwnProperty(o)&&(i[o]=t,s=!0),s||(n[o]=t)})}return{cptQuery:e,dataQuery:i,otherQuery:n}},filter:function(t,e,i){function n(t,e,i,n){return null==t[i]||e[n||i]===t[i]}var o=this.eventInfo;if(!o)return!0;var a=o.targetEl,r=o.packedEvent,s=o.model,l=o.view;if(!s||!l)return!0;var u=e.cptQuery,h=e.dataQuery;return n(u,s,"mainType")&&n(u,s,"subType")&&n(u,s,"index","componentIndex")&&n(u,s,"name")&&n(u,s,"id")&&n(h,r,"name")&&n(h,r,"dataIndex")&&n(h,r,"dataType")&&(!l.filterForExposedEvent||l.filterForExposedEvent(t,e.otherQuery,a,r))},afterTrigger:function(){this.eventInfo=null}};var XT={},jT={},YT=[],qT=[],KT=[],$T=[],JT={},QT={},tA={},eA={},iA=new Date-0,nA=new Date-0,oA="_echarts_instance_",aA=Ls;Bs(2e3,aT),Ns(BI),Os(5e3,function(t){var e=R();t.eachSeries(function(t){var i=t.get("stack");if(i){var n=e.get(i)||e.set(i,[]),o=t.getData(),a={stackResultDimension:o.getCalculationInfo("stackResultDimension"),stackedOverDimension:o.getCalculationInfo("stackedOverDimension"),stackedDimension:o.getCalculationInfo("stackedDimension"),stackedByDimension:o.getCalculationInfo("stackedByDimension"),isStackedByIndex:o.getCalculationInfo("isStackedByIndex"),data:o,seriesModel:t};if(!a.stackedDimension||!a.isStackedByIndex&&!a.stackedByDimension)return;n.length&&o.setCalculationInfo("stackedOnSeries",n[n.length-1].seriesModel),n.push(a)}}),e.each(ar)}),Gs("default",function(t,e){r(e=e||{},{text:"loading",color:"#c23531",textColor:"#000",maskColor:"rgba(255, 255, 255, 0.8)",zlevel:0});var i=new yM({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4}),n=new SM({shape:{startAngle:-lT/2,endAngle:-lT/2+.1,r:10},style:{stroke:e.color,lineCap:"round",lineWidth:5},zlevel:e.zlevel,z:10001}),o=new yM({style:{fill:"none",text:e.text,textPosition:"right",textDistance:10,textFill:e.textColor},zlevel:e.zlevel,z:10001});n.animateShape(!0).when(1e3,{endAngle:3*lT/2}).start("circularInOut"),n.animateShape(!0).when(1e3,{startAngle:3*lT/2}).delay(300).start("circularInOut");var a=new tb;return a.add(n),a.add(o),a.add(i),a.resize=function(){var e=t.getWidth()/2,a=t.getHeight()/2;n.setShape({cx:e,cy:a});var r=n.shape.r;o.setShape({x:e-r,y:a-r,width:2*r,height:2*r}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},a.resize(),a}),Es({type:"highlight",event:"highlight",update:"highlight"},B),Es({type:"downplay",event:"downplay",update:"downplay"},B),Ps("light",mT),Ps("dark",yT);var rA={};Xs.prototype={constructor:Xs,add:function(t){return this._add=t,this},update:function(t){return this._update=t,this},remove:function(t){return this._remove=t,this},execute:function(){var t=this._old,e=this._new,i={},n=[],o=[];for(js(t,{},n,"_oldKeyGetter",this),js(e,i,o,"_newKeyGetter",this),a=0;ax[1]&&(x[1]=y)}e&&(this._nameList[d]=e[f])}this._rawCount=this._count=l,this._extent={},el(this)},yA._initDataFromProvider=function(t,e){if(!(t>=e)){for(var i,n=this._chunkSize,o=this._rawData,a=this._storage,r=this.dimensions,s=r.length,l=this._dimensionInfos,u=this._nameList,h=this._idList,c=this._rawExtent,d=this._nameRepeatCount={},f=this._chunkCount,p=0;pM[1]&&(M[1]=S)}if(!o.pure){var I=u[v];if(m&&null==I)if(null!=m.name)u[v]=I=m.name;else if(null!=i){var T=r[i],A=a[T][y];if(A){I=A[x];var D=l[T].ordinalMeta;D&&D.categories.length&&(I=D.categories[I])}}var C=null==m?null:m.id;null==C&&null!=I&&(d[I]=d[I]||0,C=I,d[I]>0&&(C+="__ec__"+d[I]),d[I]++),null!=C&&(h[v]=C)}}!o.persistent&&o.clean&&o.clean(),this._rawCount=this._count=e,this._extent={},el(this)}},yA.count=function(){return this._count},yA.getIndices=function(){var t=this._indices;if(t){var e=t.constructor,i=this._count;if(e===Array){n=new e(i);for(o=0;o=0&&e=0&&ea&&(a=s)}return i=[o,a],this._extent[t]=i,i},yA.getApproximateExtent=function(t){return t=this.getDimension(t),this._approximateExtent[t]||this.getDataExtent(t)},yA.setApproximateExtent=function(t,e){e=this.getDimension(e),this._approximateExtent[e]=t.slice()},yA.getCalculationInfo=function(t){return this._calculationInfo[t]},yA.setCalculationInfo=function(t,e){lA(t)?a(this._calculationInfo,t):this._calculationInfo[t]=e},yA.getSum=function(t){var e=0;if(this._storage[t])for(var i=0,n=this.count();i=this._rawCount||t<0)return-1;var e=this._indices,i=e[t];if(null!=i&&it))return a;o=a-1}}return-1},yA.indicesOfNearest=function(t,e,i){var n=[];if(!this._storage[t])return n;null==i&&(i=1/0);for(var o=Number.MAX_VALUE,a=-1,r=0,s=this.count();r=0&&a<0)&&(o=u,a=l,n.length=0),n.push(r))}return n},yA.getRawIndex=nl,yA.getRawDataItem=function(t){if(this._rawData.persistent)return this._rawData.getItem(this.getRawIndex(t));for(var e=[],i=0;i=l&&w<=u||isNaN(w))&&(a[r++]=c),c++;h=!0}else if(2===n){for(var d=this._storage[s],v=this._storage[e[1]],y=t[e[1]][0],x=t[e[1]][1],f=0;f=l&&w<=u||isNaN(w))&&(b>=y&&b<=x||isNaN(b))&&(a[r++]=c),c++}h=!0}}if(!h)if(1===n)for(m=0;m=l&&w<=u||isNaN(w))&&(a[r++]=M)}else for(m=0;mt[I][1])&&(S=!1)}S&&(a[r++]=this.getRawIndex(m))}return rb[1]&&(b[1]=w)}}}return o},yA.downSample=function(t,e,i,n){for(var o=sl(this,[t]),a=o._storage,r=[],s=Math.floor(1/e),l=a[t],u=this.count(),h=this._chunkSize,c=o._rawExtent[t],d=new($s(this))(u),f=0,p=0;pu-p&&(s=u-p,r.length=s);for(var g=0;gc[1]&&(c[1]=x),d[f++]=_}return o._count=f,o._indices=d,o.getRawIndex=ol,o},yA.getItemModel=function(t){var e=this.hostModel;return new No(this.getRawDataItem(t),e,e&&e.ecModel)},yA.diff=function(t){var e=this;return new Xs(t?t.getIndices():[],this.getIndices(),function(e){return al(t,e)},function(t){return al(e,t)})},yA.getVisual=function(t){var e=this._visual;return e&&e[t]},yA.setVisual=function(t,e){if(lA(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},yA.setLayout=function(t,e){if(lA(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},yA.getLayout=function(t){return this._layout[t]},yA.getItemLayout=function(t){return this._itemLayouts[t]},yA.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?a(this._itemLayouts[t]||{},e):e},yA.clearItemLayouts=function(){this._itemLayouts.length=0},yA.getItemVisual=function(t,e,i){var n=this._itemVisuals[t],o=n&&n[e];return null!=o||i?o:this.getVisual(e)},yA.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{},o=this.hasItemVisual;if(this._itemVisuals[t]=n,lA(e))for(var a in e)e.hasOwnProperty(a)&&(n[a]=e[a],o[a]=!0);else n[e]=i,o[e]=!0},yA.clearAllVisual=function(){this._visual={},this._itemVisuals=[],this.hasItemVisual={}};var xA=function(t){t.seriesIndex=this.seriesIndex,t.dataIndex=this.dataIndex,t.dataType=this.dataType};yA.setItemGraphicEl=function(t,e){var i=this.hostModel;e&&(e.dataIndex=t,e.dataType=this.dataType,e.seriesIndex=i&&i.seriesIndex,"group"===e.type&&e.traverse(xA,e)),this._graphicEls[t]=e},yA.getItemGraphicEl=function(t){return this._graphicEls[t]},yA.eachItemGraphicEl=function(t,e){d(this._graphicEls,function(i,n){i&&t&&t.call(e,i,n)})},yA.cloneShallow=function(t){if(!t){var e=f(this.dimensions,this.getDimensionInfo,this);t=new vA(e,this.hostModel)}if(t._storage=this._storage,Qs(t,this),this._indices){var i=this._indices.constructor;t._indices=new i(this._indices)}else t._indices=null;return t.getRawIndex=t._indices?ol:nl,t},yA.wrapMethod=function(t,e){var i=this[t];"function"==typeof i&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=i.apply(this,arguments);return e.apply(this,[t].concat(C(arguments)))})},yA.TRANSFERABLE_METHODS=["cloneShallow","downSample","map"],yA.CHANGABLE_METHODS=["filterSelf","selectRange"];var _A=function(t,e){return e=e||{},hl(e.coordDimensions||[],t,{dimsDef:e.dimensionsDefine||t.dimensionsDefine,encodeDef:e.encodeDefine||t.encodeDefine,dimCount:e.dimensionsCount,generateCoord:e.generateCoord,generateCoordCount:e.generateCoordCount})};xl.prototype.parse=function(t){return t},xl.prototype.getSetting=function(t){return this._setting[t]},xl.prototype.contain=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},xl.prototype.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},xl.prototype.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},xl.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},xl.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},xl.prototype.getExtent=function(){return this._extent.slice()},xl.prototype.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},xl.prototype.isBlank=function(){return this._isBlank},xl.prototype.setBlank=function(t){this._isBlank=t},xl.prototype.getLabel=null,ji(xl),$i(xl,{registerWhenExtend:!0}),_l.createByAxisModel=function(t){var e=t.option,i=e.data,n=i&&f(i,bl);return new _l({categories:n,needCollect:!n,deduplication:!1!==e.dedplication})};var wA=_l.prototype;wA.getOrdinal=function(t){return wl(this).get(t)},wA.parseAndCollect=function(t){var e,i=this._needCollect;if("string"!=typeof t&&!i)return t;if(i&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var n=wl(this);return null==(e=n.get(t))&&(i?(e=this.categories.length,this.categories[e]=t,n.set(t,e)):e=NaN),e};var bA=xl.prototype,SA=xl.extend({type:"ordinal",init:function(t,e){t&&!y(t)||(t=new _l({categories:t})),this._ordinalMeta=t,this._extent=e||[0,t.categories.length-1]},parse:function(t){return"string"==typeof t?this._ordinalMeta.getOrdinal(t):Math.round(t)},contain:function(t){return t=this.parse(t),bA.contain.call(this,t)&&null!=this._ordinalMeta.categories[t]},normalize:function(t){return bA.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(bA.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){if(!this.isBlank())return this._ordinalMeta.categories[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},getOrdinalMeta:function(){return this._ordinalMeta},niceTicks:B,niceExtent:B});SA.create=function(){return new SA};var MA=Go,IA=Go,TA=xl.extend({type:"interval",_interval:0,_intervalPrecision:2,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),TA.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=Ml(t)},getTicks:function(){return Al(this._interval,this._extent,this._niceExtent,this._intervalPrecision)},getLabel:function(t,e){if(null==t)return"";var i=e&&e.precision;return null==i?i=Ho(t)||0:"auto"===i&&(i=this._intervalPrecision),t=IA(t,i,!0),ta(t)},niceTicks:function(t,e,i){t=t||5;var n=this._extent,o=n[1]-n[0];if(isFinite(o)){o<0&&(o=-o,n.reverse());var a=Sl(n,t,e,i);this._intervalPrecision=a.intervalPrecision,this._interval=a.interval,this._niceExtent=a.niceTickExtent}},niceExtent:function(t){var e=this._extent;if(e[0]===e[1])if(0!==e[0]){var i=e[0];t.fixMax?e[0]-=i/2:(e[1]+=i/2,e[0]-=i/2)}else e[1]=1;var n=e[1]-e[0];isFinite(n)||(e[0]=0,e[1]=1),this.niceTicks(t.splitNumber,t.minInterval,t.maxInterval);var o=this._interval;t.fixMin||(e[0]=IA(Math.floor(e[0]/o)*o)),t.fixMax||(e[1]=IA(Math.ceil(e[1]/o)*o))}});TA.create=function(){return new TA};var AA="__ec_stack_",DA="undefined"!=typeof Float32Array?Float32Array:Array,CA={seriesType:"bar",plan:$I(),reset:function(t){if(Rl(t)&&zl(t)){var e=t.getData(),i=t.coordinateSystem,n=i.getBaseAxis(),o=i.getOtherAxis(n),a=e.mapDimension(o.dim),r=e.mapDimension(n.dim),s=o.isHorizontal(),l=s?0:1,u=Ol(Pl([t]),n,t).width;return u>.5||(u=.5),{progress:function(t,e){for(var n,h=new DA(2*t.count),c=[],d=[],f=0;null!=(n=t.next());)d[l]=e.get(a,n),d[1-l]=e.get(r,n),c=i.dataToPoint(d,null,c),h[f++]=c[0],h[f++]=c[1];e.setLayout({largePoints:h,barWidth:u,valueAxisStart:Bl(0,o),valueAxisHorizontal:s})}}}}},LA=TA.prototype,kA=Math.ceil,PA=Math.floor,NA=function(t,e,i,n){for(;i>>1;t[o][1]i&&(a=i);var r=EA.length,s=NA(EA,a,0,r),l=EA[Math.min(s,r-1)],u=l[1];"year"===l[0]&&(u*=$o(o/u/t,!0));var h=this.getSetting("useUTC")?0:60*new Date(+n[0]||+n[1]).getTimezoneOffset()*1e3,c=[Math.round(kA((n[0]-h)/u)*u+h),Math.round(PA((n[1]-h)/u)*u+h)];Tl(c,n),this._stepLvl=l,this._interval=u,this._niceExtent=c},parse:function(t){return+Yo(t)}});d(["contain","normalize"],function(t){OA.prototype[t]=function(e){return LA[t].call(this,this.parse(e))}});var EA=[["hh:mm:ss",1e3],["hh:mm:ss",5e3],["hh:mm:ss",1e4],["hh:mm:ss",15e3],["hh:mm:ss",3e4],["hh:mm\nMM-dd",6e4],["hh:mm\nMM-dd",3e5],["hh:mm\nMM-dd",6e5],["hh:mm\nMM-dd",9e5],["hh:mm\nMM-dd",18e5],["hh:mm\nMM-dd",36e5],["hh:mm\nMM-dd",72e5],["hh:mm\nMM-dd",216e5],["hh:mm\nMM-dd",432e5],["MM-dd\nyyyy",864e5],["MM-dd\nyyyy",1728e5],["MM-dd\nyyyy",2592e5],["MM-dd\nyyyy",3456e5],["MM-dd\nyyyy",432e6],["MM-dd\nyyyy",5184e5],["week",6048e5],["MM-dd\nyyyy",864e6],["week",12096e5],["week",18144e5],["month",26784e5],["week",36288e5],["month",53568e5],["week",6048e6],["quarter",8208e6],["month",107136e5],["month",13392e6],["half-year",16416e6],["month",214272e5],["month",26784e6],["year",32832e6]];OA.create=function(t){return new OA({useUTC:t.ecModel.get("useUTC")})};var RA=xl.prototype,zA=TA.prototype,BA=Ho,VA=Go,GA=Math.floor,FA=Math.ceil,WA=Math.pow,HA=Math.log,ZA=xl.extend({type:"log",base:10,$constructor:function(){xl.apply(this,arguments),this._originalScale=new TA},getTicks:function(){var t=this._originalScale,e=this._extent,i=t.getExtent();return f(zA.getTicks.call(this),function(n){var o=Go(WA(this.base,n));return o=n===e[0]&&t.__fixMin?Vl(o,i[0]):o,o=n===e[1]&&t.__fixMax?Vl(o,i[1]):o},this)},getLabel:zA.getLabel,scale:function(t){return t=RA.scale.call(this,t),WA(this.base,t)},setExtent:function(t,e){var i=this.base;t=HA(t)/HA(i),e=HA(e)/HA(i),zA.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,e=RA.getExtent.call(this);e[0]=WA(t,e[0]),e[1]=WA(t,e[1]);var i=this._originalScale,n=i.getExtent();return i.__fixMin&&(e[0]=Vl(e[0],n[0])),i.__fixMax&&(e[1]=Vl(e[1],n[1])),e},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=HA(t[0])/HA(e),t[1]=HA(t[1])/HA(e),RA.unionExtent.call(this,t)},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(i===1/0||i<=0)){var n=qo(i);for(t/i*n<=.5&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var o=[Go(FA(e[0]/n)*n),Go(GA(e[1]/n)*n)];this._interval=n,this._niceExtent=o}},niceExtent:function(t){zA.niceExtent.call(this,t);var e=this._originalScale;e.__fixMin=t.fixMin,e.__fixMax=t.fixMax}});d(["contain","normalize"],function(t){ZA.prototype[t]=function(e){return e=HA(e)/HA(this.base),RA[t].call(this,e)}}),ZA.create=function(){return new ZA};var UA={getMin:function(t){var e=this.option,i=t||null==e.rangeStart?e.min:e.rangeStart;return this.axis&&null!=i&&"dataMin"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getMax:function(t){var e=this.option,i=t||null==e.rangeEnd?e.max:e.rangeEnd;return this.axis&&null!=i&&"dataMax"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getNeedCrossZero:function(){var t=this.option;return null==t.rangeStart&&null==t.rangeEnd&&!t.scale},getCoordSysModel:B,setRange:function(t,e){this.option.rangeStart=t,this.option.rangeEnd=e},resetRange:function(){this.option.rangeStart=this.option.rangeEnd=null}},XA=Un({type:"triangle",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n+a),t.lineTo(i-o,n+a),t.closePath()}}),jA=Un({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n),t.lineTo(i,n+a),t.lineTo(i-o,n),t.closePath()}}),YA=Un({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,o=e.width/5*3,a=Math.max(o,e.height),r=o/2,s=r*r/(a-r),l=n-a+r+s,u=Math.asin(s/r),h=Math.cos(u)*r,c=Math.sin(u),d=Math.cos(u),f=.6*r,p=.7*r;t.moveTo(i-h,l+s),t.arc(i,l,r,Math.PI-u,2*Math.PI+u),t.bezierCurveTo(i+h-c*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-h+c*f,l+s+d*f,i-h,l+s),t.closePath()}}),qA=Un({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.height,n=e.width,o=e.x,a=e.y,r=n/3*2;t.moveTo(o,a),t.lineTo(o+r,a+i),t.lineTo(o,a+i/4*3),t.lineTo(o-r,a+i),t.lineTo(o,a),t.closePath()}}),KA={line:function(t,e,i,n,o){o.x1=t,o.y1=e+n/2,o.x2=t+i,o.y2=e+n/2},rect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n},roundRect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n,o.r=Math.min(i,n)/4},square:function(t,e,i,n,o){var a=Math.min(i,n);o.x=t,o.y=e,o.width=a,o.height=a},circle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.r=Math.min(i,n)/2},diamond:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n},pin:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},arrow:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},triangle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n}},$A={};d({line:_M,rect:yM,roundRect:yM,square:yM,circle:sM,diamond:jA,pin:YA,arrow:qA,triangle:XA},function(t,e){$A[e]=new t});var JA=Un({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},beforeBrush:function(){var t=this.style;"pin"===this.shape.symbolType&&"inside"===t.textPosition&&(t.textPosition=["50%","40%"],t.textAlign="center",t.textVerticalAlign="middle")},buildPath:function(t,e,i){var n=e.symbolType,o=$A[n];"none"!==e.symbolType&&(o||(o=$A[n="rect"]),KA[n](e.x,e.y,e.width,e.height,o.shape),o.buildPath(t,o.shape,i))}}),QA={isDimensionStacked:pl,enableDataStack:fl,getStackedDimension:gl},tD=(Object.freeze||Object)({createList:function(t){return ml(t.getSource(),t)},getLayoutRect:ca,dataStack:QA,createScale:function(t,e){var i=e;No.isInstance(e)||h(i=new No(e),UA);var n=Hl(i);return n.setExtent(t[0],t[1]),Wl(n,i),n},mixinAxisModelCommonMethods:function(t){h(t,UA)},completeDimensions:hl,createDimensions:_A,createSymbol:Jl}),eD=1e-8;eu.prototype={constructor:eu,properties:null,getBoundingRect:function(){var t=this._rect;if(t)return t;for(var e=Number.MAX_VALUE,i=[e,e],n=[-e,-e],o=[],a=[],r=this.geometries,s=0;s0}),function(t){var e=t.properties,i=t.geometry,n=i.coordinates,o=[];"Polygon"===i.type&&o.push({type:"polygon",exterior:n[0],interiors:n.slice(1)}),"MultiPolygon"===i.type&&d(n,function(t){t[0]&&o.push({type:"polygon",exterior:t[0],interiors:t.slice(1)})});var a=new eu(e.name,o,e.cp);return a.properties=e,a})},nD=Bi(),oD=[0,1],aD=function(t,e,i){this.dim=t,this.scale=e,this._extent=i||[0,0],this.inverse=!1,this.onBand=!1};aD.prototype={constructor:aD,contain:function(t){var e=this._extent,i=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return t>=i&&t<=n},containData:function(t){return this.contain(this.dataToCoord(t))},getExtent:function(){return this._extent.slice()},getPixelPrecision:function(t){return Zo(t||this.scale.getExtent(),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,e){var i=this._extent,n=this.scale;return t=n.normalize(t),this.onBand&&"ordinal"===n.type&&yu(i=i.slice(),n.count()),Bo(t,oD,i,e)},coordToData:function(t,e){var i=this._extent,n=this.scale;this.onBand&&"ordinal"===n.type&&yu(i=i.slice(),n.count());var o=Bo(t,i,oD,e);return this.scale.scale(o)},pointToData:function(t,e){},getTicksCoords:function(t){var e=(t=t||{}).tickModel||this.getTickModel(),i=au(this,e),n=f(i.ticks,function(t){return{coord:this.dataToCoord(t),tickValue:t}},this),o=e.get("alignWithLabel");return xu(this,n,i.tickCategoryInterval,o,t.clamp),n},getViewLabels:function(){return ou(this).labels},getLabelModel:function(){return this.model.getModel("axisLabel")},getTickModel:function(){return this.model.getModel("axisTick")},getBandWidth:function(){var t=this._extent,e=this.scale.getExtent(),i=e[1]-e[0]+(this.onBand?1:0);0===i&&(i=1);var n=Math.abs(t[1]-t[0]);return Math.abs(n)/i},isHorizontal:null,getRotate:null,calculateCategoryInterval:function(){return pu(this)}};var rD=iD,sD={};d(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend","defaults","clone","merge"],function(t){sD[t]=aw[t]});var lD={};d(["extendShape","extendPath","makePath","makeImage","mergePath","resizePath","createIcon","setHoverStyle","setLabelStyle","setTextStyle","setText","getFont","updateProps","initProps","getTransform","clipPointsByRect","clipRectByRect","Group","Image","Text","Circle","Sector","Ring","Polygon","Polyline","Rect","Line","BezierCurve","Arc","IncrementalDisplayable","CompoundPath","LinearGradient","RadialGradient","BoundingRect"],function(t){lD[t]=zM[t]}),YI.extend({type:"series.line",dependencies:["grid","polar"],getInitialData:function(t,e){return ml(this.getSource(),this)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clipOverflow:!0,label:{position:"top"},lineStyle:{width:2,type:"solid"},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}});var uD=wu.prototype,hD=wu.getSymbolSize=function(t,e){var i=t.getItemVisual(e,"symbolSize");return i instanceof Array?i.slice():[+i,+i]};uD._createSymbol=function(t,e,i,n,o){this.removeAll();var a=Jl(t,-1,-1,2,2,e.getItemVisual(i,"color"),o);a.attr({z2:100,culling:!0,scale:bu(n)}),a.drift=Su,this._symbolType=t,this.add(a)},uD.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(t)},uD.getSymbolPath=function(){return this.childAt(0)},uD.getScale=function(){return this.childAt(0).scale},uD.highlight=function(){this.childAt(0).trigger("emphasis")},uD.downplay=function(){this.childAt(0).trigger("normal")},uD.setZ=function(t,e){var i=this.childAt(0);i.zlevel=t,i.z=e},uD.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":"pointer"},uD.updateData=function(t,e,i){this.silent=!1;var n=t.getItemVisual(e,"symbol")||"circle",o=t.hostModel,a=hD(t,e),r=n!==this._symbolType;if(r){var s=t.getItemVisual(e,"symbolKeepAspect");this._createSymbol(n,t,e,a,s)}else(l=this.childAt(0)).silent=!1,Io(l,{scale:bu(a)},o,e);if(this._updateCommon(t,e,a,i),r){var l=this.childAt(0),u=i&&i.fadeIn,h={scale:l.scale.slice()};u&&(h.style={opacity:l.style.opacity}),l.scale=[0,0],u&&(l.style.opacity=0),To(l,h,o,e)}this._seriesModel=o};var cD=["itemStyle"],dD=["emphasis","itemStyle"],fD=["label"],pD=["emphasis","label"];uD._updateCommon=function(t,e,i,n){var o=this.childAt(0),r=t.hostModel,s=t.getItemVisual(e,"color");"image"!==o.type&&o.useStyle({strokeNoScale:!0});var l=n&&n.itemStyle,u=n&&n.hoverItemStyle,h=n&&n.symbolRotate,c=n&&n.symbolOffset,d=n&&n.labelModel,f=n&&n.hoverLabelModel,p=n&&n.hoverAnimation,g=n&&n.cursorStyle;if(!n||t.hasItemOption){var m=n&&n.itemModel?n.itemModel:t.getItemModel(e);l=m.getModel(cD).getItemStyle(["color"]),u=m.getModel(dD).getItemStyle(),h=m.getShallow("symbolRotate"),c=m.getShallow("symbolOffset"),d=m.getModel(fD),f=m.getModel(pD),p=m.getShallow("hoverAnimation"),g=m.getShallow("cursor")}else u=a({},u);var v=o.style;o.attr("rotation",(h||0)*Math.PI/180||0),c&&o.attr("position",[Vo(c[0],i[0]),Vo(c[1],i[1])]),g&&o.attr("cursor",g),o.setColor(s,n&&n.symbolInnerColor),o.setStyle(l);var y=t.getItemVisual(e,"opacity");null!=y&&(v.opacity=y);var x=t.getItemVisual(e,"liftZ"),_=o.__z2Origin;null!=x?null==_&&(o.__z2Origin=o.z2,o.z2+=x):null!=_&&(o.z2=_,o.__z2Origin=null);var w=n&&n.useNameLabel;go(v,u,d,f,{labelFetcher:r,labelDataIndex:e,defaultText:function(e,i){return w?t.getName(e):_u(t,e)},isRectText:!0,autoColor:s}),o.off("mouseover").off("mouseout").off("emphasis").off("normal"),o.hoverStyle=u,fo(o),o.__symbolOriginalScale=bu(i),p&&r.isAnimationEnabled()&&o.on("mouseover",Mu).on("mouseout",Iu).on("emphasis",Tu).on("normal",Au)},uD.fadeOut=function(t,e){var i=this.childAt(0);this.silent=i.silent=!0,!(e&&e.keepLabel)&&(i.style.text=null),Io(i,{style:{opacity:0},scale:[0,0]},this._seriesModel,this.dataIndex,t)},u(wu,tb);var gD=Du.prototype;gD.updateData=function(t,e){e=Lu(e);var i=this.group,n=t.hostModel,o=this._data,a=this._symbolCtor,r=ku(t);o||i.removeAll(),t.diff(o).add(function(n){var o=t.getItemLayout(n);if(Cu(t,o,n,e)){var s=new a(t,n,r);s.attr("position",o),t.setItemGraphicEl(n,s),i.add(s)}}).update(function(s,l){var u=o.getItemGraphicEl(l),h=t.getItemLayout(s);Cu(t,h,s,e)?(u?(u.updateData(t,s,r),Io(u,{position:h},n)):(u=new a(t,s)).attr("position",h),i.add(u),t.setItemGraphicEl(s,u)):i.remove(u)}).remove(function(t){var e=o.getItemGraphicEl(t);e&&e.fadeOut(function(){i.remove(e)})}).execute(),this._data=t},gD.isPersistent=function(){return!0},gD.updateLayout=function(){var t=this._data;t&&t.eachItemGraphicEl(function(e,i){var n=t.getItemLayout(i);e.attr("position",n)})},gD.incrementalPrepareUpdate=function(t){this._seriesScope=ku(t),this._data=null,this.group.removeAll()},gD.incrementalUpdate=function(t,e,i){i=Lu(i);for(var n=t.start;n0&&Ru(i[o-1]);o--);for(;n0&&Ru(i[a-1]);a--);for(;o=0){var r=o.getItemGraphicEl(a);if(!r){var s=o.getItemLayout(a);if(!s)return;(r=new wu(o,a)).position=s,r.setZ(t.get("zlevel"),t.get("z")),r.ignore=isNaN(s[0])||isNaN(s[1]),r.__temp=!0,o.setItemGraphicEl(a,r),r.stopSymbolAnimation(!0),this.group.add(r)}r.highlight()}else Ar.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var o=t.getData(),a=zi(o,n);if(null!=a&&a>=0){var r=o.getItemGraphicEl(a);r&&(r.__temp?(o.setItemGraphicEl(a,null),this.group.remove(r)):r.downplay())}else Ar.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new MD({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new ID({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_updateAnimation:function(t,e,i,n,o,a){var r=this._polyline,s=this._polygon,l=t.hostModel,u=mD(this._data,t,this._stackedOnPoints,e,this._coordSys,i,this._valueOrigin,a),h=u.current,c=u.stackedOnCurrent,d=u.next,f=u.stackedOnNext;o&&(h=Yu(u.current,i,o),c=Yu(u.stackedOnCurrent,i,o),d=Yu(u.next,i,o),f=Yu(u.stackedOnNext,i,o)),r.shape.__points=u.current,r.shape.points=h,Io(r,{shape:{points:d}},l),s&&(s.setShape({points:h,stackedOnPoints:c}),Io(s,{shape:{points:d,stackedOnPoints:f}},l));for(var p=[],g=u.status,m=0;me&&(e=t[i]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,i=0;ie[1]&&e.reverse(),e},getOtherAxis:function(){this.grid.getOtherAxis()},pointToData:function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},toLocalCoord:null,toGlobalCoord:null},u(kD,aD);var PD={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#333",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},ND={};ND.categoryAxis=n({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},PD),ND.valueAxis=n({boundaryGap:[0,0],splitNumber:5},PD),ND.timeAxis=r({scale:!0,min:"dataMin",max:"dataMax"},ND.valueAxis),ND.logAxis=r({scale:!0,logBase:10},ND.valueAxis);var OD=["value","category","time","log"],ED=function(t,e,i,a){d(OD,function(r){e.extend({type:t+"Axis."+r,mergeDefaultAndTheme:function(e,o){var a=this.layoutMode,s=a?ga(e):{};n(e,o.getTheme().get(r+"Axis")),n(e,this.getDefaultOption()),e.type=i(t,e),a&&pa(e,s,a)},optionUpdated:function(){"category"===this.option.type&&(this.__ordinalMeta=_l.createByAxisModel(this))},getCategories:function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},getOrdinalMeta:function(){return this.__ordinalMeta},defaultOption:o([{},ND[r+"Axis"],a],!0)})}),lI.registerSubTypeDefaulter(t+"Axis",v(i,t))},RD=lI.extend({type:"cartesian2dAxis",axis:null,init:function(){RD.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){RD.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){RD.superApply(this,"restoreData",arguments),this.resetRange()},getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"grid",index:this.option.gridIndex,id:this.option.gridId})[0]}});n(RD.prototype,UA);var zD={offset:0};ED("x",RD,th,zD),ED("y",RD,th,zD),lI.extend({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}});var BD=ih.prototype;BD.type="grid",BD.axisPointerEnabled=!0,BD.getRect=function(){return this._rect},BD.update=function(t,e){var i=this._axesMap;this._updateScale(t,this.model),d(i.x,function(t){Wl(t.scale,t.model)}),d(i.y,function(t){Wl(t.scale,t.model)});var n={};d(i.x,function(t){nh(i,"y",t,n)}),d(i.y,function(t){nh(i,"x",t,n)}),this.resize(this.model,e)},BD.resize=function(t,e,i){function n(){d(a,function(t){var e=t.isHorizontal(),i=e?[0,o.width]:[0,o.height],n=t.inverse?1:0;t.setExtent(i[n],i[1-n]),ah(t,e?o.x:o.y)})}var o=ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;n(),!i&&t.get("containLabel")&&(d(a,function(t){if(!t.model.get("axisLabel.inside")){var e=jl(t);if(e){var i=t.isHorizontal()?"height":"width",n=t.model.get("axisLabel.margin");o[i]-=e[i]+n,"top"===t.position?o.y+=e.height+n:"left"===t.position&&(o.x+=e.width+n)}}}),n())},BD.getAxis=function(t,e){var i=this._axesMap[t];if(null!=i){if(null==e)for(var n in i)if(i.hasOwnProperty(n))return i[n];return i[e]}},BD.getAxes=function(){return this._axesList.slice()},BD.getCartesian=function(t,e){if(null!=t&&null!=e){var i="x"+t+"y"+e;return this._coordsMap[i]}w(t)&&(e=t.yAxisIndex,t=t.xAxisIndex);for(var n=0,o=this._coordsList;nu[1]?-1:1,c=["start"===o?u[0]-h*l:"end"===o?u[1]+h*l:(u[0]+u[1])/2,ph(o)?t.labelOffset+r*l:0],d=e.get("nameRotate");null!=d&&(d=d*GD/180);var f;ph(o)?n=HD(t.rotation,null!=d?d:t.rotation,r):(n=uh(t,o,d||0,u),null!=(f=t.axisNameAvailableWidth)&&(f=Math.abs(f/Math.sin(n.rotation)),!isFinite(f)&&(f=null)));var p=s.getFont(),g=e.get("nameTruncate",!0)||{},m=g.ellipsis,v=T(t.nameTruncateMaxWidth,g.maxWidth,f),y=null!=m&&null!=v?tI(i,v,p,m,{minChar:2,placeholder:g.placeholder}):i,x=e.get("tooltip",!0),_=e.mainType,w={componentType:_,name:i,$vars:["name"]};w[_+"Index"]=e.componentIndex;var b=new rM({anid:"name",__fullText:i,__truncatedText:y,position:c,rotation:n.rotation,silent:hh(e),z2:1,tooltip:x&&x.show?a({content:i,formatter:function(){return i},formatterParams:w},x):null});mo(b.style,s,{text:y,textFont:p,textFill:s.getTextColor()||e.get("axisLine.lineStyle.color"),textAlign:n.textAlign,textVerticalAlign:n.textVerticalAlign}),e.get("triggerEvent")&&(b.eventData=lh(e),b.eventData.targetType="axisName",b.eventData.name=i),this._dumbGroup.add(b),b.updateTransform(),this.group.add(b),b.decomposeTransform()}}},HD=FD.innerTextLayout=function(t,e,i){var n,o,a=Xo(e-t);return jo(a)?(o=i>0?"top":"bottom",n="center"):jo(a-GD)?(o=i>0?"bottom":"top",n="center"):(o="middle",n=a>0&&a0?"right":"left":i>0?"left":"right"),{rotation:a,textAlign:n,textVerticalAlign:o}},ZD=d,UD=v,XD=Ws({type:"axis",_axisPointer:null,axisPointerClass:null,render:function(t,e,i,n){this.axisPointerClass&&Sh(t),XD.superApply(this,"render",arguments),Dh(this,t,0,i,0,!0)},updateAxisPointer:function(t,e,i,n,o){Dh(this,t,0,i,0,!1)},remove:function(t,e){var i=this._axisPointer;i&&i.remove(e),XD.superApply(this,"remove",arguments)},dispose:function(t,e){Ch(this,e),XD.superApply(this,"dispose",arguments)}}),jD=[];XD.registerAxisPointerClass=function(t,e){jD[t]=e},XD.getAxisPointerClass=function(t){return t&&jD[t]};var YD=["axisLine","axisTickLabel","axisName"],qD=["splitArea","splitLine"],KD=XD.extend({type:"cartesianAxis",axisPointerClass:"CartesianAxisPointer",render:function(t,e,i,n){this.group.removeAll();var o=this._axisGroup;if(this._axisGroup=new tb,this.group.add(this._axisGroup),t.get("show")){var a=t.getCoordSysModel(),r=Lh(a,t),s=new FD(t,r);d(YD,s.add,s),this._axisGroup.add(s.getGroup()),d(qD,function(e){t.get(e+".show")&&this["_"+e](t,a)},this),Lo(o,this._axisGroup,t),KD.superCall(this,"render",t,e,i,n)}},remove:function(){this._splitAreaColors=null},_splitLine:function(t,e){var i=t.axis;if(!i.scale.isBlank()){var n=t.getModel("splitLine"),o=n.getModel("lineStyle"),a=o.get("color");a=y(a)?a:[a];for(var s=e.coordinateSystem.getRect(),l=i.isHorizontal(),u=0,h=i.getTicksCoords({tickModel:n}),c=[],d=[],f=o.getLineStyle(),p=0;p1){var c;"string"==typeof o?c=DD[o]:"function"==typeof o&&(c=o),c&&t.setData(n.downSample(n.mapDimension(s.dim),1/h,c,CD))}}}}}("line"));var $D=YI.extend({type:"series.__base_bar__",getInitialData:function(t,e){return ml(this.getSource(),this)},getMarkerPosition:function(t){var e=this.coordinateSystem;if(e){var i=e.dataToPoint(e.clampData(t)),n=this.getData(),o=n.getLayout("offset"),a=n.getLayout("size");return i[e.getBaseAxis().isHorizontal()?0:1]+=o+a/2,i}return[NaN,NaN]},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod",itemStyle:{},emphasis:{}}});$D.extend({type:"series.bar",dependencies:["grid","polar"],brushSelector:"rect",getProgressive:function(){return!!this.get("large")&&this.get("progressive")},getProgressiveThreshold:function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t}});var JD=Qb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["stroke","barBorderColor"],["lineWidth","barBorderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),QD={getBarItemStyle:function(t){var e=JD(this,t);if(this.getBorderLineDash){var i=this.getBorderLineDash();i&&(e.lineDash=i)}return e}},tC=["itemStyle","barBorderWidth"];a(No.prototype,QD),Zs({type:"bar",render:function(t,e,i){this._updateDrawMode(t);var n=t.get("coordinateSystem");return"cartesian2d"!==n&&"polar"!==n||(this._isLargeDraw?this._renderLarge(t,e,i):this._renderNormal(t,e,i)),this.group},incrementalPrepareRender:function(t,e,i){this._clear(),this._updateDrawMode(t)},incrementalRender:function(t,e,i,n){this._incrementalRenderLarge(t,e)},_updateDrawMode:function(t){var e=t.pipelineContext.large;(null==this._isLargeDraw||e^this._isLargeDraw)&&(this._isLargeDraw=e,this._clear())},_renderNormal:function(t,e,i){var n,o=this.group,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.getBaseAxis();"cartesian2d"===s.type?n=l.isHorizontal():"polar"===s.type&&(n="angle"===l.dim);var u=t.isAnimationEnabled()?t:null;a.diff(r).add(function(e){if(a.hasValue(e)){var i=a.getItemModel(e),r=iC[s.type](a,e,i),l=eC[s.type](a,e,i,r,n,u);a.setItemGraphicEl(e,l),o.add(l),Eh(l,a,e,i,r,t,n,"polar"===s.type)}}).update(function(e,i){var l=r.getItemGraphicEl(i);if(a.hasValue(e)){var h=a.getItemModel(e),c=iC[s.type](a,e,h);l?Io(l,{shape:c},u,e):l=eC[s.type](a,e,h,c,n,u,!0),a.setItemGraphicEl(e,l),o.add(l),Eh(l,a,e,h,c,t,n,"polar"===s.type)}else o.remove(l)}).remove(function(t){var e=r.getItemGraphicEl(t);"cartesian2d"===s.type?e&&Nh(t,u,e):e&&Oh(t,u,e)}).execute(),this._data=a},_renderLarge:function(t,e,i){this._clear(),zh(t,this.group)},_incrementalRenderLarge:function(t,e){zh(e,this.group,!0)},dispose:B,remove:function(t){this._clear(t)},_clear:function(t){var e=this.group,i=this._data;t&&t.get("animation")&&i&&!this._isLargeDraw?i.eachItemGraphicEl(function(e){"sector"===e.type?Oh(e.dataIndex,t,e):Nh(e.dataIndex,t,e)}):e.removeAll(),this._data=null}});var eC={cartesian2d:function(t,e,i,n,o,r,s){var l=new yM({shape:a({},n)});if(r){var u=l.shape,h=o?"height":"width",c={};u[h]=0,c[h]=n[h],zM[s?"updateProps":"initProps"](l,{shape:c},r,e)}return l},polar:function(t,e,i,n,o,a,s){var l=n.startAngle0?1:-1,r=n.height>0?1:-1;return{x:n.x+a*o/2,y:n.y+r*o/2,width:n.width-a*o,height:n.height-r*o}},polar:function(t,e,i){var n=t.getItemLayout(e);return{cx:n.cx,cy:n.cy,r0:n.r0,r:n.r,startAngle:n.startAngle,endAngle:n.endAngle}}},nC=Pn.extend({type:"largeBar",shape:{points:[]},buildPath:function(t,e){for(var i=e.points,n=this.__startPoint,o=this.__valueIdx,a=0;a0&&"scale"!==u){var d=o.getItemLayout(0),f=Math.max(i.getWidth(),i.getHeight())/2,p=m(r.removeClipPath,r);r.setClipPath(this._createClipPath(d.cx,d.cy,f,d.startAngle,d.clockwise,p,t))}else r.removeClipPath();this._data=o}},dispose:function(){},_createClipPath:function(t,e,i,n,o,a,r){var s=new hM({shape:{cx:t,cy:e,r0:0,r:i,startAngle:n,endAngle:n,clockwise:o}});return To(s,{shape:{endAngle:n+(o?1:-1)*Math.PI*2}},r,a),s},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var lC=function(t,e){d(e,function(e){e.update="updateView",Es(e,function(i,n){var o={};return n.eachComponent({mainType:"series",subType:t,query:i},function(t){t[e.method]&&t[e.method](i.name,i.dataIndex);var n=t.getData();n.each(function(e){var i=n.getName(e);o[i]=t.isSelected(i)||!1})}),{name:i.name,selected:o}})})},uC=function(t){return{getTargetSeries:function(e){var i={},n=R();return e.eachSeriesByType(t,function(t){t.__paletteScope=i,n.set(t.uid,t)}),n},reset:function(t,e){var i=t.getRawData(),n={},o=t.getData();o.each(function(t){var e=o.getRawIndex(t);n[e]=t}),i.each(function(e){var a=n[e],r=null!=a&&o.getItemVisual(a,"color",!0);if(r)i.setItemVisual(e,"color",r);else{var s=i.getItemModel(e).get("itemStyle.color")||t.getColorFromPalette(i.getName(e)||e+"",t.__paletteScope,i.count());i.setItemVisual(e,"color",s),null!=a&&o.setItemVisual(a,"color",s)}})}}},hC=function(t,e,i,n){var o,a,r=t.getData(),s=[],l=!1;r.each(function(i){var n,u,h,c,d=r.getItemLayout(i),f=r.getItemModel(i),p=f.getModel("label"),g=p.get("position")||f.get("emphasis.label.position"),m=f.getModel("labelLine"),v=m.get("length"),y=m.get("length2"),x=(d.startAngle+d.endAngle)/2,_=Math.cos(x),w=Math.sin(x);o=d.cx,a=d.cy;var b="inside"===g||"inner"===g;if("center"===g)n=d.cx,u=d.cy,c="center";else{var S=(b?(d.r+d.r0)/2*_:d.r*_)+o,M=(b?(d.r+d.r0)/2*w:d.r*w)+a;if(n=S+3*_,u=M+3*w,!b){var I=S+_*(v+e-d.r),T=M+w*(v+e-d.r),A=I+(_<0?-1:1)*y,D=T;n=A+(_<0?-5:5),u=D,h=[[S,M],[I,T],[A,D]]}c=b?"center":_>0?"left":"right"}var C=p.getFont(),L=p.get("rotate")?_<0?-x+Math.PI:-x:0,k=ke(t.getFormattedLabel(i,"normal")||r.getName(i),C,c,"top");l=!!L,d.label={x:n,y:u,position:g,height:k.height,len:v,len2:y,linePoints:h,textAlign:c,verticalAlign:"middle",rotation:L,inside:b},b||s.push(d.label)}),!l&&t.get("avoidLabelOverlap")&&Hh(s,o,a,e,i,n)},cC=2*Math.PI,dC=Math.PI/180,fC=function(t){return{seriesType:t,reset:function(t,e){var i=e.findComponents({mainType:"legend"});if(i&&i.length){var n=t.getData();n.filterSelf(function(t){for(var e=n.getName(t),o=0;o=0;s--){var l=2*s,u=n[l]-a/2,h=n[l+1]-r/2;if(t>=u&&e>=h&&t<=u+a&&e<=h+r)return s}return-1}}),gC=Uh.prototype;gC.isPersistent=function(){return!this._incremental},gC.updateData=function(t){this.group.removeAll();var e=new pC({rectHover:!0,cursor:"default"});e.setShape({points:t.getLayout("symbolPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},gC.updateLayout=function(t){if(!this._incremental){var e=t.getLayout("symbolPoints");this.group.eachChild(function(t){if(null!=t.startIndex){var i=2*(t.endIndex-t.startIndex),n=4*t.startIndex*2;e=new Float32Array(e.buffer,n,i)}t.setShape("points",e)})}},gC.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>2e6?(this._incremental||(this._incremental=new Zn({silent:!0})),this.group.add(this._incremental)):this._incremental=null},gC.incrementalUpdate=function(t,e){var i;this._incremental?(i=new pC,this._incremental.addDisplayable(i,!0)):((i=new pC({rectHover:!0,cursor:"default",startIndex:t.start,endIndex:t.end})).incremental=!0,this.group.add(i)),i.setShape({points:e.getLayout("symbolPoints")}),this._setCommon(i,e,!!this._incremental)},gC._setCommon=function(t,e,i){var n=e.hostModel,o=e.getVisual("symbolSize");t.setShape("size",o instanceof Array?o:[o,o]),t.symbolProxy=Jl(e.getVisual("symbol"),0,0,0,0),t.setColor=t.symbolProxy.setColor;var a=t.shape.size[0]<4;t.useStyle(n.getModel("itemStyle").getItemStyle(a?["color","shadowBlur","shadowColor"]:["color"]));var r=e.getVisual("color");r&&t.setColor(r),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>=0&&(t.dataIndex=i+(t.startIndex||0))}))},gC.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},gC._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()},Zs({type:"scatter",render:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).updateData(n),this._finished=!0},incrementalPrepareRender:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).incrementalPrepareUpdate(n),this._finished=!1},incrementalRender:function(t,e,i){this._symbolDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},updateTransform:function(t,e,i){var n=t.getData();if(this.group.dirty(),!this._finished||n.count()>1e4||!this._symbolDraw.isPersistent())return{update:!0};var o=AD().reset(t);o.progress&&o.progress({start:0,end:n.count()},n),this._symbolDraw.updateLayout(n)},_updateSymbolDraw:function(t,e){var i=this._symbolDraw,n=e.pipelineContext.large;return i&&n===this._isLargeDraw||(i&&i.remove(),i=this._symbolDraw=n?new Uh:new Du,this._isLargeDraw=n,this.group.removeAll()),this.group.add(i.group),i},remove:function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},dispose:function(){}}),Bs(TD("scatter","circle")),zs(AD("scatter")),u(Xh,aD),jh.prototype.getIndicatorAxes=function(){return this._indicatorAxes},jh.prototype.dataToPoint=function(t,e){var i=this._indicatorAxes[e];return this.coordToPoint(i.dataToCoord(t),e)},jh.prototype.coordToPoint=function(t,e){var i=this._indicatorAxes[e].angle;return[this.cx+t*Math.cos(i),this.cy-t*Math.sin(i)]},jh.prototype.pointToData=function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=Math.sqrt(e*e+i*i);e/=n,i/=n;for(var o,a=Math.atan2(-i,e),r=1/0,s=-1,l=0;ln[0]&&isFinite(c)&&isFinite(n[0]))}else{r.getTicks().length-1>a&&(u=i(u));var d=Math.round((n[0]+n[1])/2/u)*u,f=Math.round(a/2);r.setExtent(Go(d-f*u),Go(d+(a-f)*u)),r.setInterval(u)}})},jh.dimensions=[],jh.create=function(t,e){var i=[];return t.eachComponent("radar",function(n){var o=new jh(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeriesByType("radar",function(t){"radar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("radarIndex")||0])}),i},Fa.register("radar",jh);var mC=ND.valueAxis,vC=(Fs({type:"radar",optionUpdated:function(){var t=this.get("boundaryGap"),e=this.get("splitNumber"),o=this.get("scale"),s=this.get("axisLine"),l=this.get("axisTick"),u=this.get("axisLabel"),h=this.get("name"),c=this.get("name.show"),d=this.get("name.formatter"),p=this.get("nameGap"),g=this.get("triggerEvent"),m=f(this.get("indicator")||[],function(f){null!=f.max&&f.max>0&&!f.min?f.min=0:null!=f.min&&f.min<0&&!f.max&&(f.max=0);var m=h;if(null!=f.color&&(m=r({color:f.color},h)),f=n(i(f),{boundaryGap:t,splitNumber:e,scale:o,axisLine:s,axisTick:l,axisLabel:u,name:f.text,nameLocation:"end",nameGap:p,nameTextStyle:m,triggerEvent:g},!1),c||(f.name=""),"string"==typeof d){var v=f.name;f.name=d.replace("{value}",null!=v?v:"")}else"function"==typeof d&&(f.name=d(f.name,f));var y=a(new No(f,null,this.ecModel),UA);return y.mainType="radar",y.componentIndex=this.componentIndex,y},this);this.getIndicatorModels=function(){return m}},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"75%",startAngle:90,name:{show:!0},boundaryGap:[0,0],splitNumber:5,nameGap:15,scale:!1,shape:"polygon",axisLine:n({lineStyle:{color:"#bbb"}},mC.axisLine),axisLabel:Yh(mC.axisLabel,!1),axisTick:Yh(mC.axisTick,!1),splitLine:Yh(mC.splitLine,!0),splitArea:Yh(mC.splitArea,!0),indicator:[]}}),["axisLine","axisTickLabel","axisName"]);Ws({type:"radar",render:function(t,e,i){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},_buildAxes:function(t){var e=t.coordinateSystem;d(f(e.getIndicatorAxes(),function(t){return new FD(t.model,{position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})}),function(t){d(vC,t.add,t),this.group.add(t.getGroup())},this)},_buildSplitLineAndArea:function(t){function e(t,e,i){var n=i%e.length;return t[n]=t[n]||[],n}var i=t.coordinateSystem,n=i.getIndicatorAxes();if(n.length){var o=t.get("shape"),a=t.getModel("splitLine"),s=t.getModel("splitArea"),l=a.getModel("lineStyle"),u=s.getModel("areaStyle"),h=a.get("show"),c=s.get("show"),p=l.get("color"),g=u.get("color");p=y(p)?p:[p],g=y(g)?g:[g];var m=[],v=[];if("circle"===o)for(var x=n[0].getTicksCoords(),_=i.cx,w=i.cy,b=0;b"+f(i,function(i,n){var o=e.get(e.mapDimension(i.dim),t);return ia(i.name+" : "+o)}).join("
")},defaultOption:{zlevel:0,z:2,coordinateSystem:"radar",legendHoverLink:!0,radarIndex:0,lineStyle:{width:2,type:"solid"},label:{position:"top"},symbol:"emptyCircle",symbolSize:4}});Zs({type:"radar",render:function(t,e,n){function o(t,e){var i=t.getItemVisual(e,"symbol")||"circle",n=t.getItemVisual(e,"color");if("none"!==i){var o=qh(t.getItemVisual(e,"symbolSize")),a=Jl(i,-1,-1,2,2,n);return a.attr({style:{strokeNoScale:!0},z2:100,scale:[o[0]/2,o[1]/2]}),a}}function a(e,i,n,a,r,s){n.removeAll();for(var l=0;l"+ia(n+" : "+i)},getTooltipPosition:function(t){if(null!=t){var e=this.getData().getName(t),i=this.coordinateSystem,n=i.getRegion(e);return n&&i.dataToPoint(n.center)}},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},defaultOption:{zlevel:0,z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:.75,showLegendSymbol:!0,dataRangeHoverLink:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}}}}),aC);var EC="\0_ec_interaction_mutex";Es({type:"takeGlobalCursor",event:"globalCursorTaken",update:"update"},function(){}),h(oc,fw);var RC={axisPointer:1,tooltip:1,brush:1};xc.prototype={constructor:xc,draw:function(t,e,i,n,o){var a="geo"===t.mainType,r=t.getData&&t.getData();a&&e.eachComponent({mainType:"series",subType:"map"},function(e){r||e.getHostGeoModel()!==t||(r=e.getData())});var s=t.coordinateSystem;this._updateBackground(s);var l=this._regionsGroup,u=this.group,h=s.scale,c={position:s.position,scale:h};!l.childAt(0)||o?u.attr(c):Io(u,c,t),l.removeAll();var f=["itemStyle"],p=["emphasis","itemStyle"],g=["label"],m=["emphasis","label"],v=R();d(s.regions,function(e){var i=v.get(e.name)||v.set(e.name,new tb),n=new MM({shape:{paths:[]}});i.add(n);var o,s=(C=t.getRegionModel(e.name)||t).getModel(f),u=C.getModel(p),c=mc(s),y=mc(u),x=C.getModel(g),_=C.getModel(m);if(r){o=r.indexOfName(e.name);var w=r.getItemVisual(o,"color",!0);w&&(c.fill=w)}d(e.geometries,function(t){if("polygon"===t.type){n.shape.paths.push(new pM({shape:{points:t.exterior}}));for(var e=0;e<(t.interiors?t.interiors.length:0);e++)n.shape.paths.push(new pM({shape:{points:t.interiors[e]}}))}}),n.setStyle(c),n.style.strokeNoScale=!0,n.culling=!0;var b=x.get("show"),S=_.get("show"),M=r&&isNaN(r.get(r.mapDimension("value"),o)),I=r&&r.getItemLayout(o);if(a||M&&(b||S)||I&&I.showLabel){var T,A=a?e.name:o;(!r||o>=0)&&(T=t);var D=new rM({position:e.center.slice(),scale:[1/h[0],1/h[1]],z2:10,silent:!0});go(D.style,D.hoverStyle={},x,_,{labelFetcher:T,labelDataIndex:A,defaultText:e.name,useInsideStyle:!1},{textAlign:"center",textVerticalAlign:"middle"}),i.add(D)}if(r)r.setItemGraphicEl(o,i);else{var C=t.getRegionModel(e.name);n.eventData={componentType:"geo",componentIndex:t.componentIndex,geoIndex:t.componentIndex,name:e.name,region:C&&C.option||{}}}(i.__regions||(i.__regions=[])).push(e),fo(i,y,{hoverSilentOnTouch:!!t.get("selectedMode")}),l.add(i)}),this._updateController(t,e,i),vc(this,t,l,i,n),yc(t,l)},remove:function(){this._regionsGroup.removeAll(),this._backgroundGroup.removeAll(),this._controller.dispose(),this._mapName&&OC.removeGraphic(this._mapName,this.uid),this._mapName=null,this._controllerHost={}},_updateBackground:function(t){var e=t.map;this._mapName!==e&&d(OC.makeGraphic(e,this.uid),function(t){this._backgroundGroup.add(t)},this),this._mapName=e},_updateController:function(t,e,i){function n(){var e={type:"geoRoam",componentType:l};return e[l+"Id"]=t.id,e}var o=t.coordinateSystem,r=this._controller,s=this._controllerHost;s.zoomLimit=t.get("scaleLimit"),s.zoom=o.getZoom(),r.enable(t.get("roam")||!1);var l=t.mainType;r.off("pan").on("pan",function(t){this._mouseDownFlag=!1,fc(s,t.dx,t.dy),i.dispatchAction(a(n(),{dx:t.dx,dy:t.dy}))},this),r.off("zoom").on("zoom",function(t){if(this._mouseDownFlag=!1,pc(s,t.scale,t.originX,t.originY),i.dispatchAction(a(n(),{zoom:t.scale,originX:t.originX,originY:t.originY})),this._updateGroup){var e=this.group.scale;this._regionsGroup.traverse(function(t){"text"===t.type&&t.attr("scale",[1/e[0],1/e[1]])})}},this),r.setPointerChecker(function(e,n,a){return o.getViewRectAfterRoam().contain(n,a)&&!gc(e,i,t)})}};var zC="__seriesMapHighDown",BC="__seriesMapCallKey";Zs({type:"map",render:function(t,e,i,n){if(!n||"mapToggleSelect"!==n.type||n.from!==this.uid){var o=this.group;if(o.removeAll(),!t.getHostGeoModel()){if(n&&"geoRoam"===n.type&&"series"===n.componentType&&n.seriesId===t.id)(a=this._mapDraw)&&o.add(a.group);else if(t.needsDrawMap){var a=this._mapDraw||new xc(i,!0);o.add(a.group),a.draw(t,e,i,this,n),this._mapDraw=a}else this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null;t.get("showLegendSymbol")&&e.getComponent("legend")&&this._renderSymbols(t,e,i)}}},remove:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null,this.group.removeAll()},dispose:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null},_renderSymbols:function(t,e,i){var n=t.originalData,o=this.group;n.each(n.mapDimension("value"),function(e,i){if(!isNaN(e)){var r=n.getItemLayout(i);if(r&&r.point){var s=r.point,l=r.offset,u=new sM({style:{fill:t.getData().getVisual("color")},shape:{cx:s[0]+9*l,cy:s[1],r:3},silent:!0,z2:8+(l?0:NM+1)});if(!l){var h=t.mainSeries.getData(),c=n.getName(i),d=h.indexOfName(c),f=n.getItemModel(i),p=f.getModel("label"),g=f.getModel("emphasis.label"),m=h.getItemGraphicEl(d),y=A(t.getFormattedLabel(d,"normal"),c),x=A(t.getFormattedLabel(d,"emphasis"),y),_=m[zC],w=Math.random();if(!_){_=m[zC]={};var b=v(_c,!0),S=v(_c,!1);m.on("mouseover",b).on("mouseout",S).on("emphasis",b).on("normal",S)}m[BC]=w,a(_,{recordVersion:w,circle:u,labelModel:p,hoverLabelModel:g,emphasisText:x,normalText:y}),wc(_,!1)}o.add(u)}}})}}),Es({type:"geoRoam",event:"geoRoam",update:"updateTransform"},function(t,e){var i=t.componentType||"series";e.eachComponent({mainType:i,query:t},function(e){var n=e.coordinateSystem;if("geo"===n.type){var o=bc(n,t,e.get("scaleLimit"));e.setCenter&&e.setCenter(o.center),e.setZoom&&e.setZoom(o.zoom),"series"===i&&d(e.seriesGroup,function(t){t.setCenter(o.center),t.setZoom(o.zoom)})}})});var VC=Q;h(Sc,Tw),Mc.prototype={constructor:Mc,type:"view",dimensions:["x","y"],setBoundingRect:function(t,e,i,n){return this._rect=new de(t,e,i,n),this._rect},getBoundingRect:function(){return this._rect},setViewRect:function(t,e,i,n){this.transformTo(t,e,i,n),this._viewRect=new de(t,e,i,n)},transformTo:function(t,e,i,n){var o=this.getBoundingRect(),a=this._rawTransformable;a.transform=o.calculateTransform(new de(t,e,i,n)),a.decomposeTransform(),this._updateTransform()},setCenter:function(t){t&&(this._center=t,this._updateCenterAndZoom())},setZoom:function(t){t=t||1;var e=this.zoomLimit;e&&(null!=e.max&&(t=Math.min(e.max,t)),null!=e.min&&(t=Math.max(e.min,t))),this._zoom=t,this._updateCenterAndZoom()},getDefaultCenter:function(){var t=this.getBoundingRect();return[t.x+t.width/2,t.y+t.height/2]},getCenter:function(){return this._center||this.getDefaultCenter()},getZoom:function(){return this._zoom||1},getRoamTransform:function(){return this._roamTransformable.getLocalTransform()},_updateCenterAndZoom:function(){var t=this._rawTransformable.getLocalTransform(),e=this._roamTransformable,i=this.getDefaultCenter(),n=this.getCenter(),o=this.getZoom();n=Q([],n,t),i=Q([],i,t),e.origin=n,e.position=[i[0]-n[0],i[1]-n[1]],e.scale=[o,o],this._updateTransform()},_updateTransform:function(){var t=this._roamTransformable,e=this._rawTransformable;e.parent=t,t.updateTransform(),e.updateTransform(),wt(this.transform||(this.transform=[]),e.transform||xt()),this._rawTransform=e.getLocalTransform(),this.invTransform=this.invTransform||[],Tt(this.invTransform,this.transform),this.decomposeTransform()},getViewRect:function(){return this._viewRect},getViewRectAfterRoam:function(){var t=this.getBoundingRect().clone();return t.applyTransform(this.transform),t},dataToPoint:function(t,e,i){var n=e?this._rawTransform:this.transform;return i=i||[],n?VC(i,t,n):G(i,t)},pointToData:function(t){var e=this.invTransform;return e?VC([],t,e):[t[0],t[1]]},convertToPixel:v(Ic,"dataToPoint"),convertFromPixel:v(Ic,"pointToData"),containPoint:function(t){return this.getViewRectAfterRoam().contain(t[0],t[1])}},h(Mc,Tw),Tc.prototype={constructor:Tc,type:"geo",dimensions:["lng","lat"],containCoord:function(t){for(var e=this.regions,i=0;ie&&(e=n.height)}this.height=e+1},getNodeById:function(t){if(this.getId()===t)return this;for(var e=0,i=this.children,n=i.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},getLayout:function(){return this.hostTree.data.getItemLayout(this.dataIndex)},getModel:function(t){if(!(this.dataIndex<0)){var e,i=this.hostTree,n=i.data.getItemModel(this.dataIndex),o=this.getLevelModel();return o||0!==this.children.length&&(0===this.children.length||!1!==this.isExpand)||(e=this.getLeavesModel()),n.getModel(t,(o||e||i.hostModel).getModel(t))}},getLevelModel:function(){return(this.hostTree.levelModels||[])[this.depth]},getLeavesModel:function(){return this.hostTree.leavesModel},setVisual:function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},getVisual:function(t,e){return this.hostTree.data.getItemVisual(this.dataIndex,t,e)},getRawIndex:function(){return this.hostTree.data.getRawIndex(this.dataIndex)},getId:function(){return this.hostTree.data.getId(this.dataIndex)},isAncestorOf:function(t){for(var e=t.parentNode;e;){if(e===this)return!0;e=e.parentNode}return!1},isDescendantOf:function(t){return t!==this&&t.isAncestorOf(this)}},Vc.prototype={constructor:Vc,type:"tree",eachNode:function(t,e,i){this.root.eachNode(t,e,i)},getNodeByDataIndex:function(t){var e=this.data.getRawIndex(t);return this._nodes[e]},getNodeByName:function(t){return this.root.getNodeByName(t)},update:function(){for(var t=this.data,e=this._nodes,i=0,n=e.length;ia&&(a=t.depth)});var r=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:a;return o.root.eachNode("preorder",function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=r}),o.data},getOrient:function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},formatTooltip:function(t){for(var e=this.getData().tree,i=e.root.children[0],n=e.getNodeByDataIndex(t),o=n.getValue(),a=n.name;n&&n!==i;)a=n.parentNode.name+"."+a,n=n.parentNode;return ia(a+(isNaN(o)||null==o?"":" : "+o))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderColor:"#c23531",borderWidth:1.5},label:{show:!0,color:"#555"},leaves:{label:{show:!0}},animationEasing:"linear",animationDuration:700,animationDurationUpdate:1e3}}),Zs({type:"tree",init:function(t,e){this._oldTree,this._mainGroup=new tb,this._controller=new oc(e.getZr()),this._controllerHost={target:this.group},this.group.add(this._mainGroup)},render:function(t,e,i,n){var o=t.getData(),a=t.layoutInfo,r=this._mainGroup,s=t.get("layout");"radial"===s?r.attr("position",[a.x+a.width/2,a.y+a.height/2]):r.attr("position",[a.x,a.y]),this._updateViewCoordSys(t),this._updateController(t,e,i);var l=this._data,u={expandAndCollapse:t.get("expandAndCollapse"),layout:s,orient:t.getOrient(),curvature:t.get("lineStyle.curveness"),symbolRotate:t.get("symbolRotate"),symbolOffset:t.get("symbolOffset"),hoverAnimation:t.get("hoverAnimation"),useNameLabel:!0,fadeIn:!0};o.diff(l).add(function(e){td(o,e)&&id(o,e,null,r,t,u)}).update(function(e,i){var n=l.getItemGraphicEl(i);td(o,e)?id(o,e,n,r,t,u):n&&nd(l,i,n,r,t,u)}).remove(function(e){var i=l.getItemGraphicEl(e);i&&nd(l,e,i,r,t,u)}).execute(),this._nodeScaleRatio=t.get("nodeScaleRatio"),this._updateNodeAndLinkScale(t),!0===u.expandAndCollapse&&o.eachItemGraphicEl(function(e,n){e.off("click").on("click",function(){i.dispatchAction({type:"treeExpandAndCollapse",seriesId:t.id,dataIndex:n})})}),this._data=o},_updateViewCoordSys:function(t){var e=t.getData(),i=[];e.each(function(t){var n=e.getItemLayout(t);!n||isNaN(n.x)||isNaN(n.y)||i.push([+n.x,+n.y])});var n=[],o=[];fn(i,n,o),o[0]-n[0]==0&&(o[0]+=1,n[0]-=1),o[1]-n[1]==0&&(o[1]+=1,n[1]-=1);var a=t.coordinateSystem=new Mc;a.zoomLimit=t.get("scaleLimit"),a.setBoundingRect(n[0],n[1],o[0]-n[0],o[1]-n[1]),a.setCenter(t.get("center")),a.setZoom(t.get("zoom")),this.group.attr({position:a.position,scale:a.scale}),this._viewCoordSys=a},_updateController:function(t,e,i){var n=this._controller,o=this._controllerHost,a=this.group;n.setPointerChecker(function(e,n,o){var r=a.getBoundingRect();return r.applyTransform(a.transform),r.contain(n,o)&&!gc(e,i,t)}),n.enable(t.get("roam")),o.zoomLimit=t.get("scaleLimit"),o.zoom=t.coordinateSystem.getZoom(),n.off("pan").off("zoom").on("pan",function(e){fc(o,e.dx,e.dy),i.dispatchAction({seriesId:t.id,type:"treeRoam",dx:e.dx,dy:e.dy})},this).on("zoom",function(e){pc(o,e.scale,e.originX,e.originY),i.dispatchAction({seriesId:t.id,type:"treeRoam",zoom:e.scale,originX:e.originX,originY:e.originY}),this._updateNodeAndLinkScale(t)},this)},_updateNodeAndLinkScale:function(t){var e=t.getData(),i=this._getNodeGlobalScale(t),n=[i,i];e.eachItemGraphicEl(function(t,e){t.attr("scale",n)})},_getNodeGlobalScale:function(t){var e=t.coordinateSystem;if("view"!==e.type)return 1;var i=this._nodeScaleRatio,n=e.scale,o=n&&n[0]||1;return((e.getZoom()-1)*i+1)/o},dispose:function(){this._controller&&this._controller.dispose(),this._controllerHost={}},remove:function(){this._mainGroup.removeAll(),this._data=null}}),Es({type:"treeExpandAndCollapse",event:"treeExpandAndCollapse",update:"update"},function(t,e){e.eachComponent({mainType:"series",subType:"tree",query:t},function(e){var i=t.dataIndex,n=e.getData().tree.getNodeByDataIndex(i);n.isExpand=!n.isExpand})}),Es({type:"treeRoam",event:"treeRoam",update:"none"},function(t,e){e.eachComponent({mainType:"series",subType:"tree",query:t},function(e){var i=bc(e.coordinateSystem,t);e.setCenter&&e.setCenter(i.center),e.setZoom&&e.setZoom(i.zoom)})});Bs(TD("tree","circle")),zs(function(t,e){t.eachSeriesByType("tree",function(t){sd(t,e)})}),YI.extend({type:"series.treemap",layoutMode:"box",dependencies:["grid","polar"],_viewRoot:null,defaultOption:{progressive:0,hoverLayerThreshold:1/0,left:"center",top:"middle",right:null,bottom:null,width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",borderColor:"rgba(255,255,255,0.7)",borderWidth:1,shadowColor:"rgba(150,150,150,1)",shadowBlur:3,shadowOffsetX:0,shadowOffsetY:0,textStyle:{color:"#fff"}},emphasis:{textStyle:{}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",ellipsis:!0},upperLabel:{show:!1,position:[0,"50%"],height:20,color:"#fff",ellipsis:!0,verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],color:"#fff",ellipsis:!0,verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},getInitialData:function(t,e){var i={name:t.name,children:t.data};dd(i);var n=t.levels||[];n=t.levels=fd(n,e);var o={};return o.levels=n,Vc.createTree(i,this,o).data},optionUpdated:function(){this.resetViewRoot()},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=ta(y(i)?i[0]:i);return ia(e.getName(t)+": "+n)},getDataParams:function(t){var e=YI.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(t);return e.treePathInfo=cd(i,this),e},setLayoutInfo:function(t){this.layoutInfo=this.layoutInfo||{},a(this.layoutInfo,t)},mapIdToIndex:function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=R(),this._idIndexMapCount=0);var i=e.get(t);return null==i&&e.set(t,i=this._idIndexMapCount++),i},getViewRoot:function(){return this._viewRoot},resetViewRoot:function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)}});var UC=5;pd.prototype={constructor:pd,render:function(t,e,i,n){var o=t.getModel("breadcrumb"),a=this.group;if(a.removeAll(),o.get("show")&&i){var r=o.getModel("itemStyle"),s=r.getModel("textStyle"),l={pos:{left:o.get("left"),right:o.get("right"),top:o.get("top"),bottom:o.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:o.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(i,l,s),this._renderContent(t,l,r,s,n),da(a,l.pos,l.box)}},_prepare:function(t,e,i){for(var n=t;n;n=n.parentNode){var o=n.getModel().get("name"),a=i.getTextRect(o),r=Math.max(a.width+16,e.emptyItemWidth);e.totalWidth+=r+8,e.renderList.push({node:n,text:o,width:r})}},_renderContent:function(t,e,i,n,o){for(var a=0,s=e.emptyItemWidth,l=t.get("breadcrumb.height"),u=ha(e.pos,e.box),h=e.totalWidth,c=e.renderList,d=c.length-1;d>=0;d--){var f=c[d],p=f.node,g=f.width,m=f.text;h>u.width&&(h-=g-s,g=s,m=null);var y=new pM({shape:{points:gd(a,0,g,l,d===c.length-1,0===d)},style:r(i.getItemStyle(),{lineJoin:"bevel",text:m,textFill:n.getTextColor(),textFont:n.getFont()}),z:10,onclick:v(o,p)});this.group.add(y),md(y,t,p),a+=g+8}},remove:function(){this.group.removeAll()}};var XC=m,jC=tb,YC=yM,qC=d,KC=["label"],$C=["emphasis","label"],JC=["upperLabel"],QC=["emphasis","upperLabel"],tL=10,eL=1,iL=2,nL=Qb([["fill","color"],["stroke","strokeColor"],["lineWidth","strokeWidth"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),oL=function(t){var e=nL(t);return e.stroke=e.fill=e.lineWidth=null,e};Zs({type:"treemap",init:function(t,e){this._containerGroup,this._storage={nodeGroup:[],background:[],content:[]},this._oldTree,this._breadcrumb,this._controller,this._state="ready"},render:function(t,e,i,n){if(!(l(e.findComponents({mainType:"series",subType:"treemap",query:n}),t)<0)){this.seriesModel=t,this.api=i,this.ecModel=e;var o=ld(n,["treemapZoomToNode","treemapRootToNode"],t),a=n&&n.type,r=t.layoutInfo,s=!this._oldTree,u=this._storage,h="treemapRootToNode"===a&&o&&u?{rootNodeGroup:u.nodeGroup[o.node.getRawIndex()],direction:n.direction}:null,c=this._giveContainerGroup(r),d=this._doRender(c,t,h);s||a&&"treemapZoomToNode"!==a&&"treemapRootToNode"!==a?d.renderFinally():this._doAnimation(c,d,t,h),this._resetController(i),this._renderBreadcrumb(t,i,o)}},_giveContainerGroup:function(t){var e=this._containerGroup;return e||(e=this._containerGroup=new jC,this._initEvents(e),this.group.add(e)),e.attr("position",[t.x,t.y]),e},_doRender:function(t,e,i){function n(t,e,i,o,a){function r(t){return t.getId()}function s(r,s){var l=null!=r?t[r]:null,u=null!=s?e[s]:null,c=h(l,u,i,a);c&&n(l&&l.viewChildren||[],u&&u.viewChildren||[],c,o,a+1)}o?(e=t,qC(t,function(t,e){!t.isRemoved()&&s(e,e)})):new Xs(e,t,r,r).add(s).update(s).remove(v(s,null)).execute()}var o=e.getData().tree,a=this._oldTree,r={nodeGroup:[],background:[],content:[]},s={nodeGroup:[],background:[],content:[]},l=this._storage,u=[],h=v(yd,e,s,l,i,r,u);n(o.root?[o.root]:[],a&&a.root?[a.root]:[],t,o===a||!a,0);var c=function(t){var e={nodeGroup:[],background:[],content:[]};return t&&qC(t,function(t,i){var n=e[i];qC(t,function(t){t&&(n.push(t),t.__tmWillDelete=1)})}),e}(l);return this._oldTree=o,this._storage=s,{lastsForAnimation:r,willDeleteEls:c,renderFinally:function(){qC(c,function(t){qC(t,function(t){t.parent&&t.parent.remove(t)})}),qC(u,function(t){t.invisible=!0,t.dirty()})}}},_doAnimation:function(t,e,i,n){if(i.get("animation")){var o=i.get("animationDurationUpdate"),r=i.get("animationEasing"),s=vd();qC(e.willDeleteEls,function(t,e){qC(t,function(t,i){if(!t.invisible){var a,l=t.parent;if(n&&"drillDown"===n.direction)a=l===n.rootNodeGroup?{shape:{x:0,y:0,width:l.__tmNodeWidth,height:l.__tmNodeHeight},style:{opacity:0}}:{style:{opacity:0}};else{var u=0,h=0;l.__tmWillDelete||(u=l.__tmNodeWidth/2,h=l.__tmNodeHeight/2),a="nodeGroup"===e?{position:[u,h],style:{opacity:0}}:{shape:{x:u,y:h,width:0,height:0},style:{opacity:0}}}a&&s.add(t,a,o,r)}})}),qC(this._storage,function(t,i){qC(t,function(t,n){var l=e.lastsForAnimation[i][n],u={};l&&("nodeGroup"===i?l.old&&(u.position=t.position.slice(),t.attr("position",l.old)):(l.old&&(u.shape=a({},t.shape),t.setShape(l.old)),l.fadein?(t.setStyle("opacity",0),u.style={opacity:1}):1!==t.style.opacity&&(u.style={opacity:1})),s.add(t,u,o,r))})},this),this._state="animating",s.done(XC(function(){this._state="ready",e.renderFinally()},this)).start()}},_resetController:function(t){var e=this._controller;e||((e=this._controller=new oc(t.getZr())).enable(this.seriesModel.get("roam")),e.on("pan",XC(this._onPan,this)),e.on("zoom",XC(this._onZoom,this)));var i=new de(0,0,t.getWidth(),t.getHeight());e.setPointerChecker(function(t,e,n){return i.contain(e,n)})},_clearController:function(){var t=this._controller;t&&(t.dispose(),t=null)},_onPan:function(t){if("animating"!==this._state&&(Math.abs(t.dx)>3||Math.abs(t.dy)>3)){var e=this.seriesModel.getData().tree.root;if(!e)return;var i=e.getLayout();if(!i)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:i.x+t.dx,y:i.y+t.dy,width:i.width,height:i.height}})}},_onZoom:function(t){var e=t.originX,i=t.originY;if("animating"!==this._state){var n=this.seriesModel.getData().tree.root;if(!n)return;var o=n.getLayout();if(!o)return;var a=new de(o.x,o.y,o.width,o.height),r=this.seriesModel.layoutInfo;e-=r.x,i-=r.y;var s=xt();St(s,s,[-e,-i]),It(s,s,[t.scale,t.scale]),St(s,s,[e,i]),a.applyTransform(s),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:a.x,y:a.y,width:a.width,height:a.height}})}},_initEvents:function(t){t.on("click",function(t){if("ready"===this._state){var e=this.seriesModel.get("nodeClick",!0);if(e){var i=this.findTarget(t.offsetX,t.offsetY);if(i){var n=i.node;if(n.getLayout().isLeafRoot)this._rootToNode(i);else if("zoomToNode"===e)this._zoomToNode(i);else if("link"===e){var o=n.hostTree.data.getItemModel(n.dataIndex),a=o.get("link",!0),r=o.get("target",!0)||"blank";a&&window.open(a,r)}}}}},this)},_renderBreadcrumb:function(t,e,i){i||(i=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(i={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new pd(this.group))).render(t,e,i.node,XC(function(e){"animating"!==this._state&&(hd(t.getViewRoot(),e)?this._rootToNode({node:e}):this._zoomToNode({node:e}))},this))},remove:function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},dispose:function(){this._clearController()},_zoomToNode:function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},_rootToNode:function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},findTarget:function(t,e){var i;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},function(n){var o=this._storage.background[n.getRawIndex()];if(o){var a=o.transformCoordToLocal(t,e),r=o.shape;if(!(r.x<=a[0]&&a[0]<=r.x+r.width&&r.y<=a[1]&&a[1]<=r.y+r.height))return!1;i={node:n,offsetX:a[0],offsetY:a[1]}}},this),i}});for(var aL=["treemapZoomToNode","treemapRender","treemapMove"],rL=0;rL=0&&t.call(e,i[o],o)},TL.eachEdge=function(t,e){for(var i=this.edges,n=i.length,o=0;o=0&&i[o].node1.dataIndex>=0&&i[o].node2.dataIndex>=0&&t.call(e,i[o],o)},TL.breadthFirstTraverse=function(t,e,i,n){if(Jd.isInstance(e)||(e=this._nodesMap[$d(e)]),e){for(var o="out"===i?"outEdges":"in"===i?"inEdges":"edges",a=0;a=0&&i.node2.dataIndex>=0});for(var o=0,a=n.length;o=0&&this[t][e].setItemVisual(this.dataIndex,i,n)},getVisual:function(i,n){return this[t][e].getItemVisual(this.dataIndex,i,n)},setLayout:function(i,n){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,i,n)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}};h(Jd,AL("hostGraph","data")),h(Qd,AL("hostGraph","edgeData")),IL.Node=Jd,IL.Edge=Qd,Yi(Jd),Yi(Qd);var DL=function(t,e,i,n,o){for(var a=new IL(n),r=0;r "+f)),h++)}var p,g=i.get("coordinateSystem");if("cartesian2d"===g||"polar"===g)p=ml(t,i);else{var m=Fa.get(g),v=m&&"view"!==m.type?m.dimensions||[]:[];l(v,"value")<0&&v.concat(["value"]);var y=_A(t,{coordDimensions:v});(p=new vA(y,i)).initData(t)}var x=new vA(["value"],i);return x.initData(u,s),o&&o(p,x),kc({mainData:p,struct:a,structAttr:"graph",datas:{node:p,edge:x},datasAttr:{node:"data",edge:"edgeData"}}),a.update(),a},CL=Hs({type:"series.graph",init:function(t){CL.superApply(this,"init",arguments),this.legendDataProvider=function(){return this._categoriesData},this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeOption:function(t){CL.superApply(this,"mergeOption",arguments),this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeDefaultAndTheme:function(t){CL.superApply(this,"mergeDefaultAndTheme",arguments),Ci(t,["edgeLabel"],["show"])},getInitialData:function(t,e){var i=t.edges||t.links||[],n=t.data||t.nodes||[],o=this;if(n&&i)return DL(n,i,this,!0,function(t,i){function n(t){return(t=this.parsePath(t))&&"label"===t[0]?r:t&&"emphasis"===t[0]&&"label"===t[1]?l:this.parentModel}t.wrapMethod("getItemModel",function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t});var a=o.getModel("edgeLabel"),r=new No({label:a.option},a.parentModel,e),s=o.getModel("emphasis.edgeLabel"),l=new No({emphasis:{label:s.option}},s.parentModel,e);i.wrapMethod("getItemModel",function(t){return t.customizeGetParent(n),t})}).data},getGraph:function(){return this.getData().graph},getEdgeData:function(){return this.getGraph().edgeData},getCategoriesData:function(){return this._categoriesData},formatTooltip:function(t,e,i){if("edge"===i){var n=this.getData(),o=this.getDataParams(t,i),a=n.graph.getEdgeByIndex(t),r=n.getName(a.node1.dataIndex),s=n.getName(a.node2.dataIndex),l=[];return null!=r&&l.push(r),null!=s&&l.push(s),l=ia(l.join(" > ")),o.value&&(l+=" : "+ia(o.value)),l}return CL.superApply(this,"formatTooltip",arguments)},_updateCategoriesData:function(){var t=f(this.option.categories||[],function(t){return null!=t.value?t:a({value:0},t)}),e=new vA(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray(function(t){return e.getItemModel(t,!0)})},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},isAnimationEnabled:function(){return CL.superCall(this,"isAnimationEnabled")&&!("force"===this.get("layout")&&this.get("force.layoutAnimation"))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",legendHoverLink:!0,hoverAnimation:!0,layout:null,focusNodeAdjacency:!1,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle"},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,curveness:0,opacity:.5},emphasis:{label:{show:!0}}}}),LL=_M.prototype,kL=bM.prototype,PL=Un({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){(tf(e)?LL:kL).buildPath(t,e)},pointAt:function(t){return tf(this.shape)?LL.pointAt.call(this,t):kL.pointAt.call(this,t)},tangentAt:function(t){var e=this.shape,i=tf(e)?[e.x2-e.x1,e.y2-e.y1]:kL.tangentAt.call(this,t);return q(i,i)}}),NL=["fromSymbol","toSymbol"],OL=rf.prototype;OL.beforeUpdate=function(){var t=this,e=t.childOfName("fromSymbol"),i=t.childOfName("toSymbol"),n=t.childOfName("label");if(e||i||!n.ignore){for(var o=1,a=this.parent;a;)a.scale&&(o/=a.scale[0]),a=a.parent;var r=t.childOfName("line");if(this.__dirty||r.__dirty){var s=r.shape.percent,l=r.pointAt(0),u=r.pointAt(s),h=U([],u,l);if(q(h,h),e&&(e.attr("position",l),c=r.tangentAt(0),e.attr("rotation",Math.PI/2-Math.atan2(c[1],c[0])),e.attr("scale",[o*s,o*s])),i){i.attr("position",u);var c=r.tangentAt(1);i.attr("rotation",-Math.PI/2-Math.atan2(c[1],c[0])),i.attr("scale",[o*s,o*s])}if(!n.ignore){n.attr("position",u);var d,f,p,g=5*o;if("end"===n.__position)d=[h[0]*g+u[0],h[1]*g+u[1]],f=h[0]>.8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";else if("middle"===n.__position){var m=s/2,v=[(c=r.tangentAt(m))[1],-c[0]],y=r.pointAt(m);v[1]>0&&(v[0]=-v[0],v[1]=-v[1]),d=[y[0]+v[0]*g,y[1]+v[1]*g],f="center",p="bottom";var x=-Math.atan2(c[1],c[0]);u[0].8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";n.attr({style:{textVerticalAlign:n.__verticalAlign||p,textAlign:n.__textAlign||f},position:d,scale:[o,o]})}}}},OL._createLine=function(t,e,i){var n=t.hostModel,o=of(t.getItemLayout(e));o.shape.percent=0,To(o,{shape:{percent:1}},n,e),this.add(o);var a=new rM({name:"label",lineLabelOriginalOpacity:1});this.add(a),d(NL,function(i){var n=nf(i,t,e);this.add(n),this[ef(i)]=t.getItemVisual(e,i)},this),this._updateCommonStl(t,e,i)},OL.updateData=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=t.getItemLayout(e),r={shape:{}};af(r.shape,a),Io(o,r,n,e),d(NL,function(i){var n=t.getItemVisual(e,i),o=ef(i);if(this[o]!==n){this.remove(this.childOfName(i));var a=nf(i,t,e);this.add(a)}this[o]=n},this),this._updateCommonStl(t,e,i)},OL._updateCommonStl=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=i&&i.lineStyle,s=i&&i.hoverLineStyle,l=i&&i.labelModel,u=i&&i.hoverLabelModel;if(!i||t.hasItemOption){var h=t.getItemModel(e);a=h.getModel("lineStyle").getLineStyle(),s=h.getModel("emphasis.lineStyle").getLineStyle(),l=h.getModel("label"),u=h.getModel("emphasis.label")}var c=t.getItemVisual(e,"color"),f=D(t.getItemVisual(e,"opacity"),a.opacity,1);o.useStyle(r({strokeNoScale:!0,fill:"none",stroke:c,opacity:f},a)),o.hoverStyle=s,d(NL,function(t){var e=this.childOfName(t);e&&(e.setColor(c),e.setStyle({opacity:f}))},this);var p,g,m=l.getShallow("show"),v=u.getShallow("show"),y=this.childOfName("label");if((m||v)&&(p=c||"#000",null==(g=n.getFormattedLabel(e,"normal",t.dataType)))){var x=n.getRawValue(e);g=null==x?t.getName(e):isFinite(x)?Go(x):x}var _=m?g:null,w=v?A(n.getFormattedLabel(e,"emphasis",t.dataType),g):null,b=y.style;null==_&&null==w||(mo(y.style,l,{text:_},{autoColor:p}),y.__textAlign=b.textAlign,y.__verticalAlign=b.textVerticalAlign,y.__position=l.get("position")||"middle"),y.hoverStyle=null!=w?{text:w,textFill:u.getTextColor(!0),fontStyle:u.getShallow("fontStyle"),fontWeight:u.getShallow("fontWeight"),fontSize:u.getShallow("fontSize"),fontFamily:u.getShallow("fontFamily")}:{text:null},y.ignore=!m&&!v,fo(this)},OL.highlight=function(){this.trigger("emphasis")},OL.downplay=function(){this.trigger("normal")},OL.updateLayout=function(t,e){this.setLinePoints(t.getItemLayout(e))},OL.setLinePoints=function(t){var e=this.childOfName("line");af(e.shape,t),e.dirty()},u(rf,tb);var EL=sf.prototype;EL.isPersistent=function(){return!0},EL.updateData=function(t){var e=this,i=e.group,n=e._lineData;e._lineData=t,n||i.removeAll();var o=hf(t);t.diff(n).add(function(i){lf(e,t,i,o)}).update(function(i,a){uf(e,n,t,a,i,o)}).remove(function(t){i.remove(n.getItemGraphicEl(t))}).execute()},EL.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl(function(e,i){e.updateLayout(t,i)},this)},EL.incrementalPrepareUpdate=function(t){this._seriesScope=hf(t),this._lineData=null,this.group.removeAll()},EL.incrementalUpdate=function(t,e){for(var i=t.start;i=o/3?1:2),l=e.y-n(r)*a*(a>=o/3?1:2);r=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+i(r)*a,e.y+n(r)*a),t.lineTo(e.x+i(e.angle)*o,e.y+n(e.angle)*o),t.lineTo(e.x-i(r)*a,e.y-n(r)*a),t.lineTo(s,l)}}),YL=2*Math.PI,qL=(Ar.extend({type:"gauge",render:function(t,e,i){this.group.removeAll();var n=t.get("axisLine.lineStyle.color"),o=Sf(t,i);this._renderMain(t,e,i,n,o)},dispose:function(){},_renderMain:function(t,e,i,n,o){for(var a=this.group,r=t.getModel("axisLine").getModel("lineStyle"),s=t.get("clockwise"),l=-t.get("startAngle")/180*Math.PI,u=-t.get("endAngle")/180*Math.PI,h=(u-l)%YL,c=l,d=r.get("width"),f=0;f=t&&(0===e?0:n[e-1][0]).4?"bottom":"middle",textAlign:A<-.4?"left":A>.4?"right":"center"},{autoColor:P}),silent:!0}))}if(g.get("show")&&T!==v){for(var N=0;N<=y;N++){var A=Math.cos(w),D=Math.sin(w),O=new _M({shape:{x1:A*c+u,y1:D*c+h,x2:A*(c-_)+u,y2:D*(c-_)+h},silent:!0,style:I});"auto"===I.stroke&&O.setStyle({stroke:n((T+N/y)/v)}),l.add(O),w+=S}w-=S}else w+=b}},_renderPointer:function(t,e,i,n,o,a,r,s){var l=this.group,u=this._data;if(t.get("pointer.show")){var h=[+t.get("min"),+t.get("max")],c=[a,r],d=t.getData(),f=d.mapDimension("value");d.diff(u).add(function(e){var i=new jL({shape:{angle:a}});To(i,{shape:{angle:Bo(d.get(f,e),h,c,!0)}},t),l.add(i),d.setItemGraphicEl(e,i)}).update(function(e,i){var n=u.getItemGraphicEl(i);Io(n,{shape:{angle:Bo(d.get(f,e),h,c,!0)}},t),l.add(n),d.setItemGraphicEl(e,n)}).remove(function(t){var e=u.getItemGraphicEl(t);l.remove(e)}).execute(),d.eachItemGraphicEl(function(t,e){var i=d.getItemModel(e),a=i.getModel("pointer");t.setShape({x:o.cx,y:o.cy,width:Vo(a.get("width"),o.r),r:Vo(a.get("length"),o.r)}),t.useStyle(i.getModel("itemStyle").getItemStyle()),"auto"===t.style.fill&&t.setStyle("fill",n(Bo(d.get(f,e),h,[0,1],!0))),fo(t,i.getModel("emphasis.itemStyle").getItemStyle())}),this._data=d}else u&&u.eachItemGraphicEl(function(t){l.remove(t)})},_renderTitle:function(t,e,i,n,o){var a=t.getData(),r=a.mapDimension("value"),s=t.getModel("title");if(s.get("show")){var l=s.get("offsetCenter"),u=o.cx+Vo(l[0],o.r),h=o.cy+Vo(l[1],o.r),c=+t.get("min"),d=+t.get("max"),f=n(Bo(t.getData().get(r,0),[c,d],[0,1],!0));this.group.add(new rM({silent:!0,style:mo({},s,{x:u,y:h,text:a.getName(0),textAlign:"center",textVerticalAlign:"middle"},{autoColor:f,forceRich:!0})}))}},_renderDetail:function(t,e,i,n,o){var a=t.getModel("detail"),r=+t.get("min"),s=+t.get("max");if(a.get("show")){var l=a.get("offsetCenter"),u=o.cx+Vo(l[0],o.r),h=o.cy+Vo(l[1],o.r),c=Vo(a.get("width"),o.r),d=Vo(a.get("height"),o.r),f=t.getData(),p=f.get(f.mapDimension("value"),0),g=n(Bo(p,[r,s],[0,1],!0));this.group.add(new rM({silent:!0,style:mo({},a,{x:u,y:h,text:Mf(p,a.get("formatter")),textWidth:isNaN(c)?null:c,textHeight:isNaN(d)?null:d,textAlign:"center",textVerticalAlign:"middle"},{autoColor:g,forceRich:!0})}))}}}),Hs({type:"series.funnel",init:function(t){qL.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()},this._defaultLabelLine(t)},getInitialData:function(t,e){return oC(this,["value"])},_defaultLabelLine:function(t){Ci(t,"labelLine",["show"]);var e=t.labelLine,i=t.emphasis.labelLine;e.show=e.show&&t.label.show,i.show=i.show&&t.emphasis.label.show},getDataParams:function(t){var e=this.getData(),i=qL.superCall(this,"getDataParams",t),n=e.mapDimension("value"),o=e.getSum(n);return i.percent=o?+(e.get(n,t)/o*100).toFixed(2):0,i.$vars.push("percent"),i},defaultOption:{zlevel:0,z:2,legendHoverLink:!0,left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1,type:"solid"}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}}}})),KL=If.prototype,$L=["itemStyle","opacity"];KL.updateData=function(t,e,i){var n=this.childAt(0),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e),l=t.getItemModel(e).get($L);l=null==l?1:l,n.useStyle({}),i?(n.setShape({points:s.points}),n.setStyle({opacity:0}),To(n,{style:{opacity:l}},o,e)):Io(n,{style:{opacity:l},shape:{points:s.points}},o,e);var u=a.getModel("itemStyle"),h=t.getItemVisual(e,"color");n.setStyle(r({lineJoin:"round",fill:h},u.getItemStyle(["opacity"]))),n.hoverStyle=u.getModel("emphasis").getItemStyle(),this._updateLabel(t,e),fo(this)},KL._updateLabel=function(t,e){var i=this.childAt(1),n=this.childAt(2),o=t.hostModel,a=t.getItemModel(e),r=t.getItemLayout(e).label,s=t.getItemVisual(e,"color");Io(i,{shape:{points:r.linePoints||r.linePoints}},o,e),Io(n,{style:{x:r.x,y:r.y}},o,e),n.attr({rotation:r.rotation,origin:[r.x,r.y],z2:10});var l=a.getModel("label"),u=a.getModel("emphasis.label"),h=a.getModel("labelLine"),c=a.getModel("emphasis.labelLine"),s=t.getItemVisual(e,"color");go(n.style,n.hoverStyle={},l,u,{labelFetcher:t.hostModel,labelDataIndex:e,defaultText:t.getName(e),autoColor:s,useInsideStyle:!!r.inside},{textAlign:r.textAlign,textVerticalAlign:r.verticalAlign}),n.ignore=n.normalIgnore=!l.get("show"),n.hoverIgnore=!u.get("show"),i.ignore=i.normalIgnore=!h.get("show"),i.hoverIgnore=!c.get("show"),i.setStyle({stroke:s}),i.setStyle(h.getModel("lineStyle").getLineStyle()),i.hoverStyle=c.getModel("lineStyle").getLineStyle()},u(If,tb);Ar.extend({type:"funnel",render:function(t,e,i){var n=t.getData(),o=this._data,a=this.group;n.diff(o).add(function(t){var e=new If(n,t);n.setItemGraphicEl(t,e),a.add(e)}).update(function(t,e){var i=o.getItemGraphicEl(e);i.updateData(n,t),a.add(i),n.setItemGraphicEl(t,i)}).remove(function(t){var e=o.getItemGraphicEl(t);a.remove(e)}).execute(),this._data=n},remove:function(){this.group.removeAll(),this._data=null},dispose:function(){}});Bs(uC("funnel")),zs(function(t,e,i){t.eachSeriesByType("funnel",function(t){var i=t.getData(),n=i.mapDimension("value"),o=t.get("sort"),a=Tf(t,e),r=Af(i,o),s=[Vo(t.get("minSize"),a.width),Vo(t.get("maxSize"),a.width)],l=i.getDataExtent(n),u=t.get("min"),h=t.get("max");null==u&&(u=Math.min(l[0],0)),null==h&&(h=l[1]);var c=t.get("funnelAlign"),d=t.get("gap"),f=(a.height-d*(i.count()-1))/i.count(),p=a.y,g=function(t,e){var o,r=Bo(i.get(n,t)||0,[u,h],s,!0);switch(c){case"left":o=a.x;break;case"center":o=a.x+(a.width-r)/2;break;case"right":o=a.x+a.width-r}return[[o,e],[o+r,e]]};"ascending"===o&&(f=-f,d=-d,p+=a.height,r=r.reverse());for(var m=0;ma&&(e[1-n]=e[n]+h.sign*a),e},tk=d,ek=Math.min,ik=Math.max,nk=Math.floor,ok=Math.ceil,ak=Go,rk=Math.PI;Nf.prototype={type:"parallel",constructor:Nf,_init:function(t,e,i){var n=t.dimensions,o=t.parallelAxisIndex;tk(n,function(t,i){var n=o[i],a=e.getComponent("parallelAxis",n),r=this._axesMap.set(t,new JL(t,Hl(a),[0,0],a.get("type"),n)),s="category"===r.type;r.onBand=s&&a.get("boundaryGap"),r.inverse=a.get("inverse"),a.axis=r,r.model=a,r.coordinateSystem=a.coordinateSystem=this},this)},update:function(t,e){this._updateAxesFromSeries(this._model,t)},containPoint:function(t){var e=this._makeLayoutInfo(),i=e.axisBase,n=e.layoutBase,o=e.pixelDimIndex,a=t[1-o],r=t[o];return a>=i&&a<=i+e.axisLength&&r>=n&&r<=n+e.layoutLength},getModel:function(){return this._model},_updateAxesFromSeries:function(t,e){e.eachSeries(function(i){if(t.contains(i,e)){var n=i.getData();tk(this.dimensions,function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(n,n.mapDimension(t)),Wl(e.scale,e.model)},this)}},this)},resize:function(t,e){this._rect=ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},getRect:function(){return this._rect},_makeLayoutInfo:function(){var t,e=this._model,i=this._rect,n=["x","y"],o=["width","height"],a=e.get("layout"),r="horizontal"===a?0:1,s=i[o[r]],l=[0,s],u=this.dimensions.length,h=Of(e.get("axisExpandWidth"),l),c=Of(e.get("axisExpandCount")||0,[0,u]),d=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,f=e.get("axisExpandWindow");f?(t=Of(f[1]-f[0],l),f[1]=f[0]+t):(t=Of(h*(c-1),l),(f=[h*(e.get("axisExpandCenter")||nk(u/2))-t/2])[1]=f[0]+t);var p=(s-t)/(u-c);p<3&&(p=0);var g=[nk(ak(f[0]/h,1))+1,ok(ak(f[1]/h,1))-1],m=p/h*f[0];return{layout:a,pixelDimIndex:r,layoutBase:i[n[r]],layoutLength:s,axisBase:i[n[1-r]],axisLength:i[o[1-r]],axisExpandable:d,axisExpandWidth:h,axisCollapseWidth:p,axisExpandWindow:f,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:m}},_layoutAxes:function(){var t=this._rect,e=this._axesMap,i=this.dimensions,n=this._makeLayoutInfo(),o=n.layout;e.each(function(t){var e=[0,n.axisLength],i=t.inverse?1:0;t.setExtent(e[i],e[1-i])}),tk(i,function(e,i){var a=(n.axisExpandable?Rf:Ef)(i,n),r={horizontal:{x:a.position,y:n.axisLength},vertical:{x:0,y:a.position}},s={horizontal:rk/2,vertical:0},l=[r[o].x+t.x,r[o].y+t.y],u=s[o],h=xt();Mt(h,h,u),St(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:a.axisNameAvailableWidth,axisLabelShow:a.axisLabelShow,nameTruncateMaxWidth:a.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}},this)},getAxis:function(t){return this._axesMap.get(t)},dataToPoint:function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},eachActiveState:function(t,e,i,n){null==i&&(i=0),null==n&&(n=t.count());var o=this._axesMap,a=this.dimensions,r=[],s=[];d(a,function(e){r.push(t.mapDimension(e)),s.push(o.get(e).model)});for(var l=this.hasAxisBrushed(),u=i;uo*(1-h[0])?(l="jump",r=s-o*(1-h[2])):(r=s-o*h[1])>=0&&(r=s-o*(1-h[1]))<=0&&(r=0),(r*=e.axisExpandWidth/u)?QL(r,n,a,"all"):l="none";else{o=n[1]-n[0];(n=[ik(0,a[1]*s/o-o/2)])[1]=ek(a[1],n[0]+o),n[0]=n[1]-o}return{axisExpandWindow:n,behavior:l}}},Fa.register("parallel",{create:function(t,e){var i=[];return t.eachComponent("parallel",function(n,o){var a=new Nf(n,t,e);a.name="parallel_"+o,a.resize(n,e),n.coordinateSystem=a,a.model=n,i.push(a)}),t.eachSeries(function(e){if("parallel"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"parallel",index:e.get("parallelIndex"),id:e.get("parallelId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}});var sk=lI.extend({type:"baseParallelAxis",axis:null,activeIntervals:[],getAreaSelectStyle:function(){return Qb([["fill","color"],["lineWidth","borderWidth"],["stroke","borderColor"],["width","width"],["opacity","opacity"]])(this.getModel("areaSelectStyle"))},setActiveIntervals:function(t){var e=this.activeIntervals=i(t);if(e)for(var n=e.length-1;n>=0;n--)Fo(e[n])},getActiveState:function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(t))return"inactive";if(1===e.length){var i=e[0];if(i[0]<=t&&t<=i[1])return"active"}else for(var n=0,o=e.length;n5)return;var n=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==n.behavior&&this._dispatchExpand({axisExpandWindow:n.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&Ip(this,"mousemove")){var e=this._model,i=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),n=i.behavior;"jump"===n&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===n?null:{axisExpandWindow:i.axisExpandWindow,animation:"jump"===n&&null})}}};Ns(function(t){Cf(t),Lf(t)}),YI.extend({type:"series.parallel",dependencies:["parallel"],visualColorAccessPath:"lineStyle.color",getInitialData:function(t,e){var i=this.getSource();return Tp(i,this),ml(i,this)},getRawIndicesByActiveState:function(t){var e=this.coordinateSystem,i=this.getData(),n=[];return e.eachActiveState(i,function(e,o){t===e&&n.push(i.getRawIndex(o))}),n},defaultOption:{zlevel:0,z:2,coordinateSystem:"parallel",parallelIndex:0,label:{show:!1},inactiveOpacity:.05,activeOpacity:1,lineStyle:{width:1,opacity:.45,type:"solid"},emphasis:{label:{show:!1}},progressive:500,smooth:!1,animationEasing:"linear"}});var Dk=.3,Ck=(Ar.extend({type:"parallel",init:function(){this._dataGroup=new tb,this.group.add(this._dataGroup),this._data,this._initialized},render:function(t,e,i,n){var o=this._dataGroup,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.dimensions,u=kp(t);if(a.diff(r).add(function(t){Pp(Lp(a,o,t,l,s),a,t,u)}).update(function(e,i){var o=r.getItemGraphicEl(i),h=Cp(a,e,l,s);a.setItemGraphicEl(e,o),Io(o,{shape:{points:h}},n&&!1===n.animation?null:t,e),Pp(o,a,e,u)}).remove(function(t){var e=r.getItemGraphicEl(t);o.remove(e)}).execute(),!this._initialized){this._initialized=!0;var h=Dp(s,t,function(){setTimeout(function(){o.removeClipPath()})});o.setClipPath(h)}this._data=a},incrementalPrepareRender:function(t,e,i){this._initialized=!0,this._data=null,this._dataGroup.removeAll()},incrementalRender:function(t,e,i){for(var n=e.getData(),o=e.coordinateSystem,a=o.dimensions,r=kp(e),s=t.start;sn&&(n=e)}),d(e,function(e){var o=new hL({type:"color",mappingMethod:"linear",dataExtent:[i,n],visual:t.get("color")}).mapValueToVisual(e.getLayout().value);e.setVisual("color",o);var a=e.getModel().get("itemStyle.color");null!=a&&e.setVisual("color",a)})}})});var Ok={_baseAxisDim:null,getInitialData:function(t,e){var i,n,o=e.getComponent("xAxis",this.get("xAxisIndex")),a=e.getComponent("yAxis",this.get("yAxisIndex")),r=o.get("type"),s=a.get("type");"category"===r?(t.layout="horizontal",i=o.getOrdinalMeta(),n=!0):"category"===s?(t.layout="vertical",i=a.getOrdinalMeta(),n=!0):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],f=[o,a],p=f[u].get("type"),g=f[1-u].get("type"),m=t.data;if(m&&n){var v=[];d(m,function(t,e){var i;t.value&&y(t.value)?(i=t.value.slice(),t.value.unshift(e)):y(t)?(i=t.slice(),t.unshift(e)):i=t,v.push(i)}),t.data=v}var x=this.defaultValueDimensions;return oC(this,{coordDimensions:[{name:h,type:qs(p),ordinalMeta:i,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:qs(g),dimsDef:x.slice()}],dimensionsCount:x.length+1})},getBaseAxis:function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis}};h(YI.extend({type:"series.boxplot",dependencies:["xAxis","yAxis","grid"],defaultValueDimensions:[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],dimensions:null,defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:2,shadowOffsetY:2,shadowColor:"rgba(0,0,0,0.4)"}},animationEasing:"elasticOut",animationDuration:800}}),Ok,!0);var Ek=["itemStyle"],Rk=["emphasis","itemStyle"],zk=(Ar.extend({type:"boxplot",render:function(t,e,i){var n=t.getData(),o=this.group,a=this._data;this._data||o.removeAll();var r="horizontal"===t.get("layout")?1:0;n.diff(a).add(function(t){if(n.hasValue(t)){var e=ig(n.getItemLayout(t),n,t,r,!0);n.setItemGraphicEl(t,e),o.add(e)}}).update(function(t,e){var i=a.getItemGraphicEl(e);if(n.hasValue(t)){var s=n.getItemLayout(t);i?ng(s,i,n,t):i=ig(s,n,t,r),o.add(i),n.setItemGraphicEl(t,i)}else o.remove(i)}).remove(function(t){var e=a.getItemGraphicEl(t);e&&o.remove(e)}).execute(),this._data=n},remove:function(t){var e=this.group,i=this._data;this._data=null,i&&i.eachItemGraphicEl(function(t){t&&e.remove(t)})},dispose:B}),Pn.extend({type:"boxplotBoxPath",shape:{},buildPath:function(t,e){var i=e.points,n=0;for(t.moveTo(i[n][0],i[n][1]),n++;n<4;n++)t.lineTo(i[n][0],i[n][1]);for(t.closePath();n0?jk:Yk)}function n(t,e){return e.get(t>0?Uk:Xk)}var o=t.getData(),a=t.pipelineContext.large;if(o.setVisual({legendSymbol:"roundRect",colorP:i(1,t),colorN:i(-1,t),borderColorP:n(1,t),borderColorN:n(-1,t)}),!e.isSeriesFiltered(t))return!a&&{progress:function(t,e){for(var o;null!=(o=t.next());){var a=e.getItemModel(o),r=e.getItemLayout(o).sign;e.setItemVisual(o,{color:i(r,a),borderColor:n(r,a)})}}}}},Kk="undefined"!=typeof Float32Array?Float32Array:Array,$k={seriesType:"candlestick",plan:$I(),reset:function(t){var e=t.coordinateSystem,i=t.getData(),n=pg(t,i),o=0,a=1,r=["x","y"],s=i.mapDimension(r[o]),l=i.mapDimension(r[a],!0),u=l[0],h=l[1],c=l[2],d=l[3];if(i.setLayout({candleWidth:n,isSimpleBox:n<=1.3}),!(null==s||l.length<4))return{progress:t.pipelineContext.large?function(t,i){for(var n,r,l=new Kk(5*t.count),f=0,p=[],g=[];null!=(r=t.next());){var m=i.get(s,r),v=i.get(u,r),y=i.get(h,r),x=i.get(c,r),_=i.get(d,r);isNaN(m)||isNaN(x)||isNaN(_)?(l[f++]=NaN,f+=4):(l[f++]=fg(i,r,v,y,h),p[o]=m,p[a]=x,n=e.dataToPoint(p,null,g),l[f++]=n?n[0]:NaN,l[f++]=n?n[1]:NaN,p[a]=_,n=e.dataToPoint(p,null,g),l[f++]=n?n[1]:NaN)}i.setLayout("largePoints",l)}:function(t,i){function r(t,i){var n=[];return n[o]=i,n[a]=t,isNaN(i)||isNaN(t)?[NaN,NaN]:e.dataToPoint(n)}function l(t,e,i){var a=e.slice(),r=e.slice();a[o]=Jn(a[o]+n/2,1,!1),r[o]=Jn(r[o]-n/2,1,!0),i?t.push(a,r):t.push(r,a)}function f(t){return t[o]=Jn(t[o],1),t}for(var p;null!=(p=t.next());){var g=i.get(s,p),m=i.get(u,p),v=i.get(h,p),y=i.get(c,p),x=i.get(d,p),_=Math.min(m,v),w=Math.max(m,v),b=r(_,g),S=r(w,g),M=r(y,g),I=r(x,g),T=[];l(T,S,0),l(T,b,1),T.push(f(I),f(S),f(M),f(b)),i.setItemLayout(p,{sign:fg(i,p,m,v,h),initBaseline:m>v?S[a]:b[a],ends:T,brushRect:function(t,e,i){var s=r(t,i),l=r(e,i);return s[o]-=n/2,l[o]-=n/2,{x:s[0],y:s[1],width:a?n:l[0]-s[0],height:a?l[1]-s[1]:n}}(y,x,g)})}}}}};Ns(function(t){t&&y(t.series)&&d(t.series,function(t){w(t)&&"k"===t.type&&(t.type="candlestick")})}),Bs(qk),zs($k),YI.extend({type:"series.effectScatter",dependencies:["grid","polar"],getInitialData:function(t,e){return ml(this.getSource(),this)},brushSelector:"point",defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,effectType:"ripple",progressive:0,showEffectOn:"render",rippleEffect:{period:4,scale:2.5,brushType:"fill"},symbolSize:10}});var Jk=vg.prototype;Jk.stopEffectAnimation=function(){this.childAt(1).removeAll()},Jk.startEffectAnimation=function(t){for(var e=t.symbolType,i=t.color,n=this.childAt(1),o=0;o<3;o++){var a=Jl(e,-1,-1,2,2,i);a.attr({style:{strokeNoScale:!0},z2:99,silent:!0,scale:[.5,.5]});var r=-o/3*t.period+t.effectOffset;a.animate("",!0).when(t.period,{scale:[t.rippleScale/2,t.rippleScale/2]}).delay(r).start(),a.animateStyle(!0).when(t.period,{opacity:0}).delay(r).start(),n.add(a)}mg(n,t)},Jk.updateEffectAnimation=function(t){for(var e=this._effectCfg,i=this.childAt(1),n=["symbolType","period","rippleScale"],o=0;o "))},preventIncremental:function(){return!!this.get("effect.show")},getProgressive:function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},getProgressiveThreshold:function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},defaultOption:{coordinateSystem:"geo",zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,label:{show:!1,position:"end"},lineStyle:{opacity:.5}}}),iP=xg.prototype;iP.createLine=function(t,e,i){return new rf(t,e,i)},iP._updateEffectSymbol=function(t,e){var i=t.getItemModel(e).getModel("effect"),n=i.get("symbolSize"),o=i.get("symbol");y(n)||(n=[n,n]);var a=i.get("color")||t.getItemVisual(e,"color"),r=this.childAt(1);this._symbolType!==o&&(this.remove(r),(r=Jl(o,-.5,-.5,1,1,a)).z2=100,r.culling=!0,this.add(r)),r&&(r.setStyle("shadowColor",a),r.setStyle(i.getItemStyle(["color"])),r.attr("scale",n),r.setColor(a),r.attr("scale",n),this._symbolType=o,this._updateEffectAnimation(t,i,e))},iP._updateEffectAnimation=function(t,e,i){var n=this.childAt(1);if(n){var o=this,a=t.getItemLayout(i),r=1e3*e.get("period"),s=e.get("loop"),l=e.get("constantSpeed"),u=T(e.get("delay"),function(e){return e/t.count()*r/3}),h="function"==typeof u;if(n.ignore=!0,this.updateAnimationPoints(n,a),l>0&&(r=this.getLineLength(n)/l*1e3),r!==this._period||s!==this._loop){n.stopAnimation();var c=u;h&&(c=u(i)),n.__t>0&&(c=-r*n.__t),n.__t=0;var d=n.animate("",s).when(r,{__t:1}).delay(c).during(function(){o.updateSymbolPosition(n)});s||d.done(function(){o.remove(n)}),d.start()}this._period=r,this._loop=s}},iP.getLineLength=function(t){return uw(t.__p1,t.__cp1)+uw(t.__cp1,t.__p2)},iP.updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},iP.updateData=function(t,e,i){this.childAt(0).updateData(t,e,i),this._updateEffectSymbol(t,e)},iP.updateSymbolPosition=function(t){var e=t.__p1,i=t.__p2,n=t.__cp1,o=t.__t,a=t.position,r=sn,s=ln;a[0]=r(e[0],n[0],i[0],o),a[1]=r(e[1],n[1],i[1],o);var l=s(e[0],n[0],i[0],o),u=s(e[1],n[1],i[1],o);t.rotation=-Math.atan2(u,l)-Math.PI/2,t.ignore=!1},iP.updateLayout=function(t,e){this.childAt(0).updateLayout(t,e);var i=t.getItemModel(e).getModel("effect");this._updateEffectAnimation(t,i,e)},u(xg,tb);var nP=_g.prototype;nP._createPolyline=function(t,e,i){var n=t.getItemLayout(e),o=new gM({shape:{points:n}});this.add(o),this._updateCommonStl(t,e,i)},nP.updateData=function(t,e,i){var n=t.hostModel;Io(this.childAt(0),{shape:{points:t.getItemLayout(e)}},n,e),this._updateCommonStl(t,e,i)},nP._updateCommonStl=function(t,e,i){var n=this.childAt(0),o=t.getItemModel(e),a=t.getItemVisual(e,"color"),s=i&&i.lineStyle,l=i&&i.hoverLineStyle;i&&!t.hasItemOption||(s=o.getModel("lineStyle").getLineStyle(),l=o.getModel("emphasis.lineStyle").getLineStyle()),n.useStyle(r({strokeNoScale:!0,fill:"none",stroke:a},s)),n.hoverStyle=l,fo(this)},nP.updateLayout=function(t,e){this.childAt(0).setShape("points",t.getItemLayout(e))},u(_g,tb);var oP=wg.prototype;oP.createLine=function(t,e,i){return new _g(t,e,i)},oP.updateAnimationPoints=function(t,e){this._points=e;for(var i=[0],n=0,o=1;o=0&&!(n[r]<=e);r--);r=Math.min(r,o-2)}else{for(var r=a;re);r++);r=Math.min(r-1,o-2)}J(t.position,i[r],i[r+1],(e-n[r])/(n[r+1]-n[r]));var s=i[r+1][0]-i[r][0],l=i[r+1][1]-i[r][1];t.rotation=-Math.atan2(l,s)-Math.PI/2,this._lastFrame=r,this._lastFramePercent=e,t.ignore=!1}},u(wg,xg);var aP=Un({shape:{polyline:!1,curveness:0,segs:[]},buildPath:function(t,e){var i=e.segs,n=e.curveness;if(e.polyline)for(r=0;r0){t.moveTo(i[r++],i[r++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*n,d=(l+h)/2-(u-s)*n;t.quadraticCurveTo(c,d,u,h)}else t.lineTo(u,h)}},findDataIndex:function(t,e){var i=this.shape,n=i.segs,o=i.curveness;if(i.polyline)for(var a=0,r=0;r0)for(var l=n[r++],u=n[r++],h=1;h0){if(_n(l,u,(l+c)/2-(u-d)*o,(u+d)/2-(c-l)*o,c,d))return a}else if(yn(l,u,c,d))return a;a++}return-1}}),rP=bg.prototype;rP.isPersistent=function(){return!this._incremental},rP.updateData=function(t){this.group.removeAll();var e=new aP({rectHover:!0,cursor:"default"});e.setShape({segs:t.getLayout("linesPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},rP.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>5e5?(this._incremental||(this._incremental=new Zn({silent:!0})),this.group.add(this._incremental)):this._incremental=null},rP.incrementalUpdate=function(t,e){var i=new aP;i.setShape({segs:e.getLayout("linesPoints")}),this._setCommon(i,e,!!this._incremental),this._incremental?this._incremental.addDisplayable(i,!0):(i.rectHover=!0,i.cursor="default",i.__startIndex=t.start,this.group.add(i))},rP.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},rP._setCommon=function(t,e,i){var n=e.hostModel;t.setShape({polyline:n.get("polyline"),curveness:n.get("lineStyle.curveness")}),t.useStyle(n.getModel("lineStyle").getLineStyle()),t.style.strokeNoScale=!0;var o=e.getVisual("color");o&&t.setStyle("stroke",o),t.setStyle("fill"),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>0&&(t.dataIndex=i+t.__startIndex)}))},rP._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()};var sP={seriesType:"lines",plan:$I(),reset:function(t){var e=t.coordinateSystem,i=t.get("polyline"),n=t.pipelineContext.large;return{progress:function(o,a){var r=[];if(n){var s,l=o.end-o.start;if(i){for(var u=0,h=o.start;h0){var I=a(v)?s:l;v>0&&(v=v*S+b),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(y,0,0),h},_getBrush:function(){var t=this._brushCanvas||(this._brushCanvas=iw()),e=this.pointSize+this.blurSize,i=2*e;t.width=i,t.height=i;var n=t.getContext("2d");return n.clearRect(0,0,i,i),n.shadowOffsetX=i,n.shadowBlur=this.blurSize,n.shadowColor="#000",n.beginPath(),n.arc(-e,e,this.pointSize,0,2*Math.PI,!0),n.closePath(),n.fill(),t},_getGradient:function(t,e,i){for(var n=this._gradientPixels,o=n[i]||(n[i]=new Uint8ClampedArray(1024)),a=[0,0,0,0],r=0,s=0;s<256;s++)e[i](s/255,!0,a),o[r++]=a[0],o[r++]=a[1],o[r++]=a[2],o[r++]=a[3];return o}},Zs({type:"heatmap",render:function(t,e,i){var n;e.eachComponent("visualMap",function(e){e.eachTargetSeries(function(i){i===t&&(n=e)})}),this.group.removeAll(),this._incrementalDisplayable=null;var o=t.coordinateSystem;"cartesian2d"===o.type||"calendar"===o.type?this._renderOnCartesianAndCalendar(t,i,0,t.getData().count()):Ag(o)&&this._renderOnGeo(o,t,n,i)},incrementalPrepareRender:function(t,e,i){this.group.removeAll()},incrementalRender:function(t,e,i,n){e.coordinateSystem&&this._renderOnCartesianAndCalendar(e,n,t.start,t.end,!0)},_renderOnCartesianAndCalendar:function(t,e,i,n,o){var r,s,l=t.coordinateSystem;if("cartesian2d"===l.type){var u=l.getAxis("x"),h=l.getAxis("y");r=u.getBandWidth(),s=h.getBandWidth()}for(var c=this.group,d=t.getData(),f=t.getModel("itemStyle").getItemStyle(["color"]),p=t.getModel("emphasis.itemStyle").getItemStyle(),g=t.getModel("label"),m=t.getModel("emphasis.label"),v=l.type,y="cartesian2d"===v?[d.mapDimension("x"),d.mapDimension("y"),d.mapDimension("value")]:[d.mapDimension("time"),d.mapDimension("value")],x=i;x=e.y&&t[1]<=e.y+e.height:i.contain(i.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},pointToData:function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},dataToPoint:function(t){var e=this.getAxis(),i=this.getRect(),n=[],o="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),n[o]=e.toGlobalCoord(e.dataToCoord(+t)),n[1-o]=0===o?i.y+i.height/2:i.x+i.width/2,n}},Fa.register("single",{create:function(t,e){var i=[];return t.eachComponent("singleAxis",function(n,o){var a=new $g(n,t,e);a.name="single_"+o,a.resize(n,e),n.coordinateSystem=a,i.push(a)}),t.eachSeries(function(e){if("singleAxis"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"singleAxis",index:e.get("singleAxisIndex"),id:e.get("singleAxisId")})[0];e.coordinateSystem=i&&i.coordinateSystem}}),i},dimensions:$g.prototype.dimensions});var gP=["axisLine","axisTickLabel","axisName"],mP=XD.extend({type:"singleAxis",axisPointerClass:"SingleAxisPointer",render:function(t,e,i,n){var o=this.group;o.removeAll();var a=Jg(t),r=new FD(t,a);d(gP,r.add,r),o.add(r.getGroup()),t.get("splitLine.show")&&this._splitLine(t),mP.superCall(this,"render",t,e,i,n)},_splitLine:function(t){var e=t.axis;if(!e.scale.isBlank()){var i=t.getModel("splitLine"),n=i.getModel("lineStyle"),o=n.get("width"),a=n.get("color");a=a instanceof Array?a:[a];for(var r=t.coordinateSystem.getRect(),s=e.isHorizontal(),l=[],u=0,h=e.getTicksCoords({tickModel:i}),c=[],d=[],f=0;f=0)&&i({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})})},remove:function(t,e){gm(e.getZr(),"axisPointer"),IP.superApply(this._model,"remove",arguments)},dispose:function(t,e){gm("axisPointer",e),IP.superApply(this._model,"dispose",arguments)}}),TP=Bi(),AP=i,DP=m;(mm.prototype={_group:null,_lastGraphicKey:null,_handle:null,_dragging:!1,_lastValue:null,_lastStatus:null,_payloadInfo:null,animationThreshold:15,render:function(t,e,i,n){var o=e.get("value"),a=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=i,n||this._lastValue!==o||this._lastStatus!==a){this._lastValue=o,this._lastStatus=a;var r=this._group,s=this._handle;if(!a||"hide"===a)return r&&r.hide(),void(s&&s.hide());r&&r.show(),s&&s.show();var l={};this.makeElOption(l,o,t,e,i);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(i),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(r){var c=v(vm,e,h);this.updatePointerEl(r,l,c,e),this.updateLabelEl(r,l,c,e)}else r=this._group=new tb,this.createPointerEl(r,l,t,e),this.createLabelEl(r,l,t,e),i.getZr().add(r);wm(r,e,!0),this._renderHandle(o)}},remove:function(t){this.clear(t)},dispose:function(t){this.clear(t)},determineAnimation:function(t,e){var i=e.get("animation"),n=t.axis,o="category"===n.type,a=e.get("snap");if(!a&&!o)return!1;if("auto"===i||null==i){var r=this.animationThreshold;if(o&&n.getBandWidth()>r)return!0;if(a){var s=Mh(t).seriesDataCount,l=n.getExtent();return Math.abs(l[0]-l[1])/s>r}return!1}return!0===i},makeElOption:function(t,e,i,n,o){},createPointerEl:function(t,e,i,n){var o=e.pointer;if(o){var a=TP(t).pointerEl=new zM[o.type](AP(e.pointer));t.add(a)}},createLabelEl:function(t,e,i,n){if(e.label){var o=TP(t).labelEl=new yM(AP(e.label));t.add(o),xm(o,n)}},updatePointerEl:function(t,e,i){var n=TP(t).pointerEl;n&&(n.setStyle(e.pointer.style),i(n,{shape:e.pointer.shape}))},updateLabelEl:function(t,e,i,n){var o=TP(t).labelEl;o&&(o.setStyle(e.label.style),i(o,{shape:e.label.shape,position:e.label.position}),xm(o,n))},_renderHandle:function(t){if(!this._dragging&&this.updateHandleTransform){var e=this._axisPointerModel,i=this._api.getZr(),n=this._handle,o=e.getModel("handle"),a=e.get("status");if(!o.get("show")||!a||"hide"===a)return n&&i.remove(n),void(this._handle=null);var r;this._handle||(r=!0,n=this._handle=Po(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){mw(t.event)},onmousedown:DP(this._onHandleDragMove,this,0,0),drift:DP(this._onHandleDragMove,this),ondragend:DP(this._onHandleDragEnd,this)}),i.add(n)),wm(n,e,!1);var s=["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"];n.setStyle(o.getItemStyle(null,s));var l=o.get("size");y(l)||(l=[l,l]),n.attr("scale",[l[0]/2,l[1]/2]),Nr(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,r)}},_moveHandleToValue:function(t,e){vm(this._axisPointerModel,!e&&this._moveAnimation,this._handle,_m(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},_onHandleDragMove:function(t,e){var i=this._handle;if(i){this._dragging=!0;var n=this.updateHandleTransform(_m(i),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=n,i.stopAnimation(),i.attr(_m(n)),TP(i).lastProp=null,this._doDispatchAxisPointer()}},_doDispatchAxisPointer:function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},_onHandleDragEnd:function(t){if(this._dragging=!1,this._handle){var e=this._axisPointerModel.get("value");this._moveHandleToValue(e),this._api.dispatchAction({type:"hideTip"})}},getHandleTransform:null,updateHandleTransform:null,clear:function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),i=this._group,n=this._handle;e&&i&&(this._lastGraphicKey=null,i&&e.remove(i),n&&e.remove(n),this._group=null,this._handle=null,this._payloadInfo=null)},doClear:function(){},buildLabel:function(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}}).constructor=mm,ji(mm);var CP=mm.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.grid,s=n.get("type"),l=km(r,a).getOtherAxis(a).getGlobalExtent(),u=a.toGlobalCoord(a.dataToCoord(e,!0));if(s&&"none"!==s){var h=bm(n),c=LP[s](a,u,l,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Am(e,t,Lh(r.model,i),i,n,o)},getHandleTransform:function(t,e,i){var n=Lh(e.axis.grid.model,e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Tm(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.grid,r=o.getGlobalExtent(!0),s=km(a,o).getOtherAxis(o).getGlobalExtent(),l="x"===o.dim?0:1,u=t.position;u[l]+=e[l],u[l]=Math.min(r[1],u[l]),u[l]=Math.max(r[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];var d=[{verticalAlign:"middle"},{align:"center"}];return{position:u,rotation:t.rotation,cursorPoint:c,tooltipOption:d[l]}}}),LP={line:function(t,e,i,n){var o=Dm([e,i[0]],[e,i[1]],Pm(t));return Kn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=Math.max(1,t.getBandWidth()),a=i[1]-i[0];return{type:"Rect",shape:Cm([e-o/2,i[0]],[o,a],Pm(t))}}};XD.registerAxisPointerClass("CartesianAxisPointer",CP),Ns(function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!y(e)&&(t.axisPointer.link=[e])}}),Os(VT.PROCESSOR.STATISTIC,function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=vh(t,e)}),Es({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},function(t,e,i){var n=t.currTrigger,o=[t.x,t.y],a=t,r=t.dispatchAction||m(i.dispatchAction,i),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){lm(o)&&(o=xP({seriesIndex:a.seriesIndex,dataIndex:a.dataIndex},e).point);var l=lm(o),u=a.axesInfo,h=s.axesInfo,c="leave"===n||lm(o),d={},f={},p={list:[],map:{}},g={showPointer:wP(em,f),showTooltip:wP(im,p)};_P(s.coordSysMap,function(t,e){var i=l||t.containPoint(o);_P(s.coordSysAxesInfo[e],function(t,e){var n=t.axis,a=rm(u,t);if(!c&&i&&(!u||a)){var r=a&&a.value;null!=r||l||(r=n.pointToData(o)),null!=r&&Qg(t,r,g,!1,d)}})});var v={};return _P(h,function(t,e){var i=t.linkGroup;i&&!f[e]&&_P(i.axesInfo,function(e,n){var o=f[n];if(e!==t&&o){var a=o.value;i.mapper&&(a=t.axis.scale.parse(i.mapper(a,sm(e),sm(t)))),v[t.key]=a}})}),_P(v,function(t,e){Qg(h[e],t,g,!0,d)}),nm(f,h,d),om(p,o,t,r),am(h,0,i),d}});var kP=["x","y"],PP=["width","height"],NP=mm.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.coordinateSystem,s=Om(r,1-Nm(a)),l=r.dataToPoint(e)[0],u=n.get("type");if(u&&"none"!==u){var h=bm(n),c=OP[u](a,l,s,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Am(e,t,Jg(i),i,n,o)},getHandleTransform:function(t,e,i){var n=Jg(e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Tm(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.coordinateSystem,r=Nm(o),s=Om(a,r),l=t.position;l[r]+=e[r],l[r]=Math.min(s[1],l[r]),l[r]=Math.max(s[0],l[r]);var u=Om(a,1-r),h=(u[1]+u[0])/2,c=[h,h];return c[r]=l[r],{position:l,rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}}}),OP={line:function(t,e,i,n){var o=Dm([e,i[0]],[e,i[1]],Nm(t));return Kn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=t.getBandWidth(),a=i[1]-i[0];return{type:"Rect",shape:Cm([e-o/2,i[0]],[o,a],Nm(t))}}};XD.registerAxisPointerClass("SingleAxisPointer",NP),Ws({type:"single"});var EP=YI.extend({type:"series.themeRiver",dependencies:["singleAxis"],nameMap:null,init:function(t){EP.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()}},fixData:function(t){var e=t.length,i=[];Zi(t,function(t){return t[2]}).buckets.each(function(t,e){i.push({name:e,dataList:t})});for(var n=i.length,o=-1,a=-1,r=0;ro&&(o=s,a=r)}for(var l=0;lMath.PI/2?"right":"left"):x&&"center"!==x?"left"===x?(f=u.r0+y,p>Math.PI/2&&(x="right")):"right"===x&&(f=u.r-y,p>Math.PI/2&&(x="left")):(f=(u.r+u.r0)/2,x="center"),d.attr("style",{text:l,textAlign:x,textVerticalAlign:n("verticalAlign")||"middle",opacity:n("opacity")});var _=f*g+u.cx,w=f*m+u.cy;d.attr("position",[_,w]);var b=n("rotate"),S=0;"radial"===b?(S=-p)<-Math.PI/2&&(S+=Math.PI):"tangential"===b?(S=Math.PI/2-p)>Math.PI/2?S-=Math.PI:S<-Math.PI/2&&(S+=Math.PI):"number"==typeof b&&(S=b*Math.PI/180),d.attr("rotation",S)},VP._initEvents=function(t,e,i,n){t.off("mouseover").off("mouseout").off("emphasis").off("normal");var o=this,a=function(){o.onEmphasis(n)},r=function(){o.onNormal()};i.isAnimationEnabled()&&t.on("mouseover",a).on("mouseout",r).on("emphasis",a).on("normal",r).on("downplay",function(){o.onDownplay()}).on("highlight",function(){o.onHighlight()})},u(Vm,tb);Ar.extend({type:"sunburst",init:function(){},render:function(t,e,i,n){function o(i,n){if(c||!i||i.getValue()||(i=null),i!==l&&n!==l)if(n&&n.piece)i?(n.piece.updateData(!1,i,"normal",t,e),s.setItemGraphicEl(i.dataIndex,n.piece)):a(n);else if(i){var o=new Vm(i,t,e);h.add(o),s.setItemGraphicEl(i.dataIndex,o)}}function a(t){t&&t.piece&&(h.remove(t.piece),t.piece=null)}var r=this;this.seriesModel=t,this.api=i,this.ecModel=e;var s=t.getData(),l=s.tree.root,u=t.getViewRoot(),h=this.group,c=t.get("renderLabelForZeroData"),d=[];u.eachNode(function(t){d.push(t)});var f=this._oldChildren||[];if(function(t,e){function i(t){return t.getId()}function n(i,n){o(null==i?null:t[i],null==n?null:e[n])}0===t.length&&0===e.length||new Xs(e,t,i,i).add(n).update(n).remove(v(n,null)).execute()}(d,f),function(i,n){if(n.depth>0){r.virtualPiece?r.virtualPiece.updateData(!1,i,"normal",t,e):(r.virtualPiece=new Vm(i,t,e),h.add(r.virtualPiece)),n.piece._onclickEvent&&n.piece.off("click",n.piece._onclickEvent);var o=function(t){r._rootToNode(n.parentNode)};n.piece._onclickEvent=o,r.virtualPiece.on("click",o)}else r.virtualPiece&&(h.remove(r.virtualPiece),r.virtualPiece=null)}(l,u),n&&n.highlight&&n.highlight.piece){var p=t.getShallow("highlightPolicy");n.highlight.piece.onEmphasis(p)}else if(n&&n.unhighlight){var g=this.virtualPiece;!g&&l.children.length&&(g=l.children[0].piece),g&&g.onNormal()}this._initEvents(),this._oldChildren=d},dispose:function(){},_initEvents:function(){var t=this,e=function(e){var i=!1;t.seriesModel.getViewRoot().eachNode(function(n){if(!i&&n.piece&&n.piece.childAt(0)===e.target){var o=n.getModel().get("nodeClick");if("rootToNode"===o)t._rootToNode(n);else if("link"===o){var a=n.getModel(),r=a.get("link");if(r){var s=a.get("target",!0)||"_blank";window.open(r,s)}}i=!0}})};this.group._onclickEvent&&this.group.off("click",this.group._onclickEvent),this.group.on("click",e),this.group._onclickEvent=e},_rootToNode:function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:"sunburstRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var GP="sunburstRootToNode";Es({type:GP,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=ld(t,[GP],e);if(n){var o=e.getViewRoot();o&&(t.direction=hd(o,n.node)?"rollUp":"drillDown"),e.resetViewRoot(n.node)}})});var FP="sunburstHighlight";Es({type:FP,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=ld(t,[FP],e);n&&(t.highlight=n.node)})});Es({type:"sunburstUnhighlight",update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){t.unhighlight=!0})});var WP=Math.PI/180;Bs(v(uC,"sunburst")),zs(v(function(t,e,i,n){e.eachSeriesByType(t,function(t){var e=t.get("center"),n=t.get("radius");y(n)||(n=[0,n]),y(e)||(e=[e,e]);var o=i.getWidth(),a=i.getHeight(),r=Math.min(o,a),s=Vo(e[0],o),l=Vo(e[1],a),u=Vo(n[0],r/2),h=Vo(n[1],r/2),c=-t.get("startAngle")*WP,f=t.get("minAngle")*WP,p=t.getData().tree.root,g=t.getViewRoot(),m=g.depth,v=t.get("sort");null!=v&&Zm(g,v);var x=0;d(g.children,function(t){!isNaN(t.getValue())&&x++});var _=g.getValue(),w=Math.PI/(_||x)*2,b=g.depth>0,S=g.height-(b?-1:1),M=(h-u)/(S||1),I=t.get("clockwise"),T=t.get("stillShowZeroSum"),A=I?1:-1,D=function(t,e){if(t){var i=e;if(t!==p){var n=t.getValue(),o=0===_&&T?w:n*w;on[1]&&n.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:n[1],r0:n[0]},api:{coord:m(function(n){var o=e.dataToRadius(n[0]),a=i.dataToAngle(n[1]),r=t.coordToPoint([o,a]);return r.push(o,a*Math.PI/180),r}),size:m(qm,t)}}},calendar:function(t){var e=t.getRect(),i=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:i.start,end:i.end,weeks:i.weeks,dayCount:i.allDay}},api:{coord:function(e,i){return t.dataToPoint(e,i)}}}}};YI.extend({type:"series.custom",dependencies:["grid","polar","geo","singleAxis","calendar"],defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,useTransform:!0},getInitialData:function(t,e){return ml(this.getSource(),this)},getDataParams:function(t,e,i){var n=YI.prototype.getDataParams.apply(this,arguments);return i&&(n.info=i.info),n}}),Ar.extend({type:"custom",_data:null,render:function(t,e,i,n){var o=this._data,a=t.getData(),r=this.group,s=Qm(t,a,e,i);a.diff(o).add(function(e){ev(null,e,s(e,n),t,r,a)}).update(function(e,i){ev(o.getItemGraphicEl(i),e,s(e,n),t,r,a)}).remove(function(t){var e=o.getItemGraphicEl(t);e&&r.remove(e)}).execute(),this._data=a},incrementalPrepareRender:function(t,e,i){this.group.removeAll(),this._data=null},incrementalRender:function(t,e,i,n,o){for(var a=e.getData(),r=Qm(e,a,i,n),s=t.start;s=0;l--)null==o[l]?o.splice(l,1):delete o[l].$action},_flatten:function(t,e,i){d(t,function(t){if(t){i&&(t.parentOption=i),e.push(t);var n=t.children;"group"===t.type&&n&&this._flatten(n,e,t),delete t.children}},this)},useElOptionsToUpdate:function(){var t=this._elOptionsToUpdate;return this._elOptionsToUpdate=null,t}});Ws({type:"graphic",init:function(t,e){this._elMap=R(),this._lastGraphicModel},render:function(t,e,i){t!==this._lastGraphicModel&&this._clear(),this._lastGraphicModel=t,this._updateElements(t),this._relocate(t,i)},_updateElements:function(t){var e=t.useElOptionsToUpdate();if(e){var i=this._elMap,n=this.group;d(e,function(e){var o=e.$action,a=e.id,r=i.get(a),s=e.parentId,l=null!=s?i.get(s):n,u=e.style;"text"===e.type&&u&&(e.hv&&e.hv[1]&&(u.textVerticalAlign=u.textBaseline=null),!u.hasOwnProperty("textFill")&&u.fill&&(u.textFill=u.fill),!u.hasOwnProperty("textStroke")&&u.stroke&&(u.textStroke=u.stroke));var h=fv(e);o&&"merge"!==o?"replace"===o?(dv(r,i),cv(a,l,h,i)):"remove"===o&&dv(r,i):r?r.attr(h):cv(a,l,h,i);var c=i.get(a);c&&(c.__ecGraphicWidth=e.width,c.__ecGraphicHeight=e.height,yv(c,t))})}},_relocate:function(t,e){for(var i=t.option.elements,n=this.group,o=this._elMap,a=i.length-1;a>=0;a--){var r=i[a],s=o.get(r.id);if(s){var l=s.parent;da(s,r,l===n?{width:e.getWidth(),height:e.getHeight()}:{width:l.__ecGraphicWidth||0,height:l.__ecGraphicHeight||0},null,{hv:r.hv,boundingMode:r.bounding})}}},_clear:function(){var t=this._elMap;t.each(function(e){dv(e,t)}),this._elMap=R()},dispose:function(){this._clear()}});var KP=Fs({type:"legend.plain",dependencies:["series"],layoutMode:{type:"box",ignoreSize:!0},init:function(t,e,i){this.mergeDefaultAndTheme(t,i),t.selected=t.selected||{}},mergeOption:function(t){KP.superCall(this,"mergeOption",t)},optionUpdated:function(){this._updateData(this.ecModel);var t=this._data;if(t[0]&&"single"===this.get("selectedMode")){for(var e=!1,i=0;i=0},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",textStyle:{color:"#333"},selectedMode:!0,tooltip:{show:!1}}});Es("legendToggleSelect","legendselectchanged",v(xv,"toggleSelected")),Es("legendSelect","legendselected",v(xv,"select")),Es("legendUnSelect","legendunselected",v(xv,"unSelect"));var $P=v,JP=d,QP=tb,tN=Ws({type:"legend.plain",newlineDisabled:!1,init:function(){this.group.add(this._contentGroup=new QP),this._backgroundEl,this._isFirstRender=!0},getContentGroup:function(){return this._contentGroup},render:function(t,e,i){var n=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var o=t.get("align");o&&"auto"!==o||(o="right"===t.get("left")&&"vertical"===t.get("orient")?"right":"left"),this.renderInner(o,t,e,i);var a=t.getBoxLayoutParams(),s={width:i.getWidth(),height:i.getHeight()},l=t.get("padding"),u=ca(a,s,l),h=this.layoutInner(t,o,u,n),c=ca(r({width:h.width,height:h.height},a),s,l);this.group.attr("position",[c.x-h.x,c.y-h.y]),this.group.add(this._backgroundEl=wv(h,t))}},resetInner:function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl)},renderInner:function(t,e,i,n){var o=this.getContentGroup(),a=R(),r=e.get("selectedMode"),s=[];i.eachRawSeries(function(t){!t.get("legendHoverLink")&&s.push(t.id)}),JP(e.getData(),function(l,u){var h=l.get("name");if(this.newlineDisabled||""!==h&&"\n"!==h){var c=i.getSeriesByName(h)[0];if(!a.get(h))if(c){var d=c.getData(),f=d.getVisual("color");"function"==typeof f&&(f=f(c.getDataParams(0)));var p=d.getVisual("legendSymbol")||"roundRect",g=d.getVisual("symbol");this._createItem(h,u,l,e,p,g,t,f,r).on("click",$P(bv,h,n)).on("mouseover",$P(Sv,c.name,null,n,s)).on("mouseout",$P(Mv,c.name,null,n,s)),a.set(h,!0)}else i.eachRawSeries(function(i){if(!a.get(h)&&i.legendDataProvider){var o=i.legendDataProvider(),c=o.indexOfName(h);if(c<0)return;var d=o.getItemVisual(c,"color");this._createItem(h,u,l,e,"roundRect",null,t,d,r).on("click",$P(bv,h,n)).on("mouseover",$P(Sv,null,h,n,s)).on("mouseout",$P(Mv,null,h,n,s)),a.set(h,!0)}},this)}else o.add(new QP({newline:!0}))},this)},_createItem:function(t,e,i,n,o,r,s,l,u){var h=n.get("itemWidth"),c=n.get("itemHeight"),d=n.get("inactiveColor"),f=n.get("symbolKeepAspect"),p=n.isSelected(t),g=new QP,m=i.getModel("textStyle"),v=i.get("icon"),y=i.getModel("tooltip"),x=y.parentModel;if(o=v||o,g.add(Jl(o,0,0,h,c,p?l:d,null==f||f)),!v&&r&&(r!==o||"none"===r)){var _=.8*c;"none"===r&&(r="circle"),g.add(Jl(r,(h-_)/2,(c-_)/2,_,_,p?l:d,null==f||f))}var w="left"===s?h+5:-5,b=s,S=n.get("formatter"),M=t;"string"==typeof S&&S?M=S.replace("{name}",null!=t?t:""):"function"==typeof S&&(M=S(t)),g.add(new rM({style:mo({},m,{text:M,x:w,y:c/2,textFill:p?m.getTextColor():d,textAlign:b,textVerticalAlign:"middle"})}));var I=new yM({shape:g.getBoundingRect(),invisible:!0,tooltip:y.get("show")?a({content:t,formatter:x.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:n.componentIndex,name:t,$vars:["name"]}},y.option):null});return g.add(I),g.eachChild(function(t){t.silent=!0}),I.silent=!u,this.getContentGroup().add(g),fo(g),g.__legendDataIndex=e,g},layoutInner:function(t,e,i){var n=this.getContentGroup();aI(t.get("orient"),n,t.get("itemGap"),i.width,i.height);var o=n.getBoundingRect();return n.attr("position",[-o.x,-o.y]),this.group.getBoundingRect()},remove:function(){this.getContentGroup().removeAll(),this._isFirstRender=!0}});Os(function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var i=0;ii[l],p=[-c.x,-c.y];n||(p[s]=o.position[s]);var g=[0,0],m=[-d.x,-d.y],v=A(t.get("pageButtonGap",!0),t.get("itemGap",!0));f&&("end"===t.get("pageButtonPosition",!0)?m[s]+=i[l]-d[l]:g[s]+=d[l]+v),m[1-s]+=c[u]/2-d[u]/2,o.attr("position",p),a.attr("position",g),r.attr("position",m);var y=this.group.getBoundingRect();if((y={x:0,y:0})[l]=f?i[l]:c[l],y[u]=Math.max(c[u],d[u]),y[h]=Math.min(0,d[h]+m[1-s]),a.__rectSize=i[l],f){var x={x:0,y:0};x[l]=Math.max(i[l]-d[l]-v,0),x[u]=y[u],a.setClipPath(new yM({shape:x})),a.__rectSize=x[l]}else r.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var _=this._getPageInfo(t);return null!=_.pageIndex&&Io(o,{position:_.contentPosition},!!f&&t),this._updatePageInfoView(t,_),y},_pageGo:function(t,e,i){var n=this._getPageInfo(e)[t];null!=n&&i.dispatchAction({type:"legendScroll",scrollDataIndex:n,legendId:e.id})},_updatePageInfoView:function(t,e){var i=this._controllerGroup;d(["pagePrev","pageNext"],function(n){var o=null!=e[n+"DataIndex"],a=i.childOfName(n);a&&(a.setStyle("fill",o?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),a.cursor=o?"pointer":"default")});var n=i.childOfName("pageText"),o=t.get("pageFormatter"),a=e.pageIndex,r=null!=a?a+1:0,s=e.pageCount;n&&o&&n.setStyle("text",_(o)?o.replace("{current}",r).replace("{total}",s):o({current:r,total:s}))},_getPageInfo:function(t){function e(t){if(t){var e=t.getBoundingRect(),i=e[l]+t.position[r];return{s:i,e:i+e[s],i:t.__legendDataIndex}}}function i(t,e){return t.e>=e&&t.s<=e+a}var n=t.get("scrollDataIndex",!0),o=this.getContentGroup(),a=this._containerGroup.__rectSize,r=t.getOrient().index,s=nN[r],l=oN[r],u=this._findTargetItemIndex(n),h=o.children(),c=h[u],d=h.length,f=d?1:0,p={contentPosition:o.position.slice(),pageCount:f,pageIndex:f-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!c)return p;var g=e(c);p.contentPosition[r]=-g.s;for(var m=u+1,v=g,y=g,x=null;m<=d;++m)(!(x=e(h[m]))&&y.e>v.s+a||x&&!i(x,v.s))&&(v=y.i>v.i?y:x)&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=v.i),++p.pageCount),y=x;for(var m=u-1,v=g,y=g,x=null;m>=-1;--m)(x=e(h[m]))&&i(y,x.s)||!(v.i=0;){var r=o.indexOf("|}"),s=o.substr(a+"{marker".length,r-a-"{marker".length);s.indexOf("sub")>-1?n["marker"+s]={textWidth:4,textHeight:4,textBorderRadius:2,textBackgroundColor:e[s],textOffset:[3,0]}:n["marker"+s]={textWidth:10,textHeight:10,textBorderRadius:5,textBackgroundColor:e[s]},a=(o=o.substr(r+1)).indexOf("{marker")}this.el=new rM({style:{rich:n,text:t,textLineHeight:20,textBackgroundColor:i.get("backgroundColor"),textBorderRadius:i.get("borderRadius"),textFill:i.get("textStyle.color"),textPadding:i.get("padding")},z:i.get("z")}),this._zr.add(this.el);var l=this;this.el.on("mouseover",function(){l._enterable&&(clearTimeout(l._hideTimeout),l._show=!0),l._inContent=!0}),this.el.on("mouseout",function(){l._enterable&&l._show&&l.hideLater(l._hideDelay),l._inContent=!1})},setEnterable:function(t){this._enterable=t},getSize:function(){var t=this.el.getBoundingRect();return[t.width,t.height]},moveTo:function(t,e){this.el&&this.el.attr("position",[t,e])},hide:function(){this.el?this.el.hide():true,this._show=!1},hideLater:function(t){!this._show||this._inContent&&this._enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(m(this.hide,this),t)):this.hide())},isShow:function(){return this._show},getOuterSize:function(){return this.getSize()}};var uN=m,hN=d,cN=Vo,dN=new yM({shape:{x:-1,y:-1,width:2,height:2}});Ws({type:"tooltip",init:function(t,e){if(!U_.node){var i=t.getComponent("tooltip").get("renderMode");this._renderMode=Hi(i);var n;"html"===this._renderMode?(n=new Cv(e.getDom(),e),this._newLine="
"):(n=new Lv(e),this._newLine="\n"),this._tooltipContent=n}},render:function(t,e,i){if(!U_.node){this.group.removeAll(),this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastDataByCoordSys=null,this._alwaysShowContent=t.get("alwaysShowContent");var n=this._tooltipContent;n.update(),n.setEnterable(t.get("enterable")),this._initGlobalListener(),this._keepShow()}},_initGlobalListener:function(){var t=this._tooltipModel.get("triggerOn");um("itemTooltip",this._api,uN(function(e,i,n){"none"!==t&&(t.indexOf(e)>=0?this._tryShow(i,n):"leave"===e&&this._hide(n))},this))},_keepShow:function(){var t=this._tooltipModel,e=this._ecModel,i=this._api;if(null!=this._lastX&&null!=this._lastY&&"none"!==t.get("triggerOn")){var n=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){n.manuallyShowTip(t,e,i,{x:n._lastX,y:n._lastY})})}},manuallyShowTip:function(t,e,i,n){if(n.from!==this.uid&&!U_.node){var o=Pv(n,i);this._ticket="";var a=n.dataByCoordSys;if(n.tooltip&&null!=n.x&&null!=n.y){var r=dN;r.position=[n.x,n.y],r.update(),r.tooltip=n.tooltip,this._tryShow({offsetX:n.x,offsetY:n.y,target:r},o)}else if(a)this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,event:{},dataByCoordSys:n.dataByCoordSys,tooltipOption:n.tooltipOption},o);else if(null!=n.seriesIndex){if(this._manuallyAxisShowTip(t,e,i,n))return;var s=xP(n,e),l=s.point[0],u=s.point[1];null!=l&&null!=u&&this._tryShow({offsetX:l,offsetY:u,position:n.position,target:s.el,event:{}},o)}else null!=n.x&&null!=n.y&&(i.dispatchAction({type:"updateAxisPointer",x:n.x,y:n.y}),this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,target:i.getZr().findHover(n.x,n.y).target,event:{}},o))}},manuallyHideTip:function(t,e,i,n){var o=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&o.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=null,n.from!==this.uid&&this._hide(Pv(n,i))},_manuallyAxisShowTip:function(t,e,i,n){var o=n.seriesIndex,a=n.dataIndex,r=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=o&&null!=a&&null!=r){var s=e.getSeriesByIndex(o);if(s&&"axis"===(t=kv([s.getData().getItemModel(a),s,(s.coordinateSystem||{}).model,t])).get("trigger"))return i.dispatchAction({type:"updateAxisPointer",seriesIndex:o,dataIndex:a,position:n.position}),!0}},_tryShow:function(t,e){var i=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var n=t.dataByCoordSys;n&&n.length?this._showAxisTooltip(n,t):i&&null!=i.dataIndex?(this._lastDataByCoordSys=null,this._showSeriesItemTooltip(t,i,e)):i&&i.tooltip?(this._lastDataByCoordSys=null,this._showComponentItemTooltip(t,i,e)):(this._lastDataByCoordSys=null,this._hide(e))}},_showOrMove:function(t,e){var i=t.get("showDelay");e=m(e,this),clearTimeout(this._showTimout),i>0?this._showTimout=setTimeout(e,i):e()},_showAxisTooltip:function(t,e){var i=this._ecModel,o=this._tooltipModel,a=[e.offsetX,e.offsetY],r=[],s=[],l=kv([e.tooltipOption,o]),u=this._renderMode,h=this._newLine,c={};hN(t,function(t){hN(t.dataByAxis,function(t){var e=i.getComponent(t.axisDim+"Axis",t.axisIndex),o=t.value,a=[];if(e&&null!=o){var l=Im(o,e.axis,i,t.seriesDataIndices,t.valueLabelOpt);d(t.seriesDataIndices,function(r){var h=i.getSeriesByIndex(r.seriesIndex),d=r.dataIndexInside,f=h&&h.getDataParams(d);if(f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=Xl(e.axis,o),f.axisValueLabel=l,f){s.push(f);var p,g=h.formatTooltip(d,!0,null,u);if(w(g)){p=g.html;var m=g.markers;n(c,m)}else p=g;a.push(p)}});var f=l;"html"!==u?r.push(a.join(h)):r.push((f?ia(f)+h:"")+a.join(h))}})},this),r.reverse(),r=r.join(this._newLine+this._newLine);var f=e.position;this._showOrMove(l,function(){this._updateContentNotChangedOnAxis(t)?this._updatePosition(l,f,a[0],a[1],this._tooltipContent,s):this._showTooltipContent(l,r,s,Math.random(),a[0],a[1],f,void 0,c)})},_showSeriesItemTooltip:function(t,e,i){var n=this._ecModel,o=e.seriesIndex,a=n.getSeriesByIndex(o),r=e.dataModel||a,s=e.dataIndex,l=e.dataType,u=r.getData(),h=kv([u.getItemModel(s),r,a&&(a.coordinateSystem||{}).model,this._tooltipModel]),c=h.get("trigger");if(null==c||"item"===c){var d,f,p=r.getDataParams(s,l),g=r.formatTooltip(s,!1,l,this._renderMode);w(g)?(d=g.html,f=g.markers):(d=g,f=null);var m="item_"+r.name+"_"+s;this._showOrMove(h,function(){this._showTooltipContent(h,d,p,m,t.offsetX,t.offsetY,t.position,t.target,f)}),i({type:"showTip",dataIndexInside:s,dataIndex:u.getRawIndex(s),seriesIndex:o,from:this.uid})}},_showComponentItemTooltip:function(t,e,i){var n=e.tooltip;if("string"==typeof n){var o=n;n={content:o,formatter:o}}var a=new No(n,this._tooltipModel,this._ecModel),r=a.get("content"),s=Math.random();this._showOrMove(a,function(){this._showTooltipContent(a,r,a.get("formatterParams")||{},s,t.offsetX,t.offsetY,t.position,e)}),i({type:"showTip",from:this.uid})},_showTooltipContent:function(t,e,i,n,o,a,r,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent,h=t.get("formatter");r=r||t.get("position");var c=e;if(h&&"string"==typeof h)c=na(h,i,!0);else if("function"==typeof h){var d=uN(function(e,n){e===this._ticket&&(u.setContent(n,l,t),this._updatePosition(t,r,o,a,u,i,s))},this);this._ticket=n,c=h(i,n,d)}u.setContent(c,l,t),u.show(t),this._updatePosition(t,r,o,a,u,i,s)}},_updatePosition:function(t,e,i,n,o,a,r){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=o.getSize(),h=t.get("align"),c=t.get("verticalAlign"),d=r&&r.getBoundingRect().clone();if(r&&d.applyTransform(r.transform),"function"==typeof e&&(e=e([i,n],a,o.el,d,{viewSize:[s,l],contentSize:u.slice()})),y(e))i=cN(e[0],s),n=cN(e[1],l);else if(w(e)){e.width=u[0],e.height=u[1];var f=ca(e,{width:s,height:l});i=f.x,n=f.y,h=null,c=null}else"string"==typeof e&&r?(i=(p=Ev(e,d,u))[0],n=p[1]):(i=(p=Nv(i,n,o,s,l,h?null:20,c?null:20))[0],n=p[1]);if(h&&(i-=Rv(h)?u[0]/2:"right"===h?u[0]:0),c&&(n-=Rv(c)?u[1]/2:"bottom"===c?u[1]:0),t.get("confine")){var p=Ov(i,n,o,s,l);i=p[0],n=p[1]}o.moveTo(i,n)},_updateContentNotChangedOnAxis:function(t){var e=this._lastDataByCoordSys,i=!!e&&e.length===t.length;return i&&hN(e,function(e,n){var o=e.dataByAxis||{},a=(t[n]||{}).dataByAxis||[];(i&=o.length===a.length)&&hN(o,function(t,e){var n=a[e]||{},o=t.seriesDataIndices||[],r=n.seriesDataIndices||[];(i&=t.value===n.value&&t.axisType===n.axisType&&t.axisId===n.axisId&&o.length===r.length)&&hN(o,function(t,e){var n=r[e];i&=t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})})}),this._lastDataByCoordSys=t,!!i},_hide:function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},dispose:function(t,e){U_.node||(this._tooltipContent.hide(),gm("itemTooltip",e))}}),Es({type:"showTip",event:"showTip",update:"tooltip:manuallyShowTip"},function(){}),Es({type:"hideTip",event:"hideTip",update:"tooltip:manuallyHideTip"},function(){}),Gv.prototype={constructor:Gv,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToRadius:aD.prototype.dataToCoord,radiusToData:aD.prototype.coordToData},u(Gv,aD);var fN=Bi();Fv.prototype={constructor:Fv,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToAngle:aD.prototype.dataToCoord,angleToData:aD.prototype.coordToData,calculateCategoryInterval:function(){var t=this,e=t.getLabelModel(),i=t.scale,n=i.getExtent(),o=i.count();if(n[1]-n[0]<1)return 0;var a=n[0],r=t.dataToCoord(a+1)-t.dataToCoord(a),s=Math.abs(r),l=ke(a,e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var h=Math.max(0,Math.floor(u)),c=fN(t.model),d=c.lastAutoInterval,f=c.lastTickCount;return null!=d&&null!=f&&Math.abs(d-h)<=1&&Math.abs(f-o)<=1&&d>h?h=d:(c.lastTickCount=o,c.lastAutoInterval=h),h}},u(Fv,aD);var pN=function(t){this.name=t||"",this.cx=0,this.cy=0,this._radiusAxis=new Gv,this._angleAxis=new Fv,this._radiusAxis.polar=this._angleAxis.polar=this};pN.prototype={type:"polar",axisPointerEnabled:!0,constructor:pN,dimensions:["radius","angle"],model:null,containPoint:function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},containData:function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},getAxis:function(t){return this["_"+t+"Axis"]},getAxes:function(){return[this._radiusAxis,this._angleAxis]},getAxesByScale:function(t){var e=[],i=this._angleAxis,n=this._radiusAxis;return i.scale.type===t&&e.push(i),n.scale.type===t&&e.push(n),e},getAngleAxis:function(){return this._angleAxis},getRadiusAxis:function(){return this._radiusAxis},getOtherAxis:function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},getBaseAxis:function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},getTooltipAxes:function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},dataToPoint:function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},pointToData:function(t,e){var i=this.pointToCoord(t);return[this._radiusAxis.radiusToData(i[0],e),this._angleAxis.angleToData(i[1],e)]},pointToCoord:function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=this.getAngleAxis(),o=n.getExtent(),a=Math.min(o[0],o[1]),r=Math.max(o[0],o[1]);n.inverse?a=r-360:r=a+360;var s=Math.sqrt(e*e+i*i);e/=s,i/=s;for(var l=Math.atan2(-i,e)/Math.PI*180,u=lr;)l+=360*u;return[s,l]},coordToPoint:function(t){var e=t[0],i=t[1]/180*Math.PI;return[Math.cos(i)*e+this.cx,-Math.sin(i)*e+this.cy]}};var gN=lI.extend({type:"polarAxis",axis:null,getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"polar",index:this.option.polarIndex,id:this.option.polarId})[0]}});n(gN.prototype,UA);var mN={angle:{startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:!1}},radius:{splitNumber:5}};ED("angle",gN,Wv,mN.angle),ED("radius",gN,Wv,mN.radius),Fs({type:"polar",dependencies:["polarAxis","angleAxis"],coordinateSystem:null,findAxisModel:function(t){var e;return this.ecModel.eachComponent(t,function(t){t.getCoordSysModel()===this&&(e=t)},this),e},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"80%"}});var vN={dimensions:pN.prototype.dimensions,create:function(t,e){var i=[];return t.eachComponent("polar",function(t,n){var o=new pN(n);o.update=Zv;var a=o.getRadiusAxis(),r=o.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");Uv(a,s),Uv(r,l),Hv(o,t,e),i.push(o),t.coordinateSystem=o,o.model=t}),t.eachSeries(function(e){if("polar"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"polar",index:e.get("polarIndex"),id:e.get("polarId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}};Fa.register("polar",vN);var yN=["axisLine","axisLabel","axisTick","splitLine","splitArea"];XD.extend({type:"angleAxis",axisPointerClass:"PolarAxisPointer",render:function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,o=n.polar,a=o.getRadiusAxis().getExtent(),r=n.getTicksCoords(),s=f(n.getViewLabels(),function(t){return(t=i(t)).coord=n.dataToCoord(t.tickValue),t});Yv(s),Yv(r),d(yN,function(e){!t.get(e+".show")||n.scale.isBlank()&&"axisLine"!==e||this["_"+e](t,o,r,a,s)},this)}},_axisLine:function(t,e,i,n){var o=t.getModel("axisLine.lineStyle"),a=new sM({shape:{cx:e.cx,cy:e.cy,r:n[jv(e)]},style:o.getLineStyle(),z2:1,silent:!0});a.style.fill=null,this.group.add(a)},_axisTick:function(t,e,i,n){var o=t.getModel("axisTick"),a=(o.get("inside")?-1:1)*o.get("length"),s=n[jv(e)],l=f(i,function(t){return new _M({shape:Xv(e,[s,s+a],t.coord)})});this.group.add(OM(l,{style:r(o.getModel("lineStyle").getLineStyle(),{stroke:t.get("axisLine.lineStyle.color")})}))},_axisLabel:function(t,e,i,n,o){var a=t.getCategories(!0),r=t.getModel("axisLabel"),s=r.get("margin");d(o,function(i,o){var l=r,u=i.tickValue,h=n[jv(e)],c=e.coordToPoint([h+s,i.coord]),d=e.cx,f=e.cy,p=Math.abs(c[0]-d)/h<.3?"center":c[0]>d?"left":"right",g=Math.abs(c[1]-f)/h<.3?"middle":c[1]>f?"top":"bottom";a&&a[u]&&a[u].textStyle&&(l=new No(a[u].textStyle,r,r.ecModel));var m=new rM({silent:!0});this.group.add(m),mo(m.style,l,{x:c[0],y:c[1],textFill:l.getTextColor()||t.get("axisLine.lineStyle.color"),text:i.formattedLabel,textAlign:p,textVerticalAlign:g})},this)},_splitLine:function(t,e,i,n){var o=t.getModel("splitLine").getModel("lineStyle"),a=o.get("color"),s=0;a=a instanceof Array?a:[a];for(var l=[],u=0;u=0?"p":"n",M=y;v&&(n[r][b]||(n[r][b]={p:y,n:y}),M=n[r][b][S]);var I,T,A,D;if("radius"===h.dim){var C=h.dataToRadius(w)-y,L=a.dataToAngle(b);Math.abs(C)=0},kN.findTargetInfo=function(t,e){for(var i=this._targetInfoList,n=dy(e,t),o=0;o=0||AN(n,t.getAxis("y").model)>=0)&&a.push(t)}),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:a[0],coordSyses:a,getPanelRect:ON.grid,xAxisDeclared:r[t.id],yAxisDeclared:s[t.id]})}))},geo:function(t,e){TN(t.geoModels,function(t){var i=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:i,coordSyses:[i],getPanelRect:ON.geo})})}},NN=[function(t,e){var i=t.xAxisModel,n=t.yAxisModel,o=t.gridModel;return!o&&i&&(o=i.axis.grid.model),!o&&n&&(o=n.axis.grid.model),o&&o===e.gridModel},function(t,e){var i=t.geoModel;return i&&i===e.geoModel}],ON={grid:function(){return this.coordSys.grid.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(Ao(t)),e}},EN={lineX:DN(fy,0),lineY:DN(fy,1),rect:function(t,e,i){var n=e[CN[t]]([i[0][0],i[1][0]]),o=e[CN[t]]([i[0][1],i[1][1]]),a=[cy([n[0],o[0]]),cy([n[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,i){var n=[[1/0,-1/0],[1/0,-1/0]];return{values:f(i,function(i){var o=e[CN[t]](i);return n[0][0]=Math.min(n[0][0],o[0]),n[1][0]=Math.min(n[1][0],o[1]),n[0][1]=Math.max(n[0][1],o[0]),n[1][1]=Math.max(n[1][1],o[1]),o}),xyMinMax:n}}},RN={lineX:DN(py,0),lineY:DN(py,1),rect:function(t,e,i){return[[t[0][0]-i[0]*e[0][0],t[0][1]-i[0]*e[0][1]],[t[1][0]-i[1]*e[1][0],t[1][1]-i[1]*e[1][1]]]},polygon:function(t,e,i){return f(t,function(t,n){return[t[0]-i[0]*e[n][0],t[1]-i[1]*e[n][1]]})}},zN=["inBrush","outOfBrush"],BN="__ecBrushSelect",VN="__ecInBrushSelectEvent",GN=VT.VISUAL.BRUSH;zs(GN,function(t,e,i){t.eachComponent({mainType:"brush"},function(e){i&&"takeGlobalCursor"===i.type&&e.setBrushOption("brush"===i.key?i.brushOption:{brushType:!1}),(e.brushTargetManager=new hy(e.option,t)).setInputRanges(e.areas,t)})}),Bs(GN,function(t,e,n){var o,a,s=[];t.eachComponent({mainType:"brush"},function(e,n){function l(t){return"all"===m||v[t]}function u(t){return!!t.length}function h(t,e){var i=t.coordinateSystem;w|=i.hasAxisBrushed(),l(e)&&i.eachActiveState(t.getData(),function(t,e){"active"===t&&(x[e]=1)})}function c(i,n,o){var a=_y(i);if(a&&!wy(e,n)&&(d(b,function(n){a[n.brushType]&&e.brushTargetManager.controlSeries(n,i,t)&&o.push(n),w|=u(o)}),l(n)&&u(o))){var r=i.getData();r.each(function(t){xy(a,o,r,t)&&(x[t]=1)})}}var p={brushId:e.id,brushIndex:n,brushName:e.name,areas:i(e.areas),selected:[]};s.push(p);var g=e.option,m=g.brushLink,v=[],x=[],_=[],w=0;n||(o=g.throttleType,a=g.throttleDelay);var b=f(e.areas,function(t){return by(r({boundingRect:FN[t.brushType](t)},t))}),S=ty(e.option,zN,function(t){t.mappingMethod="fixed"});y(m)&&d(m,function(t){v[t]=1}),t.eachSeries(function(t,e){var i=_[e]=[];"parallel"===t.subType?h(t,e):c(t,e,i)}),t.eachSeries(function(t,e){var i={seriesId:t.id,seriesIndex:e,seriesName:t.name,dataIndex:[]};p.selected.push(i);var n=_y(t),o=_[e],a=t.getData(),r=l(e)?function(t){return x[t]?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"}:function(t){return xy(n,o,a,t)?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"};(l(e)?w:u(o))&&iy(zN,S,a,r)})}),vy(e,o,a,s,n)});var FN={lineX:B,lineY:B,rect:function(t){return Sy(t.range)},polygon:function(t){for(var e,i=t.range,n=0,o=i.length;ne[0][1]&&(e[0][1]=a[0]),a[1]e[1][1]&&(e[1][1]=a[1])}return e&&Sy(e)}},WN=["#ddd"];Fs({type:"brush",dependencies:["geo","grid","xAxis","yAxis","parallel","series"],defaultOption:{toolbox:null,brushLink:null,seriesIndex:"all",geoIndex:null,xAxisIndex:null,yAxisIndex:null,brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(120,140,180,0.3)",borderColor:"rgba(120,140,180,0.8)"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},areas:[],brushType:null,brushOption:{},coordInfoList:[],optionUpdated:function(t,e){var i=this.option;!e&&ey(i,t,["inBrush","outOfBrush"]);var n=i.inBrush=i.inBrush||{};i.outOfBrush=i.outOfBrush||{color:WN},n.hasOwnProperty("liftZ")||(n.liftZ=5)},setAreas:function(t){t&&(this.areas=f(t,function(t){return My(this.option,t)},this))},setBrushOption:function(t){this.brushOption=My(this.option,t),this.brushType=this.brushOption.brushType}});Ws({type:"brush",init:function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new zf(e.getZr())).on("brush",m(this._onBrush,this)).mount()},render:function(t){return this.model=t,Iy.apply(this,arguments)},updateTransform:Iy,updateView:Iy,dispose:function(){this._brushController.dispose()},_onBrush:function(t,e){var n=this.model.id;this.model.brushTargetManager.setOutputRanges(t,this.ecModel),(!e.isEnd||e.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:n,areas:i(t),$from:n})}}),Es({type:"brush",event:"brush"},function(t,e){e.eachComponent({mainType:"brush",query:t},function(e){e.setAreas(t.areas)})}),Es({type:"brushSelect",event:"brushSelected",update:"none"},function(){});var HN={},ZN=rT.toolbox.brush;Dy.defaultOption={show:!0,type:["rect","polygon","lineX","lineY","keep","clear"],icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:i(ZN.title)};var UN=Dy.prototype;UN.render=UN.updateView=function(t,e,i){var n,o,a;e.eachComponent({mainType:"brush"},function(t){n=t.brushType,o=t.brushOption.brushMode||"single",a|=t.areas.length}),this._brushType=n,this._brushMode=o,d(t.get("type",!0),function(e){t.setIconStatus(e,("keep"===e?"multiple"===o:"clear"===e?a:e===n)?"emphasis":"normal")})},UN.getIcons=function(){var t=this.model,e=t.get("icon",!0),i={};return d(t.get("type",!0),function(t){e[t]&&(i[t]=e[t])}),i},UN.onclick=function(t,e,i){var n=this._brushType,o=this._brushMode;"clear"===i?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===i?n:n!==i&&i,brushMode:"keep"===i?"multiple"===o?"single":"multiple":o}})},Ty("brush",Dy),Ns(function(t,e){var i=t&&t.brush;if(y(i)||(i=i?[i]:[]),i.length){var n=[];d(i,function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(n=n.concat(e))});var o=t&&t.toolbox;y(o)&&(o=o[0]),o||(o={feature:{}},t.toolbox=[o]);var a=o.feature||(o.feature={}),r=a.brush||(a.brush={}),s=r.type||(r.type=[]);s.push.apply(s,n),Jv(s),e&&!s.length&&s.push.apply(s,SN)}});Cy.prototype={constructor:Cy,type:"calendar",dimensions:["time","value"],getDimensionsInfo:function(){return[{name:"time",type:"time"},"value"]},getRangeInfo:function(){return this._rangeInfo},getModel:function(){return this._model},getRect:function(){return this._rect},getCellWidth:function(){return this._sw},getCellHeight:function(){return this._sh},getOrient:function(){return this._orient},getFirstDayOfWeek:function(){return this._firstDayOfWeek},getDateInfo:function(t){var e=(t=Yo(t)).getFullYear(),i=t.getMonth()+1;i=i<10?"0"+i:i;var n=t.getDate();n=n<10?"0"+n:n;var o=t.getDay();return o=Math.abs((o+7-this.getFirstDayOfWeek())%7),{y:e,m:i,d:n,day:o,time:t.getTime(),formatedDate:e+"-"+i+"-"+n,date:t}},getNextNDay:function(t,e){return 0===(e=e||0)?this.getDateInfo(t):((t=new Date(this.getDateInfo(t).time)).setDate(t.getDate()+e),this.getDateInfo(t))},update:function(t,e){function i(t,e){return null!=t[e]&&"auto"!==t[e]}this._firstDayOfWeek=+this._model.getModel("dayLabel").get("firstDay"),this._orient=this._model.get("orient"),this._lineWidth=this._model.getModel("itemStyle").getItemStyle().lineWidth||0,this._rangeInfo=this._getRangeInfo(this._initRangeOption());var n=this._rangeInfo.weeks||1,o=["width","height"],a=this._model.get("cellSize").slice(),r=this._model.getBoxLayoutParams(),s="horizontal"===this._orient?[n,7]:[7,n];d([0,1],function(t){i(a,t)&&(r[o[t]]=a[t]*s[t])});var l={width:e.getWidth(),height:e.getHeight()},u=this._rect=ca(r,l);d([0,1],function(t){i(a,t)||(a[t]=u[o[t]]/s[t])}),this._sw=a[0],this._sh=a[1]},dataToPoint:function(t,e){y(t)&&(t=t[0]),null==e&&(e=!0);var i=this.getDateInfo(t),n=this._rangeInfo,o=i.formatedDate;if(e&&!(i.time>=n.start.time&&i.timea.end.time&&t.reverse(),t},_getRangeInfo:function(t){var e;(t=[this.getDateInfo(t[0]),this.getDateInfo(t[1])])[0].time>t[1].time&&(e=!0,t.reverse());var i=Math.floor(t[1].time/864e5)-Math.floor(t[0].time/864e5)+1,n=new Date(t[0].time),o=n.getDate(),a=t[1].date.getDate();if(n.setDate(o+i-1),n.getDate()!==a)for(var r=n.getTime()-t[1].time>0?1:-1;n.getDate()!==a&&(n.getTime()-t[1].time)*r>0;)i-=r,n.setDate(o+i-1);var s=Math.floor((i+t[0].day+6)/7),l=e?1-s:s-1;return e&&t.reverse(),{range:[t[0].formatedDate,t[1].formatedDate],start:t[0],end:t[1],allDay:i,weeks:s,nthWeek:l,fweek:t[0].day,lweek:t[1].day}},_getDateByWeeksAndDay:function(t,e,i){var n=this._getRangeInfo(i);if(t>n.weeks||0===t&&en.lweek)return!1;var o=7*(t-1)-n.fweek+e,a=new Date(n.start.time);return a.setDate(n.start.d+o),this.getDateInfo(a)}},Cy.dimensions=Cy.prototype.dimensions,Cy.getDimensionsInfo=Cy.prototype.getDimensionsInfo,Cy.create=function(t,e){var i=[];return t.eachComponent("calendar",function(n){var o=new Cy(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeries(function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])}),i},Fa.register("calendar",Cy);var XN=lI.extend({type:"calendar",coordinateSystem:null,defaultOption:{zlevel:0,z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",nameMap:"en",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",nameMap:"en",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},init:function(t,e,i,n){var o=ga(t);XN.superApply(this,"init",arguments),ky(t,o)},mergeOption:function(t,e){XN.superApply(this,"mergeOption",arguments),ky(this.option,t)}}),jN={EN:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],CN:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},YN={EN:["S","M","T","W","T","F","S"],CN:["日","一","二","三","四","五","六"]};Ws({type:"calendar",_tlpoints:null,_blpoints:null,_firstDayOfMonth:null,_firstDayPoints:null,render:function(t,e,i){var n=this.group;n.removeAll();var o=t.coordinateSystem,a=o.getRangeInfo(),r=o.getOrient();this._renderDayRect(t,a,n),this._renderLines(t,a,r,n),this._renderYearText(t,a,r,n),this._renderMonthText(t,r,n),this._renderWeekText(t,a,r,n)},_renderDayRect:function(t,e,i){for(var n=t.coordinateSystem,o=t.getModel("itemStyle").getItemStyle(),a=n.getCellWidth(),r=n.getCellHeight(),s=e.start.time;s<=e.end.time;s=n.getNextNDay(s,1).time){var l=n.dataToRect([s],!1).tl,u=new yM({shape:{x:l[0],y:l[1],width:a,height:r},cursor:"default",style:o});i.add(u)}},_renderLines:function(t,e,i,n){function o(e){a._firstDayOfMonth.push(r.getDateInfo(e)),a._firstDayPoints.push(r.dataToRect([e],!1).tl);var o=a._getLinePointsOfOneWeek(t,e,i);a._tlpoints.push(o[0]),a._blpoints.push(o[o.length-1]),l&&a._drawSplitline(o,s,n)}var a=this,r=t.coordinateSystem,s=t.getModel("splitLine.lineStyle").getLineStyle(),l=t.get("splitLine.show"),u=s.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var h=e.start,c=0;h.time<=e.end.time;c++){o(h.formatedDate),0===c&&(h=r.getDateInfo(e.start.y+"-"+e.start.m));var d=h.date;d.setMonth(d.getMonth()+1),h=r.getDateInfo(d)}o(r.getNextNDay(e.end.time,1).formatedDate),l&&this._drawSplitline(a._getEdgesPoints(a._tlpoints,u,i),s,n),l&&this._drawSplitline(a._getEdgesPoints(a._blpoints,u,i),s,n)},_getEdgesPoints:function(t,e,i){var n=[t[0].slice(),t[t.length-1].slice()],o="horizontal"===i?0:1;return n[0][o]=n[0][o]-e/2,n[1][o]=n[1][o]+e/2,n},_drawSplitline:function(t,e,i){var n=new gM({z2:20,shape:{points:t},style:e});i.add(n)},_getLinePointsOfOneWeek:function(t,e,i){var n=t.coordinateSystem;e=n.getDateInfo(e);for(var o=[],a=0;a<7;a++){var r=n.getNextNDay(e.time,a),s=n.dataToRect([r.time],!1);o[2*r.day]=s.tl,o[2*r.day+1]=s["horizontal"===i?"bl":"tr"]}return o},_formatterLabel:function(t,e){return"string"==typeof t&&t?oa(t,e):"function"==typeof t?t(e):e.nameMap},_yearTextPositionControl:function(t,e,i,n,o){e=e.slice();var a=["center","bottom"];"bottom"===n?(e[1]+=o,a=["center","top"]):"left"===n?e[0]-=o:"right"===n?(e[0]+=o,a=["center","top"]):e[1]-=o;var r=0;return"left"!==n&&"right"!==n||(r=Math.PI/2),{rotation:r,position:e,style:{textAlign:a[0],textVerticalAlign:a[1]}}},_renderYearText:function(t,e,i,n){var o=t.getModel("yearLabel");if(o.get("show")){var a=o.get("margin"),r=o.get("position");r||(r="horizontal"!==i?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===i?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},d=e.start.y;+e.end.y>+e.start.y&&(d=d+"-"+e.end.y);var f=o.get("formatter"),p={start:e.start.y,end:e.end.y,nameMap:d},g=this._formatterLabel(f,p),m=new rM({z2:30});mo(m.style,o,{text:g}),m.attr(this._yearTextPositionControl(m,c[r],i,r,a)),n.add(m)}},_monthTextPositionControl:function(t,e,i,n,o){var a="left",r="top",s=t[0],l=t[1];return"horizontal"===i?(l+=o,e&&(a="center"),"start"===n&&(r="bottom")):(s+=o,e&&(r="middle"),"start"===n&&(a="right")),{x:s,y:l,textAlign:a,textVerticalAlign:r}},_renderMonthText:function(t,e,i){var n=t.getModel("monthLabel");if(n.get("show")){var o=n.get("nameMap"),r=n.get("margin"),s=n.get("position"),l=n.get("align"),u=[this._tlpoints,this._blpoints];_(o)&&(o=jN[o.toUpperCase()]||[]);var h="start"===s?0:1,c="horizontal"===e?0:1;r="start"===s?-r:r;for(var d="center"===l,f=0;f=r[0]&&t<=r[1]}if(t===this._dataZoomModel){var n=this._dimName,o=this.getTargetSeriesModels(),a=t.get("filterMode"),r=this._valueWindow;"none"!==a&&$N(o,function(t){var e=t.getData(),o=e.mapDimension(n,!0);o.length&&("weakFilter"===a?e.filterSelf(function(t){for(var i,n,a,s=0;sr[1];if(u&&!h&&!c)return!0;u&&(a=!0),h&&(i=!0),c&&(n=!0)}return a&&i&&n}):$N(o,function(n){if("empty"===a)t.setData(e.map(n,function(t){return i(t)?t:NaN}));else{var o={};o[n]=r,e.selectRange(o)}}),$N(o,function(t){e.setApproximateExtent(r,t)}))})}}};var tO=d,eO=KN,iO=Fs({type:"dataZoom",dependencies:["xAxis","yAxis","zAxis","radiusAxis","angleAxis","singleAxis","series"],defaultOption:{zlevel:0,z:4,orient:null,xAxisIndex:null,yAxisIndex:null,filterMode:"filter",throttle:null,start:0,end:100,startValue:null,endValue:null,minSpan:null,maxSpan:null,minValueSpan:null,maxValueSpan:null,rangeMode:null},init:function(t,e,i){this._dataIntervalByAxis={},this._dataInfo={},this._axisProxies={},this.textStyleModel,this._autoThrottle=!0,this._rangePropMode=["percent","percent"];var n=By(t);this.mergeDefaultAndTheme(t,i),this.doInit(n)},mergeOption:function(t){var e=By(t);n(this.option,t,!0),this.doInit(e)},doInit:function(t){var e=this.option;U_.canvasSupported||(e.realtime=!1),this._setDefaultThrottle(t),Vy(this,t),tO([["start","startValue"],["end","endValue"]],function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=null)},this),this.textStyleModel=this.getModel("textStyle"),this._resetTarget(),this._giveAxisProxies()},_giveAxisProxies:function(){var t=this._axisProxies;this.eachTargetAxis(function(e,i,n,o){var a=this.dependentModels[e.axis][i],r=a.__dzAxisProxy||(a.__dzAxisProxy=new QN(e.name,i,this,o));t[e.name+"_"+i]=r},this)},_resetTarget:function(){var t=this.option,e=this._judgeAutoMode();eO(function(e){var i=e.axisIndex;t[i]=Di(t[i])},this),"axisIndex"===e?this._autoSetAxisIndex():"orient"===e&&this._autoSetOrient()},_judgeAutoMode:function(){var t=this.option,e=!1;eO(function(i){null!=t[i.axisIndex]&&(e=!0)},this);var i=t.orient;return null==i&&e?"orient":e?void 0:(null==i&&(t.orient="horizontal"),"axisIndex")},_autoSetAxisIndex:function(){var t=!0,e=this.get("orient",!0),i=this.option,n=this.dependentModels;if(t){var o="vertical"===e?"y":"x";n[o+"Axis"].length?(i[o+"AxisIndex"]=[0],t=!1):tO(n.singleAxis,function(n){t&&n.get("orient",!0)===e&&(i.singleAxisIndex=[n.componentIndex],t=!1)})}t&&eO(function(e){if(t){var n=[],o=this.dependentModels[e.axis];if(o.length&&!n.length)for(var a=0,r=o.length;a0?100:20}},getFirstTargetAxisModel:function(){var t;return eO(function(e){if(null==t){var i=this.get(e.axisIndex);i.length&&(t=this.dependentModels[e.axis][i[0]])}},this),t},eachTargetAxis:function(t,e){var i=this.ecModel;eO(function(n){tO(this.get(n.axisIndex),function(o){t.call(e,n,o,this,i)},this)},this)},getAxisProxy:function(t,e){return this._axisProxies[t+"_"+e]},getAxisModel:function(t,e){var i=this.getAxisProxy(t,e);return i&&i.getAxisModel()},setRawRange:function(t,e){var i=this.option;tO([["start","startValue"],["end","endValue"]],function(e){null==t[e[0]]&&null==t[e[1]]||(i[e[0]]=t[e[0]],i[e[1]]=t[e[1]])},this),!e&&Vy(this,t)},getPercentRange:function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},getValueRange:function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var i=this.findRepresentativeAxisProxy();return i?i.getDataValueWindow():void 0},findRepresentativeAxisProxy:function(t){if(t)return t.__dzAxisProxy;var e=this._axisProxies;for(var i in e)if(e.hasOwnProperty(i)&&e[i].hostedBy(this))return e[i];for(var i in e)if(e.hasOwnProperty(i)&&!e[i].hostedBy(this))return e[i]},getRangePropMode:function(){return this._rangePropMode.slice()}}),nO=qI.extend({type:"dataZoom",render:function(t,e,i,n){this.dataZoomModel=t,this.ecModel=e,this.api=i},getTargetCoordInfo:function(){function t(t,e,i,n){for(var o,a=0;a0&&e%g)p+=f;else{var i=null==t||isNaN(t)||""===t,n=i?0:aO(t,a,u,!0);i&&!l&&e?(c.push([c[c.length-1][0],0]),d.push([d[d.length-1][0],0])):!i&&l&&(c.push([p,0]),d.push([p,0])),c.push([p,n]),d.push([p,n]),p+=f,l=i}});var m=this.dataZoomModel;this._displayables.barGroup.add(new pM({shape:{points:c},style:r({fill:m.get("dataBackgroundColor")},m.getModel("dataBackground.areaStyle").getAreaStyle()),silent:!0,z2:-20})),this._displayables.barGroup.add(new gM({shape:{points:d},style:m.getModel("dataBackground.lineStyle").getLineStyle(),silent:!0,z2:-19}))}}},_prepareDataShadowInfo:function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var i,n=this.ecModel;return t.eachTargetAxis(function(o,a){d(t.getAxisProxy(o.name,a).getTargetSeriesModels(),function(t){if(!(i||!0!==e&&l(cO,t.get("type"))<0)){var r,s=n.getComponent(o.axis,a).axis,u=Gy(o.name),h=t.coordinateSystem;null!=u&&h.getOtherAxis&&(r=h.getOtherAxis(s).inverse),u=t.getData().mapDimension(u),i={thisAxis:s,series:t,thisDim:o.name,otherDim:u,otherAxisInverse:r}}},this)},this),i}},_renderHandle:function(){var t=this._displayables,e=t.handles=[],i=t.handleLabels=[],n=this._displayables.barGroup,o=this._size,a=this.dataZoomModel;n.add(t.filler=new oO({draggable:!0,cursor:Fy(this._orient),drift:sO(this._onDragMove,this,"all"),onmousemove:function(t){mw(t.event)},ondragstart:sO(this._showDataInfo,this,!0),ondragend:sO(this._onDragEnd,this),onmouseover:sO(this._showDataInfo,this,!0),onmouseout:sO(this._showDataInfo,this,!1),style:{fill:a.get("fillerColor"),textPosition:"inside"}})),n.add(new oO($n({silent:!0,shape:{x:0,y:0,width:o[0],height:o[1]},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}}))),lO([0,1],function(t){var o=Po(a.get("handleIcon"),{cursor:Fy(this._orient),draggable:!0,drift:sO(this._onDragMove,this,t),onmousemove:function(t){mw(t.event)},ondragend:sO(this._onDragEnd,this),onmouseover:sO(this._showDataInfo,this,!0),onmouseout:sO(this._showDataInfo,this,!1)},{x:-1,y:0,width:2,height:2}),r=o.getBoundingRect();this._handleHeight=Vo(a.get("handleSize"),this._size[1]),this._handleWidth=r.width/r.height*this._handleHeight,o.setStyle(a.getModel("handleStyle").getItemStyle());var s=a.get("handleColor");null!=s&&(o.style.fill=s),n.add(e[t]=o);var l=a.textStyleModel;this.group.add(i[t]=new rM({silent:!0,invisible:!0,style:{x:0,y:0,text:"",textVerticalAlign:"middle",textAlign:"center",textFill:l.getTextColor(),textFont:l.getFont()},z2:10}))},this)},_resetInterval:function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[aO(t[0],[0,100],e,!0),aO(t[1],[0,100],e,!0)]},_updateInterval:function(t,e){var i=this.dataZoomModel,n=this._handleEnds,o=this._getViewExtent(),a=i.findRepresentativeAxisProxy().getMinMaxSpan(),r=[0,100];QL(e,n,o,i.get("zoomLock")?"all":t,null!=a.minSpan?aO(a.minSpan,r,o,!0):null,null!=a.maxSpan?aO(a.maxSpan,r,o,!0):null);var s=this._range,l=this._range=rO([aO(n[0],o,r,!0),aO(n[1],o,r,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},_updateView:function(t){var e=this._displayables,i=this._handleEnds,n=rO(i.slice()),o=this._size;lO([0,1],function(t){var n=e.handles[t],a=this._handleHeight;n.attr({scale:[a/2,a/2],position:[i[t],o[1]/2-a/2]})},this),e.filler.setShape({x:n[0],y:0,width:n[1]-n[0],height:o[1]}),this._updateDataInfo(t)},_updateDataInfo:function(t){function e(t){var e=Ao(n.handles[t].parent,this.group),i=Co(0===t?"right":"left",e),s=this._handleWidth/2+hO,l=Do([c[t]+(0===t?-s:s),this._size[1]/2],e);o[t].setStyle({x:l[0],y:l[1],textVerticalAlign:a===uO?"middle":i,textAlign:a===uO?i:"center",text:r[t]})}var i=this.dataZoomModel,n=this._displayables,o=n.handleLabels,a=this._orient,r=["",""];if(i.get("showDetail")){var s=i.findRepresentativeAxisProxy();if(s){var l=s.getAxisModel().axis,u=this._range,h=t?s.calculateDataWindow({start:u[0],end:u[1]}).valueWindow:s.getDataValueWindow();r=[this._formatLabel(h[0],l),this._formatLabel(h[1],l)]}}var c=rO(this._handleEnds.slice());e.call(this,0),e.call(this,1)},_formatLabel:function(t,e){var i=this.dataZoomModel,n=i.get("labelFormatter"),o=i.get("labelPrecision");null!=o&&"auto"!==o||(o=e.getPixelPrecision());var a=null==t||isNaN(t)?"":"category"===e.type||"time"===e.type?e.scale.getLabel(Math.round(t)):t.toFixed(Math.min(o,20));return x(n)?n(t,a):_(n)?n.replace("{value}",a):a},_showDataInfo:function(t){t=this._dragging||t;var e=this._displayables.handleLabels;e[0].attr("invisible",!t),e[1].attr("invisible",!t)},_onDragMove:function(t,e,i){this._dragging=!0;var n=Do([e,i],this._displayables.barGroup.getLocalTransform(),!0),o=this._updateInterval(t,n[0]),a=this.dataZoomModel.get("realtime");this._updateView(!a),o&&a&&this._dispatchZoomAction()},_onDragEnd:function(){this._dragging=!1,this._showDataInfo(!1),!this.dataZoomModel.get("realtime")&&this._dispatchZoomAction()},_onClickPanelClick:function(t){var e=this._size,i=this._displayables.barGroup.transformCoordToLocal(t.offsetX,t.offsetY);if(!(i[0]<0||i[0]>e[0]||i[1]<0||i[1]>e[1])){var n=this._handleEnds,o=(n[0]+n[1])/2,a=this._updateInterval("all",i[0]-o);this._updateView(),a&&this._dispatchZoomAction()}},_dispatchZoomAction:function(){var t=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,start:t[0],end:t[1]})},_findCoordRect:function(){var t;if(lO(this.getTargetCoordInfo(),function(e){if(!t&&e.length){var i=e[0].model.coordinateSystem;t=i.getRect&&i.getRect()}}),!t){var e=this.api.getWidth(),i=this.api.getHeight();t={x:.2*e,y:.2*i,width:.6*e,height:.6*i}}return t}});iO.extend({type:"dataZoom.inside",defaultOption:{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}});var fO="\0_ec_dataZoom_roams",pO=m,gO=nO.extend({type:"dataZoom.inside",init:function(t,e){this._range},render:function(t,e,i,n){gO.superApply(this,"render",arguments),this._range=t.getPercentRange(),d(this.getTargetCoordInfo(),function(e,n){var o=f(e,function(t){return Zy(t.model)});d(e,function(e){var a=e.model,r={};d(["pan","zoom","scrollMove"],function(t){r[t]=pO(mO[t],this,e,n)},this),Wy(i,{coordId:Zy(a),allCoordIds:o,containsPoint:function(t,e,i){return a.coordinateSystem.containPoint([e,i])},dataZoomId:t.id,dataZoomModel:t,getRange:r})},this)},this)},dispose:function(){Hy(this.api,this.dataZoomModel.id),gO.superApply(this,"dispose",arguments),this._range=null}}),mO={zoom:function(t,e,i,n){var o=this._range,a=o.slice(),r=t.axisModels[0];if(r){var s=vO[e](null,[n.originX,n.originY],r,i,t),l=(s.signal>0?s.pixelStart+s.pixelLength-s.pixel:s.pixel-s.pixelStart)/s.pixelLength*(a[1]-a[0])+a[0],u=Math.max(1/n.scale,0);a[0]=(a[0]-l)*u+l,a[1]=(a[1]-l)*u+l;var h=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return QL(0,a,[0,100],0,h.minSpan,h.maxSpan),this._range=a,o[0]!==a[0]||o[1]!==a[1]?a:void 0}},pan:Ky(function(t,e,i,n,o,a){var r=vO[n]([a.oldX,a.oldY],[a.newX,a.newY],e,o,i);return r.signal*(t[1]-t[0])*r.pixel/r.pixelLength}),scrollMove:Ky(function(t,e,i,n,o,a){return vO[n]([0,0],[a.scrollDelta,a.scrollDelta],e,o,i).signal*(t[1]-t[0])*a.scrollDelta})},vO={grid:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem.getRect();return t=t||[0,0],"x"===a.dim?(r.pixel=e[0]-t[0],r.pixelLength=s.width,r.pixelStart=s.x,r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=s.height,r.pixelStart=s.y,r.signal=a.inverse?-1:1),r},polar:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===i.mainType?(r.pixel=e[0]-t[0],r.pixelLength=l[1]-l[0],r.pixelStart=l[0],r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=u[1]-u[0],r.pixelStart=u[0],r.signal=a.inverse?-1:1),r},singleAxis:function(t,e,i,n,o){var a=i.axis,r=o.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===a.orient?(s.pixel=e[0]-t[0],s.pixelLength=r.width,s.pixelStart=r.x,s.signal=a.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=r.height,s.pixelStart=r.y,s.signal=a.inverse?-1:1),s}};Os({getTargetSeries:function(t){var e=R();return t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){d(n.getAxisProxy(t.name,i).getTargetSeriesModels(),function(t){e.set(t.uid,t)})})}),e},modifyOutputEnd:!0,overallReset:function(t,e){t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).reset(n,e)}),t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).filterData(n,e)})}),t.eachComponent("dataZoom",function(t){var e=t.findRepresentativeAxisProxy(),i=e.getDataPercentWindow(),n=e.getDataValueWindow();t.setRawRange({start:i[0],end:i[1],startValue:n[0],endValue:n[1]},!0)})}}),Es("dataZoom",function(t,e){var i=Ny(m(e.eachComponent,e,"dataZoom"),KN,function(t,e){return t.get(e.axisIndex)}),n=[];e.eachComponent({mainType:"dataZoom",query:t},function(t,e){n.push.apply(n,i(t).nodes)}),d(n,function(e,i){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})})});var yO=d,xO=function(t){var e=t&&t.visualMap;y(e)||(e=e?[e]:[]),yO(e,function(t){if(t){$y(t,"splitList")&&!$y(t,"pieces")&&(t.pieces=t.splitList,delete t.splitList);var e=t.pieces;e&&y(e)&&yO(e,function(t){w(t)&&($y(t,"start")&&!$y(t,"min")&&(t.min=t.start),$y(t,"end")&&!$y(t,"max")&&(t.max=t.end))})}})};lI.registerSubTypeDefaulter("visualMap",function(t){return t.categories||(t.pieces?t.pieces.length>0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"});var _O=VT.VISUAL.COMPONENT;Bs(_O,{createOnAllSeries:!0,reset:function(t,e){var i=[];return e.eachComponent("visualMap",function(e){var n=t.pipelineContext;!e.isTargetSeries(t)||n&&n.large||i.push(ny(e.stateList,e.targetVisuals,m(e.getValueState,e),e.getDataDimension(t.getData())))}),i}}),Bs(_O,{createOnAllSeries:!0,reset:function(t,e){var i=t.getData(),n=[];e.eachComponent("visualMap",function(e){if(e.isTargetSeries(t)){var o=e.getVisualMeta(m(Jy,null,t,e))||{stops:[],outerColors:[]},a=e.getDataDimension(i),r=i.getDimensionInfo(a);null!=r&&(o.dimension=r.index,n.push(o))}}),t.getData().setVisual("visualMeta",n)}});var wO={get:function(t,e,n){var o=i((bO[t]||{})[e]);return n&&y(o)?o[o.length-1]:o}},bO={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},SO=hL.mapVisual,MO=hL.eachVisual,IO=y,TO=d,AO=Fo,DO=Bo,CO=B,LO=Fs({type:"visualMap",dependencies:["series"],stateList:["inRange","outOfRange"],replacableOptionKeys:["inRange","outOfRange","target","controller","color"],dataBound:[-1/0,1/0],layoutMode:{type:"box",ignoreSize:!0},defaultOption:{show:!0,zlevel:0,z:4,seriesIndex:"all",min:0,max:200,dimension:null,inRange:null,outOfRange:null,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,color:null,formatter:null,text:null,textStyle:{color:"#333"}},init:function(t,e,i){this._dataExtent,this.targetVisuals={},this.controllerVisuals={},this.textStyleModel,this.itemSize,this.mergeDefaultAndTheme(t,i)},optionUpdated:function(t,e){var i=this.option;U_.canvasSupported||(i.realtime=!1),!e&&ey(i,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},resetVisual:function(t){var e=this.stateList;t=m(t,this),this.controllerVisuals=ty(this.option.controller,e,t),this.targetVisuals=ty(this.option.target,e,t)},getTargetSeriesIndices:function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries(function(t,i){e.push(i)}):e=Di(t),e},eachTargetSeries:function(t,e){d(this.getTargetSeriesIndices(),function(i){t.call(e,this.ecModel.getSeriesByIndex(i))},this)},isTargetSeries:function(t){var e=!1;return this.eachTargetSeries(function(i){i===t&&(e=!0)}),e},formatValueText:function(t,e,i){function n(t){return t===l[0]?"min":t===l[1]?"max":(+t).toFixed(Math.min(s,20))}var o,a,r=this.option,s=r.precision,l=this.dataBound,u=r.formatter;return i=i||["<",">"],y(t)&&(t=t.slice(),o=!0),a=e?t:o?[n(t[0]),n(t[1])]:n(t),_(u)?u.replace("{value}",o?a[0]:a).replace("{value2}",o?a[1]:a):x(u)?o?u(t[0],t[1]):u(t):o?t[0]===l[0]?i[0]+" "+a[1]:t[1]===l[1]?i[1]+" "+a[0]:a[0]+" - "+a[1]:a},resetExtent:function(){var t=this.option,e=AO([t.min,t.max]);this._dataExtent=e},getDataDimension:function(t){var e=this.option.dimension,i=t.dimensions;if(null!=e||i.length){if(null!=e)return t.getDimension(e);for(var n=t.dimensions,o=n.length-1;o>=0;o--){var a=n[o];if(!t.getDimensionInfo(a).isCalculationCoord)return a}}},getExtent:function(){return this._dataExtent.slice()},completeVisualOption:function(){function t(t){IO(o.color)&&!t.inRange&&(t.inRange={color:o.color.slice().reverse()}),t.inRange=t.inRange||{color:e.get("gradientColor")},TO(this.stateList,function(e){var i=t[e];if(_(i)){var n=wO.get(i,"active",l);n?(t[e]={},t[e][i]=n):delete t[e]}},this)}var e=this.ecModel,o=this.option,a={inRange:o.inRange,outOfRange:o.outOfRange},r=o.target||(o.target={}),s=o.controller||(o.controller={});n(r,a),n(s,a);var l=this.isCategory();t.call(this,r),t.call(this,s),function(t,e,i){var n=t[e],o=t[i];n&&!o&&(o=t[i]={},TO(n,function(t,e){if(hL.isValidType(e)){var i=wO.get(e,"inactive",l);null!=i&&(o[e]=i,"color"!==e||o.hasOwnProperty("opacity")||o.hasOwnProperty("colorAlpha")||(o.opacity=[0,0]))}}))}.call(this,r,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,o=this.get("inactiveColor");TO(this.stateList,function(a){var r=this.itemSize,s=t[a];s||(s=t[a]={color:l?o:[o]}),null==s.symbol&&(s.symbol=e&&i(e)||(l?"roundRect":["roundRect"])),null==s.symbolSize&&(s.symbolSize=n&&i(n)||(l?r[0]:[r[0],r[0]])),s.symbol=SO(s.symbol,function(t){return"none"===t||"square"===t?"roundRect":t});var u=s.symbolSize;if(null!=u){var h=-1/0;MO(u,function(t){t>h&&(h=t)}),s.symbolSize=SO(u,function(t){return DO(t,[0,h],[0,r[0]],!0)})}},this)}.call(this,s)},resetItemSize:function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},isCategory:function(){return!!this.option.categories},setSelected:CO,getValueState:CO,getVisualMeta:CO}),kO=[20,140],PO=LO.extend({type:"visualMap.continuous",defaultOption:{align:"auto",calculable:!1,range:null,realtime:!0,itemHeight:null,itemWidth:null,hoverLink:!0,hoverLinkDataSize:null,hoverLinkOnHandle:null},optionUpdated:function(t,e){PO.superApply(this,"optionUpdated",arguments),this.resetExtent(),this.resetVisual(function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()}),this._resetRange()},resetItemSize:function(){PO.superApply(this,"resetItemSize",arguments);var t=this.itemSize;"horizontal"===this._orient&&t.reverse(),(null==t[0]||isNaN(t[0]))&&(t[0]=kO[0]),(null==t[1]||isNaN(t[1]))&&(t[1]=kO[1])},_resetRange:function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},completeVisualOption:function(){LO.prototype.completeVisualOption.apply(this,arguments),d(this.stateList,function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=0)},this)},setSelected:function(t){this.option.range=t.slice(),this._resetRange()},getSelected:function(){var t=this.getExtent(),e=Fo((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=i[1]||t<=e[1])?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){t[0]<=e&&e<=t[1]&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getVisualMeta:function(t){function e(e,i){o.push({value:e,color:t(e,i)})}for(var i=Qy(0,0,this.getExtent()),n=Qy(0,0,this.option.range.slice()),o=[],a=0,r=0,s=n.length,l=i.length;rt[1])break;i.push({color:this.getControllerVisual(a,"color",e),offset:o/100})}return i.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),i},_createBarPoints:function(t,e){var i=this.visualMapModel.itemSize;return[[i[0]-e[0],t[0]],[i[0],t[0]],[i[0],t[1]],[i[0]-e[1],t[1]]]},_createBarGroup:function(t){var e=this._orient,i=this.visualMapModel.get("inverse");return new tb("horizontal"!==e||i?"horizontal"===e&&i?{scale:"bottom"===t?[-1,1]:[1,1],rotation:-Math.PI/2}:"vertical"!==e||i?{scale:"left"===t?[1,1]:[-1,1]}:{scale:"left"===t?[1,-1]:[-1,-1]}:{scale:"bottom"===t?[1,1]:[-1,1],rotation:Math.PI/2})},_updateHandle:function(t,e){if(this._useHandle){var i=this._shapes,n=this.visualMapModel,o=i.handleThumbs,a=i.handleLabels;EO([0,1],function(r){var s=o[r];s.setStyle("fill",e.handlesColor[r]),s.position[1]=t[r];var l=Do(i.handleLabelPoints[r],Ao(s,this.group));a[r].setStyle({x:l[0],y:l[1],text:n.formatValueText(this._dataInterval[r]),textVerticalAlign:"middle",textAlign:this._applyTransform("horizontal"===this._orient?0===r?"bottom":"top":"left",i.barGroup)})},this)}},_showIndicator:function(t,e,i,n){var o=this.visualMapModel,a=o.getExtent(),r=o.itemSize,s=[0,r[1]],l=OO(t,a,s,!0),u=this._shapes,h=u.indicator;if(h){h.position[1]=l,h.attr("invisible",!1),h.setShape("points",ox(!!i,n,l,r[1]));var c={convertOpacityToAlpha:!0},d=this.getControllerVisual(t,"color",c);h.setStyle("fill",d);var f=Do(u.indicatorLabelPoint,Ao(h,this.group)),p=u.indicatorLabel;p.attr("invisible",!1);var g=this._applyTransform("left",u.barGroup),m=this._orient;p.setStyle({text:(i||"")+o.formatValueText(e),textVerticalAlign:"horizontal"===m?g:"middle",textAlign:"horizontal"===m?"center":g,x:f[0],y:f[1]})}},_enableHoverLinkToSeries:function(){var t=this;this._shapes.barGroup.on("mousemove",function(e){if(t._hovering=!0,!t._dragging){var i=t.visualMapModel.itemSize,n=t._applyTransform([e.offsetX,e.offsetY],t._shapes.barGroup,!0,!0);n[1]=RO(zO(0,n[1]),i[1]),t._doHoverLinkToSeries(n[1],0<=n[0]&&n[0]<=i[0])}}).on("mouseout",function(){t._hovering=!1,!t._dragging&&t._clearHoverLinkToSeries()})},_enableHoverLinkFromSeries:function(){var t=this.api.getZr();this.visualMapModel.option.hoverLink?(t.on("mouseover",this._hoverLinkFromSeriesMouseOver,this),t.on("mouseout",this._hideIndicator,this)):this._clearHoverLinkFromSeries()},_doHoverLinkToSeries:function(t,e){var i=this.visualMapModel,n=i.itemSize;if(i.option.hoverLink){var o=[0,n[1]],a=i.getExtent();t=RO(zO(o[0],t),o[1]);var r=ax(i,a,o),s=[t-r,t+r],l=OO(t,o,a,!0),u=[OO(s[0],o,a,!0),OO(s[1],o,a,!0)];s[0]o[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",r):u[1]===1/0?this._showIndicator(l,u[0],"> ",r):this._showIndicator(l,l,"≈ ",r));var h=this._hoverLinkDataIndices,c=[];(e||rx(i))&&(c=this._hoverLinkDataIndices=i.findTargetDataIndices(u));var d=Ri(h,c);this._dispatchHighDown("downplay",ex(d[0])),this._dispatchHighDown("highlight",ex(d[1]))}},_hoverLinkFromSeriesMouseOver:function(t){var e=t.target,i=this.visualMapModel;if(e&&null!=e.dataIndex){var n=this.ecModel.getSeriesByIndex(e.seriesIndex);if(i.isTargetSeries(n)){var o=n.getData(e.dataType),a=o.get(i.getDataDimension(o),e.dataIndex,!0);isNaN(a)||this._showIndicator(a,a)}}},_hideIndicator:function(){var t=this._shapes;t.indicator&&t.indicator.attr("invisible",!0),t.indicatorLabel&&t.indicatorLabel.attr("invisible",!0)},_clearHoverLinkToSeries:function(){this._hideIndicator();var t=this._hoverLinkDataIndices;this._dispatchHighDown("downplay",ex(t)),t.length=0},_clearHoverLinkFromSeries:function(){this._hideIndicator();var t=this.api.getZr();t.off("mouseover",this._hoverLinkFromSeriesMouseOver),t.off("mouseout",this._hideIndicator)},_applyTransform:function(t,e,i,n){var o=Ao(e,n?null:this.group);return zM[y(t)?"applyTransform":"transformDirection"](t,o,i)},_dispatchHighDown:function(t,e){e&&e.length&&this.api.dispatchAction({type:t,batch:e})},dispose:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()},remove:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()}});Es({type:"selectDataRange",event:"dataRangeSelected",update:"update"},function(t,e){e.eachComponent({mainType:"visualMap",query:t},function(e){e.setSelected(t.selected)})}),Ns(xO);var FO=LO.extend({type:"visualMap.piecewise",defaultOption:{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieceList:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0,showLabel:null},optionUpdated:function(t,e){FO.superApply(this,"optionUpdated",arguments),this._pieceList=[],this.resetExtent();var n=this._mode=this._determineMode();WO[this._mode].call(this),this._resetSelected(t,e);var o=this.option.categories;this.resetVisual(function(t,e){"categories"===n?(t.mappingMethod="category",t.categories=i(o)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=f(this._pieceList,function(t){var t=i(t);return"inRange"!==e&&(t.visual=null),t}))})},completeVisualOption:function(){function t(t,e,i){return t&&t[e]&&(w(t[e])?t[e].hasOwnProperty(i):t[e]===i)}var e=this.option,i={},n=hL.listVisualTypes(),o=this.isCategory();d(e.pieces,function(t){d(n,function(e){t.hasOwnProperty(e)&&(i[e]=1)})}),d(i,function(i,n){var a=0;d(this.stateList,function(i){a|=t(e,i,n)||t(e.target,i,n)},this),!a&&d(this.stateList,function(t){(e[t]||(e[t]={}))[n]=wO.get(n,"inRange"===t?"active":"inactive",o)})},this),LO.prototype.completeVisualOption.apply(this,arguments)},_resetSelected:function(t,e){var i=this.option,n=this._pieceList,o=(e?i:t).selected||{};if(i.selected=o,d(n,function(t,e){var i=this.getSelectedMapKey(t);o.hasOwnProperty(i)||(o[i]=!0)},this),"single"===i.selectedMode){var a=!1;d(n,function(t,e){var i=this.getSelectedMapKey(t);o[i]&&(a?o[i]=!1:a=!0)},this)}},getSelectedMapKey:function(t){return"categories"===this._mode?t.value+"":t.index+""},getPieceList:function(){return this._pieceList},_determineMode:function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},setSelected:function(t){this.option.selected=i(t)},getValueState:function(t){var e=hL.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){hL.findPieceIndex(e,this._pieceList)===t&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getRepresentValue:function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var i=t.interval||[];e=i[0]===-1/0&&i[1]===1/0?0:(i[0]+i[1])/2}return e},getVisualMeta:function(t){function e(e,a){var r=o.getRepresentValue({interval:e});a||(a=o.getValueState(r));var s=t(r,a);e[0]===-1/0?n[0]=s:e[1]===1/0?n[1]=s:i.push({value:e[0],color:s},{value:e[1],color:s})}if(!this.isCategory()){var i=[],n=[],o=this,a=this._pieceList.slice();if(a.length){var r=a[0].interval[0];r!==-1/0&&a.unshift({interval:[-1/0,r]}),(r=a[a.length-1].interval[1])!==1/0&&a.push({interval:[r,1/0]})}else a.push({interval:[-1/0,1/0]});var s=-1/0;return d(a,function(t){var i=t.interval;i&&(i[0]>s&&e([s,i[0]],"outOfRange"),e(i.slice()),s=i[1])},this),{stops:i,outerColors:n}}}}),WO={splitNumber:function(){var t=this.option,e=this._pieceList,i=Math.min(t.precision,20),n=this.getExtent(),o=t.splitNumber;o=Math.max(parseInt(o,10),1),t.splitNumber=o;for(var a=(n[1]-n[0])/o;+a.toFixed(i)!==a&&i<5;)i++;t.precision=i,a=+a.toFixed(i);var r=0;t.minOpen&&e.push({index:r++,interval:[-1/0,n[0]],close:[0,0]});for(var s=n[0],l=r+o;r","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,i)},this)}};NO.extend({type:"visualMap.piecewise",doRender:function(){var t=this.group;t.removeAll();var e=this.visualMapModel,i=e.get("textGap"),n=e.textStyleModel,o=n.getFont(),a=n.getTextColor(),r=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=T(e.get("showLabel",!0),!u);u&&this._renderEndsText(t,u[0],s,h,r),d(l.viewPieceList,function(n){var l=n.piece,u=new tb;u.onclick=m(this._onItemClick,this,l),this._enableHoverLink(u,n.indexInModelPieceList);var c=e.getRepresentValue(l);if(this._createItemSymbol(u,c,[0,0,s[0],s[1]]),h){var d=this.visualMapModel.getValueState(c);u.add(new rM({style:{x:"right"===r?-i:s[0]+i,y:s[1]/2,text:l.text,textVerticalAlign:"middle",textAlign:r,textFont:o,textFill:a,opacity:"outOfRange"===d?.5:1}}))}t.add(u)},this),u&&this._renderEndsText(t,u[1],s,h,r),aI(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},_enableHoverLink:function(t,e){function i(t){var i=this.visualMapModel;i.option.hoverLink&&this.api.dispatchAction({type:t,batch:ex(i.findTargetDataIndices(e))})}t.on("mouseover",m(i,this,"highlight")).on("mouseout",m(i,this,"downplay"))},_getItemAlign:function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return tx(t,this.api,t.itemSize);var i=e.align;return i&&"auto"!==i||(i="left"),i},_renderEndsText:function(t,e,i,n,o){if(e){var a=new tb,r=this.visualMapModel.textStyleModel;a.add(new rM({style:{x:n?"right"===o?i[0]:0:i[0]/2,y:i[1]/2,textVerticalAlign:"middle",textAlign:n?o:"center",text:e,textFont:r.getFont(),textFill:r.getTextColor()}})),t.add(a)}},_getViewData:function(){var t=this.visualMapModel,e=f(t.getPieceList(),function(t,e){return{piece:t,indexInModelPieceList:e}}),i=t.get("text"),n=t.get("orient"),o=t.get("inverse");return("horizontal"===n?o:!o)?e.reverse():i&&(i=i.slice().reverse()),{viewPieceList:e,endsText:i}},_createItemSymbol:function(t,e,i){t.add(Jl(this.getControllerVisual(e,"symbol"),i[0],i[1],i[2],i[3],this.getControllerVisual(e,"color")))},_onItemClick:function(t){var e=this.visualMapModel,n=e.option,o=i(n.selected),a=e.getSelectedMapKey(t);"single"===n.selectedMode?(o[a]=!0,d(o,function(t,e){o[e]=e===a})):o[a]=!o[a],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:o})}});Ns(xO);var HO=ta,ZO=ia,UO=Fs({type:"marker",dependencies:["series","grid","polar","geo"],init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i),this.mergeOption(t,i,n.createdBySelf,!0)},isAnimationEnabled:function(){if(U_.node)return!1;var t=this.__hostSeries;return this.getShallow("animation")&&t&&t.isAnimationEnabled()},mergeOption:function(t,e,i,n){var o=this.constructor,r=this.mainType+"Model";i||e.eachSeries(function(t){var i=t.get(this.mainType,!0),s=t[r];i&&i.data?(s?s.mergeOption(i,e,!0):(n&&ux(i),d(i.data,function(t){t instanceof Array?(ux(t[0]),ux(t[1])):ux(t)}),a(s=new o(i,this,e),{mainType:this.mainType,seriesIndex:t.seriesIndex,name:t.name,createdBySelf:!0}),s.__hostSeries=t),t[r]=s):t[r]=null},this)},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=y(i)?f(i,HO).join(", "):HO(i),o=e.getName(t),a=ZO(this.name);return(null!=i||o)&&(a+="
"),o&&(a+=ZO(o),null!=i&&(a+=" : ")),null!=i&&(a+=ZO(n)),a},getData:function(){return this._data},setData:function(t){this._data=t}});h(UO,ZI),UO.extend({type:"markPoint",defaultOption:{zlevel:0,z:5,symbol:"pin",symbolSize:50,tooltip:{trigger:"item"},label:{show:!0,position:"inside"},itemStyle:{borderWidth:2},emphasis:{label:{show:!0}}}});var XO=l,jO=v,YO={min:jO(dx,"min"),max:jO(dx,"max"),average:jO(dx,"average")},qO=Ws({type:"marker",init:function(){this.markerGroupMap=R()},render:function(t,e,i){var n=this.markerGroupMap;n.each(function(t){t.__keep=!1});var o=this.type+"Model";e.eachSeries(function(t){var n=t[o];n&&this.renderSeries(t,n,e,i)},this),n.each(function(t){!t.__keep&&this.group.remove(t.group)},this)},renderSeries:function(){}});qO.extend({type:"markPoint",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markPointModel;e&&(xx(e.getData(),t,i),this.markerGroupMap.get(t.id).updateLayout(e))},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,r=t.getData(),s=this.markerGroupMap,l=s.get(a)||s.set(a,new Du),u=_x(o,t,e);e.setData(u),xx(e.getData(),t,n),u.each(function(t){var i=u.getItemModel(t),n=i.getShallow("symbolSize");"function"==typeof n&&(n=n(e.getRawValue(t),e.getDataParams(t))),u.setItemVisual(t,{symbolSize:n,color:i.get("itemStyle.color")||r.getVisual("color"),symbol:i.getShallow("symbol")})}),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl(function(t){t.traverse(function(t){t.dataModel=e})}),l.__keep=!0,l.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markPoint=t.markPoint||{}}),UO.extend({type:"markLine",defaultOption:{zlevel:0,z:5,symbol:["circle","arrow"],symbolSize:[8,16],precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end"},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"}});var KO=function(t,e,o,r){var s=t.getData(),l=r.type;if(!y(r)&&("min"===l||"max"===l||"average"===l||"median"===l||null!=r.xAxis||null!=r.yAxis)){var u,h;if(null!=r.yAxis||null!=r.xAxis)u=null!=r.yAxis?"y":"x",e.getAxis(u),h=T(r.yAxis,r.xAxis);else{var c=px(r,s,e,t);u=c.valueDataDim,c.valueAxis,h=yx(s,u,l)}var d="x"===u?0:1,f=1-d,p=i(r),g={};p.type=null,p.coord=[],g.coord=[],p.coord[f]=-1/0,g.coord[f]=1/0;var m=o.get("precision");m>=0&&"number"==typeof h&&(h=+h.toFixed(Math.min(m,20))),p.coord[d]=g.coord[d]=h,r=[p,g,{type:l,valueIndex:r.valueIndex,value:h}]}return r=[fx(t,r[0]),fx(t,r[1]),a({},r[2])],r[2].type=r[2].type||"",n(r[2],r[0]),n(r[2],r[1]),r};qO.extend({type:"markLine",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markLineModel;if(e){var n=e.getData(),o=e.__from,a=e.__to;o.each(function(e){Ix(o,e,!0,t,i),Ix(a,e,!1,t,i)}),n.each(function(t){n.setItemLayout(t,[o.getItemLayout(t),a.getItemLayout(t)])}),this.markerGroupMap.get(t.id).updateLayout()}},this)},renderSeries:function(t,e,i,n){function o(e,i,o){var a=e.getItemModel(i);Ix(e,i,o,t,n),e.setItemVisual(i,{symbolSize:a.get("symbolSize")||g[o?0:1],symbol:a.get("symbol",!0)||p[o?0:1],color:a.get("itemStyle.color")||s.getVisual("color")})}var a=t.coordinateSystem,r=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(r)||l.set(r,new sf);this.group.add(u.group);var h=Tx(a,t,e),c=h.from,d=h.to,f=h.line;e.__from=c,e.__to=d,e.setData(f);var p=e.get("symbol"),g=e.get("symbolSize");y(p)||(p=[p,p]),"number"==typeof g&&(g=[g,g]),h.from.each(function(t){o(c,t,!0),o(d,t,!1)}),f.each(function(t){var e=f.getItemModel(t).get("lineStyle.color");f.setItemVisual(t,{color:e||c.getItemVisual(t,"color")}),f.setItemLayout(t,[c.getItemLayout(t),d.getItemLayout(t)]),f.setItemVisual(t,{fromSymbolSize:c.getItemVisual(t,"symbolSize"),fromSymbol:c.getItemVisual(t,"symbol"),toSymbolSize:d.getItemVisual(t,"symbolSize"),toSymbol:d.getItemVisual(t,"symbol")})}),u.updateData(f),h.line.eachItemGraphicEl(function(t,i){t.traverse(function(t){t.dataModel=e})}),u.__keep=!0,u.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markLine=t.markLine||{}}),UO.extend({type:"markArea",defaultOption:{zlevel:0,z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}}});var $O=function(t,e,i,n){var a=fx(t,n[0]),r=fx(t,n[1]),s=T,l=a.coord,u=r.coord;l[0]=s(l[0],-1/0),l[1]=s(l[1],-1/0),u[0]=s(u[0],1/0),u[1]=s(u[1],1/0);var h=o([{},a,r]);return h.coord=[a.coord,r.coord],h.x0=a.x,h.y0=a.y,h.x1=r.x,h.y1=r.y,h},JO=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]];qO.extend({type:"markArea",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markAreaModel;if(e){var n=e.getData();n.each(function(e){var o=f(JO,function(o){return Lx(n,e,o,t,i)});n.setItemLayout(e,o),n.getItemGraphicEl(e).setShape("points",o)})}},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(a)||l.set(a,{group:new tb});this.group.add(u.group),u.__keep=!0;var h=kx(o,t,e);e.setData(h),h.each(function(e){h.setItemLayout(e,f(JO,function(i){return Lx(h,e,i,t,n)})),h.setItemVisual(e,{color:s.getVisual("color")})}),h.diff(u.__data).add(function(t){var e=new pM({shape:{points:h.getItemLayout(t)}});h.setItemGraphicEl(t,e),u.group.add(e)}).update(function(t,i){var n=u.__data.getItemGraphicEl(i);Io(n,{shape:{points:h.getItemLayout(t)}},e,t),u.group.add(n),h.setItemGraphicEl(t,n)}).remove(function(t){var e=u.__data.getItemGraphicEl(t);u.group.remove(e)}).execute(),h.eachItemGraphicEl(function(t,i){var n=h.getItemModel(i),o=n.getModel("label"),a=n.getModel("emphasis.label"),s=h.getItemVisual(i,"color");t.useStyle(r(n.getModel("itemStyle").getItemStyle(),{fill:Yt(s,.4),stroke:s})),t.hoverStyle=n.getModel("emphasis.itemStyle").getItemStyle(),go(t.style,t.hoverStyle,o,a,{labelFetcher:e,labelDataIndex:i,defaultText:h.getName(i)||"",isRectText:!0,autoColor:s}),fo(t,{}),t.dataModel=e}),u.__data=h,u.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markArea=t.markArea||{}});lI.registerSubTypeDefaulter("timeline",function(){return"slider"}),Es({type:"timelineChange",event:"timelineChanged",update:"prepareAndUpdate"},function(t,e){var i=e.getComponent("timeline");return i&&null!=t.currentIndex&&(i.setCurrentIndex(t.currentIndex),!i.get("loop",!0)&&i.isIndexMax()&&i.setPlayState(!1)),e.resetOption("timeline"),r({currentIndex:i.option.currentIndex},t)}),Es({type:"timelinePlayChange",event:"timelinePlayChanged",update:"update"},function(t,e){var i=e.getComponent("timeline");i&&null!=t.playState&&i.setPlayState(t.playState)});var QO=lI.extend({type:"timeline",layoutMode:"box",defaultOption:{zlevel:0,z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},init:function(t,e,i){this._data,this._names,this.mergeDefaultAndTheme(t,i),this._initData()},mergeOption:function(t){QO.superApply(this,"mergeOption",arguments),this._initData()},setCurrentIndex:function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},getCurrentIndex:function(){return this.option.currentIndex},isIndexMax:function(){return this.getCurrentIndex()>=this._data.count()-1},setPlayState:function(t){this.option.autoPlay=!!t},getPlayState:function(){return!!this.option.autoPlay},_initData:function(){var t=this.option,e=t.data||[],n=t.axisType,o=this._names=[];if("category"===n){var a=[];d(e,function(t,e){var n,r=Li(t);w(t)?(n=i(t)).value=e:n=e,a.push(n),_(r)||null!=r&&!isNaN(r)||(r=""),o.push(r+"")}),e=a}var r={category:"ordinal",time:"time"}[n]||"number";(this._data=new vA([{name:"value",type:r}],this)).initData(e,o)},getData:function(){return this._data},getCategories:function(){if("category"===this.get("axisType"))return this._names.slice()}});h(QO.extend({type:"timeline.slider",defaultOption:{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"emptyCircle",symbolSize:10,lineStyle:{show:!0,width:2,color:"#304654"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#304654"},itemStyle:{color:"#304654",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:13,color:"#c23531",borderWidth:5,borderColor:"rgba(194,53,49, 0.5)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:22,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z",prevIcon:"path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z",color:"#304654",borderColor:"#304654",borderWidth:1},emphasis:{label:{show:!0,color:"#c23531"},itemStyle:{color:"#c23531"},controlStyle:{color:"#c23531",borderColor:"#c23531",borderWidth:2}},data:[]}}),ZI);var tE=qI.extend({type:"timeline"}),eE=function(t,e,i,n){aD.call(this,t,e,i),this.type=n||"value",this.model=null};eE.prototype={constructor:eE,getLabelModel:function(){return this.model.getModel("label")},isHorizontal:function(){return"horizontal"===this.model.get("orient")}},u(eE,aD);var iE=m,nE=d,oE=Math.PI;tE.extend({type:"timeline.slider",init:function(t,e){this.api=e,this._axis,this._viewRect,this._timer,this._currentPointer,this._mainGroup,this._labelGroup},render:function(t,e,i,n){if(this.model=t,this.api=i,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var o=this._layout(t,i),a=this._createGroup("mainGroup"),r=this._createGroup("labelGroup"),s=this._axis=this._createAxis(o,t);t.formatTooltip=function(t){return ia(s.scale.getLabel(t))},nE(["AxisLine","AxisTick","Control","CurrentPointer"],function(e){this["_render"+e](o,a,s,t)},this),this._renderAxisLabel(o,r,s,t),this._position(o,t)}this._doPlayStop()},remove:function(){this._clearTimer(),this.group.removeAll()},dispose:function(){this._clearTimer()},_layout:function(t,e){var i=t.get("label.position"),n=t.get("orient"),o=Ex(t,e);null==i||"auto"===i?i="horizontal"===n?o.y+o.height/2=0||"+"===i?"left":"right"},r={horizontal:i>=0||"+"===i?"top":"bottom",vertical:"middle"},s={horizontal:0,vertical:oE/2},l="vertical"===n?o.height:o.width,u=t.getModel("controlStyle"),h=u.get("show",!0),c=h?u.get("itemSize"):0,d=h?u.get("itemGap"):0,f=c+d,p=t.get("label.rotate")||0;p=p*oE/180;var g,m,v,y,x=u.get("position",!0),_=h&&u.get("showPlayBtn",!0),w=h&&u.get("showPrevBtn",!0),b=h&&u.get("showNextBtn",!0),S=0,M=l;return"left"===x||"bottom"===x?(_&&(g=[0,0],S+=f),w&&(m=[S,0],S+=f),b&&(v=[M-c,0],M-=f)):(_&&(g=[M-c,0],M-=f),w&&(m=[0,0],S+=f),b&&(v=[M-c,0],M-=f)),y=[S,M],t.get("inverse")&&y.reverse(),{viewRect:o,mainLength:l,orient:n,rotation:s[n],labelRotation:p,labelPosOpt:i,labelAlign:t.get("label.align")||a[n],labelBaseline:t.get("label.verticalAlign")||t.get("label.baseline")||r[n],playPosition:g,prevBtnPosition:m,nextBtnPosition:v,axisExtent:y,controlSize:c,controlGap:d}},_position:function(t,e){function i(t){var e=t.position;t.origin=[c[0][0]-e[0],c[1][0]-e[1]]}function n(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function o(t,e,i,n,o){t[n]+=i[n][o]-e[n][o]}var a=this._mainGroup,r=this._labelGroup,s=t.viewRect;if("vertical"===t.orient){var l=xt(),u=s.x,h=s.y+s.height;St(l,l,[-u,-h]),Mt(l,l,-oE/2),St(l,l,[u,h]),(s=s.clone()).applyTransform(l)}var c=n(s),d=n(a.getBoundingRect()),f=n(r.getBoundingRect()),p=a.position,g=r.position;g[0]=p[0]=c[0][0];var m=t.labelPosOpt;if(isNaN(m))o(p,d,c,1,v="+"===m?0:1),o(g,f,c,1,1-v);else{var v=m>=0?0:1;o(p,d,c,1,v),g[1]=p[1]+m}a.attr("position",p),r.attr("position",g),a.rotation=r.rotation=t.rotation,i(a),i(r)},_createAxis:function(t,e){var i=e.getData(),n=e.get("axisType"),o=Hl(e,n);o.getTicks=function(){return i.mapArray(["value"],function(t){return t})};var a=i.getDataExtent("value");o.setExtent(a[0],a[1]),o.niceTicks();var r=new eE("value",o,t.axisExtent,n);return r.model=e,r},_createGroup:function(t){var e=this["_"+t]=new tb;return this.group.add(e),e},_renderAxisLine:function(t,e,i,n){var o=i.getExtent();n.get("lineStyle.show")&&e.add(new _M({shape:{x1:o[0],y1:0,x2:o[1],y2:0},style:a({lineCap:"round"},n.getModel("lineStyle").getLineStyle()),silent:!0,z2:1}))},_renderAxisTick:function(t,e,i,n){var o=n.getData(),a=i.scale.getTicks();nE(a,function(t){var a=i.dataToCoord(t),r=o.getItemModel(t),s=r.getModel("itemStyle"),l=r.getModel("emphasis.itemStyle"),u={position:[a,0],onclick:iE(this._changeTimeline,this,t)},h=zx(r,s,e,u);fo(h,l.getItemStyle()),r.get("tooltip")?(h.dataIndex=t,h.dataModel=n):h.dataIndex=h.dataModel=null},this)},_renderAxisLabel:function(t,e,i,n){if(i.getLabelModel().get("show")){var o=n.getData(),a=i.getViewLabels();nE(a,function(n){var a=n.tickValue,r=o.getItemModel(a),s=r.getModel("label"),l=r.getModel("emphasis.label"),u=i.dataToCoord(n.tickValue),h=new rM({position:[u,0],rotation:t.labelRotation-t.rotation,onclick:iE(this._changeTimeline,this,a),silent:!1});mo(h.style,s,{text:n.formattedLabel,textAlign:t.labelAlign,textVerticalAlign:t.labelBaseline}),e.add(h),fo(h,mo({},l))},this)}},_renderControl:function(t,e,i,n){function o(t,i,o,h){if(t){var c=Rx(n,i,u,{position:t,origin:[a/2,0],rotation:h?-r:0,rectHover:!0,style:s,onclick:o});e.add(c),fo(c,l)}}var a=t.controlSize,r=t.rotation,s=n.getModel("controlStyle").getItemStyle(),l=n.getModel("emphasis.controlStyle").getItemStyle(),u=[0,-a/2,a,a],h=n.getPlayState(),c=n.get("inverse",!0);o(t.nextBtnPosition,"controlStyle.nextIcon",iE(this._changeTimeline,this,c?"-":"+")),o(t.prevBtnPosition,"controlStyle.prevIcon",iE(this._changeTimeline,this,c?"+":"-")),o(t.playPosition,"controlStyle."+(h?"stopIcon":"playIcon"),iE(this._handlePlayClick,this,!h),!0)},_renderCurrentPointer:function(t,e,i,n){var o=n.getData(),a=n.getCurrentIndex(),r=o.getItemModel(a).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=iE(s._handlePointerDrag,s),t.ondragend=iE(s._handlePointerDragend,s),Bx(t,a,i,n,!0)},onUpdate:function(t){Bx(t,a,i,n)}};this._currentPointer=zx(r,r,this._mainGroup,{},this._currentPointer,l)},_handlePlayClick:function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},_handlePointerDrag:function(t,e,i){this._clearTimer(),this._pointerChangeTimeline([i.offsetX,i.offsetY])},_handlePointerDragend:function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},_pointerChangeTimeline:function(t,e){var i=this._toAxisCoord(t)[0],n=Fo(this._axis.getExtent().slice());i>n[1]&&(i=n[1]),ii.getHeight()&&(n.textPosition="top",l=!0);var u=l?-5-o.height:s+8;a+o.width/2>i.getWidth()?(n.textPosition=["100%",u],n.textAlign="right"):a-o.width/2<0&&(n.textPosition=[0,u],n.textAlign="left")}})}},updateView:function(t,e,i,n){d(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,n)})},remove:function(t,e){d(this._features,function(i){i.remove&&i.remove(t,e)}),this.group.removeAll()},dispose:function(t,e){d(this._features,function(i){i.dispose&&i.dispose(t,e)})}});var rE=rT.toolbox.saveAsImage;Gx.defaultOption={show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:rE.title,type:"png",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:rE.lang.slice()},Gx.prototype.unusable=!U_.canvasSupported,Gx.prototype.onclick=function(t,e){var i=this.model,n=i.get("name")||t.get("title.0.text")||"echarts",o=document.createElement("a"),a=i.get("type",!0)||"png";o.download=n+"."+a,o.target="_blank";var r=e.getConnectedDataURL({type:a,backgroundColor:i.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",excludeComponents:i.get("excludeComponents"),pixelRatio:i.get("pixelRatio")});if(o.href=r,"function"!=typeof MouseEvent||U_.browser.ie||U_.browser.edge)if(window.navigator.msSaveOrOpenBlob){for(var s=atob(r.split(",")[1]),l=s.length,u=new Uint8Array(l);l--;)u[l]=s.charCodeAt(l);var h=new Blob([u]);window.navigator.msSaveOrOpenBlob(h,n+"."+a)}else{var c=i.get("lang"),d='';window.open().document.write(d)}else{var f=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1});o.dispatchEvent(f)}},Ty("saveAsImage",Gx);var sE=rT.toolbox.magicType;Fx.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z",tiled:"M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z"},title:i(sE.title),option:{},seriesIndex:{}};var lE=Fx.prototype;lE.getIcons=function(){var t=this.model,e=t.get("icon"),i={};return d(t.get("type"),function(t){e[t]&&(i[t]=e[t])}),i};var uE={line:function(t,e,i,o){if("bar"===t)return n({id:e,type:"line",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.line")||{},!0)},bar:function(t,e,i,o){if("line"===t)return n({id:e,type:"bar",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.bar")||{},!0)},stack:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:"__ec_magicType_stack__"},o.get("option.stack")||{},!0)},tiled:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:""},o.get("option.tiled")||{},!0)}},hE=[["line","bar"],["stack","tiled"]];lE.onclick=function(t,e,i){var n=this.model,o=n.get("seriesIndex."+i);if(uE[i]){var a={series:[]};d(hE,function(t){l(t,i)>=0&&d(t,function(t){n.setIconStatus(t,"normal")})}),n.setIconStatus(i,"emphasis"),t.eachComponent({mainType:"series",query:null==o?null:{seriesIndex:o}},function(e){var o=e.subType,s=e.id,l=uE[i](o,s,e,n);l&&(r(l,e.option),a.series.push(l));var u=e.coordinateSystem;if(u&&"cartesian2d"===u.type&&("line"===i||"bar"===i)){var h=u.getAxesByScale("ordinal")[0];if(h){var c=h.dim+"Axis",d=t.queryComponents({mainType:c,index:e.get(name+"Index"),id:e.get(name+"Id")})[0].componentIndex;a[c]=a[c]||[];for(var f=0;f<=d;f++)a[c][d]=a[c][d]||{};a[c][d].boundaryGap="bar"===i}}}),e.dispatchAction({type:"changeMagicType",currentType:i,newOption:a})}},Es({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),Ty("magicType",Fx);var cE=rT.toolbox.dataView,dE=new Array(60).join("-"),fE="\t",pE=new RegExp("["+fE+"]+","g");$x.defaultOption={show:!0,readOnly:!1,optionToContent:null,contentToOption:null,icon:"M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28",title:i(cE.title),lang:i(cE.lang),backgroundColor:"#fff",textColor:"#000",textareaColor:"#fff",textareaBorderColor:"#333",buttonColor:"#c23531",buttonTextColor:"#fff"},$x.prototype.onclick=function(t,e){function i(){n.removeChild(a),x._dom=null}var n=e.getDom(),o=this.model;this._dom&&n.removeChild(this._dom);var a=document.createElement("div");a.style.cssText="position:absolute;left:5px;top:5px;bottom:5px;right:5px;",a.style.backgroundColor=o.get("backgroundColor")||"#fff";var r=document.createElement("h4"),s=o.get("lang")||[];r.innerHTML=s[0]||o.get("title"),r.style.cssText="margin: 10px 20px;",r.style.color=o.get("textColor");var l=document.createElement("div"),u=document.createElement("textarea");l.style.cssText="display:block;width:100%;overflow:auto;";var h=o.get("optionToContent"),c=o.get("contentToOption"),d=Ux(t);if("function"==typeof h){var f=h(e.getOption());"string"==typeof f?l.innerHTML=f:M(f)&&l.appendChild(f)}else l.appendChild(u),u.readOnly=o.get("readOnly"),u.style.cssText="width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;",u.style.color=o.get("textColor"),u.style.borderColor=o.get("textareaBorderColor"),u.style.backgroundColor=o.get("textareaColor"),u.value=d.value;var p=d.meta,g=document.createElement("div");g.style.cssText="position:absolute;bottom:0;left:0;right:0;";var m="float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px",v=document.createElement("div"),y=document.createElement("div");m+=";background-color:"+o.get("buttonColor"),m+=";color:"+o.get("buttonTextColor");var x=this;ht(v,"click",i),ht(y,"click",function(){var t;try{t="function"==typeof c?c(l,e.getOption()):Kx(u.value,p)}catch(t){throw i(),new Error("Data view format error "+t)}t&&e.dispatchAction({type:"changeDataView",newOption:t}),i()}),v.innerHTML=s[1],y.innerHTML=s[2],y.style.cssText=m,v.style.cssText=m,!o.get("readOnly")&&g.appendChild(y),g.appendChild(v),ht(u,"keydown",function(t){if(9===(t.keyCode||t.which)){var e=this.value,i=this.selectionStart,n=this.selectionEnd;this.value=e.substring(0,i)+fE+e.substring(n),this.selectionStart=this.selectionEnd=i+1,mw(t)}}),a.appendChild(r),a.appendChild(l),a.appendChild(g),l.style.height=n.clientHeight-80+"px",n.appendChild(a),this._dom=a},$x.prototype.remove=function(t,e){this._dom&&e.getDom().removeChild(this._dom)},$x.prototype.dispose=function(t,e){this.remove(t,e)},Ty("dataView",$x),Es({type:"changeDataView",event:"dataViewChanged",update:"prepareAndUpdate"},function(t,e){var i=[];d(t.newOption.series,function(t){var n=e.getSeriesByName(t.name)[0];if(n){var o=n.get("data");i.push({name:t.name,data:Jx(t.data,o)})}else i.push(a({type:"scatter"},t))}),e.mergeOption(r({series:i},t.newOption))});var gE=d,mE="\0_ec_hist_store";iO.extend({type:"dataZoom.select"}),nO.extend({type:"dataZoom.select"});var vE=rT.toolbox.dataZoom,yE=d,xE="\0_ec_\0toolbox-dataZoom_";o_.defaultOption={show:!0,icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:i(vE.title)};var _E=o_.prototype;_E.render=function(t,e,i,n){this.model=t,this.ecModel=e,this.api=i,s_(t,e,this,n,i),r_(t,e)},_E.onclick=function(t,e,i){wE[i].call(this)},_E.remove=function(t,e){this._brushController.unmount()},_E.dispose=function(t,e){this._brushController.dispose()};var wE={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(t_(this.ecModel))}};_E._onBrush=function(t,e){function i(t,e,i){var r=e.getAxis(t),s=r.model,l=n(t,s,a),u=l.findRepresentativeAxisProxy(s).getMinMaxSpan();null==u.minValueSpan&&null==u.maxValueSpan||(i=QL(0,i.slice(),r.scale.getExtent(),0,u.minValueSpan,u.maxValueSpan)),l&&(o[l.id]={dataZoomId:l.id,startValue:i[0],endValue:i[1]})}function n(t,e,i){var n;return i.eachComponent({mainType:"dataZoom",subType:"select"},function(i){i.getAxisModel(t,e.componentIndex)&&(n=i)}),n}if(e.isEnd&&t.length){var o={},a=this.ecModel;this._brushController.updateCovers([]),new hy(a_(this.model.option),a,{include:["grid"]}).matchOutputRanges(t,a,function(t,e,n){if("cartesian2d"===n.type){var o=t.brushType;"rect"===o?(i("x",n,e[0]),i("y",n,e[1])):i({lineX:"x",lineY:"y"}[o],n,e)}}),Qx(a,o),this._dispatchZoomAction(o)}},_E._dispatchZoomAction=function(t){var e=[];yE(t,function(t,n){e.push(i(t))}),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},Ty("dataZoom",o_),Ns(function(t){function e(t,e){if(e){var o=t+"Index",a=e[o];null==a||"all"===a||y(a)||(a=!1===a||"none"===a?[]:[a]),i(t,function(e,i){if(null==a||"all"===a||-1!==l(a,i)){var r={type:"select",$fromToolbox:!0,id:xE+t+i};r[o]=i,n.push(r)}})}}function i(e,i){var n=t[e];y(n)||(n=n?[n]:[]),yE(n,i)}if(t){var n=t.dataZoom||(t.dataZoom=[]);y(n)||(t.dataZoom=n=[n]);var o=t.toolbox;if(o&&(y(o)&&(o=o[0]),o&&o.feature)){var a=o.feature.dataZoom;e("xAxis",a),e("yAxis",a)}}});var bE=rT.toolbox.restore;l_.defaultOption={show:!0,icon:"M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5",title:bE.title},l_.prototype.onclick=function(t,e,i){e_(t),e.dispatchAction({type:"restore",from:this.uid})},Ty("restore",l_),Es({type:"restore",event:"restore",update:"prepareAndUpdate"},function(t,e){e.resetOption("recreate")});var SE,ME="urn:schemas-microsoft-com:vml",IE="undefined"==typeof window?null:window,TE=!1,AE=IE&&IE.document;if(AE&&!U_.canvasSupported)try{!AE.namespaces.zrvml&&AE.namespaces.add("zrvml",ME),SE=function(t){return AE.createElement("')}}catch(t){SE=function(t){return AE.createElement("<"+t+' xmlns="'+ME+'" class="zrvml">')}}var DE=ES.CMD,CE=Math.round,LE=Math.sqrt,kE=Math.abs,PE=Math.cos,NE=Math.sin,OE=Math.max;if(!U_.canvasSupported){var EE=21600,RE=EE/2,zE=function(t){t.style.cssText="position:absolute;left:0;top:0;width:1px;height:1px;",t.coordsize=EE+","+EE,t.coordorigin="0,0"},BE=function(t){return String(t).replace(/&/g,"&").replace(/"/g,""")},VE=function(t,e,i){return"rgb("+[t,e,i].join(",")+")"},GE=function(t,e){e&&t&&e.parentNode!==t&&t.appendChild(e)},FE=function(t,e){e&&t&&e.parentNode===t&&t.removeChild(e)},WE=function(t,e,i){return 1e5*(parseFloat(t)||0)+1e3*(parseFloat(e)||0)+i},HE=function(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t},ZE=function(t,e,i){var n=Gt(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=VE(n[0],n[1],n[2]),t.opacity=i*n[3])},UE=function(t){var e=Gt(t);return[VE(e[0],e[1],e[2]),e[3]]},XE=function(t,e,i){var n=e.fill;if(null!=n)if(n instanceof IM){var o,a=0,r=[0,0],s=0,l=1,u=i.getBoundingRect(),h=u.width,c=u.height;if("linear"===n.type){o="gradient";var d=i.transform,f=[n.x*h,n.y*c],p=[n.x2*h,n.y2*c];d&&(Q(f,f,d),Q(p,p,d));var g=p[0]-f[0],m=p[1]-f[1];(a=180*Math.atan2(g,m)/Math.PI)<0&&(a+=360),a<1e-6&&(a=0)}else{o="gradientradial";var f=[n.x*h,n.y*c],d=i.transform,v=i.scale,y=h,x=c;r=[(f[0]-u.x)/y,(f[1]-u.y)/x],d&&Q(f,f,d),y/=v[0]*EE,x/=v[1]*EE;var _=OE(y,x);s=0/_,l=2*n.r/_-s}var w=n.colorStops.slice();w.sort(function(t,e){return t.offset-e.offset});for(var b=w.length,S=[],M=[],I=0;I=2){var D=S[0][0],C=S[1][0],L=S[0][1]*e.opacity,k=S[1][1]*e.opacity;t.type=o,t.method="none",t.focus="100%",t.angle=a,t.color=D,t.color2=C,t.colors=M.join(","),t.opacity=k,t.opacity2=L}"radial"===o&&(t.focusposition=r.join(","))}else ZE(t,n,e.opacity)},jE=function(t,e){null!=e.lineDash&&(t.dashstyle=e.lineDash.join(" ")),null==e.stroke||e.stroke instanceof IM||ZE(t,e.stroke,e.opacity)},YE=function(t,e,i,n){var o="fill"===e,a=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(o||!o&&i.lineWidth)?(t[o?"filled":"stroked"]="true",i[e]instanceof IM&&FE(t,a),a||(a=u_(e)),o?XE(a,i,n):jE(a,i),GE(t,a)):(t[o?"filled":"stroked"]="false",FE(t,a))},qE=[[],[],[]],KE=function(t,e){var i,n,o,a,r,s,l=DE.M,u=DE.C,h=DE.L,c=DE.A,d=DE.Q,f=[],p=t.data,g=t.len();for(a=0;a.01?N&&(O+=.0125):Math.abs(E-D)<1e-4?N&&OA?x-=.0125:x+=.0125:N&&ED?y+=.0125:y-=.0125),f.push(R,CE(((A-C)*M+b)*EE-RE),",",CE(((D-L)*I+S)*EE-RE),",",CE(((A+C)*M+b)*EE-RE),",",CE(((D+L)*I+S)*EE-RE),",",CE((O*M+b)*EE-RE),",",CE((E*I+S)*EE-RE),",",CE((y*M+b)*EE-RE),",",CE((x*I+S)*EE-RE)),r=y,s=x;break;case DE.R:var z=qE[0],B=qE[1];z[0]=p[a++],z[1]=p[a++],B[0]=z[0]+p[a++],B[1]=z[1]+p[a++],e&&(Q(z,z,e),Q(B,B,e)),z[0]=CE(z[0]*EE-RE),B[0]=CE(B[0]*EE-RE),z[1]=CE(z[1]*EE-RE),B[1]=CE(B[1]*EE-RE),f.push(" m ",z[0],",",z[1]," l ",B[0],",",z[1]," l ",B[0],",",B[1]," l ",z[0],",",B[1]);break;case DE.Z:f.push(" x ")}if(i>0){f.push(n);for(var V=0;V100&&(tR=0,QE={});var i,n=eR.style;try{n.font=t,i=n.fontFamily.split(",")[0]}catch(t){}e={style:n.fontStyle||"normal",variant:n.fontVariant||"normal",weight:n.fontWeight||"normal",size:0|parseFloat(n.fontSize||12),family:i||"Microsoft YaHei"},QE[t]=e,tR++}return e};!function(t,e){bb[t]=e}("measureText",function(t,e){var i=AE;JE||((JE=i.createElement("div")).style.cssText="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;",AE.body.appendChild(JE));try{JE.style.font=e}catch(t){}return JE.innerHTML="",JE.appendChild(i.createTextNode(t)),{width:JE.offsetWidth}});for(var nR=new de,oR=[Db,di,fi,Pn,rM],aR=0;aR=o&&u+1>=a){for(var h=[],c=0;c=o&&c+1>=a)return T_(0,s.components);l[i]=s}else l[i]=void 0}r++}();if(d)return d}},pushComponent:function(t,e,i){var n=t[t.length-1];n&&n.added===e&&n.removed===i?t[t.length-1]={count:n.count+1,added:e,removed:i}:t.push({count:1,added:e,removed:i})},extractCommon:function(t,e,i,n){for(var o=e.length,a=i.length,r=t.newPos,s=r-n,l=0;r+1=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},D_.prototype.update=function(t,e){if(t){var i=this.getDefs(!1);if(t[this._domName]&&i.contains(t[this._domName]))"function"==typeof e&&e(t);else{var n=this.add(t);n&&(t[this._domName]=n)}}},D_.prototype.addDom=function(t){this.getDefs(!0).appendChild(t)},D_.prototype.removeDom=function(t){var e=this.getDefs(!1);e&&t[this._domName]&&(e.removeChild(t[this._domName]),t[this._domName]=null)},D_.prototype.getDoms=function(){var t=this.getDefs(!1);if(!t)return[];var e=[];return d(this._tagNames,function(i){var n=t.getElementsByTagName(i);e=e.concat([].slice.call(n))}),e},D_.prototype.markAllUnused=function(){var t=this;d(this.getDoms(),function(e){e[t._markLabel]="0"})},D_.prototype.markUsed=function(t){t&&(t[this._markLabel]="1")},D_.prototype.removeUnused=function(){var t=this.getDefs(!1);if(t){var e=this;d(this.getDoms(),function(i){"1"!==i[e._markLabel]&&t.removeChild(i)})}},D_.prototype.getSvgProxy=function(t){return t instanceof Pn?yR:t instanceof fi?xR:t instanceof rM?_R:yR},D_.prototype.getTextSvgElement=function(t){return t.__textSvgEl},D_.prototype.getSvgElement=function(t){return t.__svgEl},u(C_,D_),C_.prototype.addWithoutUpdate=function(t,e){if(e&&e.style){var i=this;d(["fill","stroke"],function(n){if(e.style[n]&&("linear"===e.style[n].type||"radial"===e.style[n].type)){var o,a=e.style[n],r=i.getDefs(!0);a._dom?(o=a._dom,r.contains(a._dom)||i.addDom(o)):o=i.add(a),i.markUsed(e);var s=o.getAttribute("id");t.setAttribute(n,"url(#"+s+")")}})}},C_.prototype.add=function(t){var e;if("linear"===t.type)e=this.createElement("linearGradient");else{if("radial"!==t.type)return Yw("Illegal gradient type."),null;e=this.createElement("radialGradient")}return t.id=t.id||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-gradient-"+t.id),this.updateDom(t,e),this.addDom(e),e},C_.prototype.update=function(t){var e=this;D_.prototype.update.call(this,t,function(){var i=t.type,n=t._dom.tagName;"linear"===i&&"linearGradient"===n||"radial"===i&&"radialGradient"===n?e.updateDom(t,t._dom):(e.removeDom(t),e.add(t))})},C_.prototype.updateDom=function(t,e){if("linear"===t.type)e.setAttribute("x1",t.x),e.setAttribute("y1",t.y),e.setAttribute("x2",t.x2),e.setAttribute("y2",t.y2);else{if("radial"!==t.type)return void Yw("Illegal gradient type.");e.setAttribute("cx",t.x),e.setAttribute("cy",t.y),e.setAttribute("r",t.r)}t.global?e.setAttribute("gradientUnits","userSpaceOnUse"):e.setAttribute("gradientUnits","objectBoundingBox"),e.innerHTML="";for(var i=t.colorStops,n=0,o=i.length;n0){var n,o,a=this.getDefs(!0),r=e[0],s=i?"_textDom":"_dom";r[s]?(o=r[s].getAttribute("id"),n=r[s],a.contains(n)||a.appendChild(n)):(o="zr"+this._zrId+"-clip-"+this.nextId,++this.nextId,(n=this.createElement("clipPath")).setAttribute("id",o),a.appendChild(n),r[s]=n);var l=this.getSvgProxy(r);if(r.transform&&r.parent.invTransform&&!i){var u=Array.prototype.slice.call(r.transform);bt(r.transform,r.parent.invTransform,r.transform),l.brush(r),r.transform=u}else l.brush(r);var h=this.getSvgElement(r);n.innerHTML="",n.appendChild(h.cloneNode()),t.setAttribute("clip-path","url(#"+o+")"),e.length>1&&this.updateDom(n,e.slice(1),i)}else t&&t.setAttribute("clip-path","none")},L_.prototype.markUsed=function(t){var e=this;t.__clipPaths&&t.__clipPaths.length>0&&d(t.__clipPaths,function(t){t._dom&&D_.prototype.markUsed.call(e,t._dom),t._textDom&&D_.prototype.markUsed.call(e,t._textDom)})},u(k_,D_),k_.prototype.addWithoutUpdate=function(t,e){if(e&&P_(e.style)){var i,n=e.style;n._shadowDom?(i=n._shadowDom,this.getDefs(!0).contains(n._shadowDom)||this.addDom(i)):i=this.add(e),this.markUsed(e);var o=i.getAttribute("id");t.style.filter="url(#"+o+")"}},k_.prototype.add=function(t){var e=this.createElement("filter"),i=t.style;return i._shadowDomId=i._shadowDomId||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-shadow-"+i._shadowDomId),this.updateDom(t,e),this.addDom(e),e},k_.prototype.update=function(t,e){var i=e.style;if(P_(i)){var n=this;D_.prototype.update.call(this,e,function(t){n.updateDom(e,t._shadowDom)})}else this.remove(t,i)},k_.prototype.remove=function(t,e){null!=e._shadowDomId&&(this.removeDom(e),t.style.filter="")},k_.prototype.updateDom=function(t,e){var i=e.getElementsByTagName("feDropShadow");i=0===i.length?this.createElement("feDropShadow"):i[0];var n,o,a,r,s=t.style,l=t.scale?t.scale[0]||1:1,u=t.scale?t.scale[1]||1:1;if(s.shadowBlur||s.shadowOffsetX||s.shadowOffsetY)n=s.shadowOffsetX||0,o=s.shadowOffsetY||0,a=s.shadowBlur,r=s.shadowColor;else{if(!s.textShadowBlur)return void this.removeDom(e,s);n=s.textShadowOffsetX||0,o=s.textShadowOffsetY||0,a=s.textShadowBlur,r=s.textShadowColor}i.setAttribute("dx",n/l),i.setAttribute("dy",o/u),i.setAttribute("flood-color",r);var h=a/2/l+" "+a/2/u;i.setAttribute("stdDeviation",h),e.setAttribute("x","-100%"),e.setAttribute("y","-100%"),e.setAttribute("width",Math.ceil(a/2*200)+"%"),e.setAttribute("height",Math.ceil(a/2*200)+"%"),e.appendChild(i),s._shadowDom=e},k_.prototype.markUsed=function(t){var e=t.style;e&&e._shadowDom&&D_.prototype.markUsed.call(this,e._shadowDom)};var IR=function(t,e,i,n){this.root=t,this.storage=e,this._opts=i=a({},i||{});var o=p_("svg");o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("version","1.1"),o.setAttribute("baseProfile","full"),o.style.cssText="user-select:none;position:absolute;left:0;top:0;",this.gradientManager=new C_(n,o),this.clipPathManager=new L_(n,o),this.shadowManager=new k_(n,o);var r=document.createElement("div");r.style.cssText="overflow:hidden;position:relative",this._svgRoot=o,this._viewport=r,t.appendChild(r),r.appendChild(o),this.resize(i.width,i.height),this._visibleList=[]};IR.prototype={constructor:IR,getType:function(){return"svg"},getViewportRoot:function(){return this._viewport},getViewportRootOffset:function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},refresh:function(){var t=this.storage.getDisplayList(!0);this._paintList(t)},setBackgroundColor:function(t){this._viewport.style.background=t},_paintList:function(t){this.gradientManager.markAllUnused(),this.clipPathManager.markAllUnused(),this.shadowManager.markAllUnused();var e,i=this._svgRoot,n=this._visibleList,o=t.length,a=[];for(e=0;e=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},resize:function(t,e){var i=this._viewport;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n.height=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!==t||this._height!==e){this._width=t,this._height=e;var o=i.style;o.width=t+"px",o.height=e+"px";var a=this._svgRoot;a.setAttribute("width",t),a.setAttribute("height",e)}},getWidth:function(){return this._width},getHeight:function(){return this._height},_getSize:function(t){var e=this._opts,i=["width","height"][t],n=["clientWidth","clientHeight"][t],o=["paddingLeft","paddingTop"][t],a=["paddingRight","paddingBottom"][t];if(null!=e[i]&&"auto"!==e[i])return parseFloat(e[i]);var r=this.root,s=document.defaultView.getComputedStyle(r);return(r[n]||N_(s[i])||N_(r.style[i]))-(N_(s[o])||0)-(N_(s[a])||0)|0},dispose:function(){this.root.innerHTML="",this._svgRoot=this._viewport=this.storage=null},clear:function(){this._viewport&&this.root.removeChild(this._viewport)},pathToDataUrl:function(){return this.refresh(),"data:image/svg+xml;charset=UTF-8,"+this._svgRoot.outerHTML}},d(["getLayer","insertLayer","eachLayer","eachBuiltinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","toDataURL","pathToImage"],function(t){IR.prototype[t]=F_(t)}),Ti("svg",IR),t.version="4.2.1",t.dependencies=ET,t.PRIORITY=VT,t.init=function(t,e,i){var n=ks(t);if(n)return n;var o=new us(t,e,i);return o.id="ec_"+iA++,tA[o.id]=o,Fi(t,oA,o.id),Cs(o),o},t.connect=function(t){if(y(t)){var e=t;t=null,kT(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+nA++,kT(e,function(e){e.group=t})}return eA[t]=!0,t},t.disConnect=Ls,t.disconnect=aA,t.dispose=function(t){"string"==typeof t?t=tA[t]:t instanceof us||(t=ks(t)),t instanceof us&&!t.isDisposed()&&t.dispose()},t.getInstanceByDom=ks,t.getInstanceById=function(t){return tA[t]},t.registerTheme=Ps,t.registerPreprocessor=Ns,t.registerProcessor=Os,t.registerPostUpdate=function(t){KT.push(t)},t.registerAction=Es,t.registerCoordinateSystem=Rs,t.getCoordinateSystemDimensions=function(t){var e=Fa.get(t);if(e)return e.getDimensionsInfo?e.getDimensionsInfo():e.dimensions.slice()},t.registerLayout=zs,t.registerVisual=Bs,t.registerLoading=Gs,t.extendComponentModel=Fs,t.extendComponentView=Ws,t.extendSeriesModel=Hs,t.extendChartView=Zs,t.setCanvasCreator=function(t){e("createCanvas",t)},t.registerMap=function(t,e,i){DT.registerMap(t,e,i)},t.getMap=function(t){var e=DT.retrieveMap(t);return e&&e[0]&&{geoJson:e[0].geoJSON,specialAreas:e[0].specialAreas}},t.dataTool=rA,t.zrender=Hb,t.number=YM,t.format=eI,t.throttle=Pr,t.helper=tD,t.matrix=Sw,t.vector=cw,t.color=Ww,t.parseGeoJSON=iD,t.parseGeoJson=rD,t.util=sD,t.graphic=lD,t.List=vA,t.Model=No,t.Axis=aD,t.env=U_}); \ No newline at end of file diff --git a/alpha/admin/uni_modules/qiun-data-charts/static/h5/echarts.min.js b/alpha/admin/uni_modules/qiun-data-charts/static/h5/echarts.min.js new file mode 100644 index 0000000..5396a03 --- /dev/null +++ b/alpha/admin/uni_modules/qiun-data-charts/static/h5/echarts.min.js @@ -0,0 +1,23 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* 版本为4.2.1,修改一处源码:this.el.hide() 改为 this.el?this.el.hide():true +*/ + + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.echarts={})}(this,function(t){"use strict";function e(t,e){"createCanvas"===t&&(nw=null),ew[t]=e}function i(t){if(null==t||"object"!=typeof t)return t;var e=t,n=Y_.call(t);if("[object Array]"===n){if(!O(t)){e=[];for(var o=0,a=t.length;o=0){var o="touchend"!==n?e.targetTouches[0]:e.changedTouches[0];o&&st(t,o,e,i)}else st(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;var a=e.button;return null==e.which&&void 0!==a&&gw.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ht(t,e,i){pw?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function ct(t,e,i){pw?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}function dt(t){return 2===t.which||3===t.which}function ft(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function pt(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function gt(t,e,i){return{type:t,event:i,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:i.zrX,offsetY:i.zrY,gestureEvent:i.gestureEvent,pinchX:i.pinchX,pinchY:i.pinchY,pinchScale:i.pinchScale,wheelDelta:i.zrDelta,zrByTouch:i.zrByTouch,which:i.which,stop:mt}}function mt(t){mw(this.event)}function vt(){}function yt(t,e,i){if(t[t.rectHover?"rectContain":"contain"](e,i)){for(var n,o=t;o;){if(o.clipPath&&!o.clipPath.contain(e,i))return!1;o.silent&&(n=!0),o=o.parent}return!n||xw}return!1}function xt(){var t=new bw(6);return _t(t),t}function _t(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function wt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function bt(t,e,i){var n=e[0]*i[0]+e[2]*i[1],o=e[1]*i[0]+e[3]*i[1],a=e[0]*i[2]+e[2]*i[3],r=e[1]*i[2]+e[3]*i[3],s=e[0]*i[4]+e[2]*i[5]+e[4],l=e[1]*i[4]+e[3]*i[5]+e[5];return t[0]=n,t[1]=o,t[2]=a,t[3]=r,t[4]=s,t[5]=l,t}function St(t,e,i){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+i[0],t[5]=e[5]+i[1],t}function Mt(t,e,i){var n=e[0],o=e[2],a=e[4],r=e[1],s=e[3],l=e[5],u=Math.sin(i),h=Math.cos(i);return t[0]=n*h+r*u,t[1]=-n*u+r*h,t[2]=o*h+s*u,t[3]=-o*u+h*s,t[4]=h*a+u*l,t[5]=h*l-u*a,t}function It(t,e,i){var n=i[0],o=i[1];return t[0]=e[0]*n,t[1]=e[1]*o,t[2]=e[2]*n,t[3]=e[3]*o,t[4]=e[4]*n,t[5]=e[5]*o,t}function Tt(t,e){var i=e[0],n=e[2],o=e[4],a=e[1],r=e[3],s=e[5],l=i*r-a*n;return l?(l=1/l,t[0]=r*l,t[1]=-a*l,t[2]=-n*l,t[3]=i*l,t[4]=(n*s-r*o)*l,t[5]=(a*o-i*s)*l,t):null}function At(t){var e=xt();return wt(e,t),e}function Dt(t){return t>Iw||t<-Iw}function Ct(t){this._target=t.target,this._life=t.life||1e3,this._delay=t.delay||0,this._initialized=!1,this.loop=null!=t.loop&&t.loop,this.gap=t.gap||0,this.easing=t.easing||"Linear",this.onframe=t.onframe,this.ondestroy=t.ondestroy,this.onrestart=t.onrestart,this._pausedTime=0,this._paused=!1}function Lt(t){return(t=Math.round(t))<0?0:t>255?255:t}function kt(t){return(t=Math.round(t))<0?0:t>360?360:t}function Pt(t){return t<0?0:t>1?1:t}function Nt(t){return Lt(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function Ot(t){return Pt(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function Et(t,e,i){return i<0?i+=1:i>1&&(i-=1),6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function Rt(t,e,i){return t+(e-t)*i}function zt(t,e,i,n,o){return t[0]=e,t[1]=i,t[2]=n,t[3]=o,t}function Bt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function Vt(t,e){Vw&&Bt(Vw,e),Vw=Bw.put(t,Vw||e.slice())}function Gt(t,e){if(t){e=e||[];var i=Bw.get(t);if(i)return Bt(e,i);var n=(t+="").replace(/ /g,"").toLowerCase();if(n in zw)return Bt(e,zw[n]),Vt(t,e),e;if("#"!==n.charAt(0)){var o=n.indexOf("("),a=n.indexOf(")");if(-1!==o&&a+1===n.length){var r=n.substr(0,o),s=n.substr(o+1,a-(o+1)).split(","),l=1;switch(r){case"rgba":if(4!==s.length)return void zt(e,0,0,0,1);l=Ot(s.pop());case"rgb":return 3!==s.length?void zt(e,0,0,0,1):(zt(e,Nt(s[0]),Nt(s[1]),Nt(s[2]),l),Vt(t,e),e);case"hsla":return 4!==s.length?void zt(e,0,0,0,1):(s[3]=Ot(s[3]),Ft(s,e),Vt(t,e),e);case"hsl":return 3!==s.length?void zt(e,0,0,0,1):(Ft(s,e),Vt(t,e),e);default:return}}zt(e,0,0,0,1)}else{if(4===n.length)return(u=parseInt(n.substr(1),16))>=0&&u<=4095?(zt(e,(3840&u)>>4|(3840&u)>>8,240&u|(240&u)>>4,15&u|(15&u)<<4,1),Vt(t,e),e):void zt(e,0,0,0,1);if(7===n.length){var u=parseInt(n.substr(1),16);return u>=0&&u<=16777215?(zt(e,(16711680&u)>>16,(65280&u)>>8,255&u,1),Vt(t,e),e):void zt(e,0,0,0,1)}}}}function Ft(t,e){var i=(parseFloat(t[0])%360+360)%360/360,n=Ot(t[1]),o=Ot(t[2]),a=o<=.5?o*(n+1):o+n-o*n,r=2*o-a;return e=e||[],zt(e,Lt(255*Et(r,a,i+1/3)),Lt(255*Et(r,a,i)),Lt(255*Et(r,a,i-1/3)),1),4===t.length&&(e[3]=t[3]),e}function Wt(t){if(t){var e,i,n=t[0]/255,o=t[1]/255,a=t[2]/255,r=Math.min(n,o,a),s=Math.max(n,o,a),l=s-r,u=(s+r)/2;if(0===l)e=0,i=0;else{i=u<.5?l/(s+r):l/(2-s-r);var h=((s-n)/6+l/2)/l,c=((s-o)/6+l/2)/l,d=((s-a)/6+l/2)/l;n===s?e=d-c:o===s?e=1/3+h-d:a===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,u];return null!=t[3]&&f.push(t[3]),f}}function Ht(t,e){var i=Gt(t);if(i){for(var n=0;n<3;n++)i[n]=e<0?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0,i[n]>255?i[n]=255:t[n]<0&&(i[n]=0);return qt(i,4===i.length?"rgba":"rgb")}}function Zt(t){var e=Gt(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)}function Ut(t,e,i){if(e&&e.length&&t>=0&&t<=1){i=i||[];var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=e[o],s=e[a],l=n-o;return i[0]=Lt(Rt(r[0],s[0],l)),i[1]=Lt(Rt(r[1],s[1],l)),i[2]=Lt(Rt(r[2],s[2],l)),i[3]=Pt(Rt(r[3],s[3],l)),i}}function Xt(t,e,i){if(e&&e.length&&t>=0&&t<=1){var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=Gt(e[o]),s=Gt(e[a]),l=n-o,u=qt([Lt(Rt(r[0],s[0],l)),Lt(Rt(r[1],s[1],l)),Lt(Rt(r[2],s[2],l)),Pt(Rt(r[3],s[3],l))],"rgba");return i?{color:u,leftIndex:o,rightIndex:a,value:n}:u}}function jt(t,e,i,n){if(t=Gt(t))return t=Wt(t),null!=e&&(t[0]=kt(e)),null!=i&&(t[1]=Ot(i)),null!=n&&(t[2]=Ot(n)),qt(Ft(t),"rgba")}function Yt(t,e){if((t=Gt(t))&&null!=e)return t[3]=Pt(e),qt(t,"rgba")}function qt(t,e){if(t&&t.length){var i=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(i+=","+t[3]),e+"("+i+")"}}function Kt(t,e){return t[e]}function $t(t,e,i){t[e]=i}function Jt(t,e,i){return(e-t)*i+t}function Qt(t,e,i){return i>.5?e:t}function te(t,e,i,n,o){var a=t.length;if(1===o)for(s=0;so)t.length=o;else for(r=n;r=0&&!(m[i]<=e);i--);i=Math.min(i,u-2)}else{for(i=L;ie);i++);i=Math.min(i-1,u-2)}L=i,k=e;var n=m[i+1]-m[i];if(0!==n)if(I=(e-m[i])/n,l)if(A=v[i],T=v[0===i?i:i-1],D=v[i>u-2?u-1:i+1],C=v[i>u-3?u-1:i+2],d)ne(T,A,D,C,I,I*I,I*I*I,r(t,o),g);else{if(f)a=ne(T,A,D,C,I,I*I,I*I*I,P,1),a=re(P);else{if(p)return Qt(A,D,I);a=oe(T,A,D,C,I,I*I,I*I*I)}s(t,o,a)}else if(d)te(v[i],v[i+1],I,r(t,o),g);else{var a;if(f)te(v[i],v[i+1],I,P,1),a=re(P);else{if(p)return Qt(v[i],v[i+1],I);a=Jt(v[i],v[i+1],I)}s(t,o,a)}},ondestroy:i});return e&&"spline"!==e&&(N.easing=e),N}}}function ue(t,e,i,n,o,a,r,s){_(n)?(a=o,o=n,n=0):x(o)?(a=o,o="linear",n=0):x(n)?(a=n,n=0):x(i)?(a=i,i=500):i||(i=500),t.stopAnimation(),he(t,"",t,e,i,n,s);var l=t.animators.slice(),u=l.length;u||a&&a();for(var h=0;h0&&t.animate(e,!1).when(null==o?500:o,s).delay(a||0)}function ce(t,e,i,n){if(e){var o={};o[e]={},o[e][i]=n,t.attr(o)}else t.attr(i,n)}function de(t,e,i,n){i<0&&(t+=i,i=-i),n<0&&(e+=n,n=-n),this.x=t,this.y=e,this.width=i,this.height=n}function fe(t){for(var e=0;t>=eb;)e|=1&t,t>>=1;return t+e}function pe(t,e,i,n){var o=e+1;if(o===i)return 1;if(n(t[o++],t[e])<0){for(;o=0;)o++;return o-e}function ge(t,e,i){for(i--;e>>1])<0?l=a:s=a+1;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=r}}function ve(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])>0){for(s=n-o;l0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}else{for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}for(r++;r>>1);a(t,e[i+h])>0?r=h+1:l=h}return l}function ye(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])<0){for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}else{for(s=n-o;l=0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}for(r++;r>>1);a(t,e[i+h])<0?l=h:r=h+1}return l}function xe(t,e){function i(i){var s=a[i],u=r[i],h=a[i+1],c=r[i+1];r[i]=u+c,i===l-3&&(a[i+1]=a[i+2],r[i+1]=r[i+2]),l--;var d=ye(t[h],t,s,u,0,e);s+=d,0!==(u-=d)&&0!==(c=ve(t[s+u-1],t,h,c,c-1,e))&&(u<=c?n(s,u,h,c):o(s,u,h,c))}function n(i,n,o,a){var r=0;for(r=0;r=ib||f>=ib);if(p)break;g<0&&(g=0),g+=2}if((s=g)<1&&(s=1),1===n){for(r=0;r=0;r--)t[f+r]=t[d+r];if(0===n){v=!0;break}}if(t[c--]=u[h--],1==--a){v=!0;break}if(0!=(m=a-ve(t[l],u,0,a,a-1,e))){for(a-=m,f=(c-=m)+1,d=(h-=m)+1,r=0;r=ib||m>=ib);if(v)break;p<0&&(p=0),p+=2}if((s=p)<1&&(s=1),1===a){for(f=(c-=n)+1,d=(l-=n)+1,r=n-1;r>=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else{if(0===a)throw new Error;for(d=c-(a-1),r=0;r=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else for(d=c-(a-1),r=0;r1;){var t=l-2;if(t>=1&&r[t-1]<=r[t]+r[t+1]||t>=2&&r[t-2]<=r[t]+r[t-1])r[t-1]r[t+1])break;i(t)}},this.forceMergeRuns=function(){for(;l>1;){var t=l-2;t>0&&r[t-1]s&&(l=s),me(t,i,i+l,i+a,e),a=l}r.pushRun(i,a),r.mergeRuns(),o-=a,i+=a}while(0!==o);r.forceMergeRuns()}}function we(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}function be(t,e,i){var n=null==e.x?0:e.x,o=null==e.x2?1:e.x2,a=null==e.y?0:e.y,r=null==e.y2?0:e.y2;return e.global||(n=n*i.width+i.x,o=o*i.width+i.x,a=a*i.height+i.y,r=r*i.height+i.y),n=isNaN(n)?0:n,o=isNaN(o)?1:o,a=isNaN(a)?0:a,r=isNaN(r)?0:r,t.createLinearGradient(n,a,o,r)}function Se(t,e,i){var n=i.width,o=i.height,a=Math.min(n,o),r=null==e.x?.5:e.x,s=null==e.y?.5:e.y,l=null==e.r?.5:e.r;return e.global||(r=r*n+i.x,s=s*o+i.y,l*=a),t.createRadialGradient(r,s,0,r,s,l)}function Me(){return!1}function Ie(t,e,i){var n=iw(),o=e.getWidth(),a=e.getHeight(),r=n.style;return r&&(r.position="absolute",r.left=0,r.top=0,r.width=o+"px",r.height=a+"px",n.setAttribute("data-zr-dom-id",t)),n.width=o*i,n.height=a*i,n}function Te(t){if("string"==typeof t){var e=mb.get(t);return e&&e.image}return t}function Ae(t,e,i,n,o){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!i)return e;var a=mb.get(t),r={hostEl:i,cb:n,cbPayload:o};return a?!Ce(e=a.image)&&a.pending.push(r):((e=new Image).onload=e.onerror=De,mb.put(t,e.__cachedImgObj={image:e,pending:[r]}),e.src=e.__zrImageSrc=t),e}return t}return e}function De(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;exb&&(yb=0,vb={}),yb++,vb[i]=o,o}function ke(t,e,i,n,o,a,r,s){return r?Ne(t,e,i,n,o,a,r,s):Pe(t,e,i,n,o,a,s)}function Pe(t,e,i,n,o,a,r){var s=He(t,e,o,a,r),l=Le(t,e);o&&(l+=o[1]+o[3]);var u=s.outerHeight,h=new de(Oe(0,l,i),Ee(0,u,n),l,u);return h.lineHeight=s.lineHeight,h}function Ne(t,e,i,n,o,a,r,s){var l=Ze(t,{rich:r,truncate:s,font:e,textAlign:i,textPadding:o,textLineHeight:a}),u=l.outerWidth,h=l.outerHeight;return new de(Oe(0,u,i),Ee(0,h,n),u,h)}function Oe(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function Ee(t,e,i){return"middle"===i?t-=e/2:"bottom"===i&&(t-=e),t}function Re(t,e,i){var n=e.x,o=e.y,a=e.height,r=e.width,s=a/2,l="left",u="top";switch(t){case"left":n-=i,o+=s,l="right",u="middle";break;case"right":n+=i+r,o+=s,u="middle";break;case"top":n+=r/2,o-=i,l="center",u="bottom";break;case"bottom":n+=r/2,o+=a+i,l="center";break;case"inside":n+=r/2,o+=s,l="center",u="middle";break;case"insideLeft":n+=i,o+=s,u="middle";break;case"insideRight":n+=r-i,o+=s,l="right",u="middle";break;case"insideTop":n+=r/2,o+=i,l="center";break;case"insideBottom":n+=r/2,o+=a-i,l="center",u="bottom";break;case"insideTopLeft":n+=i,o+=i;break;case"insideTopRight":n+=r-i,o+=i,l="right";break;case"insideBottomLeft":n+=i,o+=a-i,u="bottom";break;case"insideBottomRight":n+=r-i,o+=a-i,l="right",u="bottom"}return{x:n,y:o,textAlign:l,textVerticalAlign:u}}function ze(t,e,i,n,o){if(!e)return"";var a=(t+"").split("\n");o=Be(e,i,n,o);for(var r=0,s=a.length;r=r;l++)s-=r;var u=Le(i,e);return u>s&&(i="",u=0),s=t-u,n.ellipsis=i,n.ellipsisWidth=u,n.contentWidth=s,n.containerWidth=t,n}function Ve(t,e){var i=e.containerWidth,n=e.font,o=e.contentWidth;if(!i)return"";var a=Le(t,n);if(a<=i)return t;for(var r=0;;r++){if(a<=o||r>=e.maxIterations){t+=e.ellipsis;break}var s=0===r?Ge(t,o,e.ascCharWidth,e.cnCharWidth):a>0?Math.floor(t.length*o/a):0;a=Le(t=t.substr(0,s),n)}return""===t&&(t=e.placeholder),t}function Ge(t,e,i,n){for(var o=0,a=0,r=t.length;au)t="",r=[];else if(null!=h)for(var c=Be(h-(i?i[1]+i[3]:0),e,o.ellipsis,{minChar:o.minChar,placeholder:o.placeholder}),d=0,f=r.length;do&&Ue(i,t.substring(o,a)),Ue(i,n[2],n[1]),o=_b.lastIndex}of)return{lines:[],width:0,height:0};k.textWidth=Le(k.text,_);var b=y.textWidth,S=null==b||"auto"===b;if("string"==typeof b&&"%"===b.charAt(b.length-1))k.percentWidth=b,u.push(k),b=0;else{if(S){b=k.textWidth;var M=y.textBackgroundColor,I=M&&M.image;I&&Ce(I=Te(I))&&(b=Math.max(b,I.width*w/I.height))}var T=x?x[1]+x[3]:0;b+=T;var C=null!=d?d-m:null;null!=C&&Cl&&(i*=l/(c=i+n),n*=l/c),o+a>l&&(o*=l/(c=o+a),a*=l/c),n+o>u&&(n*=u/(c=n+o),o*=u/c),i+a>u&&(i*=u/(c=i+a),a*=u/c),t.moveTo(r+i,s),t.lineTo(r+l-n,s),0!==n&&t.arc(r+l-n,s+n,n,-Math.PI/2,0),t.lineTo(r+l,s+u-o),0!==o&&t.arc(r+l-o,s+u-o,o,0,Math.PI/2),t.lineTo(r+a,s+u),0!==a&&t.arc(r+a,s+u-a,a,Math.PI/2,Math.PI),t.lineTo(r,s+i),0!==i&&t.arc(r+i,s+i,i,Math.PI,1.5*Math.PI)}function Ye(t){return qe(t),d(t.rich,qe),t}function qe(t){if(t){t.font=Xe(t);var e=t.textAlign;"middle"===e&&(e="center"),t.textAlign=null==e||Mb[e]?e:"left";var i=t.textVerticalAlign||t.textBaseline;"center"===i&&(i="middle"),t.textVerticalAlign=null==i||Ib[i]?i:"top",t.textPadding&&(t.textPadding=L(t.textPadding))}}function Ke(t,e,i,n,o,a){n.rich?Je(t,e,i,n,o,a):$e(t,e,i,n,o,a)}function $e(t,e,i,n,o,a){var r,s=ii(n),l=!1,u=e.__attrCachedBy===rb.PLAIN_TEXT;a!==sb?(a&&(r=a.style,l=!s&&u&&r),e.__attrCachedBy=s?rb.NONE:rb.PLAIN_TEXT):u&&(e.__attrCachedBy=rb.NONE);var h=n.font||Sb;l&&h===(r.font||Sb)||(e.font=h);var c=t.__computedFont;t.__styleFont!==h&&(t.__styleFont=h,c=t.__computedFont=e.font);var d=n.textPadding,f=n.textLineHeight,p=t.__textCotentBlock;p&&!t.__dirtyText||(p=t.__textCotentBlock=He(i,c,d,f,n.truncate));var g=p.outerHeight,m=p.lines,v=p.lineHeight,y=ai(g,n,o),x=y.baseX,_=y.baseY,w=y.textAlign||"left",b=y.textVerticalAlign;ti(e,n,o,x,_);var S=Ee(_,g,b),M=x,I=S;if(s||d){var T=Le(i,c);d&&(T+=d[1]+d[3]);var A=Oe(x,T,w);s&&ni(t,e,n,A,S,T,g),d&&(M=hi(x,w,d),I+=d[0])}e.textAlign=w,e.textBaseline="middle",e.globalAlpha=n.opacity||1;for(B=0;B=0&&"right"===(_=b[C]).textAlign;)ei(t,e,_,n,M,v,D,"right"),I-=_.width,D-=_.width,C--;for(A+=(a-(A-m)-(y-D)-I)/2;T<=C;)ei(t,e,_=b[T],n,M,v,A+_.width/2,"center"),A+=_.width,T++;v+=M}}function ti(t,e,i,n,o){if(i&&e.textRotation){var a=e.textOrigin;"center"===a?(n=i.width/2+i.x,o=i.height/2+i.y):a&&(n=a[0]+i.x,o=a[1]+i.y),t.translate(n,o),t.rotate(-e.textRotation),t.translate(-n,-o)}}function ei(t,e,i,n,o,a,r,s){var l=n.rich[i.styleName]||{};l.text=i.text;var u=i.textVerticalAlign,h=a+o/2;"top"===u?h=a+i.height/2:"bottom"===u&&(h=a+o-i.height/2),!i.isLineHolder&&ii(l)&&ni(t,e,l,"right"===s?r-i.width:"center"===s?r-i.width/2:r,h-i.height/2,i.width,i.height);var c=i.textPadding;c&&(r=hi(r,s,c),h-=i.height/2-c[2]-i.textHeight/2),ri(e,"shadowBlur",D(l.textShadowBlur,n.textShadowBlur,0)),ri(e,"shadowColor",l.textShadowColor||n.textShadowColor||"transparent"),ri(e,"shadowOffsetX",D(l.textShadowOffsetX,n.textShadowOffsetX,0)),ri(e,"shadowOffsetY",D(l.textShadowOffsetY,n.textShadowOffsetY,0)),ri(e,"textAlign",s),ri(e,"textBaseline","middle"),ri(e,"font",i.font||Sb);var d=si(l.textStroke||n.textStroke,p),f=li(l.textFill||n.textFill),p=A(l.textStrokeWidth,n.textStrokeWidth);d&&(ri(e,"lineWidth",p),ri(e,"strokeStyle",d),e.strokeText(i.text,r,h)),f&&(ri(e,"fillStyle",f),e.fillText(i.text,r,h))}function ii(t){return!!(t.textBackgroundColor||t.textBorderWidth&&t.textBorderColor)}function ni(t,e,i,n,o,a,r){var s=i.textBackgroundColor,l=i.textBorderWidth,u=i.textBorderColor,h=_(s);if(ri(e,"shadowBlur",i.textBoxShadowBlur||0),ri(e,"shadowColor",i.textBoxShadowColor||"transparent"),ri(e,"shadowOffsetX",i.textBoxShadowOffsetX||0),ri(e,"shadowOffsetY",i.textBoxShadowOffsetY||0),h||l&&u){e.beginPath();var c=i.textBorderRadius;c?je(e,{x:n,y:o,width:a,height:r,r:c}):e.rect(n,o,a,r),e.closePath()}if(h)if(ri(e,"fillStyle",s),null!=i.fillOpacity){f=e.globalAlpha;e.globalAlpha=i.fillOpacity*i.opacity,e.fill(),e.globalAlpha=f}else e.fill();else if(w(s)){var d=s.image;(d=Ae(d,null,t,oi,s))&&Ce(d)&&e.drawImage(d,n,o,a,r)}if(l&&u)if(ri(e,"lineWidth",l),ri(e,"strokeStyle",u),null!=i.strokeOpacity){var f=e.globalAlpha;e.globalAlpha=i.strokeOpacity*i.opacity,e.stroke(),e.globalAlpha=f}else e.stroke()}function oi(t,e){e.image=t}function ai(t,e,i){var n=e.x||0,o=e.y||0,a=e.textAlign,r=e.textVerticalAlign;if(i){var s=e.textPosition;if(s instanceof Array)n=i.x+ui(s[0],i.width),o=i.y+ui(s[1],i.height);else{var l=Re(s,i,e.textDistance);n=l.x,o=l.y,a=a||l.textAlign,r=r||l.textVerticalAlign}var u=e.textOffset;u&&(n+=u[0],o+=u[1])}return{baseX:n,baseY:o,textAlign:a,textVerticalAlign:r}}function ri(t,e,i){return t[e]=ab(t,e,i),t[e]}function si(t,e){return null==t||e<=0||"transparent"===t||"none"===t?null:t.image||t.colorStops?"#000":t}function li(t){return null==t||"none"===t?null:t.image||t.colorStops?"#000":t}function ui(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t}function hi(t,e,i){return"right"===e?t-i[1]:"center"===e?t+i[3]/2-i[1]/2:t+i[3]}function ci(t,e){return null!=t&&(t||e.textBackgroundColor||e.textBorderWidth&&e.textBorderColor||e.textPadding)}function di(t){t=t||{},Kw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&"style"!==e&&(this[e]=t[e]);this.style=new ub(t.style,this),this._rect=null,this.__clipPaths=[]}function fi(t){di.call(this,t)}function pi(t){return parseInt(t,10)}function gi(t){return!!t&&(!!t.__builtin__||"function"==typeof t.resize&&"function"==typeof t.refresh)}function mi(t,e,i){return Cb.copy(t.getBoundingRect()),t.transform&&Cb.applyTransform(t.transform),Lb.width=e,Lb.height=i,!Cb.intersect(Lb)}function vi(t,e){if(t===e)return!1;if(!t||!e||t.length!==e.length)return!0;for(var i=0;i=i.length&&i.push({option:t})}}),i}function Ni(t){var e=R();Zb(t,function(t,i){var n=t.exist;n&&e.set(n.id,t)}),Zb(t,function(t,i){var n=t.option;k(!n||null==n.id||!e.get(n.id)||e.get(n.id)===t,"id duplicates: "+(n&&n.id)),n&&null!=n.id&&e.set(n.id,t),!t.keyInfo&&(t.keyInfo={})}),Zb(t,function(t,i){var n=t.exist,o=t.option,a=t.keyInfo;if(Ub(o)){if(a.name=null!=o.name?o.name+"":n?n.name:jb+i,n)a.id=n.id;else if(null!=o.id)a.id=o.id+"";else{var r=0;do{a.id="\0"+a.name+"\0"+r++}while(e.get(a.id))}e.set(a.id,t)}})}function Oi(t){var e=t.name;return!(!e||!e.indexOf(jb))}function Ei(t){return Ub(t)&&t.id&&0===(t.id+"").indexOf("\0_ec_\0")}function Ri(t,e){function i(t,e,i){for(var n=0,o=t.length;n-rS&&trS||t<-rS}function tn(t,e,i,n,o){var a=1-o;return a*a*(a*t+3*o*e)+o*o*(o*n+3*a*i)}function en(t,e,i,n,o){var a=1-o;return 3*(((e-t)*a+2*(i-e)*o)*a+(n-i)*o*o)}function nn(t,e,i,n,o,a){var r=n+3*(e-i)-t,s=3*(i-2*e+t),l=3*(e-t),u=t-o,h=s*s-3*r*l,c=s*l-9*r*u,d=l*l-3*s*u,f=0;if(Ji(h)&&Ji(c))Ji(s)?a[0]=0:(M=-l/s)>=0&&M<=1&&(a[f++]=M);else{var p=c*c-4*h*d;if(Ji(p)){var g=c/h,m=-g/2;(M=-s/r+g)>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m)}else if(p>0){var v=aS(p),y=h*s+1.5*r*(-c+v),x=h*s+1.5*r*(-c-v);(M=(-s-((y=y<0?-oS(-y,uS):oS(y,uS))+(x=x<0?-oS(-x,uS):oS(x,uS))))/(3*r))>=0&&M<=1&&(a[f++]=M)}else{var _=(2*h*s-3*r*c)/(2*aS(h*h*h)),w=Math.acos(_)/3,b=aS(h),S=Math.cos(w),M=(-s-2*b*S)/(3*r),m=(-s+b*(S+lS*Math.sin(w)))/(3*r),I=(-s+b*(S-lS*Math.sin(w)))/(3*r);M>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m),I>=0&&I<=1&&(a[f++]=I)}}return f}function on(t,e,i,n,o){var a=6*i-12*e+6*t,r=9*e+3*n-3*t-9*i,s=3*e-3*t,l=0;if(Ji(r))Qi(a)&&(c=-s/a)>=0&&c<=1&&(o[l++]=c);else{var u=a*a-4*r*s;if(Ji(u))o[0]=-a/(2*r);else if(u>0){var h=aS(u),c=(-a+h)/(2*r),d=(-a-h)/(2*r);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function an(t,e,i,n,o,a){var r=(e-t)*o+t,s=(i-e)*o+e,l=(n-i)*o+i,u=(s-r)*o+r,h=(l-s)*o+s,c=(h-u)*o+u;a[0]=t,a[1]=r,a[2]=u,a[3]=c,a[4]=c,a[5]=h,a[6]=l,a[7]=n}function rn(t,e,i,n,o,a,r,s,l,u,h){var c,d,f,p,g,m=.005,v=1/0;hS[0]=l,hS[1]=u;for(var y=0;y<1;y+=.05)cS[0]=tn(t,i,o,r,y),cS[1]=tn(e,n,a,s,y),(p=hw(hS,cS))=0&&p=0&&c<=1&&(o[l++]=c);else{var u=r*r-4*a*s;if(Ji(u))(c=-r/(2*a))>=0&&c<=1&&(o[l++]=c);else if(u>0){var h=aS(u),c=(-r+h)/(2*a),d=(-r-h)/(2*a);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function hn(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function cn(t,e,i,n,o){var a=(e-t)*n+t,r=(i-e)*n+e,s=(r-a)*n+a;o[0]=t,o[1]=a,o[2]=s,o[3]=s,o[4]=r,o[5]=i}function dn(t,e,i,n,o,a,r,s,l){var u,h=.005,c=1/0;hS[0]=r,hS[1]=s;for(var d=0;d<1;d+=.05)cS[0]=sn(t,i,o,d),cS[1]=sn(e,n,a,d),(m=hw(hS,cS))=0&&m1e-4)return s[0]=t-i,s[1]=e-n,l[0]=t+i,void(l[1]=e+n);if(yS[0]=mS(o)*i+t,yS[1]=gS(o)*n+e,xS[0]=mS(a)*i+t,xS[1]=gS(a)*n+e,u(s,yS,xS),h(l,yS,xS),(o%=vS)<0&&(o+=vS),(a%=vS)<0&&(a+=vS),o>a&&!r?a+=vS:oo&&(_S[0]=mS(f)*i+t,_S[1]=gS(f)*n+e,u(s,_S,s),h(l,_S,l))}function yn(t,e,i,n,o,a,r){if(0===o)return!1;var s=o,l=0,u=t;if(r>e+s&&r>n+s||rt+s&&a>i+s||ae+c&&h>n+c&&h>a+c&&h>s+c||ht+c&&u>i+c&&u>o+c&&u>r+c||ue+u&&l>n+u&&l>a+u||lt+u&&s>i+u&&s>o+u||si||h+uo&&(o+=zS);var d=Math.atan2(l,s);return d<0&&(d+=zS),d>=n&&d<=o||d+zS>=n&&d+zS<=o}function Sn(t,e,i,n,o,a){if(a>e&&a>n||ao?r:0}function Mn(t,e){return Math.abs(t-e)e&&u>n&&u>a&&u>s||u1&&In(),c=tn(e,n,a,s,WS[0]),p>1&&(d=tn(e,n,a,s,WS[1]))),2===p?me&&s>n&&s>a||s=0&&u<=1){for(var h=0,c=sn(e,n,a,u),d=0;di||s<-i)return 0;u=Math.sqrt(i*i-s*s);FS[0]=-u,FS[1]=u;var l=Math.abs(n-o);if(l<1e-4)return 0;if(l%VS<1e-4){n=0,o=VS;p=a?1:-1;return r>=FS[0]+t&&r<=FS[1]+t?p:0}if(a){var u=n;n=wn(o),o=wn(u)}else n=wn(n),o=wn(o);n>o&&(o+=VS);for(var h=0,c=0;c<2;c++){var d=FS[c];if(d+t>r){var f=Math.atan2(s,d),p=a?1:-1;f<0&&(f=VS+f),(f>=n&&f<=o||f+VS>=n&&f+VS<=o)&&(f>Math.PI/2&&f<1.5*Math.PI&&(p=-p),h+=p)}}return h}function Cn(t,e,i,n,o){for(var a=0,r=0,s=0,l=0,u=0,h=0;h1&&(i||(a+=Sn(r,s,l,u,n,o))),1===h&&(l=r=t[h],u=s=t[h+1]),c){case BS.M:r=l=t[h++],s=u=t[h++];break;case BS.L:if(i){if(yn(r,s,t[h],t[h+1],e,n,o))return!0}else a+=Sn(r,s,t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.C:if(i){if(xn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=Tn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.Q:if(i){if(_n(r,s,t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=An(r,s,t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case BS.A:var d=t[h++],f=t[h++],p=t[h++],g=t[h++],m=t[h++],v=t[h++];h+=1;var y=1-t[h++],x=Math.cos(m)*p+d,_=Math.sin(m)*g+f;h>1?a+=Sn(r,s,x,_,n,o):(l=x,u=_);var w=(n-d)*g/p+d;if(i){if(bn(d,f,g,m,m+v,y,e,w,o))return!0}else a+=Dn(d,f,g,m,m+v,y,w,o);r=Math.cos(m+v)*p+d,s=Math.sin(m+v)*g+f;break;case BS.R:l=r=t[h++],u=s=t[h++];var x=l+t[h++],_=u+t[h++];if(i){if(yn(l,u,x,u,e,n,o)||yn(x,u,x,_,e,n,o)||yn(x,_,l,_,e,n,o)||yn(l,_,l,u,e,n,o))return!0}else a+=Sn(x,u,x,_,n,o),a+=Sn(l,_,l,u,n,o);break;case BS.Z:if(i){if(yn(r,s,l,u,e,n,o))return!0}else a+=Sn(r,s,l,u,n,o);r=l,s=u}}return i||Mn(s,u)||(a+=Sn(r,s,l,u,n,o)||0),0!==a}function Ln(t,e,i){return Cn(t,0,!1,e,i)}function kn(t,e,i,n){return Cn(t,e,!0,i,n)}function Pn(t){di.call(this,t),this.path=null}function Nn(t,e,i,n,o,a,r,s,l,u,h){var c=l*(tM/180),d=QS(c)*(t-i)/2+JS(c)*(e-n)/2,f=-1*JS(c)*(t-i)/2+QS(c)*(e-n)/2,p=d*d/(r*r)+f*f/(s*s);p>1&&(r*=$S(p),s*=$S(p));var g=(o===a?-1:1)*$S((r*r*(s*s)-r*r*(f*f)-s*s*(d*d))/(r*r*(f*f)+s*s*(d*d)))||0,m=g*r*f/s,v=g*-s*d/r,y=(t+i)/2+QS(c)*m-JS(c)*v,x=(e+n)/2+JS(c)*m+QS(c)*v,_=nM([1,0],[(d-m)/r,(f-v)/s]),w=[(d-m)/r,(f-v)/s],b=[(-1*d-m)/r,(-1*f-v)/s],S=nM(w,b);iM(w,b)<=-1&&(S=tM),iM(w,b)>=1&&(S=0),0===a&&S>0&&(S-=2*tM),1===a&&S<0&&(S+=2*tM),h.addData(u,y,x,r,s,_,S,c,a)}function On(t){if(!t)return new ES;for(var e,i=0,n=0,o=i,a=n,r=new ES,s=ES.CMD,l=t.match(oM),u=0;u=2){if(o&&"spline"!==o){var a=fM(n,o,i,e.smoothConstraint);t.moveTo(n[0][0],n[0][1]);for(var r=n.length,s=0;s<(i?r:r-1);s++){var l=a[2*s],u=a[2*s+1],h=n[(s+1)%r];t.bezierCurveTo(l[0],l[1],u[0],u[1],h[0],h[1])}}else{"spline"===o&&(n=dM(n,i)),t.moveTo(n[0][0],n[0][1]);for(var s=1,c=n.length;s=0)?(i={textFill:null,textStroke:t.textStroke,textStrokeWidth:t.textStrokeWidth},t.textFill="#fff",null==t.textStroke&&(t.textStroke=a,null==t.textStrokeWidth&&(t.textStrokeWidth=2))):null!=a&&(i={textFill:null},t.textFill=a),i&&(t.insideRollback=i)}}function bo(t){var e=t.insideRollback;e&&(t.textFill=e.textFill,t.textStroke=e.textStroke,t.textStrokeWidth=e.textStrokeWidth,t.insideRollback=null)}function So(t,e){var i=e||e.getModel("textStyle");return P([t.fontStyle||i&&i.getShallow("fontStyle")||"",t.fontWeight||i&&i.getShallow("fontWeight")||"",(t.fontSize||i&&i.getShallow("fontSize")||12)+"px",t.fontFamily||i&&i.getShallow("fontFamily")||"sans-serif"].join(" "))}function Mo(t,e,i,n,o,a){if("function"==typeof o&&(a=o,o=null),n&&n.isAnimationEnabled()){var r=t?"Update":"",s=n.getShallow("animationDuration"+r),l=n.getShallow("animationEasing"+r),u=n.getShallow("animationDelay"+r);"function"==typeof u&&(u=u(o,n.getAnimationDelayParams?n.getAnimationDelayParams(e,o):null)),"function"==typeof s&&(s=s(o)),s>0?e.animateTo(i,s,u||0,l,a,!!a):(e.stopAnimation(),e.attr(i),a&&a())}else e.stopAnimation(),e.attr(i),a&&a()}function Io(t,e,i,n,o){Mo(!0,t,e,i,n,o)}function To(t,e,i,n,o){Mo(!1,t,e,i,n,o)}function Ao(t,e){for(var i=_t([]);t&&t!==e;)bt(i,t.getLocalTransform(),i),t=t.parent;return i}function Do(t,e,i){return e&&!c(e)&&(e=Tw.getLocalTransform(e)),i&&(e=Tt([],e)),Q([],t,e)}function Co(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),o=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-o:"bottom"===t?o:0];return a=Do(a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?"bottom":"top"}function Lo(t,e,i,n){function o(t){var e={position:F(t.position),rotation:t.rotation};return t.shape&&(e.shape=a({},t.shape)),e}if(t&&e){var r=function(t){var e={};return t.traverse(function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}(t);e.traverse(function(t){if(!t.isGroup&&t.anid){var e=r[t.anid];if(e){var n=o(t);t.attr(o(e)),Io(t,n,i,t.dataIndex)}}})}}function ko(t,e){return f(t,function(t){var i=t[0];i=LM(i,e.x),i=kM(i,e.x+e.width);var n=t[1];return n=LM(n,e.y),n=kM(n,e.y+e.height),[i,n]})}function Po(t,e,i){var n=(e=a({rectHover:!0},e)).style={strokeNoScale:!0};if(i=i||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(n.image=t.slice(8),r(n,i),new fi(e)):Xn(t.replace("path://",""),e,i,"center")}function No(t,e,i){this.parentModel=e,this.ecModel=i,this.option=t}function Oo(t,e,i){for(var n=0;n0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/o*a+i[0]}function Vo(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?zo(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t}function Go(t,e,i){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),i?t:+t}function Fo(t){return t.sort(function(t,e){return t-e}),t}function Wo(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Ho(t){var e=t.toString(),i=e.indexOf("e");if(i>0){var n=+e.slice(i+1);return n<0?-n:0}var o=e.indexOf(".");return o<0?0:e.length-1-o}function Zo(t,e){var i=Math.log,n=Math.LN10,o=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n),r=Math.min(Math.max(-o+a,0),20);return isFinite(r)?r:20}function Uo(t,e,i){if(!t[e])return 0;var n=p(t,function(t,e){return t+(isNaN(e)?0:e)},0);if(0===n)return 0;for(var o=Math.pow(10,i),a=f(t,function(t){return(isNaN(t)?0:t)/n*o*100}),r=100*o,s=f(a,function(t){return Math.floor(t)}),l=p(s,function(t,e){return t+e},0),u=f(a,function(t,e){return t-s[e]});lh&&(h=u[d],c=d);++s[c],u[c]=0,++l}return s[e]/o}function Xo(t){var e=2*Math.PI;return(t%e+e)%e}function jo(t){return t>-UM&&t=-20?+t.toFixed(n<0?-n:0):t}function Jo(t){function e(t,i,n){return t.interval[n]=0}function ta(t){return isNaN(t)?"-":(t=(t+"").split("."))[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t.length>1?"."+t[1]:"")}function ea(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}function ia(t){return null==t?"":(t+"").replace(KM,function(t,e){return $M[e]})}function na(t,e,i){y(e)||(e=[e]);var n=e.length;if(!n)return"";for(var o=e[0].$vars||[],a=0;a':'':{renderMode:o,content:"{marker"+a+"|} ",style:{color:i}}:""}function ra(t,e){return t+="","0000".substr(0,e-t.length)+t}function sa(t,e,i){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var n=Yo(e),o=i?"UTC":"",a=n["get"+o+"FullYear"](),r=n["get"+o+"Month"]()+1,s=n["get"+o+"Date"](),l=n["get"+o+"Hours"](),u=n["get"+o+"Minutes"](),h=n["get"+o+"Seconds"](),c=n["get"+o+"Milliseconds"]();return t=t.replace("MM",ra(r,2)).replace("M",r).replace("yyyy",a).replace("yy",a%100).replace("dd",ra(s,2)).replace("d",s).replace("hh",ra(l,2)).replace("h",l).replace("mm",ra(u,2)).replace("m",u).replace("ss",ra(h,2)).replace("s",h).replace("SSS",ra(c,3))}function la(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t}function ua(t,e,i,n,o){var a=0,r=0;null==n&&(n=1/0),null==o&&(o=1/0);var s=0;e.eachChild(function(l,u){var h,c,d=l.position,f=l.getBoundingRect(),p=e.childAt(u+1),g=p&&p.getBoundingRect();if("horizontal"===t){var m=f.width+(g?-g.x+f.x:0);(h=a+m)>n||l.newline?(a=0,h=m,r+=s+i,s=f.height):s=Math.max(s,f.height)}else{var v=f.height+(g?-g.y+f.y:0);(c=r+v)>o||l.newline?(a+=s+i,r=0,c=v,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=a,d[1]=r,"horizontal"===t?a=h+i:r=c+i)})}function ha(t,e,i){var n=e.width,o=e.height,a=Vo(t.x,n),r=Vo(t.y,o),s=Vo(t.x2,n),l=Vo(t.y2,o);return(isNaN(a)||isNaN(parseFloat(t.x)))&&(a=0),(isNaN(s)||isNaN(parseFloat(t.x2)))&&(s=n),(isNaN(r)||isNaN(parseFloat(t.y)))&&(r=0),(isNaN(l)||isNaN(parseFloat(t.y2)))&&(l=o),i=qM(i||0),{width:Math.max(s-a-i[1]-i[3],0),height:Math.max(l-r-i[0]-i[2],0)}}function ca(t,e,i){i=qM(i||0);var n=e.width,o=e.height,a=Vo(t.left,n),r=Vo(t.top,o),s=Vo(t.right,n),l=Vo(t.bottom,o),u=Vo(t.width,n),h=Vo(t.height,o),c=i[2]+i[0],d=i[1]+i[3],f=t.aspect;switch(isNaN(u)&&(u=n-s-d-a),isNaN(h)&&(h=o-l-c-r),null!=f&&(isNaN(u)&&isNaN(h)&&(f>n/o?u=.8*n:h=.8*o),isNaN(u)&&(u=f*h),isNaN(h)&&(h=u/f)),isNaN(a)&&(a=n-s-u-d),isNaN(r)&&(r=o-l-h-c),t.left||t.right){case"center":a=n/2-u/2-i[3];break;case"right":a=n-u-d}switch(t.top||t.bottom){case"middle":case"center":r=o/2-h/2-i[0];break;case"bottom":r=o-h-c}a=a||0,r=r||0,isNaN(u)&&(u=n-d-a-(s||0)),isNaN(h)&&(h=o-c-r-(l||0));var p=new de(a+i[3],r+i[0],u,h);return p.margin=i,p}function da(t,e,i,n,o){var a=!o||!o.hv||o.hv[0],s=!o||!o.hv||o.hv[1],l=o&&o.boundingMode||"all";if(a||s){var u;if("raw"===l)u="group"===t.type?new de(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(u=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(u=u.clone()).applyTransform(h)}e=ca(r({width:u.width,height:u.height},e),i,n);var c=t.position,d=a?e.x-u.x:0,f=s?e.y-u.y:0;t.attr("position","raw"===l?[d,f]:[c[0]+d,c[1]+f])}}function fa(t,e){return null!=t[oI[e][0]]||null!=t[oI[e][1]]&&null!=t[oI[e][2]]}function pa(t,e,i){function n(i,n){var r={},l=0,u={},h=0;if(iI(i,function(e){u[e]=t[e]}),iI(i,function(t){o(e,t)&&(r[t]=u[t]=e[t]),a(r,t)&&l++,a(u,t)&&h++}),s[n])return a(e,i[1])?u[i[2]]=null:a(e,i[2])&&(u[i[1]]=null),u;if(2!==h&&l){if(l>=2)return r;for(var c=0;ce)return t[n];return t[i-1]}function ya(t){var e=t.get("coordinateSystem"),i={coordSysName:e,coordSysDims:[],axisMap:R(),categoryAxisMap:R()},n=fI[e];if(n)return n(t,i,i.axisMap,i.categoryAxisMap),i}function xa(t){return"category"===t.get("type")}function _a(t){this.fromDataset=t.fromDataset,this.data=t.data||(t.sourceFormat===vI?{}:[]),this.sourceFormat=t.sourceFormat||yI,this.seriesLayoutBy=t.seriesLayoutBy||_I,this.dimensionsDefine=t.dimensionsDefine,this.encodeDefine=t.encodeDefine&&R(t.encodeDefine),this.startIndex=t.startIndex||0,this.dimensionsDetectCount=t.dimensionsDetectCount}function wa(t){var e=t.option.source,i=yI;if(S(e))i=xI;else if(y(e)){0===e.length&&(i=gI);for(var n=0,o=e.length;n=e:"max"===i?t<=e:t===e}function Xa(t,e){return t.join(",")===e.join(",")}function ja(t,e){AI(e=e||{},function(e,i){if(null!=e){var n=t[i];if(lI.hasClass(i)){e=Di(e);var o=Pi(n=Di(n),e);t[i]=CI(o,function(t){return t.option&&t.exist?LI(t.exist,t.option,!0):t.exist||t.option})}else t[i]=LI(n,e,!0)}})}function Ya(t){var e=t&&t.itemStyle;if(e)for(var i=0,o=OI.length;i=0;p--){var g=t[p];if(s||(d=g.data.rawIndexOf(g.stackedByDimension,c)),d>=0){var m=g.data.getByRawIndex(g.stackResultDimension,d);if(h>=0&&m>0||h<=0&&m<0){h+=m,f=m;break}}}return n[0]=h,n[1]=f,n});r.hostModel.setData(l),e.data=l})}function rr(t,e){_a.isInstance(t)||(t=_a.seriesDataToSource(t)),this._source=t;var i=this._data=t.data,n=t.sourceFormat;n===xI&&(this._offset=0,this._dimSize=e,this._data=i),a(this,GI[n===gI?n+"_"+t.seriesLayoutBy:n])}function sr(){return this._data.length}function lr(t){return this._data[t]}function ur(t){for(var e=0;ee.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function Mr(t,e){d(t.CHANGABLE_METHODS,function(i){t.wrapMethod(i,v(Ir,e))})}function Ir(t){var e=Tr(t);e&&e.setOutputEnd(this.count())}function Tr(t){var e=(t.ecModel||{}).scheduler,i=e&&e.getPipeline(t.uid);if(i){var n=i.currentTask;if(n){var o=n.agentStubMap;o&&(n=o.get(t.uid))}return n}}function Ar(){this.group=new tb,this.uid=Ro("viewChart"),this.renderTask=gr({plan:Lr,reset:kr}),this.renderTask.context={view:this}}function Dr(t,e){if(t&&(t.trigger(e),"group"===t.type))for(var i=0;i=0?n():c=setTimeout(n,-a),u=o};return d.clear=function(){c&&(clearTimeout(c),c=null)},d.debounceNextCall=function(t){l=t},d}function Nr(t,e,i,n){var o=t[e];if(o){var a=o[iT]||o,r=o[oT];if(o[nT]!==i||r!==n){if(null==i||!n)return t[e]=a;(o=t[e]=Pr(a,i,"debounce"===n))[iT]=a,o[oT]=n,o[nT]=i}return o}}function Or(t,e){var i=t[e];i&&i[iT]&&(t[e]=i[iT])}function Er(t,e,i,n){this.ecInstance=t,this.api=e,this.unfinished;var i=this._dataProcessorHandlers=i.slice(),n=this._visualHandlers=n.slice();this._allHandlers=i.concat(n),this._stageTaskMap=R()}function Rr(t,e,i,n,o){function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}o=o||{};var r;d(e,function(e,s){if(!o.visualType||o.visualType===e.visualType){var l=t._stageTaskMap.get(e.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,d=h.agentStubMap;d.each(function(t){a(o,t)&&(t.dirty(),c=!0)}),c&&h.dirty(),hT(h,n);var f=t.getPerformArgs(h,o.block);d.each(function(t){t.perform(f)}),r|=h.perform(f)}else u&&u.each(function(s,l){a(o,s)&&s.dirty();var u=t.getPerformArgs(s,o.block);u.skip=!e.performRawSeries&&i.isSeriesFiltered(s.context.model),hT(s,n),r|=s.perform(u)})}}),t.unfinished|=r}function zr(t,e,i,n,o){function a(i){var a=i.uid,s=r.get(a)||r.set(a,gr({plan:Hr,reset:Zr,count:Xr}));s.context={model:i,ecModel:n,api:o,useClearVisual:e.isVisual&&!e.isLayout,plan:e.plan,reset:e.reset,scheduler:t},jr(t,i,s)}var r=i.seriesTaskMap||(i.seriesTaskMap=R()),s=e.seriesType,l=e.getTargetSeries;e.createOnAllSeries?n.eachRawSeries(a):s?n.eachRawSeriesByType(s,a):l&&l(n,o).each(a);var u=t._pipelineMap;r.each(function(t,e){u.get(e)||(t.dispose(),r.removeKey(e))})}function Br(t,e,i,n,o){function a(e){var i=e.uid,n=s.get(i);n||(n=s.set(i,gr({reset:Gr,onDirty:Wr})),r.dirty()),n.context={model:e,overallProgress:h,modifyOutputEnd:c},n.agent=r,n.__block=h,jr(t,e,n)}var r=i.overallTask=i.overallTask||gr({reset:Vr});r.context={ecModel:n,api:o,overallReset:e.overallReset,scheduler:t};var s=r.agentStubMap=r.agentStubMap||R(),l=e.seriesType,u=e.getTargetSeries,h=!0,c=e.modifyOutputEnd;l?n.eachRawSeriesByType(l,a):u?u(n,o).each(a):(h=!1,d(n.getSeries(),a));var f=t._pipelineMap;s.each(function(t,e){f.get(e)||(t.dispose(),r.dirty(),s.removeKey(e))})}function Vr(t){t.overallReset(t.ecModel,t.api,t.payload)}function Gr(t,e){return t.overallProgress&&Fr}function Fr(){this.agent.dirty(),this.getDownstream().dirty()}function Wr(){this.agent&&this.agent.dirty()}function Hr(t){return t.plan&&t.plan(t.model,t.ecModel,t.api,t.payload)}function Zr(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=Di(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?f(e,function(t,e){return Ur(e)}):cT}function Ur(t){return function(e,i){var n=i.data,o=i.resetDefines[t];if(o&&o.dataEach)for(var a=e.start;a0?parseInt(n,10)/100:n?parseFloat(n):0;var o=i.getAttribute("stop-color")||"#000000";e.addColorStop(n,o)}i=i.nextSibling}}function Qr(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),r(e.__inheritedStyle,t.__inheritedStyle))}function ts(t){for(var e=P(t).split(_T),i=[],n=0;n0;a-=2){var r=o[a],s=o[a-1];switch(n=n||xt(),s){case"translate":r=P(r).split(_T),St(n,n,[parseFloat(r[0]),parseFloat(r[1]||0)]);break;case"scale":r=P(r).split(_T),It(n,n,[parseFloat(r[0]),parseFloat(r[1]||r[0])]);break;case"rotate":r=P(r).split(_T),Mt(n,n,parseFloat(r[0]));break;case"skew":r=P(r).split(_T),console.warn("Skew transform is not supported yet");break;case"matrix":r=P(r).split(_T);n[0]=parseFloat(r[0]),n[1]=parseFloat(r[1]),n[2]=parseFloat(r[2]),n[3]=parseFloat(r[3]),n[4]=parseFloat(r[4]),n[5]=parseFloat(r[5])}}e.setLocalTransform(n)}}function os(t){var e=t.getAttribute("style"),i={};if(!e)return i;var n={};TT.lastIndex=0;for(var o;null!=(o=TT.exec(e));)n[o[1]]=o[2];for(var a in ST)ST.hasOwnProperty(a)&&null!=n[a]&&(i[ST[a]]=n[a]);return i}function as(t,e,i){var n=e/t.width,o=i/t.height,a=Math.min(n,o);return{scale:[a,a],position:[-(t.x+t.width/2)*a+e/2,-(t.y+t.height/2)*a+i/2]}}function rs(t,e){return(new $r).parse(t,e)}function ss(t){return function(e,i,n){e=e&&e.toLowerCase(),fw.prototype[t].call(this,e,i,n)}}function ls(){fw.call(this)}function us(t,e,n){function o(t,e){return t.__prio-e.__prio}n=n||{},"string"==typeof e&&(e=JT[e]),this.id,this.group,this._dom=t;var a=this._zr=Ii(t,{renderer:n.renderer||"canvas",devicePixelRatio:n.devicePixelRatio,width:n.width,height:n.height});this._throttledZrFlush=Pr(m(a.flush,a),17),(e=i(e))&&BI(e,!0),this._theme=e,this._chartsViews=[],this._chartsMap={},this._componentsViews=[],this._componentsMap={},this._coordSysMgr=new Fa;var r=this._api=As(this);_e($T,o),_e(YT,o),this._scheduler=new Er(this,r,YT,$T),fw.call(this,this._ecEventProcessor=new Ds),this._messageCenter=new ls,this._initEvents(),this.resize=m(this.resize,this),this._pendingActions=[],a.animation.on("frame",this._onframe,this),vs(a,this),N(this)}function hs(t,e,i){var n,o=this._model,a=this._coordSysMgr.getCoordinateSystems();e=Vi(o,e);for(var r=0;re.get("hoverLayerThreshold")&&!U_.node&&i.traverse(function(t){t.isGroup||(t.useHoverLayer=!0)})}function Is(t,e){var i=t.get("blendMode")||null;e.group.traverse(function(t){t.isGroup||t.style.blend!==i&&t.setStyle("blend",i),t.eachPendingDisplayable&&t.eachPendingDisplayable(function(t){t.setStyle("blend",i)})})}function Ts(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function As(t){var e=t._coordSysMgr;return a(new Ga(t),{getCoordinateSystems:m(e.getCoordinateSystems,e),getComponentByElement:function(e){for(;e;){var i=e.__ecComponentInfo;if(null!=i)return t._model.getComponent(i.mainType,i.index);e=e.parent}}})}function Ds(){this.eventInfo}function Cs(t){function e(t,e){for(var n=0;n65535?dA:pA}function Js(t){var e=t.constructor;return e===Array?t.slice():new e(t)}function Qs(t,e){d(gA.concat(e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods,d(mA,function(n){t[n]=i(e[n])}),t._calculationInfo=a(e._calculationInfo)}function tl(t,e,i,n,o){var a=cA[e.type],r=n-1,s=e.name,l=t[s][r];if(l&&l.length=0?this._indices[t]:-1}function al(t,e){var i=t._idList[e];return null==i&&(i=il(t,t._idDimIdx,e)),null==i&&(i=hA+e),i}function rl(t){return y(t)||(t=[t]),t}function sl(t,e){var i=t.dimensions,n=new vA(f(i,t.getDimensionInfo,t),t.hostModel);Qs(n,t);for(var o=n._storage={},a=t._storage,r=0;r=0?(o[s]=ll(a[s]),n._rawExtent[s]=ul(),n._extent[s]=null):o[s]=a[s])}return n}function ll(t){for(var e=new Array(t.length),i=0;in&&(r=o.interval=n);var s=o.intervalPrecision=Ml(r);return Tl(o.niceTickExtent=[MA(Math.ceil(t[0]/r)*r,s),MA(Math.floor(t[1]/r)*r,s)],t),o}function Ml(t){return Ho(t)+2}function Il(t,e,i){t[e]=Math.max(Math.min(t[e],i[1]),i[0])}function Tl(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),Il(t,0,e),Il(t,1,e),t[0]>t[1]&&(t[0]=t[1])}function Al(t,e,i,n){var o=[];if(!t)return o;e[0]1e4)return[];return e[1]>(o.length?o[o.length-1]:i[1])&&o.push(e[1]),o}function Dl(t){return t.get("stack")||AA+t.seriesIndex}function Cl(t){return t.dim+t.index}function Ll(t){var e=[],i=t.axis;if("category"===i.type){for(var n=i.getBandWidth(),o=0;o=0?"p":"n",b=m;p&&(o[r][_]||(o[r][_]={p:m,n:m}),b=o[r][_][w]);var S,M,I,T;if(g)S=b,M=(A=i.dataToPoint([x,_]))[1]+l,I=A[0]-m,T=u,Math.abs(I)a[1]?(n=a[1],o=a[0]):(n=a[0],o=a[1]);var r=e.toGlobalCoord(e.dataToCoord(0));return ro&&(r=o),r}function Vl(t,e){return VA(t,BA(e))}function Gl(t,e){var i,n,o,a=t.type,r=e.getMin(),s=e.getMax(),l=null!=r,u=null!=s,h=t.getExtent();"ordinal"===a?i=e.getCategories().length:(y(n=e.get("boundaryGap"))||(n=[n||0,n||0]),"boolean"==typeof n[0]&&(n=[0,0]),n[0]=Vo(n[0],1),n[1]=Vo(n[1],1),o=h[1]-h[0]||Math.abs(h[0])),null==r&&(r="ordinal"===a?i?0:NaN:h[0]-n[0]*o),null==s&&(s="ordinal"===a?i?i-1:NaN:h[1]+n[1]*o),"dataMin"===r?r=h[0]:"function"==typeof r&&(r=r({min:h[0],max:h[1]})),"dataMax"===s?s=h[1]:"function"==typeof s&&(s=s({min:h[0],max:h[1]})),(null==r||!isFinite(r))&&(r=NaN),(null==s||!isFinite(s))&&(s=NaN),t.setBlank(I(r)||I(s)||"ordinal"===a&&!t.getOrdinalMeta().categories.length),e.getNeedCrossZero()&&(r>0&&s>0&&!l&&(r=0),r<0&&s<0&&!u&&(s=0));var c=e.ecModel;if(c&&"time"===a){var f,p=kl("bar",c);if(d(p,function(t){f|=t.getBaseAxis()===e.axis}),f){var g=Pl(p),m=Fl(r,s,e,g);r=m.min,s=m.max}}return[r,s]}function Fl(t,e,i,n){var o=i.axis.getExtent(),a=o[1]-o[0],r=Ol(n,i.axis);if(void 0===r)return{min:t,max:e};var s=1/0;d(r,function(t){s=Math.min(t.offset,s)});var l=-1/0;d(r,function(t){l=Math.max(t.offset+t.width,l)}),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/a)-h;return e+=c*(l/u),t-=c*(s/u),{min:t,max:e}}function Wl(t,e){var i=Gl(t,e),n=null!=e.getMin(),o=null!=e.getMax(),a=e.get("splitNumber");"log"===t.type&&(t.base=e.get("logBase"));var r=t.type;t.setExtent(i[0],i[1]),t.niceExtent({splitNumber:a,fixMin:n,fixMax:o,minInterval:"interval"===r||"time"===r?e.get("minInterval"):null,maxInterval:"interval"===r||"time"===r?e.get("maxInterval"):null});var s=e.get("interval");null!=s&&t.setInterval&&t.setInterval(s)}function Hl(t,e){if(e=e||t.get("type"))switch(e){case"category":return new SA(t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),[1/0,-1/0]);case"value":return new TA;default:return(xl.getClass(e)||TA).create(t)}}function Zl(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(i>0&&n>0||i<0&&n<0)}function Ul(t){var e=t.getLabelModel().get("formatter"),i="category"===t.type?t.scale.getExtent()[0]:null;return"string"==typeof e?e=function(e){return function(i){return i=t.scale.getLabel(i),e.replace("{value}",null!=i?i:"")}}(e):"function"==typeof e?function(n,o){return null!=i&&(o=n-i),e(Xl(t,n),o)}:function(e){return t.scale.getLabel(e)}}function Xl(t,e){return"category"===t.type?t.scale.getLabel(e):e}function jl(t){var e=t.model,i=t.scale;if(e.get("axisLabel.show")&&!i.isBlank()){var n,o,a="category"===t.type,r=i.getExtent();o=a?i.count():(n=i.getTicks()).length;var s,l=t.getLabelModel(),u=Ul(t),h=1;o>40&&(h=Math.ceil(o/40));for(var c=0;c>1^-(1&s),l=l>>1^-(1&l),o=s+=o,a=l+=a,n.push([s/i,l/i])}return n}function ou(t){return"category"===t.type?ru(t):uu(t)}function au(t,e){return"category"===t.type?lu(t,e):{ticks:t.scale.getTicks()}}function ru(t){var e=t.getLabelModel(),i=su(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:i.labelCategoryInterval}:i}function su(t,e){var i=hu(t,"labels"),n=ql(e),o=cu(i,n);if(o)return o;var a,r;return a=x(n)?vu(t,n):mu(t,r="auto"===n?fu(t):n),du(i,n,{labels:a,labelCategoryInterval:r})}function lu(t,e){var i=hu(t,"ticks"),n=ql(e),o=cu(i,n);if(o)return o;var a,r;if(e.get("show")&&!t.scale.isBlank()||(a=[]),x(n))a=vu(t,n,!0);else if("auto"===n){var s=su(t,t.getLabelModel());r=s.labelCategoryInterval,a=f(s.labels,function(t){return t.tickValue})}else a=mu(t,r=n,!0);return du(i,n,{ticks:a,tickCategoryInterval:r})}function uu(t){var e=t.scale.getTicks(),i=Ul(t);return{labels:f(e,function(e,n){return{formattedLabel:i(e,n),rawLabel:t.scale.getLabel(e),tickValue:e}})}}function hu(t,e){return nD(t)[e]||(nD(t)[e]=[])}function cu(t,e){for(var i=0;i40&&(s=Math.max(1,Math.floor(r/40)));for(var l=a[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(n)),c=Math.abs(u*Math.sin(n)),d=0,f=0;l<=a[1];l+=s){var p=0,g=0,m=ke(i(l),e.font,"center","top");p=1.3*m.width,g=1.3*m.height,d=Math.max(d,p,7),f=Math.max(f,g,7)}var v=d/h,y=f/c;isNaN(v)&&(v=1/0),isNaN(y)&&(y=1/0);var x=Math.max(0,Math.floor(Math.min(v,y))),_=nD(t.model),w=_.lastAutoInterval,b=_.lastTickCount;return null!=w&&null!=b&&Math.abs(w-x)<=1&&Math.abs(b-r)<=1&&w>x?x=w:(_.lastTickCount=r,_.lastAutoInterval=x),x}function gu(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}function mu(t,e,i){function n(t){l.push(i?t:{formattedLabel:o(t),rawLabel:a.getLabel(t),tickValue:t})}var o=Ul(t),a=t.scale,r=a.getExtent(),s=t.getLabelModel(),l=[],u=Math.max((e||0)+1,1),h=r[0],c=a.count();0!==h&&u>1&&c/u>2&&(h=Math.round(Math.ceil(h/u)*u));var d=Kl(t),f=s.get("showMinLabel")||d,p=s.get("showMaxLabel")||d;f&&h!==r[0]&&n(r[0]);for(var g=h;g<=r[1];g+=u)n(g);return p&&g!==r[1]&&n(r[1]),l}function vu(t,e,i){var n=t.scale,o=Ul(t),a=[];return d(n.getTicks(),function(t){var r=n.getLabel(t);e(t,r)&&a.push(i?t:{formattedLabel:o(t),rawLabel:r,tickValue:t})}),a}function yu(t,e){var i=(t[1]-t[0])/e/2;t[0]+=i,t[1]-=i}function xu(t,e,i,n,o){function a(t,e){return h?t>e:t0&&(t.coord-=u/(2*(e+1)))}),s={coord:e[r-1].coord+u},e.push(s)}var h=l[0]>l[1];a(e[0].coord,l[0])&&(o?e[0].coord=l[0]:e.shift()),o&&a(l[0],e[0].coord)&&e.unshift({coord:l[0]}),a(l[1],s.coord)&&(o?s.coord=l[1]:e.pop()),o&&a(s.coord,l[1])&&e.push({coord:l[1]})}}function _u(t,e){var i=t.mapDimension("defaultedLabel",!0),n=i.length;if(1===n)return fr(t,e,i[0]);if(n){for(var o=[],a=0;a0?i=n[0]:n[1]<0&&(i=n[1]),i}function Ou(t,e,i,n){var o=NaN;t.stacked&&(o=i.get(i.getCalculationInfo("stackedOverDimension"),n)),isNaN(o)&&(o=t.valueStart);var a=t.baseDataOffset,r=[];return r[a]=i.get(t.baseDim,n),r[1-a]=o,e.dataToPoint(r)}function Eu(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}function Ru(t){return isNaN(t[0])||isNaN(t[1])}function zu(t,e,i,n,o,a,r,s,l,u,h){return"none"!==u&&u?Bu.apply(this,arguments):Vu.apply(this,arguments)}function Bu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(Ru(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]);else if(l>0){var g=e[c],m="y"===u?1:0,v=(p[m]-g[m])*l;_D(bD,g),bD[m]=g[m]+v,_D(SD,p),SD[m]=p[m]-v,t.bezierCurveTo(bD[0],bD[1],SD[0],SD[1],p[0],p[1])}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function Vu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(Ru(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]),_D(bD,p);else if(l>0){var g=d+a,m=e[g];if(h)for(;m&&Ru(e[g]);)m=e[g+=a];var v=.5,y=e[c];if(!(m=e[g])||Ru(m))_D(SD,p);else{Ru(m)&&!h&&(m=p),U(wD,m,y);var x,_;if("x"===u||"y"===u){var w="x"===u?0:1;x=Math.abs(p[w]-y[w]),_=Math.abs(p[w]-m[w])}else x=uw(p,y),_=uw(p,m);xD(SD,p,wD,-l*(1-(v=_/(_+x))))}vD(bD,bD,s),yD(bD,bD,r),vD(SD,SD,s),yD(SD,SD,r),t.bezierCurveTo(bD[0],bD[1],SD[0],SD[1],p[0],p[1]),xD(bD,p,wD,l*v)}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function Gu(t,e){var i=[1/0,1/0],n=[-1/0,-1/0];if(e)for(var o=0;on[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}function Fu(t,e){if(t.length===e.length){for(var i=0;ie[0]?1:-1;e[0]+=n*i,e[1]-=n*i}return e}function Zu(t,e,i){if(!i.valueDim)return[];for(var n=[],o=0,a=e.count();oa[1]&&a.reverse();var r=o.getExtent(),s=Math.PI/180;i&&(a[0]-=.5,a[1]+=.5);var l=new hM({shape:{cx:Go(t.cx,1),cy:Go(t.cy,1),r0:Go(a[0],1),r:Go(a[1],1),startAngle:-r[0]*s,endAngle:-r[1]*s,clockwise:o.inverse}});return e&&(l.shape.endAngle=-r[0]*s,To(l,{shape:{endAngle:-r[1]*s}},n)),l}function ju(t,e,i,n){return"polar"===t.type?Xu(t,e,i,n):Uu(t,e,i,n)}function Yu(t,e,i){for(var n=e.getBaseAxis(),o="x"===n.dim||"radius"===n.dim?0:1,a=[],r=0;r=0;a--){var r=i[a].dimension,s=t.dimensions[r],l=t.getDimensionInfo(s);if("x"===(n=l&&l.coordDim)||"y"===n){o=i[a];break}}if(o){var u=e.getAxis(n),h=f(o.stops,function(t){return{coord:u.toGlobalCoord(u.dataToCoord(t.value)),color:t.color}}),c=h.length,p=o.outerColors.slice();c&&h[0].coord>h[c-1].coord&&(h.reverse(),p.reverse());var g=h[0].coord-10,m=h[c-1].coord+10,v=m-g;if(v<.001)return"transparent";d(h,function(t){t.offset=(t.coord-g)/v}),h.push({offset:c?h[c-1].offset:.5,color:p[1]||"transparent"}),h.unshift({offset:c?h[0].offset:.5,color:p[0]||"transparent"});var y=new TM(0,0,0,0,h,!0);return y[n]=g,y[n+"2"]=m,y}}}function Ku(t,e,i){var n=t.get("showAllSymbol"),o="auto"===n;if(!n||o){var a=i.getAxesByScale("ordinal")[0];if(a&&(!o||!$u(a,e))){var r=e.mapDimension(a.dim),s={};return d(a.getViewLabels(),function(t){s[t.tickValue]=1}),function(t){return!s.hasOwnProperty(e.get(r,t))}}}}function $u(t,e){var i=t.getExtent(),n=Math.abs(i[1]-i[0])/t.scale.count();isNaN(n)&&(n=0);for(var o=e.count(),a=Math.max(1,Math.round(o/5)),r=0;rn)return!1;return!0}function Ju(t){return this._axes[t]}function Qu(t){LD.call(this,t)}function th(t,e){return e.type||(e.data?"category":"value")}function eh(t,e,i){return t.getCoordSysModel()===e}function ih(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this.model=t}function nh(t,e,i,n){function o(t){return t.dim+"_"+t.index}i.getAxesOnZeroOf=function(){return a?[a]:[]};var a,r=t[e],s=i.model,l=s.get("axisLine.onZero"),u=s.get("axisLine.onZeroAxisIndex");if(l){if(null!=u)oh(r[u])&&(a=r[u]);else for(var h in r)if(r.hasOwnProperty(h)&&oh(r[h])&&!n[o(r[h])]){a=r[h];break}a&&(n[o(a)]=!0)}}function oh(t){return t&&"category"!==t.type&&"time"!==t.type&&Zl(t)}function ah(t,e){var i=t.getExtent(),n=i[0]+i[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return n-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return n-t+e}}function rh(t,e){return f(VD,function(e){return t.getReferringComponents(e)[0]})}function sh(t){return"cartesian2d"===t.get("coordinateSystem")}function lh(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e}function uh(t,e,i,n){var o,a,r=Xo(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return jo(r-GD/2)?(a=l?"bottom":"top",o="center"):jo(r-1.5*GD)?(a=l?"top":"bottom",o="center"):(a="middle",o=r<1.5*GD&&r>GD/2?l?"left":"right":l?"right":"left"),{rotation:r,textAlign:o,textVerticalAlign:a}}function hh(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)}function ch(t,e,i){if(!Kl(t.axis)){var n=t.get("axisLabel.showMinLabel"),o=t.get("axisLabel.showMaxLabel");e=e||[],i=i||[];var a=e[0],r=e[1],s=e[e.length-1],l=e[e.length-2],u=i[0],h=i[1],c=i[i.length-1],d=i[i.length-2];!1===n?(dh(a),dh(u)):fh(a,r)&&(n?(dh(r),dh(h)):(dh(a),dh(u))),!1===o?(dh(s),dh(c)):fh(l,s)&&(o?(dh(l),dh(d)):(dh(s),dh(c)))}}function dh(t){t&&(t.ignore=!0)}function fh(t,e,i){var n=t&&t.getBoundingRect().clone(),o=e&&e.getBoundingRect().clone();if(n&&o){var a=_t([]);return Mt(a,a,-t.rotation),n.applyTransform(bt([],a,t.getLocalTransform())),o.applyTransform(bt([],a,e.getLocalTransform())),n.intersect(o)}}function ph(t){return"middle"===t||"center"===t}function gh(t,e,i){var n=e.axis;if(e.get("axisTick.show")&&!n.scale.isBlank()){for(var o=e.getModel("axisTick"),a=o.getModel("lineStyle"),s=o.get("length"),l=n.getTicksCoords(),u=[],h=[],c=t._transform,d=[],f=0;f=0||t===e}function Sh(t){var e=Mh(t);if(e){var i=e.axisPointerModel,n=e.axis.scale,o=i.option,a=i.get("status"),r=i.get("value");null!=r&&(r=n.parse(r));var s=Th(i);null==a&&(o.status=s?"show":"hide");var l=n.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==r||r>l[1])&&(r=l[1]),r0?"bottom":"top":o.width>0?"left":"right";l||kh(t.style,d,n,u,a,i,p),fo(t,d)}function Rh(t,e){var i=t.get(tC)||0;return Math.min(i,Math.abs(e.width),Math.abs(e.height))}function zh(t,e,i){var n=t.getData(),o=[],a=n.getLayout("valueAxisHorizontal")?1:0;o[1-a]=n.getLayout("valueAxisStart");var r=new nC({shape:{points:n.getLayout("largePoints")},incremental:!!i,__startPoint:o,__valueIdx:a});e.add(r),Bh(r,t,n)}function Bh(t,e,i){var n=i.getVisual("borderColor")||i.getVisual("color"),o=e.getModel("itemStyle").getItemStyle(["color","borderColor"]);t.useStyle(o),t.style.fill=null,t.style.stroke=n,t.style.lineWidth=i.getLayout("barWidth")}function Vh(t,e,i,n){var o=e.getData(),a=this.dataIndex,r=o.getName(a),s=e.get("selectedOffset");n.dispatchAction({type:"pieToggleSelect",from:t,name:r,seriesId:e.id}),o.each(function(t){Gh(o.getItemGraphicEl(t),o.getItemLayout(t),e.isSelected(o.getName(t)),s,i)})}function Gh(t,e,i,n,o){var a=(e.startAngle+e.endAngle)/2,r=Math.cos(a),s=Math.sin(a),l=i?n:0,u=[r*l,s*l];o?t.animate().when(200,{position:u}).start("bounceOut"):t.attr("position",u)}function Fh(t,e){function i(){a.ignore=a.hoverIgnore,r.ignore=r.hoverIgnore}function n(){a.ignore=a.normalIgnore,r.ignore=r.normalIgnore}tb.call(this);var o=new hM({z2:2}),a=new gM,r=new rM;this.add(o),this.add(a),this.add(r),this.updateData(t,e,!0),this.on("emphasis",i).on("normal",n).on("mouseover",i).on("mouseout",n)}function Wh(t,e,i,n,o,a,r){function s(e,i){for(var n=e;n>=0&&(t[n].y-=i,!(n>0&&t[n].y>t[n-1].y+t[n-1].height));n--);}function l(t,e,i,n,o,a){for(var r=e?Number.MAX_VALUE:0,s=0,l=t.length;s=r&&(d=r-10),!e&&d<=r&&(d=r+10),t[s].x=i+d*a,r=d}}t.sort(function(t,e){return t.y-e.y});for(var u,h=0,c=t.length,d=[],f=[],p=0;pe&&a+1t[a].y+t[a].height)return void s(a,n/2);s(i-1,n/2)}(p,c,-u),h=t[p].y+t[p].height;r-h<0&&s(c-1,h-r);for(p=0;p=i?f.push(t[p]):d.push(t[p]);l(d,!1,e,i,n,o),l(f,!0,e,i,n,o)}function Hh(t,e,i,n,o,a){for(var r=[],s=[],l=0;l3?1.4:o>1?1.2:1.1;hc(this,"zoom","zoomOnMouseWheel",t,{scale:n>0?s:1/s,originX:a,originY:r})}if(i){var l=Math.abs(n);hc(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:(n>0?1:-1)*(l>3?.4:l>1?.15:.05),originX:a,originY:r})}}}function uc(t){ic(this._zr,"globalPan")||hc(this,"zoom",null,t,{scale:t.pinchScale>1?1.1:1/1.1,originX:t.pinchX,originY:t.pinchY})}function hc(t,e,i,n,o){t.pointerChecker&&t.pointerChecker(n,o.originX,o.originY)&&(mw(n.event),cc(t,e,i,n,o))}function cc(t,e,i,n,o){o.isAvailableBehavior=m(dc,null,i,n),t.trigger(e,o)}function dc(t,e,i){var n=i[t];return!t||n&&(!_(n)||e.event[n+"Key"])}function fc(t,e,i){var n=t.target,o=n.position;o[0]+=e,o[1]+=i,n.dirty()}function pc(t,e,i,n){var o=t.target,a=t.zoomLimit,r=o.position,s=o.scale,l=t.zoom=t.zoom||1;if(l*=e,a){var u=a.min||0,h=a.max||1/0;l=Math.max(Math.min(h,l),u)}var c=l/t.zoom;t.zoom=l,r[0]-=(i-r[0])*(c-1),r[1]-=(n-r[1])*(c-1),s[0]*=c,s[1]*=c,o.dirty()}function gc(t,e,i){var n=e.getComponentByElement(t.topTarget),o=n&&n.coordinateSystem;return n&&n!==i&&!RC[n.mainType]&&o&&o.model!==i}function mc(t,e){var i=t.getItemStyle(),n=t.get("areaColor");return null!=n&&(i.fill=n),i}function vc(t,e,i,n,o){i.off("click"),i.off("mousedown"),e.get("selectedMode")&&(i.on("mousedown",function(){t._mouseDownFlag=!0}),i.on("click",function(a){if(t._mouseDownFlag){t._mouseDownFlag=!1;for(var r=a.target;!r.__regions;)r=r.parent;if(r){var s={type:("geo"===e.mainType?"geo":"map")+"ToggleSelect",batch:f(r.__regions,function(t){return{name:t.name,from:o.uid}})};s[e.mainType+"Id"]=e.id,n.dispatchAction(s),yc(e,i)}}}))}function yc(t,e){e.eachChild(function(e){d(e.__regions,function(i){e.trigger(t.isSelected(i.name)?"emphasis":"normal")})})}function xc(t,e){var i=new tb;this.uid=Ro("ec_map_draw"),this._controller=new oc(t.getZr()),this._controllerHost={target:e?i:null},this.group=i,this._updateGroup=e,this._mouseDownFlag,this._mapName,this._initialized,i.add(this._regionsGroup=new tb),i.add(this._backgroundGroup=new tb)}function _c(t){var e=this[zC];e&&e.recordVersion===this[BC]&&wc(e,t)}function wc(t,e){var i=t.circle,n=t.labelModel,o=t.hoverLabelModel,a=t.emphasisText,r=t.normalText;e?(i.style.extendFrom(mo({},o,{text:o.get("show")?a:null},{isRectText:!0,useInsideStyle:!1},!0)),i.__mapOriginalZ2=i.z2,i.z2+=NM):(mo(i.style,n,{text:n.get("show")?r:null,textPosition:n.getShallow("position")||"bottom"},{isRectText:!0,useInsideStyle:!1}),i.dirty(!1),null!=i.__mapOriginalZ2&&(i.z2=i.__mapOriginalZ2,i.__mapOriginalZ2=null))}function bc(t,e,i){var n=t.getZoom(),o=t.getCenter(),a=e.zoom,r=t.dataToPoint(o);if(null!=e.dx&&null!=e.dy){r[0]-=e.dx,r[1]-=e.dy;o=t.pointToData(r);t.setCenter(o)}if(null!=a){if(i){var s=i.min||0,l=i.max||1/0;a=Math.max(Math.min(n*a,l),s)/n}t.scale[0]*=a,t.scale[1]*=a;var u=t.position,h=(e.originX-u[0])*(a-1),c=(e.originY-u[1])*(a-1);u[0]-=h,u[1]-=c,t.updateTransform();o=t.pointToData(r);t.setCenter(o),t.setZoom(a*n)}return{center:t.getCenter(),zoom:t.getZoom()}}function Sc(){Tw.call(this)}function Mc(t){this.name=t,this.zoomLimit,Tw.call(this),this._roamTransformable=new Sc,this._rawTransformable=new Sc,this._center,this._zoom}function Ic(t,e,i,n){var o=i.seriesModel,a=o?o.coordinateSystem:null;return a===this?a[t](n):null}function Tc(t,e,i,n){Mc.call(this,t),this.map=e;var o=OC.load(e,i);this._nameCoordMap=o.nameCoordMap,this._regionsMap=o.regionsMap,this._invertLongitute=null==n||n,this.regions=o.regions,this._rect=o.boundingRect}function Ac(t,e,i,n){var o=i.geoModel,a=i.seriesModel,r=o?o.coordinateSystem:a?a.coordinateSystem||(a.getReferringComponents("geo")[0]||{}).coordinateSystem:null;return r===this?r[t](n):null}function Dc(t,e){var i=t.get("boundingCoords");if(null!=i){var n=i[0],o=i[1];isNaN(n[0])||isNaN(n[1])||isNaN(o[0])||isNaN(o[1])||this.setBoundingRect(n[0],n[1],o[0]-n[0],o[1]-n[1])}var a,r=this.getBoundingRect(),s=t.get("layoutCenter"),l=t.get("layoutSize"),u=e.getWidth(),h=e.getHeight(),c=r.width/r.height*this.aspectScale,d=!1;s&&l&&(s=[Vo(s[0],u),Vo(s[1],h)],l=Vo(l,Math.min(u,h)),isNaN(s[0])||isNaN(s[1])||isNaN(l)||(d=!0));if(d){var f={};c>1?(f.width=l,f.height=l/c):(f.height=l,f.width=l*c),f.y=s[1]-f.height/2,f.x=s[0]-f.width/2}else(a=t.getBoxLayoutParams()).aspect=c,f=ca(a,{width:u,height:h});this.setViewRect(f.x,f.y,f.width,f.height),this.setCenter(t.get("center")),this.setZoom(t.get("zoom"))}function Cc(t,e){d(e.get("geoCoord"),function(e,i){t.addGeoCoord(i,e)})}function Lc(t,e){var i={};return d(t,function(t){t.each(t.mapDimension("value"),function(e,n){var o="ec-"+t.getName(n);i[o]=i[o]||[],isNaN(e)||i[o].push(e)})}),t[0].map(t[0].mapDimension("value"),function(n,o){for(var a="ec-"+t[0].getName(o),r=0,s=1/0,l=-1/0,u=i[a].length,h=0;h=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},n.push(a)}}function Wc(t,e){var i=t.isExpand?t.children:[],n=t.parentNode.children,o=t.hierNode.i?n[t.hierNode.i-1]:null;if(i.length){jc(t);var a=(i[0].hierNode.prelim+i[i.length-1].hierNode.prelim)/2;o?(t.hierNode.prelim=o.hierNode.prelim+e(t,o),t.hierNode.modifier=t.hierNode.prelim-a):t.hierNode.prelim=a}else o&&(t.hierNode.prelim=o.hierNode.prelim+e(t,o));t.parentNode.hierNode.defaultAncestor=Yc(t,o,t.parentNode.hierNode.defaultAncestor||n[0],e)}function Hc(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function Zc(t){return arguments.length?t:Qc}function Uc(t,e){var i={};return t-=Math.PI/2,i.x=e*Math.cos(t),i.y=e*Math.sin(t),i}function Xc(t,e){return ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function jc(t){for(var e=t.children,i=e.length,n=0,o=0;--i>=0;){var a=e[i];a.hierNode.prelim+=n,a.hierNode.modifier+=n,o+=a.hierNode.change,n+=a.hierNode.shift+o}}function Yc(t,e,i,n){if(e){for(var o=t,a=t,r=a.parentNode.children[0],s=e,l=o.hierNode.modifier,u=a.hierNode.modifier,h=r.hierNode.modifier,c=s.hierNode.modifier;s=qc(s),a=Kc(a),s&&a;){o=qc(o),r=Kc(r),o.hierNode.ancestor=t;var d=s.hierNode.prelim+c-a.hierNode.prelim-u+n(s,a);d>0&&(Jc($c(s,t,i),t,d),u+=d,l+=d),c+=s.hierNode.modifier,u+=a.hierNode.modifier,l+=o.hierNode.modifier,h+=r.hierNode.modifier}s&&!qc(o)&&(o.hierNode.thread=s,o.hierNode.modifier+=c-l),a&&!Kc(r)&&(r.hierNode.thread=a,r.hierNode.modifier+=u-h,i=t)}return i}function qc(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function Kc(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function $c(t,e,i){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:i}function Jc(t,e,i){var n=i/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=n,e.hierNode.shift+=i,e.hierNode.modifier+=i,e.hierNode.prelim+=i,t.hierNode.change+=n}function Qc(t,e){return t.parentNode===e.parentNode?1:2}function td(t,e){var i=t.getItemLayout(e);return i&&!isNaN(i.x)&&!isNaN(i.y)&&"none"!==t.getItemVisual(e,"symbol")}function ed(t,e,i){return i.itemModel=e,i.itemStyle=e.getModel("itemStyle").getItemStyle(),i.hoverItemStyle=e.getModel("emphasis.itemStyle").getItemStyle(),i.lineStyle=e.getModel("lineStyle").getLineStyle(),i.labelModel=e.getModel("label"),i.hoverLabelModel=e.getModel("emphasis.label"),!1===t.isExpand&&0!==t.children.length?i.symbolInnerColor=i.itemStyle.fill:i.symbolInnerColor="#fff",i}function id(t,e,i,n,o,a){var s=!i,l=t.tree.getNodeByDataIndex(e),a=ed(l,l.getModel(),a),u=t.tree.root,h=l.parentNode===u?l:l.parentNode||l,c=t.getItemGraphicEl(h.dataIndex),d=h.getLayout(),f=c?{x:c.position[0],y:c.position[1],rawX:c.__radialOldRawX,rawY:c.__radialOldRawY}:d,p=l.getLayout();s?(i=new wu(t,e,a)).attr("position",[f.x,f.y]):i.updateData(t,e,a),i.__radialOldRawX=i.__radialRawX,i.__radialOldRawY=i.__radialRawY,i.__radialRawX=p.rawX,i.__radialRawY=p.rawY,n.add(i),t.setItemGraphicEl(e,i),Io(i,{position:[p.x,p.y]},o);var g=i.getSymbolPath();if("radial"===a.layout){var m,v,y=u.children[0],x=y.getLayout(),_=y.children.length;if(p.x===x.x&&!0===l.isExpand){var w={};w.x=(y.children[0].getLayout().x+y.children[_-1].getLayout().x)/2,w.y=(y.children[0].getLayout().y+y.children[_-1].getLayout().y)/2,(m=Math.atan2(w.y-x.y,w.x-x.x))<0&&(m=2*Math.PI+m),(v=w.xx.x)||(m-=Math.PI);var b=v?"left":"right";g.setStyle({textPosition:b,textRotation:-m,textOrigin:"center",verticalAlign:"middle"})}if(l.parentNode&&l.parentNode!==u){var S=i.__edge;S||(S=i.__edge=new bM({shape:od(a,f,f),style:r({opacity:0,strokeNoScale:!0},a.lineStyle)})),Io(S,{shape:od(a,d,p),style:{opacity:1}},o),n.add(S)}}function nd(t,e,i,n,o,a){for(var r,s=t.tree.getNodeByDataIndex(e),l=t.tree.root,a=ed(s,s.getModel(),a),u=s.parentNode===l?s:s.parentNode||s;null==(r=u.getLayout());)u=u.parentNode===l?u:u.parentNode||u;Io(i,{position:[r.x+1,r.y+1]},o,function(){n.remove(i),t.setItemGraphicEl(e,null)}),i.fadeOut(null,{keepLabel:!0});var h=i.__edge;h&&Io(h,{shape:od(a,r,r),style:{opacity:0}},o,function(){n.remove(h)})}function od(t,e,i){var n,o,a,r,s,l,u,h,c=t.orient;if("radial"===t.layout){s=e.rawX,u=e.rawY,l=i.rawX,h=i.rawY;var d=Uc(s,u),f=Uc(s,u+(h-u)*t.curvature),p=Uc(l,h+(u-h)*t.curvature),g=Uc(l,h);return{x1:d.x,y1:d.y,x2:g.x,y2:g.y,cpx1:f.x,cpy1:f.y,cpx2:p.x,cpy2:p.y}}return s=e.x,u=e.y,l=i.x,h=i.y,"LR"!==c&&"RL"!==c||(n=s+(l-s)*t.curvature,o=u,a=l+(s-l)*t.curvature,r=h),"TB"!==c&&"BT"!==c||(n=s,o=u+(h-u)*t.curvature,a=l,r=h+(u-h)*t.curvature),{x1:s,y1:u,x2:l,y2:h,cpx1:n,cpy1:o,cpx2:a,cpy2:r}}function ad(t,e,i){for(var n,o=[t],a=[];n=o.pop();)if(a.push(n),n.isExpand){var r=n.children;if(r.length)for(var s=0;s=0;a--)n.push(o[a])}}function sd(t,e){var i=Xc(t,e);t.layoutInfo=i;var n=t.get("layout"),o=0,a=0,r=null;"radial"===n?(o=2*Math.PI,a=Math.min(i.height,i.width)/2,r=Zc(function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth})):(o=i.width,a=i.height,r=Zc());var s=t.getData().tree.root,l=s.children[0];if(l){Fc(s),ad(l,Wc,r),s.hierNode.modifier=-l.hierNode.prelim,rd(l,Hc);var u=l,h=l,c=l;rd(l,function(t){var e=t.getLayout().x;eh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)});var d=u===h?1:r(u,h)/2,f=d-u.getLayout().x,p=0,g=0,m=0,v=0;if("radial"===n)p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),rd(l,function(t){m=(t.getLayout().x+f)*p,v=(t.depth-1)*g;var e=Uc(m,v);t.setLayout({x:e.x,y:e.y,rawX:m,rawY:v},!0)});else{var y=t.getOrient();"RL"===y||"LR"===y?(g=a/(h.getLayout().x+d+f),p=o/(c.depth-1||1),rd(l,function(t){v=(t.getLayout().x+f)*g,m="LR"===y?(t.depth-1)*p:o-(t.depth-1)*p,t.setLayout({x:m,y:v},!0)})):"TB"!==y&&"BT"!==y||(p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),rd(l,function(t){m=(t.getLayout().x+f)*p,v="TB"===y?(t.depth-1)*g:a-(t.depth-1)*g,t.setLayout({x:m,y:v},!0)}))}}}function ld(t,e,i){if(t&&l(e,t.type)>=0){var n=i.getData().tree.root,o=t.targetNode;if("string"==typeof o&&(o=n.getNodeById(o)),o&&n.contains(o))return{node:o};var a=t.targetNodeId;if(null!=a&&(o=n.getNodeById(a)))return{node:o}}}function ud(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function hd(t,e){return l(ud(t),e)>=0}function cd(t,e){for(var i=[];t;){var n=t.dataIndex;i.push({name:t.name,dataIndex:n,value:e.getRawValue(n)}),t=t.parentNode}return i.reverse(),i}function dd(t){var e=0;d(t.children,function(t){dd(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function fd(t,e){var i=e.get("color");if(i){var n;return d(t=t||[],function(t){var e=new No(t),i=e.get("color");(e.get("itemStyle.color")||i&&"none"!==i)&&(n=!0)}),n||((t[0]||(t[0]={})).color=i.slice()),t}}function pd(t){this.group=new tb,t.add(this.group)}function gd(t,e,i,n,o,a){var r=[[o?t:t-UC,e],[t+i,e],[t+i,e+n],[o?t:t-UC,e+n]];return!a&&r.splice(2,0,[t+i+UC,e+n/2]),!o&&r.push([t,e+n/2]),r}function md(t,e,i){t.eventData={componentType:"series",componentSubType:"treemap",componentIndex:e.componentIndex,seriesIndex:e.componentIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:i&&i.dataIndex,name:i&&i.name},treePathInfo:i&&cd(i,e)}}function vd(){var t,e=[],i={};return{add:function(t,n,o,a,r){return _(a)&&(r=a,a=0),!i[t.id]&&(i[t.id]=1,e.push({el:t,target:n,time:o,delay:a,easing:r}),!0)},done:function(e){return t=e,this},start:function(){for(var n=e.length,o=0,a=e.length;o=0;a--)null==i[a]&&(delete n[e[a]],e.pop())}function bd(t,e){var i=t.visual,n=[];w(i)?sL(i,function(t){n.push(t)}):null!=i&&n.push(i);var o={color:1,symbol:1};e||1!==n.length||o.hasOwnProperty(t.type)||(n[1]=n[0]),Ld(t,n)}function Sd(t){return{applyVisual:function(e,i,n){e=this.mapValueToVisual(e),n("color",t(i("color"),e))},_doMap:Dd([0,1])}}function Md(t){var e=this.option.visual;return e[Math.round(Bo(t,[0,1],[0,e.length-1],!0))]||{}}function Id(t){return function(e,i,n){n(t,this.mapValueToVisual(e))}}function Td(t){var e=this.option.visual;return e[this.option.loop&&t!==uL?t%e.length:t]}function Ad(){return this.option.visual[0]}function Dd(t){return{linear:function(e){return Bo(e,t,this.option.visual,!0)},category:Td,piecewise:function(e,i){var n=Cd.call(this,i);return null==n&&(n=Bo(e,t,this.option.visual,!0)),n},fixed:Ad}}function Cd(t){var e=this.option,i=e.pieceList;if(e.hasSpecialVisual){var n=i[hL.findPieceIndex(t,i)];if(n&&n.visual)return n.visual[this.type]}}function Ld(t,e){return t.visual=e,"color"===t.type&&(t.parsedVisual=f(e,function(t){return Gt(t)})),e}function kd(t,e,i){return t?e<=i:e=o.length||t===o[t.depth])&&Pd(t,Vd(r,h,t,e,g,a),i,n,o,a)})}else l=Od(h),t.setVisual("color",l)}}function Nd(t,e,i,n){var o=a({},e);return d(["color","colorAlpha","colorSaturation"],function(a){var r=t.get(a,!0);null==r&&i&&(r=i[a]),null==r&&(r=e[a]),null==r&&(r=n.get(a)),null!=r&&(o[a]=r)}),o}function Od(t){var e=Rd(t,"color");if(e){var i=Rd(t,"colorAlpha"),n=Rd(t,"colorSaturation");return n&&(e=jt(e,null,null,n)),i&&(e=Yt(e,i)),e}}function Ed(t,e){return null!=e?jt(e,null,null,t):null}function Rd(t,e){var i=t[e];if(null!=i&&"none"!==i)return i}function zd(t,e,i,n,o,a){if(a&&a.length){var r=Bd(e,"color")||null!=o.color&&"none"!==o.color&&(Bd(e,"colorAlpha")||Bd(e,"colorSaturation"));if(r){var s=e.get("visualMin"),l=e.get("visualMax"),u=i.dataExtent.slice();null!=s&&su[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:r.name,dataExtent:u,visual:r.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var d=new hL(c);return d.__drColorMappingBy=h,d}}}function Bd(t,e){var i=t.get(e);return fL(i)&&i.length?{name:e,range:i}:null}function Vd(t,e,i,n,o,r){var s=a({},e);if(o){var l=o.type,u="color"===l&&o.__drColorMappingBy,h="index"===u?n:"id"===u?r.mapIdToIndex(i.getId()):i.getValue(t.get("visualDimension"));s[l]=o.mapValueToVisual(h)}return s}function Gd(t,e,i,n){var o,a;if(!t.isRemoved()){var r=t.getLayout();o=r.width,a=r.height;var s=(f=t.getModel()).get(_L),l=f.get(wL)/2,u=Kd(f),h=Math.max(s,u),c=s-l,d=h-l,f=t.getModel();t.setLayout({borderWidth:s,upperHeight:h,upperLabelHeight:u},!0);var p=(o=mL(o-2*c,0))*(a=mL(a-c-d,0)),g=Fd(t,f,p,e,i,n);if(g.length){var m={x:c,y:d,width:o,height:a},v=vL(o,a),y=1/0,x=[];x.area=0;for(var _=0,w=g.length;_=0;l--){var u=o["asc"===n?r-l-1:l].getValue();u/i*es[1]&&(s[1]=e)})}else s=[NaN,NaN];return{sum:n,dataExtent:s}}function Ud(t,e,i){for(var n,o=0,a=1/0,r=0,s=t.length;ro&&(o=n));var l=t.area*t.area,u=e*e*i;return l?mL(u*o/l,l/(u*a)):1/0}function Xd(t,e,i,n,o){var a=e===i.width?0:1,r=1-a,s=["x","y"],l=["width","height"],u=i[s[a]],h=e?t.area/e:0;(o||h>i[l[r]])&&(h=i[l[r]]);for(var c=0,d=t.length;cXM&&(u=XM),a=s}u=0?n+=u:n-=u:p>=0?n-=u:n+=u}return n}function pf(t,e){return t.getVisual("opacity")||t.getModel().get(e)}function gf(t,e,i){var n=t.getGraphicEl(),o=pf(t,e);null!=i&&(null==o&&(o=1),o*=i),n.downplay&&n.downplay(),n.traverse(function(t){if("group"!==t.type){var e=t.lineLabelOriginalOpacity;null!=e&&null==i||(e=o),t.setStyle("opacity",e)}})}function mf(t,e){var i=pf(t,e),n=t.getGraphicEl();n.highlight&&n.highlight(),n.traverse(function(t){"group"!==t.type&&t.setStyle("opacity",i)})}function vf(t){return t instanceof Array||(t=[t,t]),t}function yf(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=t.getGraph();i.eachNode(function(t){var e=t.getModel();t.setLayout([+e.get("x"),+e.get("y")])}),xf(i)}}function xf(t){t.eachEdge(function(t){var e=t.getModel().get("lineStyle.curveness")||0,i=F(t.node1.getLayout()),n=F(t.node2.getLayout()),o=[i,n];+e&&o.push([(i[0]+n[0])/2-(i[1]-n[1])*e,(i[1]+n[1])/2-(n[0]-i[0])*e]),t.setLayout(o)})}function _f(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=e.getBoundingRect(),n=t.getData(),o=n.graph,a=0,r=n.getSum("value"),s=2*Math.PI/(r||n.count()),l=i.width/2+i.x,u=i.height/2+i.y,h=Math.min(i.width,i.height)/2;o.eachNode(function(t){var e=t.getValue("value");a+=s*(r?e:1)/2,t.setLayout([h*Math.cos(a)+l,h*Math.sin(a)+u]),a+=s*(r?e:1)/2}),n.setLayout({cx:l,cy:u}),o.eachEdge(function(t){var e,i=t.getModel().get("lineStyle.curveness")||0,n=F(t.node1.getLayout()),o=F(t.node2.getLayout()),a=(n[0]+o[0])/2,r=(n[1]+o[1])/2;+i&&(e=[l*(i*=3)+a*(1-i),u*i+r*(1-i)]),t.setLayout([n,o,e])})}}function wf(t,e,i){for(var n=i.rect,o=n.width,a=n.height,r=[n.x+o/2,n.y+a/2],s=null==i.gravity?.1:i.gravity,l=0;l0?-1:i<0?1:e?-1:1}}function Pf(t,e){return Math.min(e[1],Math.max(e[0],t))}function Nf(t,e,i){this._axesMap=R(),this._axesLayout={},this.dimensions=t.dimensions,this._rect,this._model=t,this._init(t,e,i)}function Of(t,e){return ek(ik(t,e[0]),e[1])}function Ef(t,e){var i=e.layoutLength/(e.axisCount-1);return{position:i*t,axisNameAvailableWidth:i,axisLabelShow:!0}}function Rf(t,e){var i,n,o=e.layoutLength,a=e.axisExpandWidth,r=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return tmk}function $f(t){var e=t.length-1;return e<0&&(e=0),[t[0],t[e]]}function Jf(t,e,i,n){var o=new tb;return o.add(new yM({name:"main",style:ip(i),silent:!0,draggable:!0,cursor:"move",drift:uk(t,e,o,"nswe"),ondragend:uk(qf,e,{isEnd:!0})})),hk(n,function(i){o.add(new yM({name:i,style:{opacity:0},draggable:!0,silent:!0,invisible:!0,drift:uk(t,e,o,i),ondragend:uk(qf,e,{isEnd:!0})}))}),o}function Qf(t,e,i,n){var o=n.brushStyle.lineWidth||0,a=fk(o,vk),r=i[0][0],s=i[1][0],l=r-o/2,u=s-o/2,h=i[0][1],c=i[1][1],d=h-a+o/2,f=c-a+o/2,p=h-r,g=c-s,m=p+o,v=g+o;ep(t,e,"main",r,s,p,g),n.transformable&&(ep(t,e,"w",l,u,a,v),ep(t,e,"e",d,u,a,v),ep(t,e,"n",l,u,m,a),ep(t,e,"s",l,f,m,a),ep(t,e,"nw",l,u,a,a),ep(t,e,"ne",d,u,a,a),ep(t,e,"sw",l,f,a,a),ep(t,e,"se",d,f,a,a))}function tp(t,e){var i=e.__brushOption,n=i.transformable,o=e.childAt(0);o.useStyle(ip(i)),o.attr({silent:!n,cursor:n?"move":"default"}),hk(["w","e","n","s","se","sw","ne","nw"],function(i){var o=e.childOfName(i),a=ap(t,i);o&&o.attr({silent:!n,invisible:!n,cursor:n?_k[a]+"-resize":null})})}function ep(t,e,i,n,o,a,r){var s=e.childOfName(i);s&&s.setShape(hp(up(t,e,[[n,o],[n+a,o+r]])))}function ip(t){return r({strokeNoScale:!0},t.brushStyle)}function np(t,e,i,n){var o=[dk(t,i),dk(e,n)],a=[fk(t,i),fk(e,n)];return[[o[0],a[0]],[o[1],a[1]]]}function op(t){return Ao(t.group)}function ap(t,e){if(e.length>1)return("e"===(n=[ap(t,(e=e.split(""))[0]),ap(t,e[1])])[0]||"w"===n[0])&&n.reverse(),n.join("");var i={left:"w",right:"e",top:"n",bottom:"s"},n=Co({w:"left",e:"right",n:"top",s:"bottom"}[e],op(t));return i[n]}function rp(t,e,i,n,o,a,r,s){var l=n.__brushOption,u=t(l.range),h=lp(i,a,r);hk(o.split(""),function(t){var e=xk[t];u[e[0]][e[1]]+=h[e[0]]}),l.range=e(np(u[0][0],u[1][0],u[0][1],u[1][1])),Zf(i,n),qf(i,{isEnd:!1})}function sp(t,e,i,n,o){var a=e.__brushOption.range,r=lp(t,i,n);hk(a,function(t){t[0]+=r[0],t[1]+=r[1]}),Zf(t,e),qf(t,{isEnd:!1})}function lp(t,e,i){var n=t.group,o=n.transformCoordToLocal(e,i),a=n.transformCoordToLocal(0,0);return[o[0]-a[0],o[1]-a[1]]}function up(t,e,n){var o=jf(t,e);return o&&!0!==o?o.clipPath(n,t._transform):i(n)}function hp(t){var e=dk(t[0][0],t[1][0]),i=dk(t[0][1],t[1][1]);return{x:e,y:i,width:fk(t[0][0],t[1][0])-e,height:fk(t[0][1],t[1][1])-i}}function cp(t,e,i){if(t._brushType){var n=t._zr,o=t._covers,a=Xf(t,e,i);if(!t._dragging)for(var r=0;r0;a--)Yp(s,l*=.99,r),jp(s,o,i,n,r),tg(s,l,r),jp(s,o,i,n,r)}function Up(t,e){var i=[],n="vertical"===e?"y":"x",o=Zi(t,function(t){return t.getLayout()[n]});return o.keys.sort(function(t,e){return t-e}),d(o.keys,function(t){i.push(o.buckets.get(t))}),i}function Xp(t,e,i,n,o,a,r){var s=[];d(e,function(t){var e=t.length,i=0,l=0;d(t,function(t){i+=t.getLayout().value}),l="vertical"===r?(o-(e-1)*a)/i:(n-(e-1)*a)/i,s.push(l)}),s.sort(function(t,e){return t-e});var l=s[0];d(e,function(t){d(t,function(t,e){var i=t.getLayout().value*l;"vertical"===r?(t.setLayout({x:e},!0),t.setLayout({dx:i},!0)):(t.setLayout({y:e},!0),t.setLayout({dy:i},!0))})}),d(i,function(t){var e=+t.getValue()*l;t.setLayout({dy:e},!0)})}function jp(t,e,i,n,o){d(t,function(t){var a,r,s,l=0,u=t.length;if("vertical"===o){var h;for(t.sort(function(t,e){return t.getLayout().x-e.getLayout().x}),s=0;s0&&(h=a.getLayout().x+r,a.setLayout({x:h},!0)),l=a.getLayout().x+a.getLayout().dx+e;if((r=l-e-n)>0)for(h=a.getLayout().x-r,a.setLayout({x:h},!0),l=h,s=u-2;s>=0;--s)(r=(a=t[s]).getLayout().x+a.getLayout().dx+e-l)>0&&(h=a.getLayout().x-r,a.setLayout({x:h},!0)),l=a.getLayout().x}else{var c;for(t.sort(function(t,e){return t.getLayout().y-e.getLayout().y}),s=0;s0&&(c=a.getLayout().y+r,a.setLayout({y:c},!0)),l=a.getLayout().y+a.getLayout().dy+e;if((r=l-e-i)>0)for(c=a.getLayout().y-r,a.setLayout({y:c},!0),l=c,s=u-2;s>=0;--s)(r=(a=t[s]).getLayout().y+a.getLayout().dy+e-l)>0&&(c=a.getLayout().y-r,a.setLayout({y:c},!0)),l=a.getLayout().y}})}function Yp(t,e,i){d(t.slice().reverse(),function(t){d(t,function(t){if(t.outEdges.length){var n=Qp(t.outEdges,qp,i)/Qp(t.outEdges,Jp,i);if("vertical"===i){var o=t.getLayout().x+(n-$p(t,i))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(n-$p(t,i))*e;t.setLayout({y:a},!0)}}})})}function qp(t,e){return $p(t.node2,e)*t.getValue()}function Kp(t,e){return $p(t.node1,e)*t.getValue()}function $p(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function Jp(t){return t.getValue()}function Qp(t,e,i){for(var n=0,o=t.length,a=-1;++a0?"P":"N",a=n.getVisual("borderColor"+o)||n.getVisual("color"+o),r=i.getModel(Gk).getItemStyle(Wk);e.useStyle(r),e.style.fill=null,e.style.stroke=a}function fg(t,e,i,n,o){return i>n?-1:i0?t.get(o,e-1)<=n?1:-1:1}function pg(t,e){var i,n=t.getBaseAxis(),o="category"===n.type?n.getBandWidth():(i=n.getExtent(),Math.abs(i[1]-i[0])/e.count()),a=Vo(A(t.get("barMaxWidth"),o),o),r=Vo(A(t.get("barMinWidth"),1),o),s=t.get("barWidth");return null!=s?Vo(s,o):Math.max(Math.min(o/2,a),r)}function gg(t){return y(t)||(t=[+t,+t]),t}function mg(t,e){t.eachChild(function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?e.color:null,fill:"fill"===e.brushType?e.color:null}})})}function vg(t,e){tb.call(this);var i=new wu(t,e),n=new tb;this.add(i),this.add(n),n.beforeUpdate=function(){this.attr(i.getScale())},this.updateData(t,e)}function yg(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=f(e,function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),o([e,t[0],t[1]])}))}function xg(t,e,i){tb.call(this),this.add(this.createLine(t,e,i)),this._updateEffectSymbol(t,e)}function _g(t,e,i){tb.call(this),this._createPolyline(t,e,i)}function wg(t,e,i){xg.call(this,t,e,i),this._lastFrame=0,this._lastFramePercent=0}function bg(){this.group=new tb}function Sg(t){return t instanceof Array||(t=[t,t]),t}function Mg(){var t=iw();this.canvas=t,this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={}}function Ig(t,e,i){var n=t[1]-t[0],o=(e=f(e,function(e){return{interval:[(e.interval[0]-t[0])/n,(e.interval[1]-t[0])/n]}})).length,a=0;return function(t){for(n=a;n=0;n--){var r=e[n].interval;if(r[0]<=t&&t<=r[1]){a=n;break}}return n>=0&&n=e[0]&&t<=e[1]}}function Ag(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}function Dg(t,e,i,n){var o=t.getItemLayout(e),a=i.get("symbolRepeat"),r=i.get("symbolClip"),s=i.get("symbolPosition")||"start",l=(i.get("symbolRotate")||0)*Math.PI/180||0,u=i.get("symbolPatternSize")||2,h=i.isAnimationEnabled(),c={dataIndex:e,layout:o,itemModel:i,symbolType:t.getItemVisual(e,"symbol")||"circle",color:t.getItemVisual(e,"color"),symbolClip:r,symbolRepeat:a,symbolRepeatDirection:i.get("symbolRepeatDirection"),symbolPatternSize:u,rotation:l,animationModel:h?i:null,hoverAnimation:h&&i.get("hoverAnimation"),z2:i.getShallow("z",!0)||0};Cg(i,a,o,n,c),kg(t,e,o,a,r,c.boundingLength,c.pxSign,u,n,c),Pg(i,c.symbolScale,l,n,c);var d=c.symbolSize,f=i.get("symbolOffset");return y(f)&&(f=[Vo(f[0],d[0]),Vo(f[1],d[1])]),Ng(i,d,o,a,r,f,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,n,c),c}function Cg(t,e,i,n,o){var a,r=n.valueDim,s=t.get("symbolBoundingData"),l=n.coordSys.getOtherAxis(n.coordSys.getBaseAxis()),u=l.toGlobalCoord(l.dataToCoord(0)),h=1-+(i[r.wh]<=0);if(y(s)){var c=[Lg(l,s[0])-u,Lg(l,s[1])-u];c[1]0?1:a<0?-1:0}function Lg(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function kg(t,e,i,n,o,a,r,s,l,u){var h=l.valueDim,c=l.categoryDim,d=Math.abs(i[c.wh]),f=t.getItemVisual(e,"symbolSize");y(f)?f=f.slice():(null==f&&(f="100%"),f=[f,f]),f[c.index]=Vo(f[c.index],d),f[h.index]=Vo(f[h.index],n?d:Math.abs(a)),u.symbolSize=f,(u.symbolScale=[f[0]/s,f[1]/s])[h.index]*=(l.isHorizontal?-1:1)*r}function Pg(t,e,i,n,o){var a=t.get(cP)||0;a&&(fP.attr({scale:e.slice(),rotation:i}),fP.updateTransform(),a/=fP.getLineScale(),a*=e[n.valueDim.index]),o.valueLineWidth=a}function Ng(t,e,i,n,o,r,s,l,u,h,c,d){var f=c.categoryDim,p=c.valueDim,g=d.pxSign,m=Math.max(e[p.index]+l,0),v=m;if(n){var y=Math.abs(u),x=T(t.get("symbolMargin"),"15%")+"",_=!1;x.lastIndexOf("!")===x.length-1&&(_=!0,x=x.slice(0,x.length-1)),x=Vo(x,e[p.index]);var w=Math.max(m+2*x,0),b=_?0:2*x,S=Qo(n),M=S?n:Kg((y+b)/w);w=m+2*(x=(y-M*m)/2/(_?M:M-1)),b=_?0:2*x,S||"fixed"===n||(M=h?Kg((Math.abs(h)+b)/w):0),v=M*w-b,d.repeatTimes=M,d.symbolMargin=x}var I=g*(v/2),A=d.pathPosition=[];A[f.index]=i[f.wh]/2,A[p.index]="start"===s?I:"end"===s?u-I:u/2,r&&(A[0]+=r[0],A[1]+=r[1]);var D=d.bundlePosition=[];D[f.index]=i[f.xy],D[p.index]=i[p.xy];var C=d.barRectShape=a({},i);C[p.wh]=g*Math.max(Math.abs(i[p.wh]),Math.abs(A[p.index]+I)),C[f.wh]=i[f.wh];var L=d.clipShape={};L[f.xy]=-i[f.xy],L[f.wh]=c.ecSize[f.wh],L[p.xy]=0,L[p.wh]=i[p.wh]}function Og(t){var e=t.symbolPatternSize,i=Jl(t.symbolType,-e/2,-e/2,e,e,t.color);return i.attr({culling:!0}),"image"!==i.type&&i.setStyle({strokeNoScale:!0}),i}function Eg(t,e,i,n){function o(t){var e=l.slice(),n=i.pxSign,o=t;return("start"===i.symbolRepeatDirection?n>0:n<0)&&(o=h-1-t),e[u.index]=d*(o-h/2+.5)+l[u.index],{position:e,scale:i.symbolScale.slice(),rotation:i.rotation}}var a=t.__pictorialBundle,r=i.symbolSize,s=i.valueLineWidth,l=i.pathPosition,u=e.valueDim,h=i.repeatTimes||0,c=0,d=r[e.valueDim.index]+s+2*i.symbolMargin;for(jg(t,function(t){t.__pictorialAnimationIndex=c,t.__pictorialRepeatTimes=h,c0)],d=t.__pictorialBarRect;kh(d.style,h,a,n,e.seriesModel,o,c),fo(d,h)}function Kg(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}function $g(t,e,i){this.dimension="single",this.dimensions=["single"],this._axis=null,this._rect,this._init(t,e,i),this.model=t}function Jg(t,e){e=e||{};var i=t.coordinateSystem,n=t.axis,o={},a=n.position,r=n.orient,s=i.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};o.position=["vertical"===r?u.vertical[a]:l[0],"horizontal"===r?u.horizontal[a]:l[3]];var h={horizontal:0,vertical:1};o.rotation=Math.PI/2*h[r];var c={top:-1,bottom:1,right:1,left:-1};o.labelDirection=o.tickDirection=o.nameDirection=c[a],t.get("axisTick.inside")&&(o.tickDirection=-o.tickDirection),T(e.labelInside,t.get("axisLabel.inside"))&&(o.labelDirection=-o.labelDirection);var d=e.rotate;return null==d&&(d=t.get("axisLabel.rotate")),o.labelRotation="top"===a?-d:d,o.z2=1,o}function Qg(t,e,i,n,o){var r=t.axis;if(!r.scale.isBlank()&&r.containData(e))if(t.involveSeries){var s=tm(e,t),l=s.payloadBatch,u=s.snapToValue;l[0]&&null==o.seriesIndex&&a(o,l[0]),!n&&t.snap&&r.containData(u)&&null!=u&&(e=u),i.showPointer(t,e,l,o),i.showTooltip(t,s,u)}else i.showPointer(t,e)}function tm(t,e){var i=e.axis,n=i.dim,o=t,a=[],r=Number.MAX_VALUE,s=-1;return _P(e.seriesModels,function(e,l){var u,h,c=e.getData().mapDimension(n,!0);if(e.getAxisTooltipData){var d=e.getAxisTooltipData(c,t,i);h=d.dataIndices,u=d.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===i.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var f=t-u,p=Math.abs(f);p<=r&&((p=0&&s<0)&&(r=p,s=f,o=u,a.length=0),_P(h,function(t){a.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})}))}}),{payloadBatch:a,snapToValue:o}}function em(t,e,i,n){t[e.key]={value:i,payloadBatch:n}}function im(t,e,i,n){var o=i.payloadBatch,a=e.axis,r=a.model,s=e.axisPointerModel;if(e.triggerTooltip&&o.length){var l=e.coordSys.model,u=Ah(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:a.dim,axisIndex:r.componentIndex,axisType:r.type,axisId:r.id,value:n,valueLabelOpt:{precision:s.get("label.precision"),formatter:s.get("label.formatter")},seriesDataIndices:o.slice()})}}function nm(t,e,i){var n=i.axesInfo=[];_P(e,function(e,i){var o=e.axisPointerModel.option,a=t[i];a?(!e.useHandle&&(o.status="show"),o.value=a.value,o.seriesDataIndices=(a.payloadBatch||[]).slice()):!e.useHandle&&(o.status="hide"),"show"===o.status&&n.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:o.value})})}function om(t,e,i,n){if(!lm(e)&&t.list.length){var o=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};n({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:i.tooltipOption,position:i.position,dataIndexInside:o.dataIndexInside,dataIndex:o.dataIndex,seriesIndex:o.seriesIndex,dataByCoordSys:t.list})}else n({type:"hideTip"})}function am(t,e,i){var n=i.getZr(),o=bP(n).axisPointerLastHighlights||{},a=bP(n).axisPointerLastHighlights={};_P(t,function(t,e){var i=t.axisPointerModel.option;"show"===i.status&&_P(i.seriesDataIndices,function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t})});var r=[],s=[];d(o,function(t,e){!a[e]&&s.push(t)}),d(a,function(t,e){!o[e]&&r.push(t)}),s.length&&i.dispatchAction({type:"downplay",escapeConnect:!0,batch:s}),r.length&&i.dispatchAction({type:"highlight",escapeConnect:!0,batch:r})}function rm(t,e){for(var i=0;i<(t||[]).length;i++){var n=t[i];if(e.axis.dim===n.axisDim&&e.axis.model.componentIndex===n.axisIndex)return n}}function sm(t){var e=t.axis.model,i={},n=i.axisDim=t.axis.dim;return i.axisIndex=i[n+"AxisIndex"]=e.componentIndex,i.axisName=i[n+"AxisName"]=e.name,i.axisId=i[n+"AxisId"]=e.id,i}function lm(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function um(t,e,i){if(!U_.node){var n=e.getZr();SP(n).records||(SP(n).records={}),hm(n,e),(SP(n).records[t]||(SP(n).records[t]={})).handler=i}}function hm(t,e){function i(i,n){t.on(i,function(i){var o=pm(e);MP(SP(t).records,function(t){t&&n(t,i,o.dispatchAction)}),cm(o.pendings,e)})}SP(t).initialized||(SP(t).initialized=!0,i("click",v(fm,"click")),i("mousemove",v(fm,"mousemove")),i("globalout",dm))}function cm(t,e){var i,n=t.showTip.length,o=t.hideTip.length;n?i=t.showTip[n-1]:o&&(i=t.hideTip[o-1]),i&&(i.dispatchAction=null,e.dispatchAction(i))}function dm(t,e,i){t.handler("leave",null,i)}function fm(t,e,i,n){e.handler(t,i,n)}function pm(t){var e={showTip:[],hideTip:[]},i=function(n){var o=e[n.type];o?o.push(n):(n.dispatchAction=i,t.dispatchAction(n))};return{dispatchAction:i,pendings:e}}function gm(t,e){if(!U_.node){var i=e.getZr();(SP(i).records||{})[t]&&(SP(i).records[t]=null)}}function mm(){}function vm(t,e,i,n){ym(TP(i).lastProp,n)||(TP(i).lastProp=n,e?Io(i,n,t):(i.stopAnimation(),i.attr(n)))}function ym(t,e){if(w(t)&&w(e)){var i=!0;return d(e,function(e,n){i=i&&ym(t[n],e)}),!!i}return t===e}function xm(t,e){t[e.get("label.show")?"show":"hide"]()}function _m(t){return{position:t.position.slice(),rotation:t.rotation||0}}function wm(t,e,i){var n=e.get("z"),o=e.get("zlevel");t&&t.traverse(function(t){"group"!==t.type&&(null!=n&&(t.z=n),null!=o&&(t.zlevel=o),t.silent=i)})}function bm(t){var e,i=t.get("type"),n=t.getModel(i+"Style");return"line"===i?(e=n.getLineStyle()).fill=null:"shadow"===i&&((e=n.getAreaStyle()).stroke=null),e}function Sm(t,e,i,n,o){var a=Im(i.get("value"),e.axis,e.ecModel,i.get("seriesDataIndices"),{precision:i.get("label.precision"),formatter:i.get("label.formatter")}),r=i.getModel("label"),s=qM(r.get("padding")||0),l=r.getFont(),u=ke(a,l),h=o.position,c=u.width+s[1]+s[3],d=u.height+s[0]+s[2],f=o.align;"right"===f&&(h[0]-=c),"center"===f&&(h[0]-=c/2);var p=o.verticalAlign;"bottom"===p&&(h[1]-=d),"middle"===p&&(h[1]-=d/2),Mm(h,c,d,n);var g=r.get("backgroundColor");g&&"auto"!==g||(g=e.get("axisLine.lineStyle.color")),t.label={shape:{x:0,y:0,width:c,height:d,r:r.get("borderRadius")},position:h.slice(),style:{text:a,textFont:l,textFill:r.getTextColor(),textPosition:"inside",fill:g,stroke:r.get("borderColor")||"transparent",lineWidth:r.get("borderWidth")||0,shadowBlur:r.get("shadowBlur"),shadowColor:r.get("shadowColor"),shadowOffsetX:r.get("shadowOffsetX"),shadowOffsetY:r.get("shadowOffsetY")},z2:10}}function Mm(t,e,i,n){var o=n.getWidth(),a=n.getHeight();t[0]=Math.min(t[0]+e,o)-e,t[1]=Math.min(t[1]+i,a)-i,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}function Im(t,e,i,n,o){t=e.scale.parse(t);var a=e.scale.getLabel(t,{precision:o.precision}),r=o.formatter;if(r){var s={value:Xl(e,t),seriesData:[]};d(n,function(t){var e=i.getSeriesByIndex(t.seriesIndex),n=t.dataIndexInside,o=e&&e.getDataParams(n);o&&s.seriesData.push(o)}),_(r)?a=r.replace("{value}",a):x(r)&&(a=r(s))}return a}function Tm(t,e,i){var n=xt();return Mt(n,n,i.rotation),St(n,n,i.position),Do([t.dataToCoord(e),(i.labelOffset||0)+(i.labelDirection||1)*(i.labelMargin||0)],n)}function Am(t,e,i,n,o,a){var r=FD.innerTextLayout(i.rotation,0,i.labelDirection);i.labelMargin=o.get("label.margin"),Sm(e,n,o,a,{position:Tm(n.axis,t,i),align:r.textAlign,verticalAlign:r.textVerticalAlign})}function Dm(t,e,i){return i=i||0,{x1:t[i],y1:t[1-i],x2:e[i],y2:e[1-i]}}function Cm(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}function Lm(t,e,i,n,o,a){return{cx:t,cy:e,r0:i,r:n,startAngle:o,endAngle:a,clockwise:!0}}function km(t,e){var i={};return i[e.dim+"AxisIndex"]=e.index,t.getCartesian(i)}function Pm(t){return"x"===t.dim?0:1}function Nm(t){return t.isHorizontal()?0:1}function Om(t,e){var i=t.getRect();return[i[kP[e]],i[kP[e]]+i[PP[e]]]}function Em(t,e,i){var n=new yM({shape:{x:t.x-10,y:t.y-10,width:0,height:t.height+20}});return To(n,{shape:{width:t.width+20,height:t.height+20}},e,i),n}function Rm(t,e,i){if(t.count())for(var n,o=e.coordinateSystem,a=e.getLayerSeries(),r=t.mapDimension("single"),s=t.mapDimension("value"),l=f(a,function(e){return f(e.indices,function(e){var i=o.dataToPoint(t.get(r,e));return i[1]=t.get(s,e),i})}),u=zm(l),h=u.y0,c=i/u.max,d=a.length,p=a[0].indices.length,g=0;ga&&(a=u),n.push(u)}for(var h=0;ha&&(a=d)}return r.y0=o,r.max=a,r}function Bm(t){var e=0;d(t.children,function(t){Bm(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function Vm(t,e,i){function n(){r.ignore=r.hoverIgnore}function o(){r.ignore=r.normalIgnore}tb.call(this);var a=new hM({z2:zP});a.seriesIndex=e.seriesIndex;var r=new rM({z2:BP,silent:t.getModel("label").get("silent")});this.add(a),this.add(r),this.updateData(!0,t,"normal",e,i),this.on("emphasis",n).on("normal",o).on("mouseover",n).on("mouseout",o)}function Gm(t,e,i){var n=t.getVisual("color"),o=t.getVisual("visualMeta");o&&0!==o.length||(n=null);var a=t.getModel("itemStyle").get("color");if(a)return a;if(n)return n;if(0===t.depth)return i.option.color[0];var r=i.option.color.length;return a=i.option.color[Fm(t)%r]}function Fm(t){for(var e=t;e.depth>1;)e=e.parentNode;return l(t.getAncestors()[0].children,e)}function Wm(t,e,i){return i!==RP.NONE&&(i===RP.SELF?t===e:i===RP.ANCESTOR?t===e||t.isAncestorOf(e):t===e||t.isDescendantOf(e))}function Hm(t,e,i){e.getData().setItemVisual(t.dataIndex,"color",i)}function Zm(t,e){var i=t.children||[];t.children=Um(i,e),i.length&&d(t.children,function(t){Zm(t,e)})}function Um(t,e){if("function"==typeof e)return t.sort(e);var i="asc"===e;return t.sort(function(t,e){var n=(t.getValue()-e.getValue())*(i?1:-1);return 0===n?(t.dataIndex-e.dataIndex)*(i?-1:1):n})}function Xm(t,e){return e=e||[0,0],f(["x","y"],function(i,n){var o=this.getAxis(i),a=e[n],r=t[n]/2;return"category"===o.type?o.getBandWidth():Math.abs(o.dataToCoord(a-r)-o.dataToCoord(a+r))},this)}function jm(t,e){return e=e||[0,0],f([0,1],function(i){var n=e[i],o=t[i]/2,a=[],r=[];return a[i]=n-o,r[i]=n+o,a[1-i]=r[1-i]=e[1-i],Math.abs(this.dataToPoint(a)[i]-this.dataToPoint(r)[i])},this)}function Ym(t,e){var i=this.getAxis(),n=e instanceof Array?e[0]:e,o=(t instanceof Array?t[0]:t)/2;return"category"===i.type?i.getBandWidth():Math.abs(i.dataToCoord(n-o)-i.dataToCoord(n+o))}function qm(t,e){return f(["Radius","Angle"],function(i,n){var o=this["get"+i+"Axis"](),a=e[n],r=t[n]/2,s="dataTo"+i,l="category"===o.type?o.getBandWidth():Math.abs(o[s](a-r)-o[s](a+r));return"Angle"===i&&(l=l*Math.PI/180),l},this)}function Km(t){var e,i=t.type;if("path"===i){var n=t.shape,o=null!=n.width&&null!=n.height?{x:n.x||0,y:n.y||0,width:n.width,height:n.height}:null,a=lv(n);(e=Xn(a,null,o,n.layout||"center")).__customPathData=a}else"image"===i?(e=new fi({})).__customImagePath=t.style.image:"text"===i?(e=new rM({})).__customText=t.style.text:e=new(0,zM[i.charAt(0).toUpperCase()+i.slice(1)]);return e.__customGraphicType=i,e.name=t.name,e}function $m(t,e,n,o,a,r,s){var l={},u=n.style||{};if(n.shape&&(l.shape=i(n.shape)),n.position&&(l.position=n.position.slice()),n.scale&&(l.scale=n.scale.slice()),n.origin&&(l.origin=n.origin.slice()),n.rotation&&(l.rotation=n.rotation),"image"===t.type&&n.style){h=l.style={};d(["x","y","width","height"],function(e){Jm(e,h,u,t.style,r)})}if("text"===t.type&&n.style){var h=l.style={};d(["x","y"],function(e){Jm(e,h,u,t.style,r)}),!u.hasOwnProperty("textFill")&&u.fill&&(u.textFill=u.fill),!u.hasOwnProperty("textStroke")&&u.stroke&&(u.textStroke=u.stroke)}if("group"!==t.type&&(t.useStyle(u),r)){t.style.opacity=0;var c=u.opacity;null==c&&(c=1),To(t,{style:{opacity:c}},o,e)}r?t.attr(l):Io(t,l,o,e),n.hasOwnProperty("z2")&&t.attr("z2",n.z2||0),n.hasOwnProperty("silent")&&t.attr("silent",n.silent),n.hasOwnProperty("invisible")&&t.attr("invisible",n.invisible),n.hasOwnProperty("ignore")&&t.attr("ignore",n.ignore),n.hasOwnProperty("info")&&t.attr("info",n.info);var f=n.styleEmphasis,p=!1===f;t.__cusHasEmphStl&&null==f||!t.__cusHasEmphStl&&p||(ro(t,f),t.__cusHasEmphStl=!p),s&&po(t,!p)}function Jm(t,e,i,n,o){null==i[t]||o||(e[t]=i[t],i[t]=n[t])}function Qm(t,e,i,n){function o(t){null==t&&(t=h),v&&(c=e.getItemModel(t),d=c.getModel(UP),f=c.getModel(XP),p=e.getItemVisual(t,"color"),v=!1)}var s=t.get("renderItem"),l=t.coordinateSystem,u={};l&&(u=l.prepareCustoms?l.prepareCustoms():YP[l.type](l));var h,c,d,f,p,g=r({getWidth:n.getWidth,getHeight:n.getHeight,getZr:n.getZr,getDevicePixelRatio:n.getDevicePixelRatio,value:function(t,i){return null==i&&(i=h),e.get(e.getDimension(t||0),i)},style:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(HP).getItemStyle();null!=p&&(r.fill=p);var s=e.getItemVisual(n,"opacity");return null!=s&&(r.opacity=s),mo(r,d,null,{autoColor:p,isRectText:!0}),r.text=d.getShallow("show")?A(t.getFormattedLabel(n,"normal"),_u(e,n)):null,i&&a(r,i),r},styleEmphasis:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(ZP).getItemStyle();return mo(r,f,null,{isRectText:!0},!0),r.text=f.getShallow("show")?D(t.getFormattedLabel(n,"emphasis"),t.getFormattedLabel(n,"normal"),_u(e,n)):null,i&&a(r,i),r},visual:function(t,i){return null==i&&(i=h),e.getItemVisual(i,t)},barLayout:function(t){if(l.getBaseAxis)return Ll(r({axis:l.getBaseAxis()},t),n)},currentSeriesIndices:function(){return i.getCurrentSeriesIndices()},font:function(t){return So(t,i)}},u.api||{}),m={context:{},seriesId:t.id,seriesName:t.name,seriesIndex:t.seriesIndex,coordSys:u.coordSys,dataInsideLength:e.count(),encode:tv(t.getData())},v=!0;return function(t,i){return h=t,v=!0,s&&s(r({dataIndexInside:t,dataIndex:e.getRawIndex(t),actionType:i?i.type:null},m),g)}}function tv(t){var e={};return d(t.dimensions,function(i,n){var o=t.getDimensionInfo(i);if(!o.isExtraCoord){var a=o.coordDim;(e[a]=e[a]||[])[o.coordDimIndex]=n}}),e}function ev(t,e,i,n,o,a){return(t=iv(t,e,i,n,o,a,!0))&&a.setItemGraphicEl(e,t),t}function iv(t,e,i,n,o,a,r){var s=!i,l=(i=i||{}).type,u=i.shape,h=i.style;if(t&&(s||null!=l&&l!==t.__customGraphicType||"path"===l&&uv(u)&&lv(u)!==t.__customPathData||"image"===l&&hv(h,"image")&&h.image!==t.__customImagePath||"text"===l&&hv(u,"text")&&h.text!==t.__customText)&&(o.remove(t),t=null),!s){var c=!t;return!t&&(t=Km(i)),$m(t,e,i,n,a,c,r),"group"===l&&nv(t,e,i,n,a),o.add(t),t}}function nv(t,e,i,n,o){var a=i.children,r=a?a.length:0,s=i.$mergeChildren,l="byName"===s||i.diffChildrenByName,u=!1===s;if(r||l||u)if(l)ov({oldChildren:t.children()||[],newChildren:a||[],dataIndex:e,animatableModel:n,group:t,data:o});else{u&&t.removeAll();for(var h=0;hn?t-=l+a:t+=a),null!=r&&(e+u+r>o?e-=u+r:e+=r),[t,e]}function Ov(t,e,i,n,o){var a=i.getOuterSize(),r=a.width,s=a.height;return t=Math.min(t+r,n)-r,e=Math.min(e+s,o)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function Ev(t,e,i){var n=i[0],o=i[1],a=0,r=0,s=e.width,l=e.height;switch(t){case"inside":a=e.x+s/2-n/2,r=e.y+l/2-o/2;break;case"top":a=e.x+s/2-n/2,r=e.y-o-5;break;case"bottom":a=e.x+s/2-n/2,r=e.y+l+5;break;case"left":a=e.x-n-5,r=e.y+l/2-o/2;break;case"right":a=e.x+s+5,r=e.y+l/2-o/2}return[a,r]}function Rv(t){return"center"===t||"middle"===t}function zv(t){return t.get("stack")||"__ec_stack_"+t.seriesIndex}function Bv(t){return t.dim}function Vv(t,e){var i={};d(t,function(t,e){var n=t.getData(),o=t.coordinateSystem.getBaseAxis(),a=o.getExtent(),r="category"===o.type?o.getBandWidth():Math.abs(a[1]-a[0])/n.count(),s=i[Bv(o)]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},l=s.stacks;i[Bv(o)]=s;var u=zv(t);l[u]||s.autoWidthCount++,l[u]=l[u]||{width:0,maxWidth:0};var h=Vo(t.get("barWidth"),r),c=Vo(t.get("barMaxWidth"),r),d=t.get("barGap"),f=t.get("barCategoryGap");h&&!l[u].width&&(h=Math.min(s.remainedWidth,h),l[u].width=h,s.remainedWidth-=h),c&&(l[u].maxWidth=c),null!=d&&(s.gap=d),null!=f&&(s.categoryGap=f)});var n={};return d(i,function(t,e){n[e]={};var i=t.stacks,o=t.bandWidth,a=Vo(t.categoryGap,o),r=Vo(t.gap,1),s=t.remainedWidth,l=t.autoWidthCount,u=(s-a)/(l+(l-1)*r);u=Math.max(u,0),d(i,function(t,e){var i=t.maxWidth;i&&ie[0]&&(e=e.slice().reverse());var n=t.coordToPoint([e[0],i]),o=t.coordToPoint([e[1],i]);return{x1:n[0],y1:n[1],x2:o[0],y2:o[1]}}function jv(t){return t.getRadiusAxis().inverse?0:1}function Yv(t){var e=t[0],i=t[t.length-1];e&&i&&Math.abs(Math.abs(e.coord-i.coord)-360)<1e-4&&t.pop()}function qv(t,e,i){return{position:[t.cx,t.cy],rotation:i/180*Math.PI,labelDirection:-1,tickDirection:-1,nameDirection:1,labelRotate:e.getModel("axisLabel").get("rotate"),z2:1}}function Kv(t,e,i,n,o){var a=e.axis,r=a.dataToCoord(t),s=n.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=n.getRadiusAxis().getExtent();if("radius"===a.dim){var d=xt();Mt(d,d,s),St(d,d,[n.cx,n.cy]),l=Do([r,-o],d);var f=e.getModel("axisLabel").get("rotate")||0,p=FD.innerTextLayout(s,f*Math.PI/180,-1);u=p.textAlign,h=p.textVerticalAlign}else{var g=c[1];l=n.coordToPoint([g+o,r]);var m=n.cx,v=n.cy;u=Math.abs(l[0]-m)/g<.3?"center":l[0]>m?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}function $v(t,e){e.update="updateView",Es(e,function(e,i){var n={};return i.eachComponent({mainType:"geo",query:e},function(i){i[t](e.name),d(i.coordinateSystem.regions,function(t){n[t.name]=i.isSelected(t.name)||!1})}),{selected:n,name:e.name}})}function Jv(t){var e={};d(t,function(t){e[t]=1}),t.length=0,d(e,function(e,i){t.push(i)})}function Qv(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function ty(t,e,n){function o(){var t=function(){};return t.prototype.__hidden=t.prototype,new t}var a={};return MN(e,function(e){var r=a[e]=o();MN(t[e],function(t,o){if(hL.isValidType(o)){var a={type:o,visual:t};n&&n(a,e),r[o]=new hL(a),"opacity"===o&&((a=i(a)).type="colorAlpha",r.__hidden.__alphaForOpacity=new hL(a))}})}),a}function ey(t,e,n){var o;d(n,function(t){e.hasOwnProperty(t)&&Qv(e[t])&&(o=!0)}),o&&d(n,function(n){e.hasOwnProperty(n)&&Qv(e[n])?t[n]=i(e[n]):delete t[n]})}function iy(t,e,i,n,o,a){function r(t){return i.getItemVisual(h,t)}function s(t,e){i.setItemVisual(h,t,e)}function l(t,l){h=null==a?t:l;var c=i.getRawDataItem(h);if(!c||!1!==c.visualMap)for(var d=n.call(o,t),f=e[d],p=u[d],g=0,m=p.length;g1)return!1;var h=uy(i-t,o-t,n-e,a-e)/l;return!(h<0||h>1)}function ly(t){return t<=1e-6&&t>=-1e-6}function uy(t,e,i,n){return t*n-e*i}function hy(t,e,i){var n=this._targetInfoList=[],o={},a=dy(e,t);TN(PN,function(t,e){(!i||!i.include||AN(i.include,e)>=0)&&t(a,n,o)})}function cy(t){return t[0]>t[1]&&t.reverse(),t}function dy(t,e){return Vi(t,e,{includeMainTypes:LN})}function fy(t,e,i,n){var o=i.getAxis(["x","y"][t]),a=cy(f([0,1],function(t){return e?o.coordToData(o.toLocalCoord(n[t])):o.toGlobalCoord(o.dataToCoord(n[t]))})),r=[];return r[t]=a,r[1-t]=[NaN,NaN],{values:a,xyMinMax:r}}function py(t,e,i,n){return[e[0]-n[t]*i[0],e[1]-n[t]*i[1]]}function gy(t,e){var i=my(t),n=my(e),o=[i[0]/n[0],i[1]/n[1]];return isNaN(o[0])&&(o[0]=1),isNaN(o[1])&&(o[1]=1),o}function my(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}function vy(t,e,i,n,o){if(o){var a=t.getZr();a[VN]||(a[BN]||(a[BN]=yy),Nr(a,BN,i,e)(t,n))}}function yy(t,e){if(!t.isDisposed()){var i=t.getZr();i[VN]=!0,t.dispatchAction({type:"brushSelect",batch:e}),i[VN]=!1}}function xy(t,e,i,n){for(var o=0,a=e.length;o=0}function Ny(t,e,i){function n(t,e){return l(e.nodes,t)>=0}function o(t,n){var o=!1;return e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]&&(o=!0)})}),o}function a(t,n){n.nodes.push(t),e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]=!0})})}return function(i){var r={nodes:[],records:{}};if(e(function(t){r.records[t.name]={}}),!i)return r;a(i,r);var s;do{s=!1,t(function(t){!n(t,r)&&o(t,r)&&(a(t,r),s=!0)})}while(s);return r}}function Oy(t,e,i){var n=[1/0,-1/0];return $N(i,function(t){var i=t.getData();i&&$N(i.mapDimension(e,!0),function(t){var e=i.getApproximateExtent(t);e[0]n[1]&&(n[1]=e[1])})}),n[1]0?0:NaN);var r=i.getMax(!0);return null!=r&&"dataMax"!==r&&"function"!=typeof r?e[1]=r:o&&(e[1]=a>0?a-1:NaN),i.get("scale",!0)||(e[0]>0&&(e[0]=0),e[1]<0&&(e[1]=0)),e}function Ry(t,e){var i=t.getAxisModel(),n=t._percentWindow,o=t._valueWindow;if(n){var a=Zo(o,[0,500]);a=Math.min(a,20);var r=e||0===n[0]&&100===n[1];i.setRange(r?null:+o[0].toFixed(a),r?null:+o[1].toFixed(a))}}function zy(t){var e=t._minMaxSpan={},i=t._dataZoomModel;$N(["min","max"],function(n){e[n+"Span"]=i.get(n+"Span");var o=i.get(n+"ValueSpan");if(null!=o&&(e[n+"ValueSpan"]=o,null!=(o=t.getAxisModel().axis.scale.parse(o)))){var a=t._dataExtent;e[n+"Span"]=Bo(a[0]+o,a,[0,100],!0)}})}function By(t){var e={};return tO(["start","end","startValue","endValue","throttle"],function(i){t.hasOwnProperty(i)&&(e[i]=t[i])}),e}function Vy(t,e){var i=t._rangePropMode,n=t.get("rangeMode");tO([["start","startValue"],["end","endValue"]],function(t,o){var a=null!=e[t[0]],r=null!=e[t[1]];a&&!r?i[o]="percent":!a&&r?i[o]="value":n?i[o]=n[o]:a&&(i[o]="percent")})}function Gy(t){return{x:"y",y:"x",radius:"angle",angle:"radius"}[t]}function Fy(t){return"vertical"===t?"ns-resize":"ew-resize"}function Wy(t,e){var i=Uy(t),n=e.dataZoomId,o=e.coordId;d(i,function(t,i){var a=t.dataZoomInfos;a[n]&&l(e.allCoordIds,o)<0&&(delete a[n],t.count--)}),jy(i);var a=i[o];a||((a=i[o]={coordId:o,dataZoomInfos:{},count:0}).controller=Xy(t,a),a.dispatchAction=v(Yy,t)),!a.dataZoomInfos[n]&&a.count++,a.dataZoomInfos[n]=e;var r=qy(a.dataZoomInfos);a.controller.enable(r.controlType,r.opt),a.controller.setPointerChecker(e.containsPoint),Nr(a,"dispatchAction",e.dataZoomModel.get("throttle",!0),"fixRate")}function Hy(t,e){var i=Uy(t);d(i,function(t){t.controller.dispose();var i=t.dataZoomInfos;i[e]&&(delete i[e],t.count--)}),jy(i)}function Zy(t){return t.type+"\0_"+t.id}function Uy(t){var e=t.getZr();return e[fO]||(e[fO]={})}function Xy(t,e){var i=new oc(t.getZr());return d(["pan","zoom","scrollMove"],function(t){i.on(t,function(i){var n=[];d(e.dataZoomInfos,function(o){if(i.isAvailableBehavior(o.dataZoomModel.option)){var a=(o.getRange||{})[t],r=a&&a(e.controller,i);!o.dataZoomModel.get("disabled",!0)&&r&&n.push({dataZoomId:o.dataZoomId,start:r[0],end:r[1]})}}),n.length&&e.dispatchAction(n)})}),i}function jy(t){d(t,function(e,i){e.count||(e.controller.dispose(),delete t[i])})}function Yy(t,e){t.dispatchAction({type:"dataZoom",batch:e})}function qy(t){var e,i={type_true:2,type_move:1,type_false:0,type_undefined:-1},n=!0;return d(t,function(t){var o=t.dataZoomModel,a=!o.get("disabled",!0)&&(!o.get("zoomLock",!0)||"move");i["type_"+a]>i["type_"+e]&&(e=a),n&=o.get("preventDefaultMouseMove",!0)}),{controlType:e,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!n}}}function Ky(t){return function(e,i,n,o){var a=this._range,r=a.slice(),s=e.axisModels[0];if(s){var l=t(r,s,e,i,n,o);return QL(l,r,[0,100],"all"),this._range=r,a[0]!==r[0]||a[1]!==r[1]?r:void 0}}}function $y(t,e){return t&&t.hasOwnProperty&&t.hasOwnProperty(e)}function Jy(t,e,i,n){for(var o=e.targetVisuals[n],a=hL.prepareVisualTypes(o),r={color:t.getData().getVisual("color")},s=0,l=a.length;s=0&&(r[a]=+r[a].toFixed(h)),r}function fx(t,e){var n=t.getData(),o=t.coordinateSystem;if(e&&!cx(e)&&!y(e.coord)&&o){var a=o.dimensions,r=px(e,n,o,t);if((e=i(e)).type&&YO[e.type]&&r.baseAxis&&r.valueAxis){var s=XO(a,r.baseAxis.dim),l=XO(a,r.valueAxis.dim);e.coord=YO[e.type](n,r.baseDataDim,r.valueDataDim,s,l),e.value=e.coord[l]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)YO[u[h]]&&(u[h]=yx(n,n.mapDimension(a[h]),u[h]));e.coord=u}}return e}function px(t,e,i,n){var o={};return null!=t.valueIndex||null!=t.valueDim?(o.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,o.valueAxis=i.getAxis(gx(n,o.valueDataDim)),o.baseAxis=i.getOtherAxis(o.valueAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim)):(o.baseAxis=n.getBaseAxis(),o.valueAxis=i.getOtherAxis(o.baseAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim),o.valueDataDim=e.mapDimension(o.valueAxis.dim)),o}function gx(t,e){var i=t.getData(),n=i.dimensions;e=i.getDimension(e);for(var o=0;o=0)return!0}function Yx(t){for(var e=t.split(/\n+/g),i=[],n=f(Xx(e.shift()).split(pE),function(t){return{name:t,data:[]}}),o=0;o=0&&!i[o][n];o--);if(o<0){var a=t.queryComponents({mainType:"dataZoom",subType:"select",id:n})[0];if(a){var r=a.getPercentRange();i[0][n]={dataZoomId:n,start:r[0],end:r[1]}}}}),i.push(e)}function t_(t){var e=n_(t),i=e[e.length-1];e.length>1&&e.pop();var n={};return gE(i,function(t,i){for(var o=e.length-1;o>=0;o--)if(t=e[o][i]){n[i]=t;break}}),n}function e_(t){t[mE]=null}function i_(t){return n_(t).length}function n_(t){var e=t[mE];return e||(e=t[mE]=[{}]),e}function o_(t,e,i){(this._brushController=new zf(i.getZr())).on("brush",m(this._onBrush,this)).mount(),this._isZoomActive}function a_(t){var e={};return d(["xAxisIndex","yAxisIndex"],function(i){e[i]=t[i],null==e[i]&&(e[i]="all"),(!1===e[i]||"none"===e[i])&&(e[i]=[])}),e}function r_(t,e){t.setIconStatus("back",i_(e)>1?"emphasis":"normal")}function s_(t,e,i,n,o){var a=i._isZoomActive;n&&"takeGlobalCursor"===n.type&&(a="dataZoomSelect"===n.key&&n.dataZoomSelectActive),i._isZoomActive=a,t.setIconStatus("zoom",a?"emphasis":"normal");var r=new hy(a_(t.option),e,{include:["grid"]});i._brushController.setPanels(r.makePanelOpts(o,function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"})).enableBrush(!!a&&{brushType:"auto",brushStyle:{lineWidth:0,fill:"rgba(0,0,0,0.2)"}})}function l_(t){this.model=t}function u_(t){return SE(t)}function h_(){if(!TE&&AE){TE=!0;var t=AE.styleSheets;t.length<31?AE.createStyleSheet().addRule(".zrvml","behavior:url(#default#VML)"):t[0].addRule(".zrvml","behavior:url(#default#VML)")}}function c_(t){return parseInt(t,10)}function d_(t,e){h_(),this.root=t,this.storage=e;var i=document.createElement("div"),n=document.createElement("div");i.style.cssText="display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;",n.style.cssText="position:absolute;left:0;top:0;",t.appendChild(i),this._vmlRoot=n,this._vmlViewport=i,this.resize();var o=e.delFromStorage,a=e.addToStorage;e.delFromStorage=function(t){o.call(e,t),t&&t.onRemove&&t.onRemove(n)},e.addToStorage=function(t){t.onAdd&&t.onAdd(n),a.call(e,t)},this._firstPaint=!0}function f_(t){return function(){Yw('In IE8.0 VML mode painter not support method "'+t+'"')}}function p_(t){return document.createElementNS(sR,t)}function g_(t){return cR(1e4*t)/1e4}function m_(t){return t-vR}function v_(t,e){var i=e?t.textFill:t.fill;return null!=i&&i!==hR}function y_(t,e){var i=e?t.textStroke:t.stroke;return null!=i&&i!==hR}function x_(t,e){e&&__(t,"transform","matrix("+uR.call(e,",")+")")}function __(t,e,i){(!i||"linear"!==i.type&&"radial"!==i.type)&&t.setAttribute(e,i)}function w_(t,e,i){t.setAttributeNS("http://www.w3.org/1999/xlink",e,i)}function b_(t,e,i,n){if(v_(e,i)){var o=i?e.textFill:e.fill;o="transparent"===o?hR:o,"none"!==t.getAttribute("clip-path")&&o===hR&&(o="rgba(0, 0, 0, 0.002)"),__(t,"fill",o),__(t,"fill-opacity",null!=e.fillOpacity?e.fillOpacity*e.opacity:e.opacity)}else __(t,"fill",hR);if(y_(e,i)){var a=i?e.textStroke:e.stroke;__(t,"stroke",a="transparent"===a?hR:a),__(t,"stroke-width",(i?e.textStrokeWidth:e.lineWidth)/(!i&&e.strokeNoScale?n.getLineScale():1)),__(t,"paint-order",i?"stroke":"fill"),__(t,"stroke-opacity",null!=e.strokeOpacity?e.strokeOpacity:e.opacity),e.lineDash?(__(t,"stroke-dasharray",e.lineDash.join(",")),__(t,"stroke-dashoffset",cR(e.lineDashOffset||0))):__(t,"stroke-dasharray",""),e.lineCap&&__(t,"stroke-linecap",e.lineCap),e.lineJoin&&__(t,"stroke-linejoin",e.lineJoin),e.miterLimit&&__(t,"stroke-miterlimit",e.miterLimit)}else __(t,"stroke",hR)}function S_(t){for(var e=[],i=t.data,n=t.len(),o=0;o=gR||!m_(g)&&(d>-pR&&d<0||d>pR)==!!p;var y=g_(s+u*fR(c)),x=g_(l+h*dR(c));m&&(d=p?gR-1e-4:1e-4-gR,v=!0,9===o&&e.push("M",y,x));var _=g_(s+u*fR(c+d)),w=g_(l+h*dR(c+d));e.push("A",g_(u),g_(h),cR(f*mR),+v,+p,_,w);break;case lR.Z:a="Z";break;case lR.R:var _=g_(i[o++]),w=g_(i[o++]),b=g_(i[o++]),S=g_(i[o++]);e.push("M",_,w,"L",_+b,w,"L",_+b,w+S,"L",_,w+S,"L",_,w)}a&&e.push(a);for(var M=0;M=11),domSupported:"undefined"!=typeof document}}(navigator.userAgent),X_={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1,"[object CanvasPattern]":1,"[object Image]":1,"[object Canvas]":1},j_={"[object Int8Array]":1,"[object Uint8Array]":1,"[object Uint8ClampedArray]":1,"[object Int16Array]":1,"[object Uint16Array]":1,"[object Int32Array]":1,"[object Uint32Array]":1,"[object Float32Array]":1,"[object Float64Array]":1},Y_=Object.prototype.toString,q_=Array.prototype,K_=q_.forEach,$_=q_.filter,J_=q_.slice,Q_=q_.map,tw=q_.reduce,ew={},iw=function(){return ew.createCanvas()};ew.createCanvas=function(){return document.createElement("canvas")};var nw,ow="__ec_primitive__";E.prototype={constructor:E,get:function(t){return this.data.hasOwnProperty(t)?this.data[t]:null},set:function(t,e){return this.data[t]=e},each:function(t,e){void 0!==e&&(t=m(t,e));for(var i in this.data)this.data.hasOwnProperty(i)&&t(this.data[i],i)},removeKey:function(t){delete this.data[t]}};var aw=(Object.freeze||Object)({$override:e,clone:i,merge:n,mergeAll:o,extend:a,defaults:r,createCanvas:iw,getContext:s,indexOf:l,inherits:u,mixin:h,isArrayLike:c,each:d,map:f,reduce:p,filter:g,find:function(t,e,i){if(t&&e)for(var n=0,o=t.length;n3&&(n=dw.call(n,1));for(var a=e.length,r=0;r4&&(n=dw.call(n,1,n.length-1));for(var a=n[n.length-1],r=e.length,s=0;s1&&n&&n.length>1){var a=ft(n)/ft(o);!isFinite(a)&&(a=1),e.pinchScale=a;var r=pt(n);return e.pinchX=r[0],e.pinchY=r[1],{type:"pinch",target:t[0].target,event:e}}}}},xw="silent";vt.prototype.dispose=function(){};var _w=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],ww=function(t,e,i,n){fw.call(this),this.storage=t,this.painter=e,this.painterRoot=n,i=i||new vt,this.proxy=null,this._hovered={},this._lastTouchMoment,this._lastX,this._lastY,this._gestureMgr,it.call(this),this.setHandlerProxy(i)};ww.prototype={constructor:ww,setHandlerProxy:function(t){this.proxy&&this.proxy.dispose(),t&&(d(_w,function(e){t.on&&t.on(e,this[e],this)},this),t.handler=this),this.proxy=t},mousemove:function(t){var e=t.zrX,i=t.zrY,n=this._hovered,o=n.target;o&&!o.__zr&&(o=(n=this.findHover(n.x,n.y)).target);var a=this._hovered=this.findHover(e,i),r=a.target,s=this.proxy;s.setCursor&&s.setCursor(r?r.cursor:"default"),o&&r!==o&&this.dispatchToElement(n,"mouseout",t),this.dispatchToElement(a,"mousemove",t),r&&r!==o&&this.dispatchToElement(a,"mouseover",t)},mouseout:function(t){this.dispatchToElement(this._hovered,"mouseout",t);var e,i=t.toElement||t.relatedTarget;do{i=i&&i.parentNode}while(i&&9!==i.nodeType&&!(e=i===this.painterRoot));!e&&this.trigger("globalout",{event:t})},resize:function(t){this._hovered={}},dispatch:function(t,e){var i=this[t];i&&i.call(this,e)},dispose:function(){this.proxy.dispose(),this.storage=this.proxy=this.painter=null},setCursorStyle:function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},dispatchToElement:function(t,e,i){var n=(t=t||{}).target;if(!n||!n.silent){for(var o="on"+e,a=gt(e,t,i);n&&(n[o]&&(a.cancelBubble=n[o].call(n,a)),n.trigger(e,a),n=n.parent,!a.cancelBubble););a.cancelBubble||(this.trigger(e,a),this.painter&&this.painter.eachOtherLayer(function(t){"function"==typeof t[o]&&t[o].call(t,a),t.trigger&&t.trigger(e,a)}))}},findHover:function(t,e,i){for(var n=this.storage.getDisplayList(),o={x:t,y:e},a=n.length-1;a>=0;a--){var r;if(n[a]!==i&&!n[a].ignore&&(r=yt(n[a],t,e))&&(!o.topTarget&&(o.topTarget=n[a]),r!==xw)){o.target=n[a];break}}return o},processGesture:function(t,e){this._gestureMgr||(this._gestureMgr=new vw);var i=this._gestureMgr;"start"===e&&i.clear();var n=i.recognize(t,this.findHover(t.zrX,t.zrY,null).target,this.proxy.dom);if("end"===e&&i.clear(),n){var o=n.type;t.gestureEvent=o,this.dispatchToElement({target:n.target},o,n.event)}}},d(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){ww.prototype[t]=function(e){var i=this.findHover(e.zrX,e.zrY),n=i.target;if("mousedown"===t)this._downEl=n,this._downPoint=[e.zrX,e.zrY],this._upEl=n;else if("mouseup"===t)this._upEl=n;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||uw(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(i,t,e)}}),h(ww,fw),h(ww,it);var bw="undefined"==typeof Float32Array?Array:Float32Array,Sw=(Object.freeze||Object)({create:xt,identity:_t,copy:wt,mul:bt,translate:St,rotate:Mt,scale:It,invert:Tt,clone:At}),Mw=_t,Iw=5e-5,Tw=function(t){(t=t||{}).position||(this.position=[0,0]),null==t.rotation&&(this.rotation=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},Aw=Tw.prototype;Aw.transform=null,Aw.needLocalTransform=function(){return Dt(this.rotation)||Dt(this.position[0])||Dt(this.position[1])||Dt(this.scale[0]-1)||Dt(this.scale[1]-1)};var Dw=[];Aw.updateTransform=function(){var t=this.parent,e=t&&t.transform,i=this.needLocalTransform(),n=this.transform;if(i||e){n=n||xt(),i?this.getLocalTransform(n):Mw(n),e&&(i?bt(n,t.transform,n):wt(n,t.transform)),this.transform=n;var o=this.globalScaleRatio;if(null!=o&&1!==o){this.getGlobalScale(Dw);var a=Dw[0]<0?-1:1,r=Dw[1]<0?-1:1,s=((Dw[0]-a)*o+a)/Dw[0]||0,l=((Dw[1]-r)*o+r)/Dw[1]||0;n[0]*=s,n[1]*=s,n[2]*=l,n[3]*=l}this.invTransform=this.invTransform||xt(),Tt(this.invTransform,n)}else n&&Mw(n)},Aw.getLocalTransform=function(t){return Tw.getLocalTransform(this,t)},Aw.setTransform=function(t){var e=this.transform,i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},Aw.restoreTransform=function(t){var e=t.dpr||1;t.setTransform(e,0,0,e,0,0)};var Cw=[],Lw=xt();Aw.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],i=t[2]*t[2]+t[3]*t[3],n=this.position,o=this.scale;Dt(e-1)&&(e=Math.sqrt(e)),Dt(i-1)&&(i=Math.sqrt(i)),t[0]<0&&(e=-e),t[3]<0&&(i=-i),n[0]=t[4],n[1]=t[5],o[0]=e,o[1]=i,this.rotation=Math.atan2(-t[1]/i,t[0]/e)}},Aw.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(bt(Cw,t.invTransform,e),e=Cw);var i=this.origin;i&&(i[0]||i[1])&&(Lw[4]=i[0],Lw[5]=i[1],bt(Cw,e,Lw),Cw[4]-=i[0],Cw[5]-=i[1],e=Cw),this.setLocalTransform(e)}},Aw.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},Aw.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&Q(i,i,n),i},Aw.transformCoordToGlobal=function(t,e){var i=[t,e],n=this.transform;return n&&Q(i,i,n),i},Tw.getLocalTransform=function(t,e){Mw(e=e||[]);var i=t.origin,n=t.scale||[1,1],o=t.rotation||0,a=t.position||[0,0];return i&&(e[4]-=i[0],e[5]-=i[1]),It(e,e,n),o&&Mt(e,e,o),i&&(e[4]+=i[0],e[5]+=i[1]),e[4]+=a[0],e[5]+=a[1],e};var kw={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-kw.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*kw.bounceIn(2*t):.5*kw.bounceOut(2*t-1)+.5}};Ct.prototype={constructor:Ct,step:function(t,e){if(this._initialized||(this._startTime=t+this._delay,this._initialized=!0),this._paused)this._pausedTime+=e;else{var i=(t-this._startTime-this._pausedTime)/this._life;if(!(i<0)){i=Math.min(i,1);var n=this.easing,o="string"==typeof n?kw[n]:n,a="function"==typeof o?o(i):i;return this.fire("frame",a),1===i?this.loop?(this.restart(t),"restart"):(this._needsRemove=!0,"destroy"):null}}},restart:function(t){var e=(t-this._startTime-this._pausedTime)%this._life;this._startTime=t-e+this.gap,this._pausedTime=0,this._needsRemove=!1},fire:function(t,e){this[t="on"+t]&&this[t](this._target,e)},pause:function(){this._paused=!0},resume:function(){this._paused=!1}};var Pw=function(){this.head=null,this.tail=null,this._len=0},Nw=Pw.prototype;Nw.insert=function(t){var e=new Ow(t);return this.insertEntry(e),e},Nw.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},Nw.remove=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},Nw.len=function(){return this._len},Nw.clear=function(){this.head=this.tail=null,this._len=0};var Ow=function(t){this.value=t,this.next,this.prev},Ew=function(t){this._list=new Pw,this._map={},this._maxSize=t||10,this._lastRemovedEntry=null},Rw=Ew.prototype;Rw.put=function(t,e){var i=this._list,n=this._map,o=null;if(null==n[t]){var a=i.len(),r=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=i.head;i.remove(s),delete n[s.key],o=s.value,this._lastRemovedEntry=s}r?r.value=e:r=new Ow(e),r.key=t,i.insertEntry(r),n[t]=r}return o},Rw.get=function(t){var e=this._map[t],i=this._list;if(null!=e)return e!==i.tail&&(i.remove(e),i.insertEntry(e)),e.value},Rw.clear=function(){this._list.clear(),this._map={}};var zw={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},Bw=new Ew(20),Vw=null,Gw=Ut,Fw=Xt,Ww=(Object.freeze||Object)({parse:Gt,lift:Ht,toHex:Zt,fastLerp:Ut,fastMapToColor:Gw,lerp:Xt,mapToColor:Fw,modifyHSL:jt,modifyAlpha:Yt,stringify:qt}),Hw=Array.prototype.slice,Zw=function(t,e,i,n){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||Kt,this._setter=n||$t,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};Zw.prototype={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var o=this._getter(this._target,n);if(null==o)continue;0!==t&&i[n].push({time:0,value:ae(o)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},pause:function(){for(var t=0;t=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new de(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},de.create=function(t){return new de(t.x,t.y,t.width,t.height)};var tb=function(t){t=t||{},Kw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};tb.prototype={constructor:tb,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i=0&&(i.splice(n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToStorage(t),t instanceof tb&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var e=this.__zr,i=this.__storage,n=this._children,o=l(n,t);return o<0?this:(n.splice(o,1),t.parent=null,i&&(i.delFromStorage(t),t instanceof tb&&t.delChildrenFromStorage(i)),e&&e.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;e=0&&(this.delFromStorage(t),this._roots.splice(o,1),t instanceof tb&&t.delChildrenFromStorage(this))}},addToStorage:function(t){return t&&(t.__storage=this,t.dirty(!1)),this},delFromStorage:function(t){return t&&(t.__storage=null),this},dispose:function(){this._renderList=this._roots=null},displayableSortFunc:we};var ob={shadowBlur:1,shadowOffsetX:1,shadowOffsetY:1,textShadowBlur:1,textShadowOffsetX:1,textShadowOffsetY:1,textBoxShadowBlur:1,textBoxShadowOffsetX:1,textBoxShadowOffsetY:1},ab=function(t,e,i){return ob.hasOwnProperty(e)?i*=t.dpr:i},rb={NONE:0,STYLE_BIND:1,PLAIN_TEXT:2},sb=9,lb=[["shadowBlur",0],["shadowOffsetX",0],["shadowOffsetY",0],["shadowColor","#000"],["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]],ub=function(t){this.extendFrom(t,!1)};ub.prototype={constructor:ub,fill:"#000",stroke:null,opacity:1,fillOpacity:null,strokeOpacity:null,lineDash:null,lineDashOffset:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,lineWidth:1,strokeNoScale:!1,text:null,font:null,textFont:null,fontStyle:null,fontWeight:null,fontSize:null,fontFamily:null,textTag:null,textFill:"#000",textStroke:null,textWidth:null,textHeight:null,textStrokeWidth:0,textLineHeight:null,textPosition:"inside",textRect:null,textOffset:null,textAlign:null,textVerticalAlign:null,textDistance:5,textShadowColor:"transparent",textShadowBlur:0,textShadowOffsetX:0,textShadowOffsetY:0,textBoxShadowColor:"transparent",textBoxShadowBlur:0,textBoxShadowOffsetX:0,textBoxShadowOffsetY:0,transformText:!1,textRotation:0,textOrigin:null,textBackgroundColor:null,textBorderColor:null,textBorderWidth:0,textBorderRadius:0,textPadding:null,rich:null,truncate:null,blend:null,bind:function(t,e,i){var n=this,o=i&&i.style,a=!o||t.__attrCachedBy!==rb.STYLE_BIND;t.__attrCachedBy=rb.STYLE_BIND;for(var r=0;r0},extendFrom:function(t,e){if(t)for(var i in t)!t.hasOwnProperty(i)||!0!==e&&(!1===e?this.hasOwnProperty(i):null==t[i])||(this[i]=t[i])},set:function(t,e){"string"==typeof t?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(t,e,i){for(var n=("radial"===e.type?Se:be)(t,e,i),o=e.colorStops,a=0;a=0&&i.splice(n,1),t.__hoverMir=null},clearHover:function(t){for(var e=this._hoverElements,i=0;i15)break}s.__drawIndex=m,s.__drawIndex0&&t>n[0]){for(r=0;rt);r++);a=i[n[r]]}if(n.splice(r+1,0,t),i[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?s.insertBefore(e.dom,l.nextSibling):s.appendChild(e.dom)}else s.firstChild?s.insertBefore(e.dom,s.firstChild):s.appendChild(e.dom)}else Yw("Layer of zlevel "+t+" is not valid")},eachLayer:function(t,e){var i,n,o=this._zlevelList;for(n=0;n0?.01:0),this._needsManuallyCompositing),a.__builtin__||Yw("ZLevel "+s+" has been used by unkown layer "+a.id),a!==i&&(a.__used=!0,a.__startIndex!==o&&(a.__dirty=!0),a.__startIndex=o,a.incremental?a.__drawIndex=-1:a.__drawIndex=o,e(o),i=a),r.__dirty&&(a.__dirty=!0,a.incremental&&a.__drawIndex<0&&(a.__drawIndex=o))}e(o),this.eachBuiltinLayer(function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)})},clear:function(){return this.eachBuiltinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},setBackgroundColor:function(t){this._backgroundColor=t},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?n(i[t],e,!0):i[t]=e;for(var o=0;o=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;i=0||n&&l(n,r)<0)){var s=e.getShallow(r);null!=s&&(o[t[a][0]]=s)}}return o}},tS=Qb([["lineWidth","width"],["stroke","color"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),eS={getLineStyle:function(t){var e=tS(this,t),i=this.getLineDash(e.lineWidth);return i&&(e.lineDash=i),e},getLineDash:function(t){null==t&&(t=1);var e=this.get("type"),i=Math.max(t,2),n=4*t;return"solid"===e||null==e?null:"dashed"===e?[n,n]:[i,i]}},iS=Qb([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),nS={getAreaStyle:function(t,e){return iS(this,t,e)}},oS=Math.pow,aS=Math.sqrt,rS=1e-8,sS=1e-4,lS=aS(3),uS=1/3,hS=V(),cS=V(),dS=V(),fS=Math.min,pS=Math.max,gS=Math.sin,mS=Math.cos,vS=2*Math.PI,yS=V(),xS=V(),_S=V(),wS=[],bS=[],SS={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},MS=[],IS=[],TS=[],AS=[],DS=Math.min,CS=Math.max,LS=Math.cos,kS=Math.sin,PS=Math.sqrt,NS=Math.abs,OS="undefined"!=typeof Float32Array,ES=function(t){this._saveData=!t,this._saveData&&(this.data=[]),this._ctx=null};ES.prototype={constructor:ES,_xi:0,_yi:0,_x0:0,_y0:0,_ux:0,_uy:0,_len:0,_lineDash:null,_dashOffset:0,_dashIdx:0,_dashSum:0,setScale:function(t,e){this._ux=NS(1/Xw/t)||0,this._uy=NS(1/Xw/e)||0},getContext:function(){return this._ctx},beginPath:function(t){return this._ctx=t,t&&t.beginPath(),t&&(this.dpr=t.dpr),this._saveData&&(this._len=0),this._lineDash&&(this._lineDash=null,this._dashOffset=0),this},moveTo:function(t,e){return this.addData(SS.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},lineTo:function(t,e){var i=NS(t-this._xi)>this._ux||NS(e-this._yi)>this._uy||this._len<5;return this.addData(SS.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,o,a){return this.addData(SS.C,t,e,i,n,o,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,o,a):this._ctx.bezierCurveTo(t,e,i,n,o,a)),this._xi=o,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(SS.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,o,a){return this.addData(SS.A,t,e,i,i,n,o-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,o,a),this._xi=LS(o)*i+t,this._yi=kS(o)*i+e,this},arcTo:function(t,e,i,n,o){return this._ctx&&this._ctx.arcTo(t,e,i,n,o),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(SS.R,t,e,i,n),this},closePath:function(){this.addData(SS.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;ie.length&&(this._expandData(),e=this.data);for(var i=0;i0&&f<=t||h<0&&f>=t||0===h&&(c>0&&p<=e||c<0&&p>=e);)f+=h*(i=r[n=this._dashIdx]),p+=c*i,this._dashIdx=(n+1)%g,h>0&&fl||c>0&&pu||s[n%2?"moveTo":"lineTo"](h>=0?DS(f,t):CS(f,t),c>=0?DS(p,e):CS(p,e));h=f-t,c=p-e,this._dashOffset=-PS(h*h+c*c)},_dashedBezierTo:function(t,e,i,n,o,a){var r,s,l,u,h,c=this._dashSum,d=this._dashOffset,f=this._lineDash,p=this._ctx,g=this._xi,m=this._yi,v=tn,y=0,x=this._dashIdx,_=f.length,w=0;for(d<0&&(d=c+d),d%=c,r=0;r<1;r+=.1)s=v(g,t,i,o,r+.1)-v(g,t,i,o,r),l=v(m,e,n,a,r+.1)-v(m,e,n,a,r),y+=PS(s*s+l*l);for(;x<_&&!((w+=f[x])>d);x++);for(r=(w-d)/y;r<=1;)u=v(g,t,i,o,r),h=v(m,e,n,a,r),x%2?p.moveTo(u,h):p.lineTo(u,h),r+=f[x]/y,x=(x+1)%_;x%2!=0&&p.lineTo(o,a),s=o-u,l=a-h,this._dashOffset=-PS(s*s+l*l)},_dashedQuadraticTo:function(t,e,i,n){var o=i,a=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,o,a)},toStatic:function(){var t=this.data;t instanceof Array&&(t.length=this._len,OS&&(this.data=new Float32Array(t)))},getBoundingRect:function(){MS[0]=MS[1]=TS[0]=TS[1]=Number.MAX_VALUE,IS[0]=IS[1]=AS[0]=AS[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,n=0,o=0,a=0;al||NS(r-o)>u||c===h-1)&&(t.lineTo(a,r),n=a,o=r);break;case SS.C:t.bezierCurveTo(s[c++],s[c++],s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case SS.Q:t.quadraticCurveTo(s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case SS.A:var f=s[c++],p=s[c++],g=s[c++],m=s[c++],v=s[c++],y=s[c++],x=s[c++],_=s[c++],w=g>m?g:m,b=g>m?1:g/m,S=g>m?m/g:1,M=v+y;Math.abs(g-m)>.001?(t.translate(f,p),t.rotate(x),t.scale(b,S),t.arc(0,0,w,v,M,1-_),t.scale(1/b,1/S),t.rotate(-x),t.translate(-f,-p)):t.arc(f,p,w,v,M,1-_),1===c&&(e=LS(v)*g+f,i=kS(v)*m+p),n=LS(M)*g+f,o=kS(M)*m+p;break;case SS.R:e=n=s[c],i=o=s[c+1],t.rect(s[c++],s[c++],s[c++],s[c++]);break;case SS.Z:t.closePath(),n=e,o=i}}}},ES.CMD=SS;var RS=2*Math.PI,zS=2*Math.PI,BS=ES.CMD,VS=2*Math.PI,GS=1e-4,FS=[-1,-1,-1],WS=[-1,-1],HS=fb.prototype.getCanvasPattern,ZS=Math.abs,US=new ES(!0);Pn.prototype={constructor:Pn,type:"path",__dirtyPath:!0,strokeContainThreshold:5,subPixelOptimize:!1,brush:function(t,e){var i=this.style,n=this.path||US,o=i.hasStroke(),a=i.hasFill(),r=i.fill,s=i.stroke,l=a&&!!r.colorStops,u=o&&!!s.colorStops,h=a&&!!r.image,c=o&&!!s.image;if(i.bind(t,this,e),this.setTransform(t),this.__dirty){var d;l&&(d=d||this.getBoundingRect(),this._fillGradient=i.getGradient(t,r,d)),u&&(d=d||this.getBoundingRect(),this._strokeGradient=i.getGradient(t,s,d))}l?t.fillStyle=this._fillGradient:h&&(t.fillStyle=HS.call(r,t)),u?t.strokeStyle=this._strokeGradient:c&&(t.strokeStyle=HS.call(s,t));var f=i.lineDash,p=i.lineDashOffset,g=!!t.setLineDash,m=this.getGlobalScale();if(n.setScale(m[0],m[1]),this.__dirtyPath||f&&!g&&o?(n.beginPath(t),f&&!g&&(n.setLineDash(f),n.setLineDashOffset(p)),this.buildPath(n,this.shape,!1),this.path&&(this.__dirtyPath=!1)):(t.beginPath(),this.path.rebuildPath(t)),a)if(null!=i.fillOpacity){v=t.globalAlpha;t.globalAlpha=i.fillOpacity*i.opacity,n.fill(t),t.globalAlpha=v}else n.fill(t);if(f&&g&&(t.setLineDash(f),t.lineDashOffset=p),o)if(null!=i.strokeOpacity){var v=t.globalAlpha;t.globalAlpha=i.strokeOpacity*i.opacity,n.stroke(t),t.globalAlpha=v}else n.stroke(t);f&&g&&t.setLineDash([]),null!=i.text&&(this.restoreTransform(t),this.drawRectText(t,this.getBoundingRect()))},buildPath:function(t,e,i){},createPathProxy:function(){this.path=new ES},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var n=this.path;n||(n=this.path=new ES),this.__dirtyPath&&(n.beginPath(),this.buildPath(n,this.shape,!1)),t=n.getBoundingRect()}if(this._rect=t,e.hasStroke()){var o=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){o.copy(t);var a=e.lineWidth,r=e.strokeNoScale?this.getLineScale():1;e.hasFill()||(a=Math.max(a,this.strokeContainThreshold||4)),r>1e-10&&(o.width+=a/r,o.height+=a/r,o.x-=a/r/2,o.y-=a/r/2)}return o}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this.getBoundingRect(),o=this.style;if(t=i[0],e=i[1],n.contain(t,e)){var a=this.path.data;if(o.hasStroke()){var r=o.lineWidth,s=o.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(o.hasFill()||(r=Math.max(r,this.strokeContainThreshold)),kn(a,r/s,t,e)))return!0}if(o.hasFill())return Ln(a,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=this.__dirtyText=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):di.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(w(t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&ZS(t[0]-1)>1e-10&&ZS(t[3]-1)>1e-10?Math.sqrt(ZS(t[0]*t[3]-t[2]*t[1])):1}},Pn.extend=function(t){var e=function(e){Pn.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var n=this.shape;for(var o in i)!n.hasOwnProperty(o)&&i.hasOwnProperty(o)&&(n[o]=i[o])}t.init&&t.init.call(this,e)};u(e,Pn);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},u(Pn,di);var XS=ES.CMD,jS=[[],[],[]],YS=Math.sqrt,qS=Math.atan2,KS=function(t,e){var i,n,o,a,r,s,l=t.data,u=XS.M,h=XS.C,c=XS.L,d=XS.R,f=XS.A,p=XS.Q;for(o=0,a=0;o=11?function(){var e,i=this.__clipPaths,n=this.style;if(i)for(var o=0;oi-2?i-1:c+1],u=t[c>i-3?i-1:c+2]);var p=d*d,g=d*p;n.push([Bn(s[0],f[0],l[0],u[0],d,p,g),Bn(s[1],f[1],l[1],u[1],d,p,g)])}return n},fM=function(t,e,i,n){var o,a,r,s,l=[],u=[],h=[],c=[];if(n){r=[1/0,1/0],s=[-1/0,-1/0];for(var d=0,f=t.length;d=i&&a>=o)return{x:i,y:o,width:n-i,height:a-o}},createIcon:Po,Group:tb,Image:fi,Text:rM,Circle:sM,Sector:hM,Ring:cM,Polygon:pM,Polyline:gM,Rect:yM,Line:_M,BezierCurve:bM,Arc:SM,IncrementalDisplayable:Zn,CompoundPath:MM,LinearGradient:TM,RadialGradient:AM,BoundingRect:de}),BM=["textStyle","color"],VM={getTextColor:function(t){var e=this.ecModel;return this.getShallow("color")||(!t&&e?e.get(BM):null)},getFont:function(){return So({fontStyle:this.getShallow("fontStyle"),fontWeight:this.getShallow("fontWeight"),fontSize:this.getShallow("fontSize"),fontFamily:this.getShallow("fontFamily")},this.ecModel)},getTextRect:function(t){return ke(t,this.getFont(),this.getShallow("align"),this.getShallow("verticalAlign")||this.getShallow("baseline"),this.getShallow("padding"),this.getShallow("lineHeight"),this.getShallow("rich"),this.getShallow("truncateText"))}},GM=Qb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"],["textPosition"],["textAlign"]]),FM={getItemStyle:function(t,e){var i=GM(this,t,e),n=this.getBorderLineDash();return n&&(i.lineDash=n),i},getBorderLineDash:function(){var t=this.get("borderType");return"solid"===t||null==t?null:"dashed"===t?[5,5]:[1,1]}},WM=h,HM=Bi();No.prototype={constructor:No,init:null,mergeOption:function(t){n(this.option,t,!0)},get:function(t,e){return null==t?this.option:Oo(this.option,this.parsePath(t),!e&&Eo(this,t))},getShallow:function(t,e){var i=this.option,n=null==i?i:i[t],o=!e&&Eo(this,t);return null==n&&o&&(n=o.getShallow(t)),n},getModel:function(t,e){var i,n=null==t?this.option:Oo(this.option,t=this.parsePath(t));return e=e||(i=Eo(this,t))&&i.getModel(t),new No(n,e,this.ecModel)},isEmpty:function(){return null==this.option},restoreData:function(){},clone:function(){return new(0,this.constructor)(i(this.option))},setReadOnly:function(t){},parsePath:function(t){return"string"==typeof t&&(t=t.split(".")),t},customizeGetParent:function(t){HM(this).getParent=t},isAnimationEnabled:function(){if(!U_.node){if(null!=this.option.animation)return!!this.option.animation;if(this.parentModel)return this.parentModel.isAnimationEnabled()}}},ji(No),Yi(No),WM(No,eS),WM(No,nS),WM(No,VM),WM(No,FM);var ZM=0,UM=1e-4,XM=9007199254740991,jM=/^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/,YM=(Object.freeze||Object)({linearMap:Bo,parsePercent:Vo,round:Go,asc:Fo,getPrecision:Wo,getPrecisionSafe:Ho,getPixelPrecision:Zo,getPercentWithPrecision:Uo,MAX_SAFE_INTEGER:XM,remRadian:Xo,isRadianAroundZero:jo,parseDate:Yo,quantity:qo,nice:$o,quantile:function(t,e){var i=(t.length-1)*e+1,n=Math.floor(i),o=+t[n-1],a=i-n;return a?o+a*(t[n]-o):o},reformIntervals:Jo,isNumeric:Qo}),qM=L,KM=/([&<>"'])/g,$M={"&":"&","<":"<",">":">",'"':""","'":"'"},JM=["a","b","c","d","e","f","g"],QM=function(t,e){return"{"+t+(null==e?"":e)+"}"},tI=ze,eI=(Object.freeze||Object)({addCommas:ta,toCamelCase:ea,normalizeCssArray:qM,encodeHTML:ia,formatTpl:na,formatTplSimple:oa,getTooltipMarker:aa,formatTime:sa,capitalFirst:la,truncateText:tI,getTextBoundingRect:function(t){return ke(t.text,t.font,t.textAlign,t.textVerticalAlign,t.textPadding,t.textLineHeight,t.rich,t.truncate)},getTextRect:function(t,e,i,n,o,a,r,s){return ke(t,e,i,n,o,s,a,r)}}),iI=d,nI=["left","right","top","bottom","width","height"],oI=[["width","left","right"],["height","top","bottom"]],aI=ua,rI=(v(ua,"vertical"),v(ua,"horizontal"),{getBoxLayoutParams:function(){return{left:this.get("left"),top:this.get("top"),right:this.get("right"),bottom:this.get("bottom"),width:this.get("width"),height:this.get("height")}}}),sI=Bi(),lI=No.extend({type:"component",id:"",name:"",mainType:"",subType:"",componentIndex:0,defaultOption:null,ecModel:null,dependentModels:[],uid:null,layoutMode:null,$constructor:function(t,e,i,n){No.call(this,t,e,i,n),this.uid=Ro("ec_cpt_model")},init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i)},mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,o=i?ga(t):{};n(t,e.getTheme().get(this.mainType)),n(t,this.getDefaultOption()),i&&pa(t,o,i)},mergeOption:function(t,e){n(this.option,t,!0);var i=this.layoutMode;i&&pa(this.option,t,i)},optionUpdated:function(t,e){},getDefaultOption:function(){var t=sI(this);if(!t.defaultOption){for(var e=[],i=this.constructor;i;){var o=i.prototype.defaultOption;o&&e.push(o),i=i.superClass}for(var a={},r=e.length-1;r>=0;r--)a=n(a,e[r],!0);t.defaultOption=a}return t.defaultOption},getReferringComponents:function(t){return this.ecModel.queryComponents({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});$i(lI,{registerWhenExtend:!0}),function(t){var e={};t.registerSubTypeDefaulter=function(t,i){t=Ui(t),e[t.main]=i},t.determineSubType=function(i,n){var o=n.type;if(!o){var a=Ui(i).main;t.hasSubTypes(i)&&e[a]&&(o=e[a](n))}return o}}(lI),function(t,e){function i(t){var i={},a=[];return d(t,function(r){var s=n(i,r),u=o(s.originalDeps=e(r),t);s.entryCount=u.length,0===s.entryCount&&a.push(r),d(u,function(t){l(s.predecessor,t)<0&&s.predecessor.push(t);var e=n(i,t);l(e.successor,t)<0&&e.successor.push(r)})}),{graph:i,noEntryList:a}}function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}function o(t,e){var i=[];return d(t,function(t){l(e,t)>=0&&i.push(t)}),i}t.topologicalTravel=function(t,e,n,o){function a(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}if(t.length){var r=i(e),s=r.graph,l=r.noEntryList,u={};for(d(t,function(t){u[t]=!0});l.length;){var h=l.pop(),c=s[h],f=!!u[h];f&&(n.call(o,h,c.originalDeps.slice()),delete u[h]),d(c.successor,f?function(t){u[t]=!0,a(t)}:a)}d(u,function(){throw new Error("Circle dependency may exists")})}}}(lI,function(t){var e=[];return d(lI.getClassesByMainType(t),function(t){e=e.concat(t.prototype.dependencies||[])}),e=f(e,function(t){return Ui(t).main}),"dataset"!==t&&l(e,"dataset")<=0&&e.unshift("dataset"),e}),h(lI,rI);var uI="";"undefined"!=typeof navigator&&(uI=navigator.platform||"");var hI={color:["#c23531","#2f4554","#61a0a8","#d48265","#91c7ae","#749f83","#ca8622","#bda29a","#6e7074","#546570","#c4ccd3"],gradientColor:["#f6efa6","#d88273","#bf444c"],textStyle:{fontFamily:uI.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,animation:"auto",animationDuration:1e3,animationDurationUpdate:300,animationEasing:"exponentialOut",animationEasingUpdate:"cubicOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},cI=Bi(),dI={clearColorPalette:function(){cI(this).colorIdx=0,cI(this).colorNameMap={}},getColorFromPalette:function(t,e,i){var n=cI(e=e||this),o=n.colorIdx||0,a=n.colorNameMap=n.colorNameMap||{};if(a.hasOwnProperty(t))return a[t];var r=Di(this.get("color",!0)),s=this.get("colorLayer",!0),l=null!=i&&s?va(s,i):r;if((l=l||r)&&l.length){var u=l[o];return t&&(a[t]=u),n.colorIdx=(o+1)%l.length,u}}},fI={cartesian2d:function(t,e,i,n){var o=t.getReferringComponents("xAxis")[0],a=t.getReferringComponents("yAxis")[0];e.coordSysDims=["x","y"],i.set("x",o),i.set("y",a),xa(o)&&(n.set("x",o),e.firstCategoryDimIndex=0),xa(a)&&(n.set("y",a),e.firstCategoryDimIndex=1)},singleAxis:function(t,e,i,n){var o=t.getReferringComponents("singleAxis")[0];e.coordSysDims=["single"],i.set("single",o),xa(o)&&(n.set("single",o),e.firstCategoryDimIndex=0)},polar:function(t,e,i,n){var o=t.getReferringComponents("polar")[0],a=o.findAxisModel("radiusAxis"),r=o.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],i.set("radius",a),i.set("angle",r),xa(a)&&(n.set("radius",a),e.firstCategoryDimIndex=0),xa(r)&&(n.set("angle",r),e.firstCategoryDimIndex=1)},geo:function(t,e,i,n){e.coordSysDims=["lng","lat"]},parallel:function(t,e,i,n){var o=t.ecModel,a=o.getComponent("parallel",t.get("parallelIndex")),r=e.coordSysDims=a.dimensions.slice();d(a.parallelAxisIndex,function(t,a){var s=o.getComponent("parallelAxis",t),l=r[a];i.set(l,s),xa(s)&&null==e.firstCategoryDimIndex&&(n.set(l,s),e.firstCategoryDimIndex=a)})}},pI="original",gI="arrayRows",mI="objectRows",vI="keyedColumns",yI="unknown",xI="typedArray",_I="column",wI="row";_a.seriesDataToSource=function(t){return new _a({data:t,sourceFormat:S(t)?xI:pI,fromDataset:!1})},Yi(_a);var bI=Bi(),SI="\0_ec_inner",MI=No.extend({init:function(t,e,i,n){i=i||{},this.option=null,this._theme=new No(i),this._optionManager=n},setOption:function(t,e){k(!(SI in t),"please use chart.getOption()"),this._optionManager.setOption(t,e),this.resetOption(null)},resetOption:function(t){var e=!1,i=this._optionManager;if(!t||"recreate"===t){var n=i.mountOption("recreate"===t);this.option&&"recreate"!==t?(this.restoreData(),this.mergeOption(n)):Ea.call(this,n),e=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(this.mergeOption(o),e=!0)}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this,this._api);a.length&&d(a,function(t){this.mergeOption(t,e=!0)},this)}return e},mergeOption:function(t){var e=this.option,o=this._componentsMap,r=[];Sa(this),d(t,function(t,o){null!=t&&(lI.hasClass(o)?o&&r.push(o):e[o]=null==e[o]?i(t):n(e[o],t,!0))}),lI.topologicalTravel(r,lI.getAllClassMainTypes(),function(i,n){var r=Di(t[i]),s=Pi(o.get(i),r);Ni(s),d(s,function(t,e){var n=t.option;w(n)&&(t.keyInfo.mainType=i,t.keyInfo.subType=za(i,n,t.exist))});var l=Ra(o,n);e[i]=[],o.set(i,[]),d(s,function(t,n){var r=t.exist,s=t.option;if(k(w(s)||r,"Empty component definition"),s){var u=lI.getClass(i,t.keyInfo.subType,!0);if(r&&r instanceof u)r.name=t.keyInfo.name,r.mergeOption(s,this),r.optionUpdated(s,!1);else{var h=a({dependentModels:l,componentIndex:n},t.keyInfo);a(r=new u(s,this,this,h),h),r.init(s,this,this,h),r.optionUpdated(null,!0)}}else r.mergeOption({},this),r.optionUpdated({},!1);o.get(i)[n]=r,e[i][n]=r.option},this),"series"===i&&Ba(this,o.get("series"))},this),this._seriesIndicesMap=R(this._seriesIndices=this._seriesIndices||[])},getOption:function(){var t=i(this.option);return d(t,function(e,i){if(lI.hasClass(i)){for(var n=(e=Di(e)).length-1;n>=0;n--)Ei(e[n])&&e.splice(n,1);t[i]=e}}),delete t[SI],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap.get(t);if(i)return i[e||0]},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,o=t.name,a=this._componentsMap.get(e);if(!a||!a.length)return[];var r;if(null!=i)y(i)||(i=[i]),r=g(f(i,function(t){return a[t]}),function(t){return!!t});else if(null!=n){var s=y(n);r=g(a,function(t){return s&&l(n,t.id)>=0||!s&&t.id===n})}else if(null!=o){var u=y(o);r=g(a,function(t){return u&&l(o,t.name)>=0||!u&&t.name===o})}else r=a.slice();return Va(r,t)},findComponents:function(t){var e=t.query,i=t.mainType,n=function(t){var e=i+"Index",n=i+"Id",o=i+"Name";return!t||null==t[e]&&null==t[n]&&null==t[o]?null:{mainType:i,index:t[e],id:t[n],name:t[o]}}(e);return function(e){return t.filter?g(e,t.filter):e}(Va(n?this.queryComponents(n):this._componentsMap.get(i),t))},eachComponent:function(t,e,i){var n=this._componentsMap;"function"==typeof t?(i=e,e=t,n.each(function(t,n){d(t,function(t,o){e.call(i,n,t,o)})})):_(t)?d(n.get(t),e,i):w(t)&&d(this.findComponents(t),e,i)},getSeriesByName:function(t){return g(this._componentsMap.get("series"),function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap.get("series")[t]},getSeriesByType:function(t){return g(this._componentsMap.get("series"),function(e){return e.subType===t})},getSeries:function(){return this._componentsMap.get("series").slice()},getSeriesCount:function(){return this._componentsMap.get("series").length},eachSeries:function(t,e){d(this._seriesIndices,function(i){var n=this._componentsMap.get("series")[i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){d(this._componentsMap.get("series"),t,e)},eachSeriesByType:function(t,e,i){d(this._seriesIndices,function(n){var o=this._componentsMap.get("series")[n];o.subType===t&&e.call(i,o,n)},this)},eachRawSeriesByType:function(t,e,i){return d(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return null==this._seriesIndicesMap.get(t.componentIndex)},getCurrentSeriesIndices:function(){return(this._seriesIndices||[]).slice()},filterSeries:function(t,e){Ba(this,g(this._componentsMap.get("series"),t,e))},restoreData:function(t){var e=this._componentsMap;Ba(this,e.get("series"));var i=[];e.each(function(t,e){i.push(e)}),lI.topologicalTravel(i,lI.getAllClassMainTypes(),function(i,n){d(e.get(i),function(e){("series"!==i||!Na(e,t))&&e.restoreData()})})}});h(MI,dI);var II=["getDom","getZr","getWidth","getHeight","getDevicePixelRatio","dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL","getModel","getOption","getViewOfComponentModel","getViewOfSeriesModel"],TI={};Fa.prototype={constructor:Fa,create:function(t,e){var i=[];d(TI,function(n,o){var a=n.create(t,e);i=i.concat(a||[])}),this._coordinateSystems=i},update:function(t,e){d(this._coordinateSystems,function(i){i.update&&i.update(t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},Fa.register=function(t,e){TI[t]=e},Fa.get=function(t){return TI[t]};var AI=d,DI=i,CI=f,LI=n,kI=/^(min|max)?(.+)$/;Wa.prototype={constructor:Wa,setOption:function(t,e){t&&d(Di(t.series),function(t){t&&t.data&&S(t.data)&&N(t.data)}),t=DI(t,!0);var i=this._optionBackup,n=Ha.call(this,t,e,!i);this._newBaseOption=n.baseOption,i?(ja(i.baseOption,n.baseOption),n.timelineOptions.length&&(i.timelineOptions=n.timelineOptions),n.mediaList.length&&(i.mediaList=n.mediaList),n.mediaDefault&&(i.mediaDefault=n.mediaDefault)):this._optionBackup=n},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=CI(e.timelineOptions,DI),this._mediaList=CI(e.mediaList,DI),this._mediaDefault=DI(e.mediaDefault),this._currentMediaIndices=[],DI(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i.length){var n=t.getComponent("timeline");n&&(e=DI(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(t){var e=this._api.getWidth(),i=this._api.getHeight(),n=this._mediaList,o=this._mediaDefault,a=[],r=[];if(!n.length&&!o)return r;for(var s=0,l=n.length;s=1)&&(t=1),t}var i=this._upstream,n=t&&t.skip;if(this._dirty&&i){var o=this.context;o.data=o.outputData=i.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this);var a;this._plan&&!n&&(a=this._plan(this.context));var r=e(this._modBy),s=this._modDataCount||0,l=e(t&&t.modBy),u=t&&t.modDataCount||0;r===l&&s===u||(a="reset");var h;(this._dirty||"reset"===a)&&(this._dirty=!1,h=yr(this,n)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=i?i._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var d=this._dueIndex,f=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!n&&(h||d=i?null:t1&&a>0?e:t}};return s}();UI.dirty=function(){this._dirty=!0,this._onDirty&&this._onDirty(this.context)},UI.unfinished=function(){return this._progress&&this._dueIndex":"\n",s="richText"===n,l={},u=0,h=this.getData(),c=h.mapDimension("defaultedTooltip",!0),f=c.length,g=this.getRawValue(t),m=y(g),v=h.getItemVisual(t,"color");w(v)&&v.colorStops&&(v=(v.colorStops[0]||{}).color),v=v||"transparent";var x=(f>1||m&&!f?function(i){function o(t,i){var o=h.getDimensionInfo(i);if(o&&!1!==o.otherDims.tooltip){var c=o.type,d="sub"+a.seriesIndex+"at"+u,p=aa({color:v,type:"subItem",renderMode:n,markerId:d}),g="string"==typeof p?p:p.content,m=(r?g+ia(o.displayName||"-")+": ":"")+ia("ordinal"===c?t+"":"time"===c?e?"":sa("yyyy/MM/dd hh:mm:ss",t):ta(t));m&&f.push(m),s&&(l[d]=v,++u)}}var r=p(i,function(t,e,i){var n=h.getDimensionInfo(i);return t|=n&&!1!==n.tooltip&&null!=n.displayName},0),f=[];c.length?d(c,function(e){o(fr(h,t,e),e)}):d(i,o);var g=r?s?"\n":"
":"",m=g+f.join(g||", ");return{renderMode:n,content:m,style:l}}(g):o(f?fr(h,t,c[0]):m?g[0]:g)).content,_=a.seriesIndex+"at"+u,b=aa({color:v,type:"item",renderMode:n,markerId:_});l[_]=v,++u;var S=h.getName(t),M=this.name;Oi(this)||(M=""),M=M?ia(M)+(e?": ":r):"";var I="string"==typeof b?b:b.content;return{html:e?I+M+x:M+I+(S?ia(S)+": "+x:x),markers:l}},isAnimationEnabled:function(){if(U_.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){this.dataTask.dirty()},getColorFromPalette:function(t,e,i){var n=this.ecModel,o=dI.getColorFromPalette.call(this,t,e,i);return o||(o=n.getColorFromPalette(t,e,i)),o},coordDimToDataDim:function(t){return this.getRawData().mapDimension(t,!0)},getProgressive:function(){return this.get("progressive")},getProgressiveThreshold:function(){return this.get("progressiveThreshold")},getAxisTooltipData:null,getTooltipPosition:null,pipeTask:null,preventIncremental:null,pipelineContext:null});h(YI,ZI),h(YI,dI);var qI=function(){this.group=new tb,this.uid=Ro("viewComponent")};qI.prototype={constructor:qI,init:function(t,e){},render:function(t,e,i,n){},dispose:function(){},filterForExposedEvent:null};var KI=qI.prototype;KI.updateView=KI.updateLayout=KI.updateVisual=function(t,e,i,n){},ji(qI),$i(qI,{registerWhenExtend:!0});var $I=function(){var t=Bi();return function(e){var i=t(e),n=e.pipelineContext,o=i.large,a=i.progressiveRender,r=i.large=n.large,s=i.progressiveRender=n.progressiveRender;return!!(o^r||a^s)&&"reset"}},JI=Bi(),QI=$I();Ar.prototype={type:"chart",init:function(t,e){},render:function(t,e,i,n){},highlight:function(t,e,i,n){Cr(t.getData(),n,"emphasis")},downplay:function(t,e,i,n){Cr(t.getData(),n,"normal")},remove:function(t,e){this.group.removeAll()},dispose:function(){},incrementalPrepareRender:null,incrementalRender:null,updateTransform:null,filterForExposedEvent:null};var tT=Ar.prototype;tT.updateView=tT.updateLayout=tT.updateVisual=function(t,e,i,n){this.render(t,e,i,n)},ji(Ar),$i(Ar,{registerWhenExtend:!0}),Ar.markUpdateMethod=function(t,e){JI(t).updateMethod=e};var eT={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},iT="\0__throttleOriginMethod",nT="\0__throttleRate",oT="\0__throttleType",aT={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var i=t.getData(),n=(t.visualColorAccessPath||"itemStyle.color").split("."),o=t.get(n)||t.getColorFromPalette(t.name,null,e.getSeriesCount());if(i.setVisual("color",o),!e.isSeriesFiltered(t)){"function"!=typeof o||o instanceof IM||i.each(function(e){i.setItemVisual(e,"color",o(t.getDataParams(e)))});return{dataEach:i.hasItemOption?function(t,e){var i=t.getItemModel(e).get(n,!0);null!=i&&t.setItemVisual(e,"color",i)}:null}}}},rT={toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}},sT=function(t,e){function i(t,e){if("string"!=typeof t)return t;var i=t;return d(e,function(t,e){i=i.replace(new RegExp("\\{\\s*"+e+"\\s*\\}","g"),t)}),i}function n(t){var e=a.get(t);if(null==e){for(var i=t.split("."),n=rT.aria,o=0;o1?"series.multiple.prefix":"series.single.prefix"),{seriesCount:r}),e.eachSeries(function(t,e){if(e1?"multiple":"single")+".";a=i(a=n(s?u+"withName":u+"withoutName"),{seriesId:t.seriesIndex,seriesName:t.get("name"),seriesType:o(t.subType)});var c=t.getData();window.data=c,c.count()>l?a+=i(n("data.partialData"),{displayCnt:l}):a+=n("data.allData");for(var d=[],p=0;pi.blockIndex?i.step:null,a=n&&n.modDataCount;return{step:o,modBy:null!=a?Math.ceil(a/o):null,modDataCount:a}}},uT.getPipeline=function(t){return this._pipelineMap.get(t)},uT.updateStreamModes=function(t,e){var i=this._pipelineMap.get(t.uid),n=t.getData().count(),o=i.progressiveEnabled&&e.incrementalPrepareRender&&n>=i.threshold,a=t.get("large")&&n>=t.get("largeThreshold"),r="mod"===t.get("progressiveChunkMode")?n:null;t.pipelineContext=i.context={progressiveRender:o,modDataCount:r,large:a}},uT.restorePipelines=function(t){var e=this,i=e._pipelineMap=R();t.eachSeries(function(t){var n=t.getProgressive(),o=t.uid;i.set(o,{id:o,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:n&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(n||700),count:0}),jr(e,t,t.dataTask)})},uT.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.ecInstance.getModel(),i=this.api;d(this._allHandlers,function(n){var o=t.get(n.uid)||t.set(n.uid,[]);n.reset&&zr(this,n,o,e,i),n.overallReset&&Br(this,n,o,e,i)},this)},uT.prepareView=function(t,e,i,n){var o=t.renderTask,a=o.context;a.model=e,a.ecModel=i,a.api=n,o.__block=!t.incrementalPrepareRender,jr(this,e,o)},uT.performDataProcessorTasks=function(t,e){Rr(this,this._dataProcessorHandlers,t,e,{block:!0})},uT.performVisualTasks=function(t,e,i){Rr(this,this._visualHandlers,t,e,i)},uT.performSeriesTasks=function(t){var e;t.eachSeries(function(t){e|=t.dataTask.perform()}),this.unfinished|=e},uT.plan=function(){this._pipelineMap.each(function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)})};var hT=uT.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},cT=Ur(0);Er.wrapStageHandler=function(t,e){return x(t)&&(t={overallReset:t,seriesType:Yr(t)}),t.uid=Ro("stageHandler"),e&&(t.visualType=e),t};var dT,fT={},pT={};qr(fT,MI),qr(pT,Ga),fT.eachSeriesByType=fT.eachRawSeriesByType=function(t){dT=t},fT.eachComponent=function(t){"series"===t.mainType&&t.subType&&(dT=t.subType)};var gT=["#37A2DA","#32C5E9","#67E0E3","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#E062AE","#E690D1","#e7bcf3","#9d96f5","#8378EA","#96BFFF"],mT={color:gT,colorLayer:[["#37A2DA","#ffd85c","#fd7b5f"],["#37A2DA","#67E0E3","#FFDB5C","#ff9f7f","#E062AE","#9d96f5"],["#37A2DA","#32C5E9","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#e7bcf3","#8378EA","#96BFFF"],gT]},vT=["#dd6b66","#759aa0","#e69d87","#8dc1a9","#ea7e53","#eedd78","#73a373","#73b9bc","#7289ab","#91ca8c","#f49f42"],yT={color:vT,backgroundColor:"#333",tooltip:{axisPointer:{lineStyle:{color:"#eee"},crossStyle:{color:"#eee"}}},legend:{textStyle:{color:"#eee"}},textStyle:{color:"#eee"},title:{textStyle:{color:"#eee"}},toolbox:{iconStyle:{normal:{borderColor:"#eee"}}},dataZoom:{textStyle:{color:"#eee"}},visualMap:{textStyle:{color:"#eee"}},timeline:{lineStyle:{color:"#eee"},itemStyle:{normal:{color:vT[1]}},label:{normal:{textStyle:{color:"#eee"}}},controlStyle:{normal:{color:"#eee",borderColor:"#eee"}}},timeAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},logAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},valueAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},categoryAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},line:{symbol:"circle"},graph:{color:vT},gauge:{title:{textStyle:{color:"#eee"}}},candlestick:{itemStyle:{normal:{color:"#FD1050",color0:"#0CF49B",borderColor:"#FD1050",borderColor0:"#0CF49B"}}}};yT.categoryAxis.splitLine.show=!1,lI.extend({type:"dataset",defaultOption:{seriesLayoutBy:_I,sourceHeader:null,dimensions:null,source:null},optionUpdated:function(){wa(this)}}),qI.extend({type:"dataset"});var xT=Pn.extend({type:"ellipse",shape:{cx:0,cy:0,rx:0,ry:0},buildPath:function(t,e){var i=.5522848,n=e.cx,o=e.cy,a=e.rx,r=e.ry,s=a*i,l=r*i;t.moveTo(n-a,o),t.bezierCurveTo(n-a,o-l,n-s,o-r,n,o-r),t.bezierCurveTo(n+s,o-r,n+a,o-l,n+a,o),t.bezierCurveTo(n+a,o+l,n+s,o+r,n,o+r),t.bezierCurveTo(n-s,o+r,n-a,o+l,n-a,o),t.closePath()}}),_T=/[\s,]+/;$r.prototype.parse=function(t,e){e=e||{};var i=Kr(t);if(!i)throw new Error("Illegal svg");var n=new tb;this._root=n;var o=i.getAttribute("viewBox")||"",a=parseFloat(i.getAttribute("width")||e.width),r=parseFloat(i.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(r)&&(r=null),es(i,n,null,!0);for(var s=i.firstChild;s;)this._parseNode(s,n),s=s.nextSibling;var l,u;if(o){var h=P(o).split(_T);h.length>=4&&(l={x:parseFloat(h[0]||0),y:parseFloat(h[1]||0),width:parseFloat(h[2]),height:parseFloat(h[3])})}if(l&&null!=a&&null!=r&&(u=as(l,a,r),!e.ignoreViewBox)){var c=n;(n=new tb).add(c),c.scale=u.scale.slice(),c.position=u.position.slice()}return e.ignoreRootClip||null==a||null==r||n.setClipPath(new yM({shape:{x:0,y:0,width:a,height:r}})),{root:n,width:a,height:r,viewBoxRect:l,viewBoxTransform:u}},$r.prototype._parseNode=function(t,e){var i=t.nodeName.toLowerCase();"defs"===i?this._isDefine=!0:"text"===i&&(this._isText=!0);var n;if(this._isDefine){if(r=bT[i]){var o=r.call(this,t),a=t.getAttribute("id");a&&(this._defs[a]=o)}}else{var r=wT[i];r&&(n=r.call(this,t,e),e.add(n))}for(var s=t.firstChild;s;)1===s.nodeType&&this._parseNode(s,n),3===s.nodeType&&this._isText&&this._parseText(s,n),s=s.nextSibling;"defs"===i?this._isDefine=!1:"text"===i&&(this._isText=!1)},$r.prototype._parseText=function(t,e){if(1===t.nodeType){var i=t.getAttribute("dx")||0,n=t.getAttribute("dy")||0;this._textX+=parseFloat(i),this._textY+=parseFloat(n)}var o=new rM({style:{text:t.textContent,transformText:!0},position:[this._textX||0,this._textY||0]});Qr(e,o),es(t,o,this._defs);var a=o.style.fontSize;a&&a<9&&(o.style.fontSize=9,o.scale=o.scale||[1,1],o.scale[0]*=a/9,o.scale[1]*=a/9);var r=o.getBoundingRect();return this._textX+=r.width,e.add(o),o};var wT={g:function(t,e){var i=new tb;return Qr(e,i),es(t,i,this._defs),i},rect:function(t,e){var i=new yM;return Qr(e,i),es(t,i,this._defs),i.setShape({x:parseFloat(t.getAttribute("x")||0),y:parseFloat(t.getAttribute("y")||0),width:parseFloat(t.getAttribute("width")||0),height:parseFloat(t.getAttribute("height")||0)}),i},circle:function(t,e){var i=new sM;return Qr(e,i),es(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),r:parseFloat(t.getAttribute("r")||0)}),i},line:function(t,e){var i=new _M;return Qr(e,i),es(t,i,this._defs),i.setShape({x1:parseFloat(t.getAttribute("x1")||0),y1:parseFloat(t.getAttribute("y1")||0),x2:parseFloat(t.getAttribute("x2")||0),y2:parseFloat(t.getAttribute("y2")||0)}),i},ellipse:function(t,e){var i=new xT;return Qr(e,i),es(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),rx:parseFloat(t.getAttribute("rx")||0),ry:parseFloat(t.getAttribute("ry")||0)}),i},polygon:function(t,e){var i=t.getAttribute("points");i&&(i=ts(i));var n=new pM({shape:{points:i||[]}});return Qr(e,n),es(t,n,this._defs),n},polyline:function(t,e){var i=new Pn;Qr(e,i),es(t,i,this._defs);var n=t.getAttribute("points");return n&&(n=ts(n)),new gM({shape:{points:n||[]}})},image:function(t,e){var i=new fi;return Qr(e,i),es(t,i,this._defs),i.setStyle({image:t.getAttribute("xlink:href"),x:t.getAttribute("x"),y:t.getAttribute("y"),width:t.getAttribute("width"),height:t.getAttribute("height")}),i},text:function(t,e){var i=t.getAttribute("x")||0,n=t.getAttribute("y")||0,o=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0;this._textX=parseFloat(i)+parseFloat(o),this._textY=parseFloat(n)+parseFloat(a);var r=new tb;return Qr(e,r),es(t,r,this._defs),r},tspan:function(t,e){var i=t.getAttribute("x"),n=t.getAttribute("y");null!=i&&(this._textX=parseFloat(i)),null!=n&&(this._textY=parseFloat(n));var o=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0,r=new tb;return Qr(e,r),es(t,r,this._defs),this._textX+=o,this._textY+=a,r},path:function(t,e){var i=Rn(t.getAttribute("d")||"");return Qr(e,i),es(t,i,this._defs),i}},bT={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||0,10),i=parseInt(t.getAttribute("y1")||0,10),n=parseInt(t.getAttribute("x2")||10,10),o=parseInt(t.getAttribute("y2")||0,10),a=new TM(e,i,n,o);return Jr(t,a),a},radialgradient:function(t){}},ST={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-align":"textAlign","alignment-baseline":"textBaseline"},MT=/url\(\s*#(.*?)\)/,IT=/(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.e,]*)\)/g,TT=/([^\s:;]+)\s*:\s*([^:;]+)/g,AT=R(),DT={registerMap:function(t,e,i){var n;return y(e)?n=e:e.svg?n=[{type:"svg",source:e.svg,specialAreas:e.specialAreas}]:(e.geoJson&&!e.features&&(i=e.specialAreas,e=e.geoJson),n=[{type:"geoJSON",source:e,specialAreas:i}]),d(n,function(t){var e=t.type;"geoJson"===e&&(e=t.type="geoJSON"),(0,CT[e])(t)}),AT.set(t,n)},retrieveMap:function(t){return AT.get(t)}},CT={geoJSON:function(t){var e=t.source;t.geoJSON=_(e)?"undefined"!=typeof JSON&&JSON.parse?JSON.parse(e):new Function("return ("+e+");")():e},svg:function(t){t.svgXML=Kr(t.source)}},LT=k,kT=d,PT=x,NT=w,OT=lI.parseClassType,ET={zrender:"4.0.6"},RT=1e3,zT=1e3,BT=3e3,VT={PROCESSOR:{FILTER:RT,STATISTIC:5e3},VISUAL:{LAYOUT:zT,GLOBAL:2e3,CHART:BT,COMPONENT:4e3,BRUSH:5e3}},GT="__flagInMainProcess",FT="__optionUpdated",WT=/^[a-zA-Z0-9_]+$/;ls.prototype.on=ss("on"),ls.prototype.off=ss("off"),ls.prototype.one=ss("one"),h(ls,fw);var HT=us.prototype;HT._onframe=function(){if(!this._disposed){var t=this._scheduler;if(this[FT]){var e=this[FT].silent;this[GT]=!0,cs(this),ZT.update.call(this),this[GT]=!1,this[FT]=!1,gs.call(this,e),ms.call(this,e)}else if(t.unfinished){var i=1,n=this._model;this._api;t.unfinished=!1;do{var o=+new Date;t.performSeriesTasks(n),t.performDataProcessorTasks(n),fs(this,n),t.performVisualTasks(n),bs(this,this._model,0,"remain"),i-=+new Date-o}while(i>0&&t.unfinished);t.unfinished||this._zr.flush()}}},HT.getDom=function(){return this._dom},HT.getZr=function(){return this._zr},HT.setOption=function(t,e,i){var n;if(NT(e)&&(i=e.lazyUpdate,n=e.silent,e=e.notMerge),this[GT]=!0,!this._model||e){var o=new Wa(this._api),a=this._theme,r=this._model=new MI(null,null,a,o);r.scheduler=this._scheduler,r.init(null,null,a,o)}this._model.setOption(t,qT),i?(this[FT]={silent:n},this[GT]=!1):(cs(this),ZT.update.call(this),this._zr.flush(),this[FT]=!1,this[GT]=!1,gs.call(this,n),ms.call(this,n))},HT.setTheme=function(){console.error("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},HT.getModel=function(){return this._model},HT.getOption=function(){return this._model&&this._model.getOption()},HT.getWidth=function(){return this._zr.getWidth()},HT.getHeight=function(){return this._zr.getHeight()},HT.getDevicePixelRatio=function(){return this._zr.painter.dpr||window.devicePixelRatio||1},HT.getRenderedCanvas=function(t){if(U_.canvasSupported)return(t=t||{}).pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor"),this._zr.painter.getRenderedCanvas(t)},HT.getSvgDataUrl=function(){if(U_.svgSupported){var t=this._zr;return d(t.storage.getDisplayList(),function(t){t.stopAnimation(!0)}),t.painter.pathToDataUrl()}},HT.getDataURL=function(t){var e=(t=t||{}).excludeComponents,i=this._model,n=[],o=this;kT(e,function(t){i.eachComponent({mainType:t},function(t){var e=o._componentsMap[t.__viewId];e.group.ignore||(n.push(e),e.group.ignore=!0)})});var a="svg"===this._zr.painter.getType()?this.getSvgDataUrl():this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return kT(n,function(t){t.group.ignore=!1}),a},HT.getConnectedDataURL=function(t){if(U_.canvasSupported){var e=this.group,n=Math.min,o=Math.max;if(eA[e]){var a=1/0,r=1/0,s=-1/0,l=-1/0,u=[],h=t&&t.pixelRatio||1;d(tA,function(h,c){if(h.group===e){var d=h.getRenderedCanvas(i(t)),f=h.getDom().getBoundingClientRect();a=n(f.left,a),r=n(f.top,r),s=o(f.right,s),l=o(f.bottom,l),u.push({dom:d,left:f.left,top:f.top})}});var c=(s*=h)-(a*=h),f=(l*=h)-(r*=h),p=iw();p.width=c,p.height=f;var g=Ii(p);return kT(u,function(t){var e=new fi({style:{x:t.left*h-a,y:t.top*h-r,image:t.dom}});g.add(e)}),g.refreshImmediately(),p.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}},HT.convertToPixel=v(hs,"convertToPixel"),HT.convertFromPixel=v(hs,"convertFromPixel"),HT.containPixel=function(t,e){var i;return t=Vi(this._model,t),d(t,function(t,n){n.indexOf("Models")>=0&&d(t,function(t){var o=t.coordinateSystem;if(o&&o.containPoint)i|=!!o.containPoint(e);else if("seriesModels"===n){var a=this._chartsMap[t.__viewId];a&&a.containPoint&&(i|=a.containPoint(e,t))}},this)},this),!!i},HT.getVisual=function(t,e){var i=(t=Vi(this._model,t,{defaultMainType:"series"})).seriesModel.getData(),n=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?i.indexOfRawIndex(t.dataIndex):null;return null!=n?i.getItemVisual(n,e):i.getVisual(e)},HT.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},HT.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]};var ZT={prepareAndUpdate:function(t){cs(this),ZT.update.call(this,t)},update:function(t){var e=this._model,i=this._api,n=this._zr,o=this._coordSysMgr,a=this._scheduler;if(e){a.restoreData(e,t),a.performSeriesTasks(e),o.create(e,i),a.performDataProcessorTasks(e,t),fs(this,e),o.update(e,i),xs(e),a.performVisualTasks(e,t),_s(this,e,i,t);var r=e.get("backgroundColor")||"transparent";if(U_.canvasSupported)n.setBackgroundColor(r);else{var s=Gt(r);r=qt(s,"rgb"),0===s[3]&&(r="transparent")}Ss(e,i)}},updateTransform:function(t){var e=this._model,i=this,n=this._api;if(e){var o=[];e.eachComponent(function(a,r){var s=i.getViewOfComponentModel(r);if(s&&s.__alive)if(s.updateTransform){var l=s.updateTransform(r,e,n,t);l&&l.update&&o.push(s)}else o.push(s)});var a=R();e.eachSeries(function(o){var r=i._chartsMap[o.__viewId];if(r.updateTransform){var s=r.updateTransform(o,e,n,t);s&&s.update&&a.set(o.uid,1)}else a.set(o.uid,1)}),xs(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0,dirtyMap:a}),bs(i,e,0,t,a),Ss(e,this._api)}},updateView:function(t){var e=this._model;e&&(Ar.markUpdateMethod(t,"updateView"),xs(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0}),_s(this,this._model,this._api,t),Ss(e,this._api))},updateVisual:function(t){ZT.update.call(this,t)},updateLayout:function(t){ZT.update.call(this,t)}};HT.resize=function(t){this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var i=e.resetOption("media"),n=t&&t.silent;this[GT]=!0,i&&cs(this),ZT.update.call(this),this[GT]=!1,gs.call(this,n),ms.call(this,n)}},HT.showLoading=function(t,e){if(NT(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),QT[t]){var i=QT[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},HT.hideLoading=function(){this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null},HT.makeActionFromEvent=function(t){var e=a({},t);return e.type=jT[t.type],e},HT.dispatchAction=function(t,e){NT(e)||(e={silent:!!e}),XT[t.type]&&this._model&&(this[GT]?this._pendingActions.push(t):(ps.call(this,t,e.silent),e.flush?this._zr.flush(!0):!1!==e.flush&&U_.browser.weChat&&this._throttledZrFlush(),gs.call(this,e.silent),ms.call(this,e.silent)))},HT.appendData=function(t){var e=t.seriesIndex;this.getModel().getSeriesByIndex(e).appendData(t),this._scheduler.unfinished=!0},HT.on=ss("on"),HT.off=ss("off"),HT.one=ss("one");var UT=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];HT._initEvents=function(){kT(UT,function(t){var e=function(e){var i,n=this.getModel(),o=e.target;if("globalout"===t)i={};else if(o&&null!=o.dataIndex){var r=o.dataModel||n.getSeriesByIndex(o.seriesIndex);i=r&&r.getDataParams(o.dataIndex,o.dataType,o)||{}}else o&&o.eventData&&(i=a({},o.eventData));if(i){var s=i.componentType,l=i.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=i.seriesIndex);var u=s&&null!=l&&n.getComponent(s,l),h=u&&this["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];i.event=e,i.type=t,this._ecEventProcessor.eventInfo={targetEl:o,packedEvent:i,model:u,view:h},this.trigger(t,i)}};e.zrEventfulCallAtLast=!0,this._zr.on(t,e,this)},this),kT(jT,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},HT.isDisposed=function(){return this._disposed},HT.clear=function(){this.setOption({series:[]},!0)},HT.dispose=function(){if(!this._disposed){this._disposed=!0,Fi(this.getDom(),oA,"");var t=this._api,e=this._model;kT(this._componentsViews,function(i){i.dispose(e,t)}),kT(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete tA[this.id]}},h(us,fw),Ds.prototype={constructor:Ds,normalizeQuery:function(t){var e={},i={},n={};if(_(t)){var o=OT(t);e.mainType=o.main||null,e.subType=o.sub||null}else{var a=["Index","Name","Id"],r={name:1,dataIndex:1,dataType:1};d(t,function(t,o){for(var s=!1,l=0;l0&&h===o.length-u.length){var c=o.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}r.hasOwnProperty(o)&&(i[o]=t,s=!0),s||(n[o]=t)})}return{cptQuery:e,dataQuery:i,otherQuery:n}},filter:function(t,e,i){function n(t,e,i,n){return null==t[i]||e[n||i]===t[i]}var o=this.eventInfo;if(!o)return!0;var a=o.targetEl,r=o.packedEvent,s=o.model,l=o.view;if(!s||!l)return!0;var u=e.cptQuery,h=e.dataQuery;return n(u,s,"mainType")&&n(u,s,"subType")&&n(u,s,"index","componentIndex")&&n(u,s,"name")&&n(u,s,"id")&&n(h,r,"name")&&n(h,r,"dataIndex")&&n(h,r,"dataType")&&(!l.filterForExposedEvent||l.filterForExposedEvent(t,e.otherQuery,a,r))},afterTrigger:function(){this.eventInfo=null}};var XT={},jT={},YT=[],qT=[],KT=[],$T=[],JT={},QT={},tA={},eA={},iA=new Date-0,nA=new Date-0,oA="_echarts_instance_",aA=Ls;Bs(2e3,aT),Ns(BI),Os(5e3,function(t){var e=R();t.eachSeries(function(t){var i=t.get("stack");if(i){var n=e.get(i)||e.set(i,[]),o=t.getData(),a={stackResultDimension:o.getCalculationInfo("stackResultDimension"),stackedOverDimension:o.getCalculationInfo("stackedOverDimension"),stackedDimension:o.getCalculationInfo("stackedDimension"),stackedByDimension:o.getCalculationInfo("stackedByDimension"),isStackedByIndex:o.getCalculationInfo("isStackedByIndex"),data:o,seriesModel:t};if(!a.stackedDimension||!a.isStackedByIndex&&!a.stackedByDimension)return;n.length&&o.setCalculationInfo("stackedOnSeries",n[n.length-1].seriesModel),n.push(a)}}),e.each(ar)}),Gs("default",function(t,e){r(e=e||{},{text:"loading",color:"#c23531",textColor:"#000",maskColor:"rgba(255, 255, 255, 0.8)",zlevel:0});var i=new yM({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4}),n=new SM({shape:{startAngle:-lT/2,endAngle:-lT/2+.1,r:10},style:{stroke:e.color,lineCap:"round",lineWidth:5},zlevel:e.zlevel,z:10001}),o=new yM({style:{fill:"none",text:e.text,textPosition:"right",textDistance:10,textFill:e.textColor},zlevel:e.zlevel,z:10001});n.animateShape(!0).when(1e3,{endAngle:3*lT/2}).start("circularInOut"),n.animateShape(!0).when(1e3,{startAngle:3*lT/2}).delay(300).start("circularInOut");var a=new tb;return a.add(n),a.add(o),a.add(i),a.resize=function(){var e=t.getWidth()/2,a=t.getHeight()/2;n.setShape({cx:e,cy:a});var r=n.shape.r;o.setShape({x:e-r,y:a-r,width:2*r,height:2*r}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},a.resize(),a}),Es({type:"highlight",event:"highlight",update:"highlight"},B),Es({type:"downplay",event:"downplay",update:"downplay"},B),Ps("light",mT),Ps("dark",yT);var rA={};Xs.prototype={constructor:Xs,add:function(t){return this._add=t,this},update:function(t){return this._update=t,this},remove:function(t){return this._remove=t,this},execute:function(){var t=this._old,e=this._new,i={},n=[],o=[];for(js(t,{},n,"_oldKeyGetter",this),js(e,i,o,"_newKeyGetter",this),a=0;ax[1]&&(x[1]=y)}e&&(this._nameList[d]=e[f])}this._rawCount=this._count=l,this._extent={},el(this)},yA._initDataFromProvider=function(t,e){if(!(t>=e)){for(var i,n=this._chunkSize,o=this._rawData,a=this._storage,r=this.dimensions,s=r.length,l=this._dimensionInfos,u=this._nameList,h=this._idList,c=this._rawExtent,d=this._nameRepeatCount={},f=this._chunkCount,p=0;pM[1]&&(M[1]=S)}if(!o.pure){var I=u[v];if(m&&null==I)if(null!=m.name)u[v]=I=m.name;else if(null!=i){var T=r[i],A=a[T][y];if(A){I=A[x];var D=l[T].ordinalMeta;D&&D.categories.length&&(I=D.categories[I])}}var C=null==m?null:m.id;null==C&&null!=I&&(d[I]=d[I]||0,C=I,d[I]>0&&(C+="__ec__"+d[I]),d[I]++),null!=C&&(h[v]=C)}}!o.persistent&&o.clean&&o.clean(),this._rawCount=this._count=e,this._extent={},el(this)}},yA.count=function(){return this._count},yA.getIndices=function(){var t=this._indices;if(t){var e=t.constructor,i=this._count;if(e===Array){n=new e(i);for(o=0;o=0&&e=0&&ea&&(a=s)}return i=[o,a],this._extent[t]=i,i},yA.getApproximateExtent=function(t){return t=this.getDimension(t),this._approximateExtent[t]||this.getDataExtent(t)},yA.setApproximateExtent=function(t,e){e=this.getDimension(e),this._approximateExtent[e]=t.slice()},yA.getCalculationInfo=function(t){return this._calculationInfo[t]},yA.setCalculationInfo=function(t,e){lA(t)?a(this._calculationInfo,t):this._calculationInfo[t]=e},yA.getSum=function(t){var e=0;if(this._storage[t])for(var i=0,n=this.count();i=this._rawCount||t<0)return-1;var e=this._indices,i=e[t];if(null!=i&&it))return a;o=a-1}}return-1},yA.indicesOfNearest=function(t,e,i){var n=[];if(!this._storage[t])return n;null==i&&(i=1/0);for(var o=Number.MAX_VALUE,a=-1,r=0,s=this.count();r=0&&a<0)&&(o=u,a=l,n.length=0),n.push(r))}return n},yA.getRawIndex=nl,yA.getRawDataItem=function(t){if(this._rawData.persistent)return this._rawData.getItem(this.getRawIndex(t));for(var e=[],i=0;i=l&&w<=u||isNaN(w))&&(a[r++]=c),c++;h=!0}else if(2===n){for(var d=this._storage[s],v=this._storage[e[1]],y=t[e[1]][0],x=t[e[1]][1],f=0;f=l&&w<=u||isNaN(w))&&(b>=y&&b<=x||isNaN(b))&&(a[r++]=c),c++}h=!0}}if(!h)if(1===n)for(m=0;m=l&&w<=u||isNaN(w))&&(a[r++]=M)}else for(m=0;mt[I][1])&&(S=!1)}S&&(a[r++]=this.getRawIndex(m))}return rb[1]&&(b[1]=w)}}}return o},yA.downSample=function(t,e,i,n){for(var o=sl(this,[t]),a=o._storage,r=[],s=Math.floor(1/e),l=a[t],u=this.count(),h=this._chunkSize,c=o._rawExtent[t],d=new($s(this))(u),f=0,p=0;pu-p&&(s=u-p,r.length=s);for(var g=0;gc[1]&&(c[1]=x),d[f++]=_}return o._count=f,o._indices=d,o.getRawIndex=ol,o},yA.getItemModel=function(t){var e=this.hostModel;return new No(this.getRawDataItem(t),e,e&&e.ecModel)},yA.diff=function(t){var e=this;return new Xs(t?t.getIndices():[],this.getIndices(),function(e){return al(t,e)},function(t){return al(e,t)})},yA.getVisual=function(t){var e=this._visual;return e&&e[t]},yA.setVisual=function(t,e){if(lA(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},yA.setLayout=function(t,e){if(lA(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},yA.getLayout=function(t){return this._layout[t]},yA.getItemLayout=function(t){return this._itemLayouts[t]},yA.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?a(this._itemLayouts[t]||{},e):e},yA.clearItemLayouts=function(){this._itemLayouts.length=0},yA.getItemVisual=function(t,e,i){var n=this._itemVisuals[t],o=n&&n[e];return null!=o||i?o:this.getVisual(e)},yA.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{},o=this.hasItemVisual;if(this._itemVisuals[t]=n,lA(e))for(var a in e)e.hasOwnProperty(a)&&(n[a]=e[a],o[a]=!0);else n[e]=i,o[e]=!0},yA.clearAllVisual=function(){this._visual={},this._itemVisuals=[],this.hasItemVisual={}};var xA=function(t){t.seriesIndex=this.seriesIndex,t.dataIndex=this.dataIndex,t.dataType=this.dataType};yA.setItemGraphicEl=function(t,e){var i=this.hostModel;e&&(e.dataIndex=t,e.dataType=this.dataType,e.seriesIndex=i&&i.seriesIndex,"group"===e.type&&e.traverse(xA,e)),this._graphicEls[t]=e},yA.getItemGraphicEl=function(t){return this._graphicEls[t]},yA.eachItemGraphicEl=function(t,e){d(this._graphicEls,function(i,n){i&&t&&t.call(e,i,n)})},yA.cloneShallow=function(t){if(!t){var e=f(this.dimensions,this.getDimensionInfo,this);t=new vA(e,this.hostModel)}if(t._storage=this._storage,Qs(t,this),this._indices){var i=this._indices.constructor;t._indices=new i(this._indices)}else t._indices=null;return t.getRawIndex=t._indices?ol:nl,t},yA.wrapMethod=function(t,e){var i=this[t];"function"==typeof i&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=i.apply(this,arguments);return e.apply(this,[t].concat(C(arguments)))})},yA.TRANSFERABLE_METHODS=["cloneShallow","downSample","map"],yA.CHANGABLE_METHODS=["filterSelf","selectRange"];var _A=function(t,e){return e=e||{},hl(e.coordDimensions||[],t,{dimsDef:e.dimensionsDefine||t.dimensionsDefine,encodeDef:e.encodeDefine||t.encodeDefine,dimCount:e.dimensionsCount,generateCoord:e.generateCoord,generateCoordCount:e.generateCoordCount})};xl.prototype.parse=function(t){return t},xl.prototype.getSetting=function(t){return this._setting[t]},xl.prototype.contain=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},xl.prototype.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},xl.prototype.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},xl.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},xl.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},xl.prototype.getExtent=function(){return this._extent.slice()},xl.prototype.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},xl.prototype.isBlank=function(){return this._isBlank},xl.prototype.setBlank=function(t){this._isBlank=t},xl.prototype.getLabel=null,ji(xl),$i(xl,{registerWhenExtend:!0}),_l.createByAxisModel=function(t){var e=t.option,i=e.data,n=i&&f(i,bl);return new _l({categories:n,needCollect:!n,deduplication:!1!==e.dedplication})};var wA=_l.prototype;wA.getOrdinal=function(t){return wl(this).get(t)},wA.parseAndCollect=function(t){var e,i=this._needCollect;if("string"!=typeof t&&!i)return t;if(i&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var n=wl(this);return null==(e=n.get(t))&&(i?(e=this.categories.length,this.categories[e]=t,n.set(t,e)):e=NaN),e};var bA=xl.prototype,SA=xl.extend({type:"ordinal",init:function(t,e){t&&!y(t)||(t=new _l({categories:t})),this._ordinalMeta=t,this._extent=e||[0,t.categories.length-1]},parse:function(t){return"string"==typeof t?this._ordinalMeta.getOrdinal(t):Math.round(t)},contain:function(t){return t=this.parse(t),bA.contain.call(this,t)&&null!=this._ordinalMeta.categories[t]},normalize:function(t){return bA.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(bA.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){if(!this.isBlank())return this._ordinalMeta.categories[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},getOrdinalMeta:function(){return this._ordinalMeta},niceTicks:B,niceExtent:B});SA.create=function(){return new SA};var MA=Go,IA=Go,TA=xl.extend({type:"interval",_interval:0,_intervalPrecision:2,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),TA.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=Ml(t)},getTicks:function(){return Al(this._interval,this._extent,this._niceExtent,this._intervalPrecision)},getLabel:function(t,e){if(null==t)return"";var i=e&&e.precision;return null==i?i=Ho(t)||0:"auto"===i&&(i=this._intervalPrecision),t=IA(t,i,!0),ta(t)},niceTicks:function(t,e,i){t=t||5;var n=this._extent,o=n[1]-n[0];if(isFinite(o)){o<0&&(o=-o,n.reverse());var a=Sl(n,t,e,i);this._intervalPrecision=a.intervalPrecision,this._interval=a.interval,this._niceExtent=a.niceTickExtent}},niceExtent:function(t){var e=this._extent;if(e[0]===e[1])if(0!==e[0]){var i=e[0];t.fixMax?e[0]-=i/2:(e[1]+=i/2,e[0]-=i/2)}else e[1]=1;var n=e[1]-e[0];isFinite(n)||(e[0]=0,e[1]=1),this.niceTicks(t.splitNumber,t.minInterval,t.maxInterval);var o=this._interval;t.fixMin||(e[0]=IA(Math.floor(e[0]/o)*o)),t.fixMax||(e[1]=IA(Math.ceil(e[1]/o)*o))}});TA.create=function(){return new TA};var AA="__ec_stack_",DA="undefined"!=typeof Float32Array?Float32Array:Array,CA={seriesType:"bar",plan:$I(),reset:function(t){if(Rl(t)&&zl(t)){var e=t.getData(),i=t.coordinateSystem,n=i.getBaseAxis(),o=i.getOtherAxis(n),a=e.mapDimension(o.dim),r=e.mapDimension(n.dim),s=o.isHorizontal(),l=s?0:1,u=Ol(Pl([t]),n,t).width;return u>.5||(u=.5),{progress:function(t,e){for(var n,h=new DA(2*t.count),c=[],d=[],f=0;null!=(n=t.next());)d[l]=e.get(a,n),d[1-l]=e.get(r,n),c=i.dataToPoint(d,null,c),h[f++]=c[0],h[f++]=c[1];e.setLayout({largePoints:h,barWidth:u,valueAxisStart:Bl(0,o),valueAxisHorizontal:s})}}}}},LA=TA.prototype,kA=Math.ceil,PA=Math.floor,NA=function(t,e,i,n){for(;i>>1;t[o][1]i&&(a=i);var r=EA.length,s=NA(EA,a,0,r),l=EA[Math.min(s,r-1)],u=l[1];"year"===l[0]&&(u*=$o(o/u/t,!0));var h=this.getSetting("useUTC")?0:60*new Date(+n[0]||+n[1]).getTimezoneOffset()*1e3,c=[Math.round(kA((n[0]-h)/u)*u+h),Math.round(PA((n[1]-h)/u)*u+h)];Tl(c,n),this._stepLvl=l,this._interval=u,this._niceExtent=c},parse:function(t){return+Yo(t)}});d(["contain","normalize"],function(t){OA.prototype[t]=function(e){return LA[t].call(this,this.parse(e))}});var EA=[["hh:mm:ss",1e3],["hh:mm:ss",5e3],["hh:mm:ss",1e4],["hh:mm:ss",15e3],["hh:mm:ss",3e4],["hh:mm\nMM-dd",6e4],["hh:mm\nMM-dd",3e5],["hh:mm\nMM-dd",6e5],["hh:mm\nMM-dd",9e5],["hh:mm\nMM-dd",18e5],["hh:mm\nMM-dd",36e5],["hh:mm\nMM-dd",72e5],["hh:mm\nMM-dd",216e5],["hh:mm\nMM-dd",432e5],["MM-dd\nyyyy",864e5],["MM-dd\nyyyy",1728e5],["MM-dd\nyyyy",2592e5],["MM-dd\nyyyy",3456e5],["MM-dd\nyyyy",432e6],["MM-dd\nyyyy",5184e5],["week",6048e5],["MM-dd\nyyyy",864e6],["week",12096e5],["week",18144e5],["month",26784e5],["week",36288e5],["month",53568e5],["week",6048e6],["quarter",8208e6],["month",107136e5],["month",13392e6],["half-year",16416e6],["month",214272e5],["month",26784e6],["year",32832e6]];OA.create=function(t){return new OA({useUTC:t.ecModel.get("useUTC")})};var RA=xl.prototype,zA=TA.prototype,BA=Ho,VA=Go,GA=Math.floor,FA=Math.ceil,WA=Math.pow,HA=Math.log,ZA=xl.extend({type:"log",base:10,$constructor:function(){xl.apply(this,arguments),this._originalScale=new TA},getTicks:function(){var t=this._originalScale,e=this._extent,i=t.getExtent();return f(zA.getTicks.call(this),function(n){var o=Go(WA(this.base,n));return o=n===e[0]&&t.__fixMin?Vl(o,i[0]):o,o=n===e[1]&&t.__fixMax?Vl(o,i[1]):o},this)},getLabel:zA.getLabel,scale:function(t){return t=RA.scale.call(this,t),WA(this.base,t)},setExtent:function(t,e){var i=this.base;t=HA(t)/HA(i),e=HA(e)/HA(i),zA.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,e=RA.getExtent.call(this);e[0]=WA(t,e[0]),e[1]=WA(t,e[1]);var i=this._originalScale,n=i.getExtent();return i.__fixMin&&(e[0]=Vl(e[0],n[0])),i.__fixMax&&(e[1]=Vl(e[1],n[1])),e},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=HA(t[0])/HA(e),t[1]=HA(t[1])/HA(e),RA.unionExtent.call(this,t)},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(i===1/0||i<=0)){var n=qo(i);for(t/i*n<=.5&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var o=[Go(FA(e[0]/n)*n),Go(GA(e[1]/n)*n)];this._interval=n,this._niceExtent=o}},niceExtent:function(t){zA.niceExtent.call(this,t);var e=this._originalScale;e.__fixMin=t.fixMin,e.__fixMax=t.fixMax}});d(["contain","normalize"],function(t){ZA.prototype[t]=function(e){return e=HA(e)/HA(this.base),RA[t].call(this,e)}}),ZA.create=function(){return new ZA};var UA={getMin:function(t){var e=this.option,i=t||null==e.rangeStart?e.min:e.rangeStart;return this.axis&&null!=i&&"dataMin"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getMax:function(t){var e=this.option,i=t||null==e.rangeEnd?e.max:e.rangeEnd;return this.axis&&null!=i&&"dataMax"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getNeedCrossZero:function(){var t=this.option;return null==t.rangeStart&&null==t.rangeEnd&&!t.scale},getCoordSysModel:B,setRange:function(t,e){this.option.rangeStart=t,this.option.rangeEnd=e},resetRange:function(){this.option.rangeStart=this.option.rangeEnd=null}},XA=Un({type:"triangle",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n+a),t.lineTo(i-o,n+a),t.closePath()}}),jA=Un({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n),t.lineTo(i,n+a),t.lineTo(i-o,n),t.closePath()}}),YA=Un({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,o=e.width/5*3,a=Math.max(o,e.height),r=o/2,s=r*r/(a-r),l=n-a+r+s,u=Math.asin(s/r),h=Math.cos(u)*r,c=Math.sin(u),d=Math.cos(u),f=.6*r,p=.7*r;t.moveTo(i-h,l+s),t.arc(i,l,r,Math.PI-u,2*Math.PI+u),t.bezierCurveTo(i+h-c*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-h+c*f,l+s+d*f,i-h,l+s),t.closePath()}}),qA=Un({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.height,n=e.width,o=e.x,a=e.y,r=n/3*2;t.moveTo(o,a),t.lineTo(o+r,a+i),t.lineTo(o,a+i/4*3),t.lineTo(o-r,a+i),t.lineTo(o,a),t.closePath()}}),KA={line:function(t,e,i,n,o){o.x1=t,o.y1=e+n/2,o.x2=t+i,o.y2=e+n/2},rect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n},roundRect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n,o.r=Math.min(i,n)/4},square:function(t,e,i,n,o){var a=Math.min(i,n);o.x=t,o.y=e,o.width=a,o.height=a},circle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.r=Math.min(i,n)/2},diamond:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n},pin:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},arrow:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},triangle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n}},$A={};d({line:_M,rect:yM,roundRect:yM,square:yM,circle:sM,diamond:jA,pin:YA,arrow:qA,triangle:XA},function(t,e){$A[e]=new t});var JA=Un({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},beforeBrush:function(){var t=this.style;"pin"===this.shape.symbolType&&"inside"===t.textPosition&&(t.textPosition=["50%","40%"],t.textAlign="center",t.textVerticalAlign="middle")},buildPath:function(t,e,i){var n=e.symbolType,o=$A[n];"none"!==e.symbolType&&(o||(o=$A[n="rect"]),KA[n](e.x,e.y,e.width,e.height,o.shape),o.buildPath(t,o.shape,i))}}),QA={isDimensionStacked:pl,enableDataStack:fl,getStackedDimension:gl},tD=(Object.freeze||Object)({createList:function(t){return ml(t.getSource(),t)},getLayoutRect:ca,dataStack:QA,createScale:function(t,e){var i=e;No.isInstance(e)||h(i=new No(e),UA);var n=Hl(i);return n.setExtent(t[0],t[1]),Wl(n,i),n},mixinAxisModelCommonMethods:function(t){h(t,UA)},completeDimensions:hl,createDimensions:_A,createSymbol:Jl}),eD=1e-8;eu.prototype={constructor:eu,properties:null,getBoundingRect:function(){var t=this._rect;if(t)return t;for(var e=Number.MAX_VALUE,i=[e,e],n=[-e,-e],o=[],a=[],r=this.geometries,s=0;s0}),function(t){var e=t.properties,i=t.geometry,n=i.coordinates,o=[];"Polygon"===i.type&&o.push({type:"polygon",exterior:n[0],interiors:n.slice(1)}),"MultiPolygon"===i.type&&d(n,function(t){t[0]&&o.push({type:"polygon",exterior:t[0],interiors:t.slice(1)})});var a=new eu(e.name,o,e.cp);return a.properties=e,a})},nD=Bi(),oD=[0,1],aD=function(t,e,i){this.dim=t,this.scale=e,this._extent=i||[0,0],this.inverse=!1,this.onBand=!1};aD.prototype={constructor:aD,contain:function(t){var e=this._extent,i=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return t>=i&&t<=n},containData:function(t){return this.contain(this.dataToCoord(t))},getExtent:function(){return this._extent.slice()},getPixelPrecision:function(t){return Zo(t||this.scale.getExtent(),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,e){var i=this._extent,n=this.scale;return t=n.normalize(t),this.onBand&&"ordinal"===n.type&&yu(i=i.slice(),n.count()),Bo(t,oD,i,e)},coordToData:function(t,e){var i=this._extent,n=this.scale;this.onBand&&"ordinal"===n.type&&yu(i=i.slice(),n.count());var o=Bo(t,i,oD,e);return this.scale.scale(o)},pointToData:function(t,e){},getTicksCoords:function(t){var e=(t=t||{}).tickModel||this.getTickModel(),i=au(this,e),n=f(i.ticks,function(t){return{coord:this.dataToCoord(t),tickValue:t}},this),o=e.get("alignWithLabel");return xu(this,n,i.tickCategoryInterval,o,t.clamp),n},getViewLabels:function(){return ou(this).labels},getLabelModel:function(){return this.model.getModel("axisLabel")},getTickModel:function(){return this.model.getModel("axisTick")},getBandWidth:function(){var t=this._extent,e=this.scale.getExtent(),i=e[1]-e[0]+(this.onBand?1:0);0===i&&(i=1);var n=Math.abs(t[1]-t[0]);return Math.abs(n)/i},isHorizontal:null,getRotate:null,calculateCategoryInterval:function(){return pu(this)}};var rD=iD,sD={};d(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend","defaults","clone","merge"],function(t){sD[t]=aw[t]});var lD={};d(["extendShape","extendPath","makePath","makeImage","mergePath","resizePath","createIcon","setHoverStyle","setLabelStyle","setTextStyle","setText","getFont","updateProps","initProps","getTransform","clipPointsByRect","clipRectByRect","Group","Image","Text","Circle","Sector","Ring","Polygon","Polyline","Rect","Line","BezierCurve","Arc","IncrementalDisplayable","CompoundPath","LinearGradient","RadialGradient","BoundingRect"],function(t){lD[t]=zM[t]}),YI.extend({type:"series.line",dependencies:["grid","polar"],getInitialData:function(t,e){return ml(this.getSource(),this)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clipOverflow:!0,label:{position:"top"},lineStyle:{width:2,type:"solid"},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}});var uD=wu.prototype,hD=wu.getSymbolSize=function(t,e){var i=t.getItemVisual(e,"symbolSize");return i instanceof Array?i.slice():[+i,+i]};uD._createSymbol=function(t,e,i,n,o){this.removeAll();var a=Jl(t,-1,-1,2,2,e.getItemVisual(i,"color"),o);a.attr({z2:100,culling:!0,scale:bu(n)}),a.drift=Su,this._symbolType=t,this.add(a)},uD.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(t)},uD.getSymbolPath=function(){return this.childAt(0)},uD.getScale=function(){return this.childAt(0).scale},uD.highlight=function(){this.childAt(0).trigger("emphasis")},uD.downplay=function(){this.childAt(0).trigger("normal")},uD.setZ=function(t,e){var i=this.childAt(0);i.zlevel=t,i.z=e},uD.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":"pointer"},uD.updateData=function(t,e,i){this.silent=!1;var n=t.getItemVisual(e,"symbol")||"circle",o=t.hostModel,a=hD(t,e),r=n!==this._symbolType;if(r){var s=t.getItemVisual(e,"symbolKeepAspect");this._createSymbol(n,t,e,a,s)}else(l=this.childAt(0)).silent=!1,Io(l,{scale:bu(a)},o,e);if(this._updateCommon(t,e,a,i),r){var l=this.childAt(0),u=i&&i.fadeIn,h={scale:l.scale.slice()};u&&(h.style={opacity:l.style.opacity}),l.scale=[0,0],u&&(l.style.opacity=0),To(l,h,o,e)}this._seriesModel=o};var cD=["itemStyle"],dD=["emphasis","itemStyle"],fD=["label"],pD=["emphasis","label"];uD._updateCommon=function(t,e,i,n){var o=this.childAt(0),r=t.hostModel,s=t.getItemVisual(e,"color");"image"!==o.type&&o.useStyle({strokeNoScale:!0});var l=n&&n.itemStyle,u=n&&n.hoverItemStyle,h=n&&n.symbolRotate,c=n&&n.symbolOffset,d=n&&n.labelModel,f=n&&n.hoverLabelModel,p=n&&n.hoverAnimation,g=n&&n.cursorStyle;if(!n||t.hasItemOption){var m=n&&n.itemModel?n.itemModel:t.getItemModel(e);l=m.getModel(cD).getItemStyle(["color"]),u=m.getModel(dD).getItemStyle(),h=m.getShallow("symbolRotate"),c=m.getShallow("symbolOffset"),d=m.getModel(fD),f=m.getModel(pD),p=m.getShallow("hoverAnimation"),g=m.getShallow("cursor")}else u=a({},u);var v=o.style;o.attr("rotation",(h||0)*Math.PI/180||0),c&&o.attr("position",[Vo(c[0],i[0]),Vo(c[1],i[1])]),g&&o.attr("cursor",g),o.setColor(s,n&&n.symbolInnerColor),o.setStyle(l);var y=t.getItemVisual(e,"opacity");null!=y&&(v.opacity=y);var x=t.getItemVisual(e,"liftZ"),_=o.__z2Origin;null!=x?null==_&&(o.__z2Origin=o.z2,o.z2+=x):null!=_&&(o.z2=_,o.__z2Origin=null);var w=n&&n.useNameLabel;go(v,u,d,f,{labelFetcher:r,labelDataIndex:e,defaultText:function(e,i){return w?t.getName(e):_u(t,e)},isRectText:!0,autoColor:s}),o.off("mouseover").off("mouseout").off("emphasis").off("normal"),o.hoverStyle=u,fo(o),o.__symbolOriginalScale=bu(i),p&&r.isAnimationEnabled()&&o.on("mouseover",Mu).on("mouseout",Iu).on("emphasis",Tu).on("normal",Au)},uD.fadeOut=function(t,e){var i=this.childAt(0);this.silent=i.silent=!0,!(e&&e.keepLabel)&&(i.style.text=null),Io(i,{style:{opacity:0},scale:[0,0]},this._seriesModel,this.dataIndex,t)},u(wu,tb);var gD=Du.prototype;gD.updateData=function(t,e){e=Lu(e);var i=this.group,n=t.hostModel,o=this._data,a=this._symbolCtor,r=ku(t);o||i.removeAll(),t.diff(o).add(function(n){var o=t.getItemLayout(n);if(Cu(t,o,n,e)){var s=new a(t,n,r);s.attr("position",o),t.setItemGraphicEl(n,s),i.add(s)}}).update(function(s,l){var u=o.getItemGraphicEl(l),h=t.getItemLayout(s);Cu(t,h,s,e)?(u?(u.updateData(t,s,r),Io(u,{position:h},n)):(u=new a(t,s)).attr("position",h),i.add(u),t.setItemGraphicEl(s,u)):i.remove(u)}).remove(function(t){var e=o.getItemGraphicEl(t);e&&e.fadeOut(function(){i.remove(e)})}).execute(),this._data=t},gD.isPersistent=function(){return!0},gD.updateLayout=function(){var t=this._data;t&&t.eachItemGraphicEl(function(e,i){var n=t.getItemLayout(i);e.attr("position",n)})},gD.incrementalPrepareUpdate=function(t){this._seriesScope=ku(t),this._data=null,this.group.removeAll()},gD.incrementalUpdate=function(t,e,i){i=Lu(i);for(var n=t.start;n0&&Ru(i[o-1]);o--);for(;n0&&Ru(i[a-1]);a--);for(;o=0){var r=o.getItemGraphicEl(a);if(!r){var s=o.getItemLayout(a);if(!s)return;(r=new wu(o,a)).position=s,r.setZ(t.get("zlevel"),t.get("z")),r.ignore=isNaN(s[0])||isNaN(s[1]),r.__temp=!0,o.setItemGraphicEl(a,r),r.stopSymbolAnimation(!0),this.group.add(r)}r.highlight()}else Ar.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var o=t.getData(),a=zi(o,n);if(null!=a&&a>=0){var r=o.getItemGraphicEl(a);r&&(r.__temp?(o.setItemGraphicEl(a,null),this.group.remove(r)):r.downplay())}else Ar.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new MD({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new ID({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_updateAnimation:function(t,e,i,n,o,a){var r=this._polyline,s=this._polygon,l=t.hostModel,u=mD(this._data,t,this._stackedOnPoints,e,this._coordSys,i,this._valueOrigin,a),h=u.current,c=u.stackedOnCurrent,d=u.next,f=u.stackedOnNext;o&&(h=Yu(u.current,i,o),c=Yu(u.stackedOnCurrent,i,o),d=Yu(u.next,i,o),f=Yu(u.stackedOnNext,i,o)),r.shape.__points=u.current,r.shape.points=h,Io(r,{shape:{points:d}},l),s&&(s.setShape({points:h,stackedOnPoints:c}),Io(s,{shape:{points:d,stackedOnPoints:f}},l));for(var p=[],g=u.status,m=0;me&&(e=t[i]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,i=0;ie[1]&&e.reverse(),e},getOtherAxis:function(){this.grid.getOtherAxis()},pointToData:function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},toLocalCoord:null,toGlobalCoord:null},u(kD,aD);var PD={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#333",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},ND={};ND.categoryAxis=n({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},PD),ND.valueAxis=n({boundaryGap:[0,0],splitNumber:5},PD),ND.timeAxis=r({scale:!0,min:"dataMin",max:"dataMax"},ND.valueAxis),ND.logAxis=r({scale:!0,logBase:10},ND.valueAxis);var OD=["value","category","time","log"],ED=function(t,e,i,a){d(OD,function(r){e.extend({type:t+"Axis."+r,mergeDefaultAndTheme:function(e,o){var a=this.layoutMode,s=a?ga(e):{};n(e,o.getTheme().get(r+"Axis")),n(e,this.getDefaultOption()),e.type=i(t,e),a&&pa(e,s,a)},optionUpdated:function(){"category"===this.option.type&&(this.__ordinalMeta=_l.createByAxisModel(this))},getCategories:function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},getOrdinalMeta:function(){return this.__ordinalMeta},defaultOption:o([{},ND[r+"Axis"],a],!0)})}),lI.registerSubTypeDefaulter(t+"Axis",v(i,t))},RD=lI.extend({type:"cartesian2dAxis",axis:null,init:function(){RD.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){RD.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){RD.superApply(this,"restoreData",arguments),this.resetRange()},getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"grid",index:this.option.gridIndex,id:this.option.gridId})[0]}});n(RD.prototype,UA);var zD={offset:0};ED("x",RD,th,zD),ED("y",RD,th,zD),lI.extend({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}});var BD=ih.prototype;BD.type="grid",BD.axisPointerEnabled=!0,BD.getRect=function(){return this._rect},BD.update=function(t,e){var i=this._axesMap;this._updateScale(t,this.model),d(i.x,function(t){Wl(t.scale,t.model)}),d(i.y,function(t){Wl(t.scale,t.model)});var n={};d(i.x,function(t){nh(i,"y",t,n)}),d(i.y,function(t){nh(i,"x",t,n)}),this.resize(this.model,e)},BD.resize=function(t,e,i){function n(){d(a,function(t){var e=t.isHorizontal(),i=e?[0,o.width]:[0,o.height],n=t.inverse?1:0;t.setExtent(i[n],i[1-n]),ah(t,e?o.x:o.y)})}var o=ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;n(),!i&&t.get("containLabel")&&(d(a,function(t){if(!t.model.get("axisLabel.inside")){var e=jl(t);if(e){var i=t.isHorizontal()?"height":"width",n=t.model.get("axisLabel.margin");o[i]-=e[i]+n,"top"===t.position?o.y+=e.height+n:"left"===t.position&&(o.x+=e.width+n)}}}),n())},BD.getAxis=function(t,e){var i=this._axesMap[t];if(null!=i){if(null==e)for(var n in i)if(i.hasOwnProperty(n))return i[n];return i[e]}},BD.getAxes=function(){return this._axesList.slice()},BD.getCartesian=function(t,e){if(null!=t&&null!=e){var i="x"+t+"y"+e;return this._coordsMap[i]}w(t)&&(e=t.yAxisIndex,t=t.xAxisIndex);for(var n=0,o=this._coordsList;nu[1]?-1:1,c=["start"===o?u[0]-h*l:"end"===o?u[1]+h*l:(u[0]+u[1])/2,ph(o)?t.labelOffset+r*l:0],d=e.get("nameRotate");null!=d&&(d=d*GD/180);var f;ph(o)?n=HD(t.rotation,null!=d?d:t.rotation,r):(n=uh(t,o,d||0,u),null!=(f=t.axisNameAvailableWidth)&&(f=Math.abs(f/Math.sin(n.rotation)),!isFinite(f)&&(f=null)));var p=s.getFont(),g=e.get("nameTruncate",!0)||{},m=g.ellipsis,v=T(t.nameTruncateMaxWidth,g.maxWidth,f),y=null!=m&&null!=v?tI(i,v,p,m,{minChar:2,placeholder:g.placeholder}):i,x=e.get("tooltip",!0),_=e.mainType,w={componentType:_,name:i,$vars:["name"]};w[_+"Index"]=e.componentIndex;var b=new rM({anid:"name",__fullText:i,__truncatedText:y,position:c,rotation:n.rotation,silent:hh(e),z2:1,tooltip:x&&x.show?a({content:i,formatter:function(){return i},formatterParams:w},x):null});mo(b.style,s,{text:y,textFont:p,textFill:s.getTextColor()||e.get("axisLine.lineStyle.color"),textAlign:n.textAlign,textVerticalAlign:n.textVerticalAlign}),e.get("triggerEvent")&&(b.eventData=lh(e),b.eventData.targetType="axisName",b.eventData.name=i),this._dumbGroup.add(b),b.updateTransform(),this.group.add(b),b.decomposeTransform()}}},HD=FD.innerTextLayout=function(t,e,i){var n,o,a=Xo(e-t);return jo(a)?(o=i>0?"top":"bottom",n="center"):jo(a-GD)?(o=i>0?"bottom":"top",n="center"):(o="middle",n=a>0&&a0?"right":"left":i>0?"left":"right"),{rotation:a,textAlign:n,textVerticalAlign:o}},ZD=d,UD=v,XD=Ws({type:"axis",_axisPointer:null,axisPointerClass:null,render:function(t,e,i,n){this.axisPointerClass&&Sh(t),XD.superApply(this,"render",arguments),Dh(this,t,0,i,0,!0)},updateAxisPointer:function(t,e,i,n,o){Dh(this,t,0,i,0,!1)},remove:function(t,e){var i=this._axisPointer;i&&i.remove(e),XD.superApply(this,"remove",arguments)},dispose:function(t,e){Ch(this,e),XD.superApply(this,"dispose",arguments)}}),jD=[];XD.registerAxisPointerClass=function(t,e){jD[t]=e},XD.getAxisPointerClass=function(t){return t&&jD[t]};var YD=["axisLine","axisTickLabel","axisName"],qD=["splitArea","splitLine"],KD=XD.extend({type:"cartesianAxis",axisPointerClass:"CartesianAxisPointer",render:function(t,e,i,n){this.group.removeAll();var o=this._axisGroup;if(this._axisGroup=new tb,this.group.add(this._axisGroup),t.get("show")){var a=t.getCoordSysModel(),r=Lh(a,t),s=new FD(t,r);d(YD,s.add,s),this._axisGroup.add(s.getGroup()),d(qD,function(e){t.get(e+".show")&&this["_"+e](t,a)},this),Lo(o,this._axisGroup,t),KD.superCall(this,"render",t,e,i,n)}},remove:function(){this._splitAreaColors=null},_splitLine:function(t,e){var i=t.axis;if(!i.scale.isBlank()){var n=t.getModel("splitLine"),o=n.getModel("lineStyle"),a=o.get("color");a=y(a)?a:[a];for(var s=e.coordinateSystem.getRect(),l=i.isHorizontal(),u=0,h=i.getTicksCoords({tickModel:n}),c=[],d=[],f=o.getLineStyle(),p=0;p1){var c;"string"==typeof o?c=DD[o]:"function"==typeof o&&(c=o),c&&t.setData(n.downSample(n.mapDimension(s.dim),1/h,c,CD))}}}}}("line"));var $D=YI.extend({type:"series.__base_bar__",getInitialData:function(t,e){return ml(this.getSource(),this)},getMarkerPosition:function(t){var e=this.coordinateSystem;if(e){var i=e.dataToPoint(e.clampData(t)),n=this.getData(),o=n.getLayout("offset"),a=n.getLayout("size");return i[e.getBaseAxis().isHorizontal()?0:1]+=o+a/2,i}return[NaN,NaN]},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod",itemStyle:{},emphasis:{}}});$D.extend({type:"series.bar",dependencies:["grid","polar"],brushSelector:"rect",getProgressive:function(){return!!this.get("large")&&this.get("progressive")},getProgressiveThreshold:function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t}});var JD=Qb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["stroke","barBorderColor"],["lineWidth","barBorderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),QD={getBarItemStyle:function(t){var e=JD(this,t);if(this.getBorderLineDash){var i=this.getBorderLineDash();i&&(e.lineDash=i)}return e}},tC=["itemStyle","barBorderWidth"];a(No.prototype,QD),Zs({type:"bar",render:function(t,e,i){this._updateDrawMode(t);var n=t.get("coordinateSystem");return"cartesian2d"!==n&&"polar"!==n||(this._isLargeDraw?this._renderLarge(t,e,i):this._renderNormal(t,e,i)),this.group},incrementalPrepareRender:function(t,e,i){this._clear(),this._updateDrawMode(t)},incrementalRender:function(t,e,i,n){this._incrementalRenderLarge(t,e)},_updateDrawMode:function(t){var e=t.pipelineContext.large;(null==this._isLargeDraw||e^this._isLargeDraw)&&(this._isLargeDraw=e,this._clear())},_renderNormal:function(t,e,i){var n,o=this.group,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.getBaseAxis();"cartesian2d"===s.type?n=l.isHorizontal():"polar"===s.type&&(n="angle"===l.dim);var u=t.isAnimationEnabled()?t:null;a.diff(r).add(function(e){if(a.hasValue(e)){var i=a.getItemModel(e),r=iC[s.type](a,e,i),l=eC[s.type](a,e,i,r,n,u);a.setItemGraphicEl(e,l),o.add(l),Eh(l,a,e,i,r,t,n,"polar"===s.type)}}).update(function(e,i){var l=r.getItemGraphicEl(i);if(a.hasValue(e)){var h=a.getItemModel(e),c=iC[s.type](a,e,h);l?Io(l,{shape:c},u,e):l=eC[s.type](a,e,h,c,n,u,!0),a.setItemGraphicEl(e,l),o.add(l),Eh(l,a,e,h,c,t,n,"polar"===s.type)}else o.remove(l)}).remove(function(t){var e=r.getItemGraphicEl(t);"cartesian2d"===s.type?e&&Nh(t,u,e):e&&Oh(t,u,e)}).execute(),this._data=a},_renderLarge:function(t,e,i){this._clear(),zh(t,this.group)},_incrementalRenderLarge:function(t,e){zh(e,this.group,!0)},dispose:B,remove:function(t){this._clear(t)},_clear:function(t){var e=this.group,i=this._data;t&&t.get("animation")&&i&&!this._isLargeDraw?i.eachItemGraphicEl(function(e){"sector"===e.type?Oh(e.dataIndex,t,e):Nh(e.dataIndex,t,e)}):e.removeAll(),this._data=null}});var eC={cartesian2d:function(t,e,i,n,o,r,s){var l=new yM({shape:a({},n)});if(r){var u=l.shape,h=o?"height":"width",c={};u[h]=0,c[h]=n[h],zM[s?"updateProps":"initProps"](l,{shape:c},r,e)}return l},polar:function(t,e,i,n,o,a,s){var l=n.startAngle0?1:-1,r=n.height>0?1:-1;return{x:n.x+a*o/2,y:n.y+r*o/2,width:n.width-a*o,height:n.height-r*o}},polar:function(t,e,i){var n=t.getItemLayout(e);return{cx:n.cx,cy:n.cy,r0:n.r0,r:n.r,startAngle:n.startAngle,endAngle:n.endAngle}}},nC=Pn.extend({type:"largeBar",shape:{points:[]},buildPath:function(t,e){for(var i=e.points,n=this.__startPoint,o=this.__valueIdx,a=0;a0&&"scale"!==u){var d=o.getItemLayout(0),f=Math.max(i.getWidth(),i.getHeight())/2,p=m(r.removeClipPath,r);r.setClipPath(this._createClipPath(d.cx,d.cy,f,d.startAngle,d.clockwise,p,t))}else r.removeClipPath();this._data=o}},dispose:function(){},_createClipPath:function(t,e,i,n,o,a,r){var s=new hM({shape:{cx:t,cy:e,r0:0,r:i,startAngle:n,endAngle:n,clockwise:o}});return To(s,{shape:{endAngle:n+(o?1:-1)*Math.PI*2}},r,a),s},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var lC=function(t,e){d(e,function(e){e.update="updateView",Es(e,function(i,n){var o={};return n.eachComponent({mainType:"series",subType:t,query:i},function(t){t[e.method]&&t[e.method](i.name,i.dataIndex);var n=t.getData();n.each(function(e){var i=n.getName(e);o[i]=t.isSelected(i)||!1})}),{name:i.name,selected:o}})})},uC=function(t){return{getTargetSeries:function(e){var i={},n=R();return e.eachSeriesByType(t,function(t){t.__paletteScope=i,n.set(t.uid,t)}),n},reset:function(t,e){var i=t.getRawData(),n={},o=t.getData();o.each(function(t){var e=o.getRawIndex(t);n[e]=t}),i.each(function(e){var a=n[e],r=null!=a&&o.getItemVisual(a,"color",!0);if(r)i.setItemVisual(e,"color",r);else{var s=i.getItemModel(e).get("itemStyle.color")||t.getColorFromPalette(i.getName(e)||e+"",t.__paletteScope,i.count());i.setItemVisual(e,"color",s),null!=a&&o.setItemVisual(a,"color",s)}})}}},hC=function(t,e,i,n){var o,a,r=t.getData(),s=[],l=!1;r.each(function(i){var n,u,h,c,d=r.getItemLayout(i),f=r.getItemModel(i),p=f.getModel("label"),g=p.get("position")||f.get("emphasis.label.position"),m=f.getModel("labelLine"),v=m.get("length"),y=m.get("length2"),x=(d.startAngle+d.endAngle)/2,_=Math.cos(x),w=Math.sin(x);o=d.cx,a=d.cy;var b="inside"===g||"inner"===g;if("center"===g)n=d.cx,u=d.cy,c="center";else{var S=(b?(d.r+d.r0)/2*_:d.r*_)+o,M=(b?(d.r+d.r0)/2*w:d.r*w)+a;if(n=S+3*_,u=M+3*w,!b){var I=S+_*(v+e-d.r),T=M+w*(v+e-d.r),A=I+(_<0?-1:1)*y,D=T;n=A+(_<0?-5:5),u=D,h=[[S,M],[I,T],[A,D]]}c=b?"center":_>0?"left":"right"}var C=p.getFont(),L=p.get("rotate")?_<0?-x+Math.PI:-x:0,k=ke(t.getFormattedLabel(i,"normal")||r.getName(i),C,c,"top");l=!!L,d.label={x:n,y:u,position:g,height:k.height,len:v,len2:y,linePoints:h,textAlign:c,verticalAlign:"middle",rotation:L,inside:b},b||s.push(d.label)}),!l&&t.get("avoidLabelOverlap")&&Hh(s,o,a,e,i,n)},cC=2*Math.PI,dC=Math.PI/180,fC=function(t){return{seriesType:t,reset:function(t,e){var i=e.findComponents({mainType:"legend"});if(i&&i.length){var n=t.getData();n.filterSelf(function(t){for(var e=n.getName(t),o=0;o=0;s--){var l=2*s,u=n[l]-a/2,h=n[l+1]-r/2;if(t>=u&&e>=h&&t<=u+a&&e<=h+r)return s}return-1}}),gC=Uh.prototype;gC.isPersistent=function(){return!this._incremental},gC.updateData=function(t){this.group.removeAll();var e=new pC({rectHover:!0,cursor:"default"});e.setShape({points:t.getLayout("symbolPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},gC.updateLayout=function(t){if(!this._incremental){var e=t.getLayout("symbolPoints");this.group.eachChild(function(t){if(null!=t.startIndex){var i=2*(t.endIndex-t.startIndex),n=4*t.startIndex*2;e=new Float32Array(e.buffer,n,i)}t.setShape("points",e)})}},gC.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>2e6?(this._incremental||(this._incremental=new Zn({silent:!0})),this.group.add(this._incremental)):this._incremental=null},gC.incrementalUpdate=function(t,e){var i;this._incremental?(i=new pC,this._incremental.addDisplayable(i,!0)):((i=new pC({rectHover:!0,cursor:"default",startIndex:t.start,endIndex:t.end})).incremental=!0,this.group.add(i)),i.setShape({points:e.getLayout("symbolPoints")}),this._setCommon(i,e,!!this._incremental)},gC._setCommon=function(t,e,i){var n=e.hostModel,o=e.getVisual("symbolSize");t.setShape("size",o instanceof Array?o:[o,o]),t.symbolProxy=Jl(e.getVisual("symbol"),0,0,0,0),t.setColor=t.symbolProxy.setColor;var a=t.shape.size[0]<4;t.useStyle(n.getModel("itemStyle").getItemStyle(a?["color","shadowBlur","shadowColor"]:["color"]));var r=e.getVisual("color");r&&t.setColor(r),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>=0&&(t.dataIndex=i+(t.startIndex||0))}))},gC.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},gC._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()},Zs({type:"scatter",render:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).updateData(n),this._finished=!0},incrementalPrepareRender:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).incrementalPrepareUpdate(n),this._finished=!1},incrementalRender:function(t,e,i){this._symbolDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},updateTransform:function(t,e,i){var n=t.getData();if(this.group.dirty(),!this._finished||n.count()>1e4||!this._symbolDraw.isPersistent())return{update:!0};var o=AD().reset(t);o.progress&&o.progress({start:0,end:n.count()},n),this._symbolDraw.updateLayout(n)},_updateSymbolDraw:function(t,e){var i=this._symbolDraw,n=e.pipelineContext.large;return i&&n===this._isLargeDraw||(i&&i.remove(),i=this._symbolDraw=n?new Uh:new Du,this._isLargeDraw=n,this.group.removeAll()),this.group.add(i.group),i},remove:function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},dispose:function(){}}),Bs(TD("scatter","circle")),zs(AD("scatter")),u(Xh,aD),jh.prototype.getIndicatorAxes=function(){return this._indicatorAxes},jh.prototype.dataToPoint=function(t,e){var i=this._indicatorAxes[e];return this.coordToPoint(i.dataToCoord(t),e)},jh.prototype.coordToPoint=function(t,e){var i=this._indicatorAxes[e].angle;return[this.cx+t*Math.cos(i),this.cy-t*Math.sin(i)]},jh.prototype.pointToData=function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=Math.sqrt(e*e+i*i);e/=n,i/=n;for(var o,a=Math.atan2(-i,e),r=1/0,s=-1,l=0;ln[0]&&isFinite(c)&&isFinite(n[0]))}else{r.getTicks().length-1>a&&(u=i(u));var d=Math.round((n[0]+n[1])/2/u)*u,f=Math.round(a/2);r.setExtent(Go(d-f*u),Go(d+(a-f)*u)),r.setInterval(u)}})},jh.dimensions=[],jh.create=function(t,e){var i=[];return t.eachComponent("radar",function(n){var o=new jh(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeriesByType("radar",function(t){"radar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("radarIndex")||0])}),i},Fa.register("radar",jh);var mC=ND.valueAxis,vC=(Fs({type:"radar",optionUpdated:function(){var t=this.get("boundaryGap"),e=this.get("splitNumber"),o=this.get("scale"),s=this.get("axisLine"),l=this.get("axisTick"),u=this.get("axisLabel"),h=this.get("name"),c=this.get("name.show"),d=this.get("name.formatter"),p=this.get("nameGap"),g=this.get("triggerEvent"),m=f(this.get("indicator")||[],function(f){null!=f.max&&f.max>0&&!f.min?f.min=0:null!=f.min&&f.min<0&&!f.max&&(f.max=0);var m=h;if(null!=f.color&&(m=r({color:f.color},h)),f=n(i(f),{boundaryGap:t,splitNumber:e,scale:o,axisLine:s,axisTick:l,axisLabel:u,name:f.text,nameLocation:"end",nameGap:p,nameTextStyle:m,triggerEvent:g},!1),c||(f.name=""),"string"==typeof d){var v=f.name;f.name=d.replace("{value}",null!=v?v:"")}else"function"==typeof d&&(f.name=d(f.name,f));var y=a(new No(f,null,this.ecModel),UA);return y.mainType="radar",y.componentIndex=this.componentIndex,y},this);this.getIndicatorModels=function(){return m}},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"75%",startAngle:90,name:{show:!0},boundaryGap:[0,0],splitNumber:5,nameGap:15,scale:!1,shape:"polygon",axisLine:n({lineStyle:{color:"#bbb"}},mC.axisLine),axisLabel:Yh(mC.axisLabel,!1),axisTick:Yh(mC.axisTick,!1),splitLine:Yh(mC.splitLine,!0),splitArea:Yh(mC.splitArea,!0),indicator:[]}}),["axisLine","axisTickLabel","axisName"]);Ws({type:"radar",render:function(t,e,i){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},_buildAxes:function(t){var e=t.coordinateSystem;d(f(e.getIndicatorAxes(),function(t){return new FD(t.model,{position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})}),function(t){d(vC,t.add,t),this.group.add(t.getGroup())},this)},_buildSplitLineAndArea:function(t){function e(t,e,i){var n=i%e.length;return t[n]=t[n]||[],n}var i=t.coordinateSystem,n=i.getIndicatorAxes();if(n.length){var o=t.get("shape"),a=t.getModel("splitLine"),s=t.getModel("splitArea"),l=a.getModel("lineStyle"),u=s.getModel("areaStyle"),h=a.get("show"),c=s.get("show"),p=l.get("color"),g=u.get("color");p=y(p)?p:[p],g=y(g)?g:[g];var m=[],v=[];if("circle"===o)for(var x=n[0].getTicksCoords(),_=i.cx,w=i.cy,b=0;b"+f(i,function(i,n){var o=e.get(e.mapDimension(i.dim),t);return ia(i.name+" : "+o)}).join("
")},defaultOption:{zlevel:0,z:2,coordinateSystem:"radar",legendHoverLink:!0,radarIndex:0,lineStyle:{width:2,type:"solid"},label:{position:"top"},symbol:"emptyCircle",symbolSize:4}});Zs({type:"radar",render:function(t,e,n){function o(t,e){var i=t.getItemVisual(e,"symbol")||"circle",n=t.getItemVisual(e,"color");if("none"!==i){var o=qh(t.getItemVisual(e,"symbolSize")),a=Jl(i,-1,-1,2,2,n);return a.attr({style:{strokeNoScale:!0},z2:100,scale:[o[0]/2,o[1]/2]}),a}}function a(e,i,n,a,r,s){n.removeAll();for(var l=0;l"+ia(n+" : "+i)},getTooltipPosition:function(t){if(null!=t){var e=this.getData().getName(t),i=this.coordinateSystem,n=i.getRegion(e);return n&&i.dataToPoint(n.center)}},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},defaultOption:{zlevel:0,z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:.75,showLegendSymbol:!0,dataRangeHoverLink:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}}}}),aC);var EC="\0_ec_interaction_mutex";Es({type:"takeGlobalCursor",event:"globalCursorTaken",update:"update"},function(){}),h(oc,fw);var RC={axisPointer:1,tooltip:1,brush:1};xc.prototype={constructor:xc,draw:function(t,e,i,n,o){var a="geo"===t.mainType,r=t.getData&&t.getData();a&&e.eachComponent({mainType:"series",subType:"map"},function(e){r||e.getHostGeoModel()!==t||(r=e.getData())});var s=t.coordinateSystem;this._updateBackground(s);var l=this._regionsGroup,u=this.group,h=s.scale,c={position:s.position,scale:h};!l.childAt(0)||o?u.attr(c):Io(u,c,t),l.removeAll();var f=["itemStyle"],p=["emphasis","itemStyle"],g=["label"],m=["emphasis","label"],v=R();d(s.regions,function(e){var i=v.get(e.name)||v.set(e.name,new tb),n=new MM({shape:{paths:[]}});i.add(n);var o,s=(C=t.getRegionModel(e.name)||t).getModel(f),u=C.getModel(p),c=mc(s),y=mc(u),x=C.getModel(g),_=C.getModel(m);if(r){o=r.indexOfName(e.name);var w=r.getItemVisual(o,"color",!0);w&&(c.fill=w)}d(e.geometries,function(t){if("polygon"===t.type){n.shape.paths.push(new pM({shape:{points:t.exterior}}));for(var e=0;e<(t.interiors?t.interiors.length:0);e++)n.shape.paths.push(new pM({shape:{points:t.interiors[e]}}))}}),n.setStyle(c),n.style.strokeNoScale=!0,n.culling=!0;var b=x.get("show"),S=_.get("show"),M=r&&isNaN(r.get(r.mapDimension("value"),o)),I=r&&r.getItemLayout(o);if(a||M&&(b||S)||I&&I.showLabel){var T,A=a?e.name:o;(!r||o>=0)&&(T=t);var D=new rM({position:e.center.slice(),scale:[1/h[0],1/h[1]],z2:10,silent:!0});go(D.style,D.hoverStyle={},x,_,{labelFetcher:T,labelDataIndex:A,defaultText:e.name,useInsideStyle:!1},{textAlign:"center",textVerticalAlign:"middle"}),i.add(D)}if(r)r.setItemGraphicEl(o,i);else{var C=t.getRegionModel(e.name);n.eventData={componentType:"geo",componentIndex:t.componentIndex,geoIndex:t.componentIndex,name:e.name,region:C&&C.option||{}}}(i.__regions||(i.__regions=[])).push(e),fo(i,y,{hoverSilentOnTouch:!!t.get("selectedMode")}),l.add(i)}),this._updateController(t,e,i),vc(this,t,l,i,n),yc(t,l)},remove:function(){this._regionsGroup.removeAll(),this._backgroundGroup.removeAll(),this._controller.dispose(),this._mapName&&OC.removeGraphic(this._mapName,this.uid),this._mapName=null,this._controllerHost={}},_updateBackground:function(t){var e=t.map;this._mapName!==e&&d(OC.makeGraphic(e,this.uid),function(t){this._backgroundGroup.add(t)},this),this._mapName=e},_updateController:function(t,e,i){function n(){var e={type:"geoRoam",componentType:l};return e[l+"Id"]=t.id,e}var o=t.coordinateSystem,r=this._controller,s=this._controllerHost;s.zoomLimit=t.get("scaleLimit"),s.zoom=o.getZoom(),r.enable(t.get("roam")||!1);var l=t.mainType;r.off("pan").on("pan",function(t){this._mouseDownFlag=!1,fc(s,t.dx,t.dy),i.dispatchAction(a(n(),{dx:t.dx,dy:t.dy}))},this),r.off("zoom").on("zoom",function(t){if(this._mouseDownFlag=!1,pc(s,t.scale,t.originX,t.originY),i.dispatchAction(a(n(),{zoom:t.scale,originX:t.originX,originY:t.originY})),this._updateGroup){var e=this.group.scale;this._regionsGroup.traverse(function(t){"text"===t.type&&t.attr("scale",[1/e[0],1/e[1]])})}},this),r.setPointerChecker(function(e,n,a){return o.getViewRectAfterRoam().contain(n,a)&&!gc(e,i,t)})}};var zC="__seriesMapHighDown",BC="__seriesMapCallKey";Zs({type:"map",render:function(t,e,i,n){if(!n||"mapToggleSelect"!==n.type||n.from!==this.uid){var o=this.group;if(o.removeAll(),!t.getHostGeoModel()){if(n&&"geoRoam"===n.type&&"series"===n.componentType&&n.seriesId===t.id)(a=this._mapDraw)&&o.add(a.group);else if(t.needsDrawMap){var a=this._mapDraw||new xc(i,!0);o.add(a.group),a.draw(t,e,i,this,n),this._mapDraw=a}else this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null;t.get("showLegendSymbol")&&e.getComponent("legend")&&this._renderSymbols(t,e,i)}}},remove:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null,this.group.removeAll()},dispose:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null},_renderSymbols:function(t,e,i){var n=t.originalData,o=this.group;n.each(n.mapDimension("value"),function(e,i){if(!isNaN(e)){var r=n.getItemLayout(i);if(r&&r.point){var s=r.point,l=r.offset,u=new sM({style:{fill:t.getData().getVisual("color")},shape:{cx:s[0]+9*l,cy:s[1],r:3},silent:!0,z2:8+(l?0:NM+1)});if(!l){var h=t.mainSeries.getData(),c=n.getName(i),d=h.indexOfName(c),f=n.getItemModel(i),p=f.getModel("label"),g=f.getModel("emphasis.label"),m=h.getItemGraphicEl(d),y=A(t.getFormattedLabel(d,"normal"),c),x=A(t.getFormattedLabel(d,"emphasis"),y),_=m[zC],w=Math.random();if(!_){_=m[zC]={};var b=v(_c,!0),S=v(_c,!1);m.on("mouseover",b).on("mouseout",S).on("emphasis",b).on("normal",S)}m[BC]=w,a(_,{recordVersion:w,circle:u,labelModel:p,hoverLabelModel:g,emphasisText:x,normalText:y}),wc(_,!1)}o.add(u)}}})}}),Es({type:"geoRoam",event:"geoRoam",update:"updateTransform"},function(t,e){var i=t.componentType||"series";e.eachComponent({mainType:i,query:t},function(e){var n=e.coordinateSystem;if("geo"===n.type){var o=bc(n,t,e.get("scaleLimit"));e.setCenter&&e.setCenter(o.center),e.setZoom&&e.setZoom(o.zoom),"series"===i&&d(e.seriesGroup,function(t){t.setCenter(o.center),t.setZoom(o.zoom)})}})});var VC=Q;h(Sc,Tw),Mc.prototype={constructor:Mc,type:"view",dimensions:["x","y"],setBoundingRect:function(t,e,i,n){return this._rect=new de(t,e,i,n),this._rect},getBoundingRect:function(){return this._rect},setViewRect:function(t,e,i,n){this.transformTo(t,e,i,n),this._viewRect=new de(t,e,i,n)},transformTo:function(t,e,i,n){var o=this.getBoundingRect(),a=this._rawTransformable;a.transform=o.calculateTransform(new de(t,e,i,n)),a.decomposeTransform(),this._updateTransform()},setCenter:function(t){t&&(this._center=t,this._updateCenterAndZoom())},setZoom:function(t){t=t||1;var e=this.zoomLimit;e&&(null!=e.max&&(t=Math.min(e.max,t)),null!=e.min&&(t=Math.max(e.min,t))),this._zoom=t,this._updateCenterAndZoom()},getDefaultCenter:function(){var t=this.getBoundingRect();return[t.x+t.width/2,t.y+t.height/2]},getCenter:function(){return this._center||this.getDefaultCenter()},getZoom:function(){return this._zoom||1},getRoamTransform:function(){return this._roamTransformable.getLocalTransform()},_updateCenterAndZoom:function(){var t=this._rawTransformable.getLocalTransform(),e=this._roamTransformable,i=this.getDefaultCenter(),n=this.getCenter(),o=this.getZoom();n=Q([],n,t),i=Q([],i,t),e.origin=n,e.position=[i[0]-n[0],i[1]-n[1]],e.scale=[o,o],this._updateTransform()},_updateTransform:function(){var t=this._roamTransformable,e=this._rawTransformable;e.parent=t,t.updateTransform(),e.updateTransform(),wt(this.transform||(this.transform=[]),e.transform||xt()),this._rawTransform=e.getLocalTransform(),this.invTransform=this.invTransform||[],Tt(this.invTransform,this.transform),this.decomposeTransform()},getViewRect:function(){return this._viewRect},getViewRectAfterRoam:function(){var t=this.getBoundingRect().clone();return t.applyTransform(this.transform),t},dataToPoint:function(t,e,i){var n=e?this._rawTransform:this.transform;return i=i||[],n?VC(i,t,n):G(i,t)},pointToData:function(t){var e=this.invTransform;return e?VC([],t,e):[t[0],t[1]]},convertToPixel:v(Ic,"dataToPoint"),convertFromPixel:v(Ic,"pointToData"),containPoint:function(t){return this.getViewRectAfterRoam().contain(t[0],t[1])}},h(Mc,Tw),Tc.prototype={constructor:Tc,type:"geo",dimensions:["lng","lat"],containCoord:function(t){for(var e=this.regions,i=0;ie&&(e=n.height)}this.height=e+1},getNodeById:function(t){if(this.getId()===t)return this;for(var e=0,i=this.children,n=i.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},getLayout:function(){return this.hostTree.data.getItemLayout(this.dataIndex)},getModel:function(t){if(!(this.dataIndex<0)){var e,i=this.hostTree,n=i.data.getItemModel(this.dataIndex),o=this.getLevelModel();return o||0!==this.children.length&&(0===this.children.length||!1!==this.isExpand)||(e=this.getLeavesModel()),n.getModel(t,(o||e||i.hostModel).getModel(t))}},getLevelModel:function(){return(this.hostTree.levelModels||[])[this.depth]},getLeavesModel:function(){return this.hostTree.leavesModel},setVisual:function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},getVisual:function(t,e){return this.hostTree.data.getItemVisual(this.dataIndex,t,e)},getRawIndex:function(){return this.hostTree.data.getRawIndex(this.dataIndex)},getId:function(){return this.hostTree.data.getId(this.dataIndex)},isAncestorOf:function(t){for(var e=t.parentNode;e;){if(e===this)return!0;e=e.parentNode}return!1},isDescendantOf:function(t){return t!==this&&t.isAncestorOf(this)}},Vc.prototype={constructor:Vc,type:"tree",eachNode:function(t,e,i){this.root.eachNode(t,e,i)},getNodeByDataIndex:function(t){var e=this.data.getRawIndex(t);return this._nodes[e]},getNodeByName:function(t){return this.root.getNodeByName(t)},update:function(){for(var t=this.data,e=this._nodes,i=0,n=e.length;ia&&(a=t.depth)});var r=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:a;return o.root.eachNode("preorder",function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=r}),o.data},getOrient:function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},formatTooltip:function(t){for(var e=this.getData().tree,i=e.root.children[0],n=e.getNodeByDataIndex(t),o=n.getValue(),a=n.name;n&&n!==i;)a=n.parentNode.name+"."+a,n=n.parentNode;return ia(a+(isNaN(o)||null==o?"":" : "+o))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderColor:"#c23531",borderWidth:1.5},label:{show:!0,color:"#555"},leaves:{label:{show:!0}},animationEasing:"linear",animationDuration:700,animationDurationUpdate:1e3}}),Zs({type:"tree",init:function(t,e){this._oldTree,this._mainGroup=new tb,this._controller=new oc(e.getZr()),this._controllerHost={target:this.group},this.group.add(this._mainGroup)},render:function(t,e,i,n){var o=t.getData(),a=t.layoutInfo,r=this._mainGroup,s=t.get("layout");"radial"===s?r.attr("position",[a.x+a.width/2,a.y+a.height/2]):r.attr("position",[a.x,a.y]),this._updateViewCoordSys(t),this._updateController(t,e,i);var l=this._data,u={expandAndCollapse:t.get("expandAndCollapse"),layout:s,orient:t.getOrient(),curvature:t.get("lineStyle.curveness"),symbolRotate:t.get("symbolRotate"),symbolOffset:t.get("symbolOffset"),hoverAnimation:t.get("hoverAnimation"),useNameLabel:!0,fadeIn:!0};o.diff(l).add(function(e){td(o,e)&&id(o,e,null,r,t,u)}).update(function(e,i){var n=l.getItemGraphicEl(i);td(o,e)?id(o,e,n,r,t,u):n&&nd(l,i,n,r,t,u)}).remove(function(e){var i=l.getItemGraphicEl(e);i&&nd(l,e,i,r,t,u)}).execute(),this._nodeScaleRatio=t.get("nodeScaleRatio"),this._updateNodeAndLinkScale(t),!0===u.expandAndCollapse&&o.eachItemGraphicEl(function(e,n){e.off("click").on("click",function(){i.dispatchAction({type:"treeExpandAndCollapse",seriesId:t.id,dataIndex:n})})}),this._data=o},_updateViewCoordSys:function(t){var e=t.getData(),i=[];e.each(function(t){var n=e.getItemLayout(t);!n||isNaN(n.x)||isNaN(n.y)||i.push([+n.x,+n.y])});var n=[],o=[];fn(i,n,o),o[0]-n[0]==0&&(o[0]+=1,n[0]-=1),o[1]-n[1]==0&&(o[1]+=1,n[1]-=1);var a=t.coordinateSystem=new Mc;a.zoomLimit=t.get("scaleLimit"),a.setBoundingRect(n[0],n[1],o[0]-n[0],o[1]-n[1]),a.setCenter(t.get("center")),a.setZoom(t.get("zoom")),this.group.attr({position:a.position,scale:a.scale}),this._viewCoordSys=a},_updateController:function(t,e,i){var n=this._controller,o=this._controllerHost,a=this.group;n.setPointerChecker(function(e,n,o){var r=a.getBoundingRect();return r.applyTransform(a.transform),r.contain(n,o)&&!gc(e,i,t)}),n.enable(t.get("roam")),o.zoomLimit=t.get("scaleLimit"),o.zoom=t.coordinateSystem.getZoom(),n.off("pan").off("zoom").on("pan",function(e){fc(o,e.dx,e.dy),i.dispatchAction({seriesId:t.id,type:"treeRoam",dx:e.dx,dy:e.dy})},this).on("zoom",function(e){pc(o,e.scale,e.originX,e.originY),i.dispatchAction({seriesId:t.id,type:"treeRoam",zoom:e.scale,originX:e.originX,originY:e.originY}),this._updateNodeAndLinkScale(t)},this)},_updateNodeAndLinkScale:function(t){var e=t.getData(),i=this._getNodeGlobalScale(t),n=[i,i];e.eachItemGraphicEl(function(t,e){t.attr("scale",n)})},_getNodeGlobalScale:function(t){var e=t.coordinateSystem;if("view"!==e.type)return 1;var i=this._nodeScaleRatio,n=e.scale,o=n&&n[0]||1;return((e.getZoom()-1)*i+1)/o},dispose:function(){this._controller&&this._controller.dispose(),this._controllerHost={}},remove:function(){this._mainGroup.removeAll(),this._data=null}}),Es({type:"treeExpandAndCollapse",event:"treeExpandAndCollapse",update:"update"},function(t,e){e.eachComponent({mainType:"series",subType:"tree",query:t},function(e){var i=t.dataIndex,n=e.getData().tree.getNodeByDataIndex(i);n.isExpand=!n.isExpand})}),Es({type:"treeRoam",event:"treeRoam",update:"none"},function(t,e){e.eachComponent({mainType:"series",subType:"tree",query:t},function(e){var i=bc(e.coordinateSystem,t);e.setCenter&&e.setCenter(i.center),e.setZoom&&e.setZoom(i.zoom)})});Bs(TD("tree","circle")),zs(function(t,e){t.eachSeriesByType("tree",function(t){sd(t,e)})}),YI.extend({type:"series.treemap",layoutMode:"box",dependencies:["grid","polar"],_viewRoot:null,defaultOption:{progressive:0,hoverLayerThreshold:1/0,left:"center",top:"middle",right:null,bottom:null,width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",borderColor:"rgba(255,255,255,0.7)",borderWidth:1,shadowColor:"rgba(150,150,150,1)",shadowBlur:3,shadowOffsetX:0,shadowOffsetY:0,textStyle:{color:"#fff"}},emphasis:{textStyle:{}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",ellipsis:!0},upperLabel:{show:!1,position:[0,"50%"],height:20,color:"#fff",ellipsis:!0,verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],color:"#fff",ellipsis:!0,verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},getInitialData:function(t,e){var i={name:t.name,children:t.data};dd(i);var n=t.levels||[];n=t.levels=fd(n,e);var o={};return o.levels=n,Vc.createTree(i,this,o).data},optionUpdated:function(){this.resetViewRoot()},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=ta(y(i)?i[0]:i);return ia(e.getName(t)+": "+n)},getDataParams:function(t){var e=YI.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(t);return e.treePathInfo=cd(i,this),e},setLayoutInfo:function(t){this.layoutInfo=this.layoutInfo||{},a(this.layoutInfo,t)},mapIdToIndex:function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=R(),this._idIndexMapCount=0);var i=e.get(t);return null==i&&e.set(t,i=this._idIndexMapCount++),i},getViewRoot:function(){return this._viewRoot},resetViewRoot:function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)}});var UC=5;pd.prototype={constructor:pd,render:function(t,e,i,n){var o=t.getModel("breadcrumb"),a=this.group;if(a.removeAll(),o.get("show")&&i){var r=o.getModel("itemStyle"),s=r.getModel("textStyle"),l={pos:{left:o.get("left"),right:o.get("right"),top:o.get("top"),bottom:o.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:o.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(i,l,s),this._renderContent(t,l,r,s,n),da(a,l.pos,l.box)}},_prepare:function(t,e,i){for(var n=t;n;n=n.parentNode){var o=n.getModel().get("name"),a=i.getTextRect(o),r=Math.max(a.width+16,e.emptyItemWidth);e.totalWidth+=r+8,e.renderList.push({node:n,text:o,width:r})}},_renderContent:function(t,e,i,n,o){for(var a=0,s=e.emptyItemWidth,l=t.get("breadcrumb.height"),u=ha(e.pos,e.box),h=e.totalWidth,c=e.renderList,d=c.length-1;d>=0;d--){var f=c[d],p=f.node,g=f.width,m=f.text;h>u.width&&(h-=g-s,g=s,m=null);var y=new pM({shape:{points:gd(a,0,g,l,d===c.length-1,0===d)},style:r(i.getItemStyle(),{lineJoin:"bevel",text:m,textFill:n.getTextColor(),textFont:n.getFont()}),z:10,onclick:v(o,p)});this.group.add(y),md(y,t,p),a+=g+8}},remove:function(){this.group.removeAll()}};var XC=m,jC=tb,YC=yM,qC=d,KC=["label"],$C=["emphasis","label"],JC=["upperLabel"],QC=["emphasis","upperLabel"],tL=10,eL=1,iL=2,nL=Qb([["fill","color"],["stroke","strokeColor"],["lineWidth","strokeWidth"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),oL=function(t){var e=nL(t);return e.stroke=e.fill=e.lineWidth=null,e};Zs({type:"treemap",init:function(t,e){this._containerGroup,this._storage={nodeGroup:[],background:[],content:[]},this._oldTree,this._breadcrumb,this._controller,this._state="ready"},render:function(t,e,i,n){if(!(l(e.findComponents({mainType:"series",subType:"treemap",query:n}),t)<0)){this.seriesModel=t,this.api=i,this.ecModel=e;var o=ld(n,["treemapZoomToNode","treemapRootToNode"],t),a=n&&n.type,r=t.layoutInfo,s=!this._oldTree,u=this._storage,h="treemapRootToNode"===a&&o&&u?{rootNodeGroup:u.nodeGroup[o.node.getRawIndex()],direction:n.direction}:null,c=this._giveContainerGroup(r),d=this._doRender(c,t,h);s||a&&"treemapZoomToNode"!==a&&"treemapRootToNode"!==a?d.renderFinally():this._doAnimation(c,d,t,h),this._resetController(i),this._renderBreadcrumb(t,i,o)}},_giveContainerGroup:function(t){var e=this._containerGroup;return e||(e=this._containerGroup=new jC,this._initEvents(e),this.group.add(e)),e.attr("position",[t.x,t.y]),e},_doRender:function(t,e,i){function n(t,e,i,o,a){function r(t){return t.getId()}function s(r,s){var l=null!=r?t[r]:null,u=null!=s?e[s]:null,c=h(l,u,i,a);c&&n(l&&l.viewChildren||[],u&&u.viewChildren||[],c,o,a+1)}o?(e=t,qC(t,function(t,e){!t.isRemoved()&&s(e,e)})):new Xs(e,t,r,r).add(s).update(s).remove(v(s,null)).execute()}var o=e.getData().tree,a=this._oldTree,r={nodeGroup:[],background:[],content:[]},s={nodeGroup:[],background:[],content:[]},l=this._storage,u=[],h=v(yd,e,s,l,i,r,u);n(o.root?[o.root]:[],a&&a.root?[a.root]:[],t,o===a||!a,0);var c=function(t){var e={nodeGroup:[],background:[],content:[]};return t&&qC(t,function(t,i){var n=e[i];qC(t,function(t){t&&(n.push(t),t.__tmWillDelete=1)})}),e}(l);return this._oldTree=o,this._storage=s,{lastsForAnimation:r,willDeleteEls:c,renderFinally:function(){qC(c,function(t){qC(t,function(t){t.parent&&t.parent.remove(t)})}),qC(u,function(t){t.invisible=!0,t.dirty()})}}},_doAnimation:function(t,e,i,n){if(i.get("animation")){var o=i.get("animationDurationUpdate"),r=i.get("animationEasing"),s=vd();qC(e.willDeleteEls,function(t,e){qC(t,function(t,i){if(!t.invisible){var a,l=t.parent;if(n&&"drillDown"===n.direction)a=l===n.rootNodeGroup?{shape:{x:0,y:0,width:l.__tmNodeWidth,height:l.__tmNodeHeight},style:{opacity:0}}:{style:{opacity:0}};else{var u=0,h=0;l.__tmWillDelete||(u=l.__tmNodeWidth/2,h=l.__tmNodeHeight/2),a="nodeGroup"===e?{position:[u,h],style:{opacity:0}}:{shape:{x:u,y:h,width:0,height:0},style:{opacity:0}}}a&&s.add(t,a,o,r)}})}),qC(this._storage,function(t,i){qC(t,function(t,n){var l=e.lastsForAnimation[i][n],u={};l&&("nodeGroup"===i?l.old&&(u.position=t.position.slice(),t.attr("position",l.old)):(l.old&&(u.shape=a({},t.shape),t.setShape(l.old)),l.fadein?(t.setStyle("opacity",0),u.style={opacity:1}):1!==t.style.opacity&&(u.style={opacity:1})),s.add(t,u,o,r))})},this),this._state="animating",s.done(XC(function(){this._state="ready",e.renderFinally()},this)).start()}},_resetController:function(t){var e=this._controller;e||((e=this._controller=new oc(t.getZr())).enable(this.seriesModel.get("roam")),e.on("pan",XC(this._onPan,this)),e.on("zoom",XC(this._onZoom,this)));var i=new de(0,0,t.getWidth(),t.getHeight());e.setPointerChecker(function(t,e,n){return i.contain(e,n)})},_clearController:function(){var t=this._controller;t&&(t.dispose(),t=null)},_onPan:function(t){if("animating"!==this._state&&(Math.abs(t.dx)>3||Math.abs(t.dy)>3)){var e=this.seriesModel.getData().tree.root;if(!e)return;var i=e.getLayout();if(!i)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:i.x+t.dx,y:i.y+t.dy,width:i.width,height:i.height}})}},_onZoom:function(t){var e=t.originX,i=t.originY;if("animating"!==this._state){var n=this.seriesModel.getData().tree.root;if(!n)return;var o=n.getLayout();if(!o)return;var a=new de(o.x,o.y,o.width,o.height),r=this.seriesModel.layoutInfo;e-=r.x,i-=r.y;var s=xt();St(s,s,[-e,-i]),It(s,s,[t.scale,t.scale]),St(s,s,[e,i]),a.applyTransform(s),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:a.x,y:a.y,width:a.width,height:a.height}})}},_initEvents:function(t){t.on("click",function(t){if("ready"===this._state){var e=this.seriesModel.get("nodeClick",!0);if(e){var i=this.findTarget(t.offsetX,t.offsetY);if(i){var n=i.node;if(n.getLayout().isLeafRoot)this._rootToNode(i);else if("zoomToNode"===e)this._zoomToNode(i);else if("link"===e){var o=n.hostTree.data.getItemModel(n.dataIndex),a=o.get("link",!0),r=o.get("target",!0)||"blank";a&&window.open(a,r)}}}}},this)},_renderBreadcrumb:function(t,e,i){i||(i=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(i={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new pd(this.group))).render(t,e,i.node,XC(function(e){"animating"!==this._state&&(hd(t.getViewRoot(),e)?this._rootToNode({node:e}):this._zoomToNode({node:e}))},this))},remove:function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},dispose:function(){this._clearController()},_zoomToNode:function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},_rootToNode:function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},findTarget:function(t,e){var i;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},function(n){var o=this._storage.background[n.getRawIndex()];if(o){var a=o.transformCoordToLocal(t,e),r=o.shape;if(!(r.x<=a[0]&&a[0]<=r.x+r.width&&r.y<=a[1]&&a[1]<=r.y+r.height))return!1;i={node:n,offsetX:a[0],offsetY:a[1]}}},this),i}});for(var aL=["treemapZoomToNode","treemapRender","treemapMove"],rL=0;rL=0&&t.call(e,i[o],o)},TL.eachEdge=function(t,e){for(var i=this.edges,n=i.length,o=0;o=0&&i[o].node1.dataIndex>=0&&i[o].node2.dataIndex>=0&&t.call(e,i[o],o)},TL.breadthFirstTraverse=function(t,e,i,n){if(Jd.isInstance(e)||(e=this._nodesMap[$d(e)]),e){for(var o="out"===i?"outEdges":"in"===i?"inEdges":"edges",a=0;a=0&&i.node2.dataIndex>=0});for(var o=0,a=n.length;o=0&&this[t][e].setItemVisual(this.dataIndex,i,n)},getVisual:function(i,n){return this[t][e].getItemVisual(this.dataIndex,i,n)},setLayout:function(i,n){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,i,n)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}};h(Jd,AL("hostGraph","data")),h(Qd,AL("hostGraph","edgeData")),IL.Node=Jd,IL.Edge=Qd,Yi(Jd),Yi(Qd);var DL=function(t,e,i,n,o){for(var a=new IL(n),r=0;r "+f)),h++)}var p,g=i.get("coordinateSystem");if("cartesian2d"===g||"polar"===g)p=ml(t,i);else{var m=Fa.get(g),v=m&&"view"!==m.type?m.dimensions||[]:[];l(v,"value")<0&&v.concat(["value"]);var y=_A(t,{coordDimensions:v});(p=new vA(y,i)).initData(t)}var x=new vA(["value"],i);return x.initData(u,s),o&&o(p,x),kc({mainData:p,struct:a,structAttr:"graph",datas:{node:p,edge:x},datasAttr:{node:"data",edge:"edgeData"}}),a.update(),a},CL=Hs({type:"series.graph",init:function(t){CL.superApply(this,"init",arguments),this.legendDataProvider=function(){return this._categoriesData},this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeOption:function(t){CL.superApply(this,"mergeOption",arguments),this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeDefaultAndTheme:function(t){CL.superApply(this,"mergeDefaultAndTheme",arguments),Ci(t,["edgeLabel"],["show"])},getInitialData:function(t,e){var i=t.edges||t.links||[],n=t.data||t.nodes||[],o=this;if(n&&i)return DL(n,i,this,!0,function(t,i){function n(t){return(t=this.parsePath(t))&&"label"===t[0]?r:t&&"emphasis"===t[0]&&"label"===t[1]?l:this.parentModel}t.wrapMethod("getItemModel",function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t});var a=o.getModel("edgeLabel"),r=new No({label:a.option},a.parentModel,e),s=o.getModel("emphasis.edgeLabel"),l=new No({emphasis:{label:s.option}},s.parentModel,e);i.wrapMethod("getItemModel",function(t){return t.customizeGetParent(n),t})}).data},getGraph:function(){return this.getData().graph},getEdgeData:function(){return this.getGraph().edgeData},getCategoriesData:function(){return this._categoriesData},formatTooltip:function(t,e,i){if("edge"===i){var n=this.getData(),o=this.getDataParams(t,i),a=n.graph.getEdgeByIndex(t),r=n.getName(a.node1.dataIndex),s=n.getName(a.node2.dataIndex),l=[];return null!=r&&l.push(r),null!=s&&l.push(s),l=ia(l.join(" > ")),o.value&&(l+=" : "+ia(o.value)),l}return CL.superApply(this,"formatTooltip",arguments)},_updateCategoriesData:function(){var t=f(this.option.categories||[],function(t){return null!=t.value?t:a({value:0},t)}),e=new vA(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray(function(t){return e.getItemModel(t,!0)})},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},isAnimationEnabled:function(){return CL.superCall(this,"isAnimationEnabled")&&!("force"===this.get("layout")&&this.get("force.layoutAnimation"))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",legendHoverLink:!0,hoverAnimation:!0,layout:null,focusNodeAdjacency:!1,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle"},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,curveness:0,opacity:.5},emphasis:{label:{show:!0}}}}),LL=_M.prototype,kL=bM.prototype,PL=Un({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){(tf(e)?LL:kL).buildPath(t,e)},pointAt:function(t){return tf(this.shape)?LL.pointAt.call(this,t):kL.pointAt.call(this,t)},tangentAt:function(t){var e=this.shape,i=tf(e)?[e.x2-e.x1,e.y2-e.y1]:kL.tangentAt.call(this,t);return q(i,i)}}),NL=["fromSymbol","toSymbol"],OL=rf.prototype;OL.beforeUpdate=function(){var t=this,e=t.childOfName("fromSymbol"),i=t.childOfName("toSymbol"),n=t.childOfName("label");if(e||i||!n.ignore){for(var o=1,a=this.parent;a;)a.scale&&(o/=a.scale[0]),a=a.parent;var r=t.childOfName("line");if(this.__dirty||r.__dirty){var s=r.shape.percent,l=r.pointAt(0),u=r.pointAt(s),h=U([],u,l);if(q(h,h),e&&(e.attr("position",l),c=r.tangentAt(0),e.attr("rotation",Math.PI/2-Math.atan2(c[1],c[0])),e.attr("scale",[o*s,o*s])),i){i.attr("position",u);var c=r.tangentAt(1);i.attr("rotation",-Math.PI/2-Math.atan2(c[1],c[0])),i.attr("scale",[o*s,o*s])}if(!n.ignore){n.attr("position",u);var d,f,p,g=5*o;if("end"===n.__position)d=[h[0]*g+u[0],h[1]*g+u[1]],f=h[0]>.8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";else if("middle"===n.__position){var m=s/2,v=[(c=r.tangentAt(m))[1],-c[0]],y=r.pointAt(m);v[1]>0&&(v[0]=-v[0],v[1]=-v[1]),d=[y[0]+v[0]*g,y[1]+v[1]*g],f="center",p="bottom";var x=-Math.atan2(c[1],c[0]);u[0].8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";n.attr({style:{textVerticalAlign:n.__verticalAlign||p,textAlign:n.__textAlign||f},position:d,scale:[o,o]})}}}},OL._createLine=function(t,e,i){var n=t.hostModel,o=of(t.getItemLayout(e));o.shape.percent=0,To(o,{shape:{percent:1}},n,e),this.add(o);var a=new rM({name:"label",lineLabelOriginalOpacity:1});this.add(a),d(NL,function(i){var n=nf(i,t,e);this.add(n),this[ef(i)]=t.getItemVisual(e,i)},this),this._updateCommonStl(t,e,i)},OL.updateData=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=t.getItemLayout(e),r={shape:{}};af(r.shape,a),Io(o,r,n,e),d(NL,function(i){var n=t.getItemVisual(e,i),o=ef(i);if(this[o]!==n){this.remove(this.childOfName(i));var a=nf(i,t,e);this.add(a)}this[o]=n},this),this._updateCommonStl(t,e,i)},OL._updateCommonStl=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=i&&i.lineStyle,s=i&&i.hoverLineStyle,l=i&&i.labelModel,u=i&&i.hoverLabelModel;if(!i||t.hasItemOption){var h=t.getItemModel(e);a=h.getModel("lineStyle").getLineStyle(),s=h.getModel("emphasis.lineStyle").getLineStyle(),l=h.getModel("label"),u=h.getModel("emphasis.label")}var c=t.getItemVisual(e,"color"),f=D(t.getItemVisual(e,"opacity"),a.opacity,1);o.useStyle(r({strokeNoScale:!0,fill:"none",stroke:c,opacity:f},a)),o.hoverStyle=s,d(NL,function(t){var e=this.childOfName(t);e&&(e.setColor(c),e.setStyle({opacity:f}))},this);var p,g,m=l.getShallow("show"),v=u.getShallow("show"),y=this.childOfName("label");if((m||v)&&(p=c||"#000",null==(g=n.getFormattedLabel(e,"normal",t.dataType)))){var x=n.getRawValue(e);g=null==x?t.getName(e):isFinite(x)?Go(x):x}var _=m?g:null,w=v?A(n.getFormattedLabel(e,"emphasis",t.dataType),g):null,b=y.style;null==_&&null==w||(mo(y.style,l,{text:_},{autoColor:p}),y.__textAlign=b.textAlign,y.__verticalAlign=b.textVerticalAlign,y.__position=l.get("position")||"middle"),y.hoverStyle=null!=w?{text:w,textFill:u.getTextColor(!0),fontStyle:u.getShallow("fontStyle"),fontWeight:u.getShallow("fontWeight"),fontSize:u.getShallow("fontSize"),fontFamily:u.getShallow("fontFamily")}:{text:null},y.ignore=!m&&!v,fo(this)},OL.highlight=function(){this.trigger("emphasis")},OL.downplay=function(){this.trigger("normal")},OL.updateLayout=function(t,e){this.setLinePoints(t.getItemLayout(e))},OL.setLinePoints=function(t){var e=this.childOfName("line");af(e.shape,t),e.dirty()},u(rf,tb);var EL=sf.prototype;EL.isPersistent=function(){return!0},EL.updateData=function(t){var e=this,i=e.group,n=e._lineData;e._lineData=t,n||i.removeAll();var o=hf(t);t.diff(n).add(function(i){lf(e,t,i,o)}).update(function(i,a){uf(e,n,t,a,i,o)}).remove(function(t){i.remove(n.getItemGraphicEl(t))}).execute()},EL.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl(function(e,i){e.updateLayout(t,i)},this)},EL.incrementalPrepareUpdate=function(t){this._seriesScope=hf(t),this._lineData=null,this.group.removeAll()},EL.incrementalUpdate=function(t,e){for(var i=t.start;i=o/3?1:2),l=e.y-n(r)*a*(a>=o/3?1:2);r=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+i(r)*a,e.y+n(r)*a),t.lineTo(e.x+i(e.angle)*o,e.y+n(e.angle)*o),t.lineTo(e.x-i(r)*a,e.y-n(r)*a),t.lineTo(s,l)}}),YL=2*Math.PI,qL=(Ar.extend({type:"gauge",render:function(t,e,i){this.group.removeAll();var n=t.get("axisLine.lineStyle.color"),o=Sf(t,i);this._renderMain(t,e,i,n,o)},dispose:function(){},_renderMain:function(t,e,i,n,o){for(var a=this.group,r=t.getModel("axisLine").getModel("lineStyle"),s=t.get("clockwise"),l=-t.get("startAngle")/180*Math.PI,u=-t.get("endAngle")/180*Math.PI,h=(u-l)%YL,c=l,d=r.get("width"),f=0;f=t&&(0===e?0:n[e-1][0]).4?"bottom":"middle",textAlign:A<-.4?"left":A>.4?"right":"center"},{autoColor:P}),silent:!0}))}if(g.get("show")&&T!==v){for(var N=0;N<=y;N++){var A=Math.cos(w),D=Math.sin(w),O=new _M({shape:{x1:A*c+u,y1:D*c+h,x2:A*(c-_)+u,y2:D*(c-_)+h},silent:!0,style:I});"auto"===I.stroke&&O.setStyle({stroke:n((T+N/y)/v)}),l.add(O),w+=S}w-=S}else w+=b}},_renderPointer:function(t,e,i,n,o,a,r,s){var l=this.group,u=this._data;if(t.get("pointer.show")){var h=[+t.get("min"),+t.get("max")],c=[a,r],d=t.getData(),f=d.mapDimension("value");d.diff(u).add(function(e){var i=new jL({shape:{angle:a}});To(i,{shape:{angle:Bo(d.get(f,e),h,c,!0)}},t),l.add(i),d.setItemGraphicEl(e,i)}).update(function(e,i){var n=u.getItemGraphicEl(i);Io(n,{shape:{angle:Bo(d.get(f,e),h,c,!0)}},t),l.add(n),d.setItemGraphicEl(e,n)}).remove(function(t){var e=u.getItemGraphicEl(t);l.remove(e)}).execute(),d.eachItemGraphicEl(function(t,e){var i=d.getItemModel(e),a=i.getModel("pointer");t.setShape({x:o.cx,y:o.cy,width:Vo(a.get("width"),o.r),r:Vo(a.get("length"),o.r)}),t.useStyle(i.getModel("itemStyle").getItemStyle()),"auto"===t.style.fill&&t.setStyle("fill",n(Bo(d.get(f,e),h,[0,1],!0))),fo(t,i.getModel("emphasis.itemStyle").getItemStyle())}),this._data=d}else u&&u.eachItemGraphicEl(function(t){l.remove(t)})},_renderTitle:function(t,e,i,n,o){var a=t.getData(),r=a.mapDimension("value"),s=t.getModel("title");if(s.get("show")){var l=s.get("offsetCenter"),u=o.cx+Vo(l[0],o.r),h=o.cy+Vo(l[1],o.r),c=+t.get("min"),d=+t.get("max"),f=n(Bo(t.getData().get(r,0),[c,d],[0,1],!0));this.group.add(new rM({silent:!0,style:mo({},s,{x:u,y:h,text:a.getName(0),textAlign:"center",textVerticalAlign:"middle"},{autoColor:f,forceRich:!0})}))}},_renderDetail:function(t,e,i,n,o){var a=t.getModel("detail"),r=+t.get("min"),s=+t.get("max");if(a.get("show")){var l=a.get("offsetCenter"),u=o.cx+Vo(l[0],o.r),h=o.cy+Vo(l[1],o.r),c=Vo(a.get("width"),o.r),d=Vo(a.get("height"),o.r),f=t.getData(),p=f.get(f.mapDimension("value"),0),g=n(Bo(p,[r,s],[0,1],!0));this.group.add(new rM({silent:!0,style:mo({},a,{x:u,y:h,text:Mf(p,a.get("formatter")),textWidth:isNaN(c)?null:c,textHeight:isNaN(d)?null:d,textAlign:"center",textVerticalAlign:"middle"},{autoColor:g,forceRich:!0})}))}}}),Hs({type:"series.funnel",init:function(t){qL.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()},this._defaultLabelLine(t)},getInitialData:function(t,e){return oC(this,["value"])},_defaultLabelLine:function(t){Ci(t,"labelLine",["show"]);var e=t.labelLine,i=t.emphasis.labelLine;e.show=e.show&&t.label.show,i.show=i.show&&t.emphasis.label.show},getDataParams:function(t){var e=this.getData(),i=qL.superCall(this,"getDataParams",t),n=e.mapDimension("value"),o=e.getSum(n);return i.percent=o?+(e.get(n,t)/o*100).toFixed(2):0,i.$vars.push("percent"),i},defaultOption:{zlevel:0,z:2,legendHoverLink:!0,left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1,type:"solid"}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}}}})),KL=If.prototype,$L=["itemStyle","opacity"];KL.updateData=function(t,e,i){var n=this.childAt(0),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e),l=t.getItemModel(e).get($L);l=null==l?1:l,n.useStyle({}),i?(n.setShape({points:s.points}),n.setStyle({opacity:0}),To(n,{style:{opacity:l}},o,e)):Io(n,{style:{opacity:l},shape:{points:s.points}},o,e);var u=a.getModel("itemStyle"),h=t.getItemVisual(e,"color");n.setStyle(r({lineJoin:"round",fill:h},u.getItemStyle(["opacity"]))),n.hoverStyle=u.getModel("emphasis").getItemStyle(),this._updateLabel(t,e),fo(this)},KL._updateLabel=function(t,e){var i=this.childAt(1),n=this.childAt(2),o=t.hostModel,a=t.getItemModel(e),r=t.getItemLayout(e).label,s=t.getItemVisual(e,"color");Io(i,{shape:{points:r.linePoints||r.linePoints}},o,e),Io(n,{style:{x:r.x,y:r.y}},o,e),n.attr({rotation:r.rotation,origin:[r.x,r.y],z2:10});var l=a.getModel("label"),u=a.getModel("emphasis.label"),h=a.getModel("labelLine"),c=a.getModel("emphasis.labelLine"),s=t.getItemVisual(e,"color");go(n.style,n.hoverStyle={},l,u,{labelFetcher:t.hostModel,labelDataIndex:e,defaultText:t.getName(e),autoColor:s,useInsideStyle:!!r.inside},{textAlign:r.textAlign,textVerticalAlign:r.verticalAlign}),n.ignore=n.normalIgnore=!l.get("show"),n.hoverIgnore=!u.get("show"),i.ignore=i.normalIgnore=!h.get("show"),i.hoverIgnore=!c.get("show"),i.setStyle({stroke:s}),i.setStyle(h.getModel("lineStyle").getLineStyle()),i.hoverStyle=c.getModel("lineStyle").getLineStyle()},u(If,tb);Ar.extend({type:"funnel",render:function(t,e,i){var n=t.getData(),o=this._data,a=this.group;n.diff(o).add(function(t){var e=new If(n,t);n.setItemGraphicEl(t,e),a.add(e)}).update(function(t,e){var i=o.getItemGraphicEl(e);i.updateData(n,t),a.add(i),n.setItemGraphicEl(t,i)}).remove(function(t){var e=o.getItemGraphicEl(t);a.remove(e)}).execute(),this._data=n},remove:function(){this.group.removeAll(),this._data=null},dispose:function(){}});Bs(uC("funnel")),zs(function(t,e,i){t.eachSeriesByType("funnel",function(t){var i=t.getData(),n=i.mapDimension("value"),o=t.get("sort"),a=Tf(t,e),r=Af(i,o),s=[Vo(t.get("minSize"),a.width),Vo(t.get("maxSize"),a.width)],l=i.getDataExtent(n),u=t.get("min"),h=t.get("max");null==u&&(u=Math.min(l[0],0)),null==h&&(h=l[1]);var c=t.get("funnelAlign"),d=t.get("gap"),f=(a.height-d*(i.count()-1))/i.count(),p=a.y,g=function(t,e){var o,r=Bo(i.get(n,t)||0,[u,h],s,!0);switch(c){case"left":o=a.x;break;case"center":o=a.x+(a.width-r)/2;break;case"right":o=a.x+a.width-r}return[[o,e],[o+r,e]]};"ascending"===o&&(f=-f,d=-d,p+=a.height,r=r.reverse());for(var m=0;ma&&(e[1-n]=e[n]+h.sign*a),e},tk=d,ek=Math.min,ik=Math.max,nk=Math.floor,ok=Math.ceil,ak=Go,rk=Math.PI;Nf.prototype={type:"parallel",constructor:Nf,_init:function(t,e,i){var n=t.dimensions,o=t.parallelAxisIndex;tk(n,function(t,i){var n=o[i],a=e.getComponent("parallelAxis",n),r=this._axesMap.set(t,new JL(t,Hl(a),[0,0],a.get("type"),n)),s="category"===r.type;r.onBand=s&&a.get("boundaryGap"),r.inverse=a.get("inverse"),a.axis=r,r.model=a,r.coordinateSystem=a.coordinateSystem=this},this)},update:function(t,e){this._updateAxesFromSeries(this._model,t)},containPoint:function(t){var e=this._makeLayoutInfo(),i=e.axisBase,n=e.layoutBase,o=e.pixelDimIndex,a=t[1-o],r=t[o];return a>=i&&a<=i+e.axisLength&&r>=n&&r<=n+e.layoutLength},getModel:function(){return this._model},_updateAxesFromSeries:function(t,e){e.eachSeries(function(i){if(t.contains(i,e)){var n=i.getData();tk(this.dimensions,function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(n,n.mapDimension(t)),Wl(e.scale,e.model)},this)}},this)},resize:function(t,e){this._rect=ca(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},getRect:function(){return this._rect},_makeLayoutInfo:function(){var t,e=this._model,i=this._rect,n=["x","y"],o=["width","height"],a=e.get("layout"),r="horizontal"===a?0:1,s=i[o[r]],l=[0,s],u=this.dimensions.length,h=Of(e.get("axisExpandWidth"),l),c=Of(e.get("axisExpandCount")||0,[0,u]),d=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,f=e.get("axisExpandWindow");f?(t=Of(f[1]-f[0],l),f[1]=f[0]+t):(t=Of(h*(c-1),l),(f=[h*(e.get("axisExpandCenter")||nk(u/2))-t/2])[1]=f[0]+t);var p=(s-t)/(u-c);p<3&&(p=0);var g=[nk(ak(f[0]/h,1))+1,ok(ak(f[1]/h,1))-1],m=p/h*f[0];return{layout:a,pixelDimIndex:r,layoutBase:i[n[r]],layoutLength:s,axisBase:i[n[1-r]],axisLength:i[o[1-r]],axisExpandable:d,axisExpandWidth:h,axisCollapseWidth:p,axisExpandWindow:f,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:m}},_layoutAxes:function(){var t=this._rect,e=this._axesMap,i=this.dimensions,n=this._makeLayoutInfo(),o=n.layout;e.each(function(t){var e=[0,n.axisLength],i=t.inverse?1:0;t.setExtent(e[i],e[1-i])}),tk(i,function(e,i){var a=(n.axisExpandable?Rf:Ef)(i,n),r={horizontal:{x:a.position,y:n.axisLength},vertical:{x:0,y:a.position}},s={horizontal:rk/2,vertical:0},l=[r[o].x+t.x,r[o].y+t.y],u=s[o],h=xt();Mt(h,h,u),St(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:a.axisNameAvailableWidth,axisLabelShow:a.axisLabelShow,nameTruncateMaxWidth:a.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}},this)},getAxis:function(t){return this._axesMap.get(t)},dataToPoint:function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},eachActiveState:function(t,e,i,n){null==i&&(i=0),null==n&&(n=t.count());var o=this._axesMap,a=this.dimensions,r=[],s=[];d(a,function(e){r.push(t.mapDimension(e)),s.push(o.get(e).model)});for(var l=this.hasAxisBrushed(),u=i;uo*(1-h[0])?(l="jump",r=s-o*(1-h[2])):(r=s-o*h[1])>=0&&(r=s-o*(1-h[1]))<=0&&(r=0),(r*=e.axisExpandWidth/u)?QL(r,n,a,"all"):l="none";else{o=n[1]-n[0];(n=[ik(0,a[1]*s/o-o/2)])[1]=ek(a[1],n[0]+o),n[0]=n[1]-o}return{axisExpandWindow:n,behavior:l}}},Fa.register("parallel",{create:function(t,e){var i=[];return t.eachComponent("parallel",function(n,o){var a=new Nf(n,t,e);a.name="parallel_"+o,a.resize(n,e),n.coordinateSystem=a,a.model=n,i.push(a)}),t.eachSeries(function(e){if("parallel"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"parallel",index:e.get("parallelIndex"),id:e.get("parallelId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}});var sk=lI.extend({type:"baseParallelAxis",axis:null,activeIntervals:[],getAreaSelectStyle:function(){return Qb([["fill","color"],["lineWidth","borderWidth"],["stroke","borderColor"],["width","width"],["opacity","opacity"]])(this.getModel("areaSelectStyle"))},setActiveIntervals:function(t){var e=this.activeIntervals=i(t);if(e)for(var n=e.length-1;n>=0;n--)Fo(e[n])},getActiveState:function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(t))return"inactive";if(1===e.length){var i=e[0];if(i[0]<=t&&t<=i[1])return"active"}else for(var n=0,o=e.length;n5)return;var n=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==n.behavior&&this._dispatchExpand({axisExpandWindow:n.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&Ip(this,"mousemove")){var e=this._model,i=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),n=i.behavior;"jump"===n&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===n?null:{axisExpandWindow:i.axisExpandWindow,animation:"jump"===n&&null})}}};Ns(function(t){Cf(t),Lf(t)}),YI.extend({type:"series.parallel",dependencies:["parallel"],visualColorAccessPath:"lineStyle.color",getInitialData:function(t,e){var i=this.getSource();return Tp(i,this),ml(i,this)},getRawIndicesByActiveState:function(t){var e=this.coordinateSystem,i=this.getData(),n=[];return e.eachActiveState(i,function(e,o){t===e&&n.push(i.getRawIndex(o))}),n},defaultOption:{zlevel:0,z:2,coordinateSystem:"parallel",parallelIndex:0,label:{show:!1},inactiveOpacity:.05,activeOpacity:1,lineStyle:{width:1,opacity:.45,type:"solid"},emphasis:{label:{show:!1}},progressive:500,smooth:!1,animationEasing:"linear"}});var Dk=.3,Ck=(Ar.extend({type:"parallel",init:function(){this._dataGroup=new tb,this.group.add(this._dataGroup),this._data,this._initialized},render:function(t,e,i,n){var o=this._dataGroup,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.dimensions,u=kp(t);if(a.diff(r).add(function(t){Pp(Lp(a,o,t,l,s),a,t,u)}).update(function(e,i){var o=r.getItemGraphicEl(i),h=Cp(a,e,l,s);a.setItemGraphicEl(e,o),Io(o,{shape:{points:h}},n&&!1===n.animation?null:t,e),Pp(o,a,e,u)}).remove(function(t){var e=r.getItemGraphicEl(t);o.remove(e)}).execute(),!this._initialized){this._initialized=!0;var h=Dp(s,t,function(){setTimeout(function(){o.removeClipPath()})});o.setClipPath(h)}this._data=a},incrementalPrepareRender:function(t,e,i){this._initialized=!0,this._data=null,this._dataGroup.removeAll()},incrementalRender:function(t,e,i){for(var n=e.getData(),o=e.coordinateSystem,a=o.dimensions,r=kp(e),s=t.start;sn&&(n=e)}),d(e,function(e){var o=new hL({type:"color",mappingMethod:"linear",dataExtent:[i,n],visual:t.get("color")}).mapValueToVisual(e.getLayout().value);e.setVisual("color",o);var a=e.getModel().get("itemStyle.color");null!=a&&e.setVisual("color",a)})}})});var Ok={_baseAxisDim:null,getInitialData:function(t,e){var i,n,o=e.getComponent("xAxis",this.get("xAxisIndex")),a=e.getComponent("yAxis",this.get("yAxisIndex")),r=o.get("type"),s=a.get("type");"category"===r?(t.layout="horizontal",i=o.getOrdinalMeta(),n=!0):"category"===s?(t.layout="vertical",i=a.getOrdinalMeta(),n=!0):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],f=[o,a],p=f[u].get("type"),g=f[1-u].get("type"),m=t.data;if(m&&n){var v=[];d(m,function(t,e){var i;t.value&&y(t.value)?(i=t.value.slice(),t.value.unshift(e)):y(t)?(i=t.slice(),t.unshift(e)):i=t,v.push(i)}),t.data=v}var x=this.defaultValueDimensions;return oC(this,{coordDimensions:[{name:h,type:qs(p),ordinalMeta:i,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:qs(g),dimsDef:x.slice()}],dimensionsCount:x.length+1})},getBaseAxis:function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis}};h(YI.extend({type:"series.boxplot",dependencies:["xAxis","yAxis","grid"],defaultValueDimensions:[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],dimensions:null,defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:2,shadowOffsetY:2,shadowColor:"rgba(0,0,0,0.4)"}},animationEasing:"elasticOut",animationDuration:800}}),Ok,!0);var Ek=["itemStyle"],Rk=["emphasis","itemStyle"],zk=(Ar.extend({type:"boxplot",render:function(t,e,i){var n=t.getData(),o=this.group,a=this._data;this._data||o.removeAll();var r="horizontal"===t.get("layout")?1:0;n.diff(a).add(function(t){if(n.hasValue(t)){var e=ig(n.getItemLayout(t),n,t,r,!0);n.setItemGraphicEl(t,e),o.add(e)}}).update(function(t,e){var i=a.getItemGraphicEl(e);if(n.hasValue(t)){var s=n.getItemLayout(t);i?ng(s,i,n,t):i=ig(s,n,t,r),o.add(i),n.setItemGraphicEl(t,i)}else o.remove(i)}).remove(function(t){var e=a.getItemGraphicEl(t);e&&o.remove(e)}).execute(),this._data=n},remove:function(t){var e=this.group,i=this._data;this._data=null,i&&i.eachItemGraphicEl(function(t){t&&e.remove(t)})},dispose:B}),Pn.extend({type:"boxplotBoxPath",shape:{},buildPath:function(t,e){var i=e.points,n=0;for(t.moveTo(i[n][0],i[n][1]),n++;n<4;n++)t.lineTo(i[n][0],i[n][1]);for(t.closePath();n0?jk:Yk)}function n(t,e){return e.get(t>0?Uk:Xk)}var o=t.getData(),a=t.pipelineContext.large;if(o.setVisual({legendSymbol:"roundRect",colorP:i(1,t),colorN:i(-1,t),borderColorP:n(1,t),borderColorN:n(-1,t)}),!e.isSeriesFiltered(t))return!a&&{progress:function(t,e){for(var o;null!=(o=t.next());){var a=e.getItemModel(o),r=e.getItemLayout(o).sign;e.setItemVisual(o,{color:i(r,a),borderColor:n(r,a)})}}}}},Kk="undefined"!=typeof Float32Array?Float32Array:Array,$k={seriesType:"candlestick",plan:$I(),reset:function(t){var e=t.coordinateSystem,i=t.getData(),n=pg(t,i),o=0,a=1,r=["x","y"],s=i.mapDimension(r[o]),l=i.mapDimension(r[a],!0),u=l[0],h=l[1],c=l[2],d=l[3];if(i.setLayout({candleWidth:n,isSimpleBox:n<=1.3}),!(null==s||l.length<4))return{progress:t.pipelineContext.large?function(t,i){for(var n,r,l=new Kk(5*t.count),f=0,p=[],g=[];null!=(r=t.next());){var m=i.get(s,r),v=i.get(u,r),y=i.get(h,r),x=i.get(c,r),_=i.get(d,r);isNaN(m)||isNaN(x)||isNaN(_)?(l[f++]=NaN,f+=4):(l[f++]=fg(i,r,v,y,h),p[o]=m,p[a]=x,n=e.dataToPoint(p,null,g),l[f++]=n?n[0]:NaN,l[f++]=n?n[1]:NaN,p[a]=_,n=e.dataToPoint(p,null,g),l[f++]=n?n[1]:NaN)}i.setLayout("largePoints",l)}:function(t,i){function r(t,i){var n=[];return n[o]=i,n[a]=t,isNaN(i)||isNaN(t)?[NaN,NaN]:e.dataToPoint(n)}function l(t,e,i){var a=e.slice(),r=e.slice();a[o]=Jn(a[o]+n/2,1,!1),r[o]=Jn(r[o]-n/2,1,!0),i?t.push(a,r):t.push(r,a)}function f(t){return t[o]=Jn(t[o],1),t}for(var p;null!=(p=t.next());){var g=i.get(s,p),m=i.get(u,p),v=i.get(h,p),y=i.get(c,p),x=i.get(d,p),_=Math.min(m,v),w=Math.max(m,v),b=r(_,g),S=r(w,g),M=r(y,g),I=r(x,g),T=[];l(T,S,0),l(T,b,1),T.push(f(I),f(S),f(M),f(b)),i.setItemLayout(p,{sign:fg(i,p,m,v,h),initBaseline:m>v?S[a]:b[a],ends:T,brushRect:function(t,e,i){var s=r(t,i),l=r(e,i);return s[o]-=n/2,l[o]-=n/2,{x:s[0],y:s[1],width:a?n:l[0]-s[0],height:a?l[1]-s[1]:n}}(y,x,g)})}}}}};Ns(function(t){t&&y(t.series)&&d(t.series,function(t){w(t)&&"k"===t.type&&(t.type="candlestick")})}),Bs(qk),zs($k),YI.extend({type:"series.effectScatter",dependencies:["grid","polar"],getInitialData:function(t,e){return ml(this.getSource(),this)},brushSelector:"point",defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,effectType:"ripple",progressive:0,showEffectOn:"render",rippleEffect:{period:4,scale:2.5,brushType:"fill"},symbolSize:10}});var Jk=vg.prototype;Jk.stopEffectAnimation=function(){this.childAt(1).removeAll()},Jk.startEffectAnimation=function(t){for(var e=t.symbolType,i=t.color,n=this.childAt(1),o=0;o<3;o++){var a=Jl(e,-1,-1,2,2,i);a.attr({style:{strokeNoScale:!0},z2:99,silent:!0,scale:[.5,.5]});var r=-o/3*t.period+t.effectOffset;a.animate("",!0).when(t.period,{scale:[t.rippleScale/2,t.rippleScale/2]}).delay(r).start(),a.animateStyle(!0).when(t.period,{opacity:0}).delay(r).start(),n.add(a)}mg(n,t)},Jk.updateEffectAnimation=function(t){for(var e=this._effectCfg,i=this.childAt(1),n=["symbolType","period","rippleScale"],o=0;o "))},preventIncremental:function(){return!!this.get("effect.show")},getProgressive:function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},getProgressiveThreshold:function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},defaultOption:{coordinateSystem:"geo",zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,label:{show:!1,position:"end"},lineStyle:{opacity:.5}}}),iP=xg.prototype;iP.createLine=function(t,e,i){return new rf(t,e,i)},iP._updateEffectSymbol=function(t,e){var i=t.getItemModel(e).getModel("effect"),n=i.get("symbolSize"),o=i.get("symbol");y(n)||(n=[n,n]);var a=i.get("color")||t.getItemVisual(e,"color"),r=this.childAt(1);this._symbolType!==o&&(this.remove(r),(r=Jl(o,-.5,-.5,1,1,a)).z2=100,r.culling=!0,this.add(r)),r&&(r.setStyle("shadowColor",a),r.setStyle(i.getItemStyle(["color"])),r.attr("scale",n),r.setColor(a),r.attr("scale",n),this._symbolType=o,this._updateEffectAnimation(t,i,e))},iP._updateEffectAnimation=function(t,e,i){var n=this.childAt(1);if(n){var o=this,a=t.getItemLayout(i),r=1e3*e.get("period"),s=e.get("loop"),l=e.get("constantSpeed"),u=T(e.get("delay"),function(e){return e/t.count()*r/3}),h="function"==typeof u;if(n.ignore=!0,this.updateAnimationPoints(n,a),l>0&&(r=this.getLineLength(n)/l*1e3),r!==this._period||s!==this._loop){n.stopAnimation();var c=u;h&&(c=u(i)),n.__t>0&&(c=-r*n.__t),n.__t=0;var d=n.animate("",s).when(r,{__t:1}).delay(c).during(function(){o.updateSymbolPosition(n)});s||d.done(function(){o.remove(n)}),d.start()}this._period=r,this._loop=s}},iP.getLineLength=function(t){return uw(t.__p1,t.__cp1)+uw(t.__cp1,t.__p2)},iP.updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},iP.updateData=function(t,e,i){this.childAt(0).updateData(t,e,i),this._updateEffectSymbol(t,e)},iP.updateSymbolPosition=function(t){var e=t.__p1,i=t.__p2,n=t.__cp1,o=t.__t,a=t.position,r=sn,s=ln;a[0]=r(e[0],n[0],i[0],o),a[1]=r(e[1],n[1],i[1],o);var l=s(e[0],n[0],i[0],o),u=s(e[1],n[1],i[1],o);t.rotation=-Math.atan2(u,l)-Math.PI/2,t.ignore=!1},iP.updateLayout=function(t,e){this.childAt(0).updateLayout(t,e);var i=t.getItemModel(e).getModel("effect");this._updateEffectAnimation(t,i,e)},u(xg,tb);var nP=_g.prototype;nP._createPolyline=function(t,e,i){var n=t.getItemLayout(e),o=new gM({shape:{points:n}});this.add(o),this._updateCommonStl(t,e,i)},nP.updateData=function(t,e,i){var n=t.hostModel;Io(this.childAt(0),{shape:{points:t.getItemLayout(e)}},n,e),this._updateCommonStl(t,e,i)},nP._updateCommonStl=function(t,e,i){var n=this.childAt(0),o=t.getItemModel(e),a=t.getItemVisual(e,"color"),s=i&&i.lineStyle,l=i&&i.hoverLineStyle;i&&!t.hasItemOption||(s=o.getModel("lineStyle").getLineStyle(),l=o.getModel("emphasis.lineStyle").getLineStyle()),n.useStyle(r({strokeNoScale:!0,fill:"none",stroke:a},s)),n.hoverStyle=l,fo(this)},nP.updateLayout=function(t,e){this.childAt(0).setShape("points",t.getItemLayout(e))},u(_g,tb);var oP=wg.prototype;oP.createLine=function(t,e,i){return new _g(t,e,i)},oP.updateAnimationPoints=function(t,e){this._points=e;for(var i=[0],n=0,o=1;o=0&&!(n[r]<=e);r--);r=Math.min(r,o-2)}else{for(var r=a;re);r++);r=Math.min(r-1,o-2)}J(t.position,i[r],i[r+1],(e-n[r])/(n[r+1]-n[r]));var s=i[r+1][0]-i[r][0],l=i[r+1][1]-i[r][1];t.rotation=-Math.atan2(l,s)-Math.PI/2,this._lastFrame=r,this._lastFramePercent=e,t.ignore=!1}},u(wg,xg);var aP=Un({shape:{polyline:!1,curveness:0,segs:[]},buildPath:function(t,e){var i=e.segs,n=e.curveness;if(e.polyline)for(r=0;r0){t.moveTo(i[r++],i[r++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*n,d=(l+h)/2-(u-s)*n;t.quadraticCurveTo(c,d,u,h)}else t.lineTo(u,h)}},findDataIndex:function(t,e){var i=this.shape,n=i.segs,o=i.curveness;if(i.polyline)for(var a=0,r=0;r0)for(var l=n[r++],u=n[r++],h=1;h0){if(_n(l,u,(l+c)/2-(u-d)*o,(u+d)/2-(c-l)*o,c,d))return a}else if(yn(l,u,c,d))return a;a++}return-1}}),rP=bg.prototype;rP.isPersistent=function(){return!this._incremental},rP.updateData=function(t){this.group.removeAll();var e=new aP({rectHover:!0,cursor:"default"});e.setShape({segs:t.getLayout("linesPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},rP.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>5e5?(this._incremental||(this._incremental=new Zn({silent:!0})),this.group.add(this._incremental)):this._incremental=null},rP.incrementalUpdate=function(t,e){var i=new aP;i.setShape({segs:e.getLayout("linesPoints")}),this._setCommon(i,e,!!this._incremental),this._incremental?this._incremental.addDisplayable(i,!0):(i.rectHover=!0,i.cursor="default",i.__startIndex=t.start,this.group.add(i))},rP.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},rP._setCommon=function(t,e,i){var n=e.hostModel;t.setShape({polyline:n.get("polyline"),curveness:n.get("lineStyle.curveness")}),t.useStyle(n.getModel("lineStyle").getLineStyle()),t.style.strokeNoScale=!0;var o=e.getVisual("color");o&&t.setStyle("stroke",o),t.setStyle("fill"),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>0&&(t.dataIndex=i+t.__startIndex)}))},rP._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()};var sP={seriesType:"lines",plan:$I(),reset:function(t){var e=t.coordinateSystem,i=t.get("polyline"),n=t.pipelineContext.large;return{progress:function(o,a){var r=[];if(n){var s,l=o.end-o.start;if(i){for(var u=0,h=o.start;h0){var I=a(v)?s:l;v>0&&(v=v*S+b),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(y,0,0),h},_getBrush:function(){var t=this._brushCanvas||(this._brushCanvas=iw()),e=this.pointSize+this.blurSize,i=2*e;t.width=i,t.height=i;var n=t.getContext("2d");return n.clearRect(0,0,i,i),n.shadowOffsetX=i,n.shadowBlur=this.blurSize,n.shadowColor="#000",n.beginPath(),n.arc(-e,e,this.pointSize,0,2*Math.PI,!0),n.closePath(),n.fill(),t},_getGradient:function(t,e,i){for(var n=this._gradientPixels,o=n[i]||(n[i]=new Uint8ClampedArray(1024)),a=[0,0,0,0],r=0,s=0;s<256;s++)e[i](s/255,!0,a),o[r++]=a[0],o[r++]=a[1],o[r++]=a[2],o[r++]=a[3];return o}},Zs({type:"heatmap",render:function(t,e,i){var n;e.eachComponent("visualMap",function(e){e.eachTargetSeries(function(i){i===t&&(n=e)})}),this.group.removeAll(),this._incrementalDisplayable=null;var o=t.coordinateSystem;"cartesian2d"===o.type||"calendar"===o.type?this._renderOnCartesianAndCalendar(t,i,0,t.getData().count()):Ag(o)&&this._renderOnGeo(o,t,n,i)},incrementalPrepareRender:function(t,e,i){this.group.removeAll()},incrementalRender:function(t,e,i,n){e.coordinateSystem&&this._renderOnCartesianAndCalendar(e,n,t.start,t.end,!0)},_renderOnCartesianAndCalendar:function(t,e,i,n,o){var r,s,l=t.coordinateSystem;if("cartesian2d"===l.type){var u=l.getAxis("x"),h=l.getAxis("y");r=u.getBandWidth(),s=h.getBandWidth()}for(var c=this.group,d=t.getData(),f=t.getModel("itemStyle").getItemStyle(["color"]),p=t.getModel("emphasis.itemStyle").getItemStyle(),g=t.getModel("label"),m=t.getModel("emphasis.label"),v=l.type,y="cartesian2d"===v?[d.mapDimension("x"),d.mapDimension("y"),d.mapDimension("value")]:[d.mapDimension("time"),d.mapDimension("value")],x=i;x=e.y&&t[1]<=e.y+e.height:i.contain(i.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},pointToData:function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},dataToPoint:function(t){var e=this.getAxis(),i=this.getRect(),n=[],o="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),n[o]=e.toGlobalCoord(e.dataToCoord(+t)),n[1-o]=0===o?i.y+i.height/2:i.x+i.width/2,n}},Fa.register("single",{create:function(t,e){var i=[];return t.eachComponent("singleAxis",function(n,o){var a=new $g(n,t,e);a.name="single_"+o,a.resize(n,e),n.coordinateSystem=a,i.push(a)}),t.eachSeries(function(e){if("singleAxis"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"singleAxis",index:e.get("singleAxisIndex"),id:e.get("singleAxisId")})[0];e.coordinateSystem=i&&i.coordinateSystem}}),i},dimensions:$g.prototype.dimensions});var gP=["axisLine","axisTickLabel","axisName"],mP=XD.extend({type:"singleAxis",axisPointerClass:"SingleAxisPointer",render:function(t,e,i,n){var o=this.group;o.removeAll();var a=Jg(t),r=new FD(t,a);d(gP,r.add,r),o.add(r.getGroup()),t.get("splitLine.show")&&this._splitLine(t),mP.superCall(this,"render",t,e,i,n)},_splitLine:function(t){var e=t.axis;if(!e.scale.isBlank()){var i=t.getModel("splitLine"),n=i.getModel("lineStyle"),o=n.get("width"),a=n.get("color");a=a instanceof Array?a:[a];for(var r=t.coordinateSystem.getRect(),s=e.isHorizontal(),l=[],u=0,h=e.getTicksCoords({tickModel:i}),c=[],d=[],f=0;f=0)&&i({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})})},remove:function(t,e){gm(e.getZr(),"axisPointer"),IP.superApply(this._model,"remove",arguments)},dispose:function(t,e){gm("axisPointer",e),IP.superApply(this._model,"dispose",arguments)}}),TP=Bi(),AP=i,DP=m;(mm.prototype={_group:null,_lastGraphicKey:null,_handle:null,_dragging:!1,_lastValue:null,_lastStatus:null,_payloadInfo:null,animationThreshold:15,render:function(t,e,i,n){var o=e.get("value"),a=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=i,n||this._lastValue!==o||this._lastStatus!==a){this._lastValue=o,this._lastStatus=a;var r=this._group,s=this._handle;if(!a||"hide"===a)return r&&r.hide(),void(s&&s.hide());r&&r.show(),s&&s.show();var l={};this.makeElOption(l,o,t,e,i);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(i),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(r){var c=v(vm,e,h);this.updatePointerEl(r,l,c,e),this.updateLabelEl(r,l,c,e)}else r=this._group=new tb,this.createPointerEl(r,l,t,e),this.createLabelEl(r,l,t,e),i.getZr().add(r);wm(r,e,!0),this._renderHandle(o)}},remove:function(t){this.clear(t)},dispose:function(t){this.clear(t)},determineAnimation:function(t,e){var i=e.get("animation"),n=t.axis,o="category"===n.type,a=e.get("snap");if(!a&&!o)return!1;if("auto"===i||null==i){var r=this.animationThreshold;if(o&&n.getBandWidth()>r)return!0;if(a){var s=Mh(t).seriesDataCount,l=n.getExtent();return Math.abs(l[0]-l[1])/s>r}return!1}return!0===i},makeElOption:function(t,e,i,n,o){},createPointerEl:function(t,e,i,n){var o=e.pointer;if(o){var a=TP(t).pointerEl=new zM[o.type](AP(e.pointer));t.add(a)}},createLabelEl:function(t,e,i,n){if(e.label){var o=TP(t).labelEl=new yM(AP(e.label));t.add(o),xm(o,n)}},updatePointerEl:function(t,e,i){var n=TP(t).pointerEl;n&&(n.setStyle(e.pointer.style),i(n,{shape:e.pointer.shape}))},updateLabelEl:function(t,e,i,n){var o=TP(t).labelEl;o&&(o.setStyle(e.label.style),i(o,{shape:e.label.shape,position:e.label.position}),xm(o,n))},_renderHandle:function(t){if(!this._dragging&&this.updateHandleTransform){var e=this._axisPointerModel,i=this._api.getZr(),n=this._handle,o=e.getModel("handle"),a=e.get("status");if(!o.get("show")||!a||"hide"===a)return n&&i.remove(n),void(this._handle=null);var r;this._handle||(r=!0,n=this._handle=Po(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){mw(t.event)},onmousedown:DP(this._onHandleDragMove,this,0,0),drift:DP(this._onHandleDragMove,this),ondragend:DP(this._onHandleDragEnd,this)}),i.add(n)),wm(n,e,!1);var s=["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"];n.setStyle(o.getItemStyle(null,s));var l=o.get("size");y(l)||(l=[l,l]),n.attr("scale",[l[0]/2,l[1]/2]),Nr(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,r)}},_moveHandleToValue:function(t,e){vm(this._axisPointerModel,!e&&this._moveAnimation,this._handle,_m(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},_onHandleDragMove:function(t,e){var i=this._handle;if(i){this._dragging=!0;var n=this.updateHandleTransform(_m(i),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=n,i.stopAnimation(),i.attr(_m(n)),TP(i).lastProp=null,this._doDispatchAxisPointer()}},_doDispatchAxisPointer:function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},_onHandleDragEnd:function(t){if(this._dragging=!1,this._handle){var e=this._axisPointerModel.get("value");this._moveHandleToValue(e),this._api.dispatchAction({type:"hideTip"})}},getHandleTransform:null,updateHandleTransform:null,clear:function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),i=this._group,n=this._handle;e&&i&&(this._lastGraphicKey=null,i&&e.remove(i),n&&e.remove(n),this._group=null,this._handle=null,this._payloadInfo=null)},doClear:function(){},buildLabel:function(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}}).constructor=mm,ji(mm);var CP=mm.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.grid,s=n.get("type"),l=km(r,a).getOtherAxis(a).getGlobalExtent(),u=a.toGlobalCoord(a.dataToCoord(e,!0));if(s&&"none"!==s){var h=bm(n),c=LP[s](a,u,l,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Am(e,t,Lh(r.model,i),i,n,o)},getHandleTransform:function(t,e,i){var n=Lh(e.axis.grid.model,e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Tm(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.grid,r=o.getGlobalExtent(!0),s=km(a,o).getOtherAxis(o).getGlobalExtent(),l="x"===o.dim?0:1,u=t.position;u[l]+=e[l],u[l]=Math.min(r[1],u[l]),u[l]=Math.max(r[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];var d=[{verticalAlign:"middle"},{align:"center"}];return{position:u,rotation:t.rotation,cursorPoint:c,tooltipOption:d[l]}}}),LP={line:function(t,e,i,n){var o=Dm([e,i[0]],[e,i[1]],Pm(t));return Kn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=Math.max(1,t.getBandWidth()),a=i[1]-i[0];return{type:"Rect",shape:Cm([e-o/2,i[0]],[o,a],Pm(t))}}};XD.registerAxisPointerClass("CartesianAxisPointer",CP),Ns(function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!y(e)&&(t.axisPointer.link=[e])}}),Os(VT.PROCESSOR.STATISTIC,function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=vh(t,e)}),Es({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},function(t,e,i){var n=t.currTrigger,o=[t.x,t.y],a=t,r=t.dispatchAction||m(i.dispatchAction,i),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){lm(o)&&(o=xP({seriesIndex:a.seriesIndex,dataIndex:a.dataIndex},e).point);var l=lm(o),u=a.axesInfo,h=s.axesInfo,c="leave"===n||lm(o),d={},f={},p={list:[],map:{}},g={showPointer:wP(em,f),showTooltip:wP(im,p)};_P(s.coordSysMap,function(t,e){var i=l||t.containPoint(o);_P(s.coordSysAxesInfo[e],function(t,e){var n=t.axis,a=rm(u,t);if(!c&&i&&(!u||a)){var r=a&&a.value;null!=r||l||(r=n.pointToData(o)),null!=r&&Qg(t,r,g,!1,d)}})});var v={};return _P(h,function(t,e){var i=t.linkGroup;i&&!f[e]&&_P(i.axesInfo,function(e,n){var o=f[n];if(e!==t&&o){var a=o.value;i.mapper&&(a=t.axis.scale.parse(i.mapper(a,sm(e),sm(t)))),v[t.key]=a}})}),_P(v,function(t,e){Qg(h[e],t,g,!0,d)}),nm(f,h,d),om(p,o,t,r),am(h,0,i),d}});var kP=["x","y"],PP=["width","height"],NP=mm.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.coordinateSystem,s=Om(r,1-Nm(a)),l=r.dataToPoint(e)[0],u=n.get("type");if(u&&"none"!==u){var h=bm(n),c=OP[u](a,l,s,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Am(e,t,Jg(i),i,n,o)},getHandleTransform:function(t,e,i){var n=Jg(e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Tm(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.coordinateSystem,r=Nm(o),s=Om(a,r),l=t.position;l[r]+=e[r],l[r]=Math.min(s[1],l[r]),l[r]=Math.max(s[0],l[r]);var u=Om(a,1-r),h=(u[1]+u[0])/2,c=[h,h];return c[r]=l[r],{position:l,rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}}}),OP={line:function(t,e,i,n){var o=Dm([e,i[0]],[e,i[1]],Nm(t));return Kn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=t.getBandWidth(),a=i[1]-i[0];return{type:"Rect",shape:Cm([e-o/2,i[0]],[o,a],Nm(t))}}};XD.registerAxisPointerClass("SingleAxisPointer",NP),Ws({type:"single"});var EP=YI.extend({type:"series.themeRiver",dependencies:["singleAxis"],nameMap:null,init:function(t){EP.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()}},fixData:function(t){var e=t.length,i=[];Zi(t,function(t){return t[2]}).buckets.each(function(t,e){i.push({name:e,dataList:t})});for(var n=i.length,o=-1,a=-1,r=0;ro&&(o=s,a=r)}for(var l=0;lMath.PI/2?"right":"left"):x&&"center"!==x?"left"===x?(f=u.r0+y,p>Math.PI/2&&(x="right")):"right"===x&&(f=u.r-y,p>Math.PI/2&&(x="left")):(f=(u.r+u.r0)/2,x="center"),d.attr("style",{text:l,textAlign:x,textVerticalAlign:n("verticalAlign")||"middle",opacity:n("opacity")});var _=f*g+u.cx,w=f*m+u.cy;d.attr("position",[_,w]);var b=n("rotate"),S=0;"radial"===b?(S=-p)<-Math.PI/2&&(S+=Math.PI):"tangential"===b?(S=Math.PI/2-p)>Math.PI/2?S-=Math.PI:S<-Math.PI/2&&(S+=Math.PI):"number"==typeof b&&(S=b*Math.PI/180),d.attr("rotation",S)},VP._initEvents=function(t,e,i,n){t.off("mouseover").off("mouseout").off("emphasis").off("normal");var o=this,a=function(){o.onEmphasis(n)},r=function(){o.onNormal()};i.isAnimationEnabled()&&t.on("mouseover",a).on("mouseout",r).on("emphasis",a).on("normal",r).on("downplay",function(){o.onDownplay()}).on("highlight",function(){o.onHighlight()})},u(Vm,tb);Ar.extend({type:"sunburst",init:function(){},render:function(t,e,i,n){function o(i,n){if(c||!i||i.getValue()||(i=null),i!==l&&n!==l)if(n&&n.piece)i?(n.piece.updateData(!1,i,"normal",t,e),s.setItemGraphicEl(i.dataIndex,n.piece)):a(n);else if(i){var o=new Vm(i,t,e);h.add(o),s.setItemGraphicEl(i.dataIndex,o)}}function a(t){t&&t.piece&&(h.remove(t.piece),t.piece=null)}var r=this;this.seriesModel=t,this.api=i,this.ecModel=e;var s=t.getData(),l=s.tree.root,u=t.getViewRoot(),h=this.group,c=t.get("renderLabelForZeroData"),d=[];u.eachNode(function(t){d.push(t)});var f=this._oldChildren||[];if(function(t,e){function i(t){return t.getId()}function n(i,n){o(null==i?null:t[i],null==n?null:e[n])}0===t.length&&0===e.length||new Xs(e,t,i,i).add(n).update(n).remove(v(n,null)).execute()}(d,f),function(i,n){if(n.depth>0){r.virtualPiece?r.virtualPiece.updateData(!1,i,"normal",t,e):(r.virtualPiece=new Vm(i,t,e),h.add(r.virtualPiece)),n.piece._onclickEvent&&n.piece.off("click",n.piece._onclickEvent);var o=function(t){r._rootToNode(n.parentNode)};n.piece._onclickEvent=o,r.virtualPiece.on("click",o)}else r.virtualPiece&&(h.remove(r.virtualPiece),r.virtualPiece=null)}(l,u),n&&n.highlight&&n.highlight.piece){var p=t.getShallow("highlightPolicy");n.highlight.piece.onEmphasis(p)}else if(n&&n.unhighlight){var g=this.virtualPiece;!g&&l.children.length&&(g=l.children[0].piece),g&&g.onNormal()}this._initEvents(),this._oldChildren=d},dispose:function(){},_initEvents:function(){var t=this,e=function(e){var i=!1;t.seriesModel.getViewRoot().eachNode(function(n){if(!i&&n.piece&&n.piece.childAt(0)===e.target){var o=n.getModel().get("nodeClick");if("rootToNode"===o)t._rootToNode(n);else if("link"===o){var a=n.getModel(),r=a.get("link");if(r){var s=a.get("target",!0)||"_blank";window.open(r,s)}}i=!0}})};this.group._onclickEvent&&this.group.off("click",this.group._onclickEvent),this.group.on("click",e),this.group._onclickEvent=e},_rootToNode:function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:"sunburstRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var GP="sunburstRootToNode";Es({type:GP,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=ld(t,[GP],e);if(n){var o=e.getViewRoot();o&&(t.direction=hd(o,n.node)?"rollUp":"drillDown"),e.resetViewRoot(n.node)}})});var FP="sunburstHighlight";Es({type:FP,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=ld(t,[FP],e);n&&(t.highlight=n.node)})});Es({type:"sunburstUnhighlight",update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){t.unhighlight=!0})});var WP=Math.PI/180;Bs(v(uC,"sunburst")),zs(v(function(t,e,i,n){e.eachSeriesByType(t,function(t){var e=t.get("center"),n=t.get("radius");y(n)||(n=[0,n]),y(e)||(e=[e,e]);var o=i.getWidth(),a=i.getHeight(),r=Math.min(o,a),s=Vo(e[0],o),l=Vo(e[1],a),u=Vo(n[0],r/2),h=Vo(n[1],r/2),c=-t.get("startAngle")*WP,f=t.get("minAngle")*WP,p=t.getData().tree.root,g=t.getViewRoot(),m=g.depth,v=t.get("sort");null!=v&&Zm(g,v);var x=0;d(g.children,function(t){!isNaN(t.getValue())&&x++});var _=g.getValue(),w=Math.PI/(_||x)*2,b=g.depth>0,S=g.height-(b?-1:1),M=(h-u)/(S||1),I=t.get("clockwise"),T=t.get("stillShowZeroSum"),A=I?1:-1,D=function(t,e){if(t){var i=e;if(t!==p){var n=t.getValue(),o=0===_&&T?w:n*w;on[1]&&n.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:n[1],r0:n[0]},api:{coord:m(function(n){var o=e.dataToRadius(n[0]),a=i.dataToAngle(n[1]),r=t.coordToPoint([o,a]);return r.push(o,a*Math.PI/180),r}),size:m(qm,t)}}},calendar:function(t){var e=t.getRect(),i=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:i.start,end:i.end,weeks:i.weeks,dayCount:i.allDay}},api:{coord:function(e,i){return t.dataToPoint(e,i)}}}}};YI.extend({type:"series.custom",dependencies:["grid","polar","geo","singleAxis","calendar"],defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,useTransform:!0},getInitialData:function(t,e){return ml(this.getSource(),this)},getDataParams:function(t,e,i){var n=YI.prototype.getDataParams.apply(this,arguments);return i&&(n.info=i.info),n}}),Ar.extend({type:"custom",_data:null,render:function(t,e,i,n){var o=this._data,a=t.getData(),r=this.group,s=Qm(t,a,e,i);a.diff(o).add(function(e){ev(null,e,s(e,n),t,r,a)}).update(function(e,i){ev(o.getItemGraphicEl(i),e,s(e,n),t,r,a)}).remove(function(t){var e=o.getItemGraphicEl(t);e&&r.remove(e)}).execute(),this._data=a},incrementalPrepareRender:function(t,e,i){this.group.removeAll(),this._data=null},incrementalRender:function(t,e,i,n,o){for(var a=e.getData(),r=Qm(e,a,i,n),s=t.start;s=0;l--)null==o[l]?o.splice(l,1):delete o[l].$action},_flatten:function(t,e,i){d(t,function(t){if(t){i&&(t.parentOption=i),e.push(t);var n=t.children;"group"===t.type&&n&&this._flatten(n,e,t),delete t.children}},this)},useElOptionsToUpdate:function(){var t=this._elOptionsToUpdate;return this._elOptionsToUpdate=null,t}});Ws({type:"graphic",init:function(t,e){this._elMap=R(),this._lastGraphicModel},render:function(t,e,i){t!==this._lastGraphicModel&&this._clear(),this._lastGraphicModel=t,this._updateElements(t),this._relocate(t,i)},_updateElements:function(t){var e=t.useElOptionsToUpdate();if(e){var i=this._elMap,n=this.group;d(e,function(e){var o=e.$action,a=e.id,r=i.get(a),s=e.parentId,l=null!=s?i.get(s):n,u=e.style;"text"===e.type&&u&&(e.hv&&e.hv[1]&&(u.textVerticalAlign=u.textBaseline=null),!u.hasOwnProperty("textFill")&&u.fill&&(u.textFill=u.fill),!u.hasOwnProperty("textStroke")&&u.stroke&&(u.textStroke=u.stroke));var h=fv(e);o&&"merge"!==o?"replace"===o?(dv(r,i),cv(a,l,h,i)):"remove"===o&&dv(r,i):r?r.attr(h):cv(a,l,h,i);var c=i.get(a);c&&(c.__ecGraphicWidth=e.width,c.__ecGraphicHeight=e.height,yv(c,t))})}},_relocate:function(t,e){for(var i=t.option.elements,n=this.group,o=this._elMap,a=i.length-1;a>=0;a--){var r=i[a],s=o.get(r.id);if(s){var l=s.parent;da(s,r,l===n?{width:e.getWidth(),height:e.getHeight()}:{width:l.__ecGraphicWidth||0,height:l.__ecGraphicHeight||0},null,{hv:r.hv,boundingMode:r.bounding})}}},_clear:function(){var t=this._elMap;t.each(function(e){dv(e,t)}),this._elMap=R()},dispose:function(){this._clear()}});var KP=Fs({type:"legend.plain",dependencies:["series"],layoutMode:{type:"box",ignoreSize:!0},init:function(t,e,i){this.mergeDefaultAndTheme(t,i),t.selected=t.selected||{}},mergeOption:function(t){KP.superCall(this,"mergeOption",t)},optionUpdated:function(){this._updateData(this.ecModel);var t=this._data;if(t[0]&&"single"===this.get("selectedMode")){for(var e=!1,i=0;i=0},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",textStyle:{color:"#333"},selectedMode:!0,tooltip:{show:!1}}});Es("legendToggleSelect","legendselectchanged",v(xv,"toggleSelected")),Es("legendSelect","legendselected",v(xv,"select")),Es("legendUnSelect","legendunselected",v(xv,"unSelect"));var $P=v,JP=d,QP=tb,tN=Ws({type:"legend.plain",newlineDisabled:!1,init:function(){this.group.add(this._contentGroup=new QP),this._backgroundEl,this._isFirstRender=!0},getContentGroup:function(){return this._contentGroup},render:function(t,e,i){var n=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var o=t.get("align");o&&"auto"!==o||(o="right"===t.get("left")&&"vertical"===t.get("orient")?"right":"left"),this.renderInner(o,t,e,i);var a=t.getBoxLayoutParams(),s={width:i.getWidth(),height:i.getHeight()},l=t.get("padding"),u=ca(a,s,l),h=this.layoutInner(t,o,u,n),c=ca(r({width:h.width,height:h.height},a),s,l);this.group.attr("position",[c.x-h.x,c.y-h.y]),this.group.add(this._backgroundEl=wv(h,t))}},resetInner:function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl)},renderInner:function(t,e,i,n){var o=this.getContentGroup(),a=R(),r=e.get("selectedMode"),s=[];i.eachRawSeries(function(t){!t.get("legendHoverLink")&&s.push(t.id)}),JP(e.getData(),function(l,u){var h=l.get("name");if(this.newlineDisabled||""!==h&&"\n"!==h){var c=i.getSeriesByName(h)[0];if(!a.get(h))if(c){var d=c.getData(),f=d.getVisual("color");"function"==typeof f&&(f=f(c.getDataParams(0)));var p=d.getVisual("legendSymbol")||"roundRect",g=d.getVisual("symbol");this._createItem(h,u,l,e,p,g,t,f,r).on("click",$P(bv,h,n)).on("mouseover",$P(Sv,c.name,null,n,s)).on("mouseout",$P(Mv,c.name,null,n,s)),a.set(h,!0)}else i.eachRawSeries(function(i){if(!a.get(h)&&i.legendDataProvider){var o=i.legendDataProvider(),c=o.indexOfName(h);if(c<0)return;var d=o.getItemVisual(c,"color");this._createItem(h,u,l,e,"roundRect",null,t,d,r).on("click",$P(bv,h,n)).on("mouseover",$P(Sv,null,h,n,s)).on("mouseout",$P(Mv,null,h,n,s)),a.set(h,!0)}},this)}else o.add(new QP({newline:!0}))},this)},_createItem:function(t,e,i,n,o,r,s,l,u){var h=n.get("itemWidth"),c=n.get("itemHeight"),d=n.get("inactiveColor"),f=n.get("symbolKeepAspect"),p=n.isSelected(t),g=new QP,m=i.getModel("textStyle"),v=i.get("icon"),y=i.getModel("tooltip"),x=y.parentModel;if(o=v||o,g.add(Jl(o,0,0,h,c,p?l:d,null==f||f)),!v&&r&&(r!==o||"none"===r)){var _=.8*c;"none"===r&&(r="circle"),g.add(Jl(r,(h-_)/2,(c-_)/2,_,_,p?l:d,null==f||f))}var w="left"===s?h+5:-5,b=s,S=n.get("formatter"),M=t;"string"==typeof S&&S?M=S.replace("{name}",null!=t?t:""):"function"==typeof S&&(M=S(t)),g.add(new rM({style:mo({},m,{text:M,x:w,y:c/2,textFill:p?m.getTextColor():d,textAlign:b,textVerticalAlign:"middle"})}));var I=new yM({shape:g.getBoundingRect(),invisible:!0,tooltip:y.get("show")?a({content:t,formatter:x.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:n.componentIndex,name:t,$vars:["name"]}},y.option):null});return g.add(I),g.eachChild(function(t){t.silent=!0}),I.silent=!u,this.getContentGroup().add(g),fo(g),g.__legendDataIndex=e,g},layoutInner:function(t,e,i){var n=this.getContentGroup();aI(t.get("orient"),n,t.get("itemGap"),i.width,i.height);var o=n.getBoundingRect();return n.attr("position",[-o.x,-o.y]),this.group.getBoundingRect()},remove:function(){this.getContentGroup().removeAll(),this._isFirstRender=!0}});Os(function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var i=0;ii[l],p=[-c.x,-c.y];n||(p[s]=o.position[s]);var g=[0,0],m=[-d.x,-d.y],v=A(t.get("pageButtonGap",!0),t.get("itemGap",!0));f&&("end"===t.get("pageButtonPosition",!0)?m[s]+=i[l]-d[l]:g[s]+=d[l]+v),m[1-s]+=c[u]/2-d[u]/2,o.attr("position",p),a.attr("position",g),r.attr("position",m);var y=this.group.getBoundingRect();if((y={x:0,y:0})[l]=f?i[l]:c[l],y[u]=Math.max(c[u],d[u]),y[h]=Math.min(0,d[h]+m[1-s]),a.__rectSize=i[l],f){var x={x:0,y:0};x[l]=Math.max(i[l]-d[l]-v,0),x[u]=y[u],a.setClipPath(new yM({shape:x})),a.__rectSize=x[l]}else r.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var _=this._getPageInfo(t);return null!=_.pageIndex&&Io(o,{position:_.contentPosition},!!f&&t),this._updatePageInfoView(t,_),y},_pageGo:function(t,e,i){var n=this._getPageInfo(e)[t];null!=n&&i.dispatchAction({type:"legendScroll",scrollDataIndex:n,legendId:e.id})},_updatePageInfoView:function(t,e){var i=this._controllerGroup;d(["pagePrev","pageNext"],function(n){var o=null!=e[n+"DataIndex"],a=i.childOfName(n);a&&(a.setStyle("fill",o?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),a.cursor=o?"pointer":"default")});var n=i.childOfName("pageText"),o=t.get("pageFormatter"),a=e.pageIndex,r=null!=a?a+1:0,s=e.pageCount;n&&o&&n.setStyle("text",_(o)?o.replace("{current}",r).replace("{total}",s):o({current:r,total:s}))},_getPageInfo:function(t){function e(t){if(t){var e=t.getBoundingRect(),i=e[l]+t.position[r];return{s:i,e:i+e[s],i:t.__legendDataIndex}}}function i(t,e){return t.e>=e&&t.s<=e+a}var n=t.get("scrollDataIndex",!0),o=this.getContentGroup(),a=this._containerGroup.__rectSize,r=t.getOrient().index,s=nN[r],l=oN[r],u=this._findTargetItemIndex(n),h=o.children(),c=h[u],d=h.length,f=d?1:0,p={contentPosition:o.position.slice(),pageCount:f,pageIndex:f-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!c)return p;var g=e(c);p.contentPosition[r]=-g.s;for(var m=u+1,v=g,y=g,x=null;m<=d;++m)(!(x=e(h[m]))&&y.e>v.s+a||x&&!i(x,v.s))&&(v=y.i>v.i?y:x)&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=v.i),++p.pageCount),y=x;for(var m=u-1,v=g,y=g,x=null;m>=-1;--m)(x=e(h[m]))&&i(y,x.s)||!(v.i=0;){var r=o.indexOf("|}"),s=o.substr(a+"{marker".length,r-a-"{marker".length);s.indexOf("sub")>-1?n["marker"+s]={textWidth:4,textHeight:4,textBorderRadius:2,textBackgroundColor:e[s],textOffset:[3,0]}:n["marker"+s]={textWidth:10,textHeight:10,textBorderRadius:5,textBackgroundColor:e[s]},a=(o=o.substr(r+1)).indexOf("{marker")}this.el=new rM({style:{rich:n,text:t,textLineHeight:20,textBackgroundColor:i.get("backgroundColor"),textBorderRadius:i.get("borderRadius"),textFill:i.get("textStyle.color"),textPadding:i.get("padding")},z:i.get("z")}),this._zr.add(this.el);var l=this;this.el.on("mouseover",function(){l._enterable&&(clearTimeout(l._hideTimeout),l._show=!0),l._inContent=!0}),this.el.on("mouseout",function(){l._enterable&&l._show&&l.hideLater(l._hideDelay),l._inContent=!1})},setEnterable:function(t){this._enterable=t},getSize:function(){var t=this.el.getBoundingRect();return[t.width,t.height]},moveTo:function(t,e){this.el&&this.el.attr("position",[t,e])},hide:function(){this.el?this.el.hide():true,this._show=!1},hideLater:function(t){!this._show||this._inContent&&this._enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(m(this.hide,this),t)):this.hide())},isShow:function(){return this._show},getOuterSize:function(){return this.getSize()}};var uN=m,hN=d,cN=Vo,dN=new yM({shape:{x:-1,y:-1,width:2,height:2}});Ws({type:"tooltip",init:function(t,e){if(!U_.node){var i=t.getComponent("tooltip").get("renderMode");this._renderMode=Hi(i);var n;"html"===this._renderMode?(n=new Cv(e.getDom(),e),this._newLine="
"):(n=new Lv(e),this._newLine="\n"),this._tooltipContent=n}},render:function(t,e,i){if(!U_.node){this.group.removeAll(),this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastDataByCoordSys=null,this._alwaysShowContent=t.get("alwaysShowContent");var n=this._tooltipContent;n.update(),n.setEnterable(t.get("enterable")),this._initGlobalListener(),this._keepShow()}},_initGlobalListener:function(){var t=this._tooltipModel.get("triggerOn");um("itemTooltip",this._api,uN(function(e,i,n){"none"!==t&&(t.indexOf(e)>=0?this._tryShow(i,n):"leave"===e&&this._hide(n))},this))},_keepShow:function(){var t=this._tooltipModel,e=this._ecModel,i=this._api;if(null!=this._lastX&&null!=this._lastY&&"none"!==t.get("triggerOn")){var n=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){n.manuallyShowTip(t,e,i,{x:n._lastX,y:n._lastY})})}},manuallyShowTip:function(t,e,i,n){if(n.from!==this.uid&&!U_.node){var o=Pv(n,i);this._ticket="";var a=n.dataByCoordSys;if(n.tooltip&&null!=n.x&&null!=n.y){var r=dN;r.position=[n.x,n.y],r.update(),r.tooltip=n.tooltip,this._tryShow({offsetX:n.x,offsetY:n.y,target:r},o)}else if(a)this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,event:{},dataByCoordSys:n.dataByCoordSys,tooltipOption:n.tooltipOption},o);else if(null!=n.seriesIndex){if(this._manuallyAxisShowTip(t,e,i,n))return;var s=xP(n,e),l=s.point[0],u=s.point[1];null!=l&&null!=u&&this._tryShow({offsetX:l,offsetY:u,position:n.position,target:s.el,event:{}},o)}else null!=n.x&&null!=n.y&&(i.dispatchAction({type:"updateAxisPointer",x:n.x,y:n.y}),this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,target:i.getZr().findHover(n.x,n.y).target,event:{}},o))}},manuallyHideTip:function(t,e,i,n){var o=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&o.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=null,n.from!==this.uid&&this._hide(Pv(n,i))},_manuallyAxisShowTip:function(t,e,i,n){var o=n.seriesIndex,a=n.dataIndex,r=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=o&&null!=a&&null!=r){var s=e.getSeriesByIndex(o);if(s&&"axis"===(t=kv([s.getData().getItemModel(a),s,(s.coordinateSystem||{}).model,t])).get("trigger"))return i.dispatchAction({type:"updateAxisPointer",seriesIndex:o,dataIndex:a,position:n.position}),!0}},_tryShow:function(t,e){var i=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var n=t.dataByCoordSys;n&&n.length?this._showAxisTooltip(n,t):i&&null!=i.dataIndex?(this._lastDataByCoordSys=null,this._showSeriesItemTooltip(t,i,e)):i&&i.tooltip?(this._lastDataByCoordSys=null,this._showComponentItemTooltip(t,i,e)):(this._lastDataByCoordSys=null,this._hide(e))}},_showOrMove:function(t,e){var i=t.get("showDelay");e=m(e,this),clearTimeout(this._showTimout),i>0?this._showTimout=setTimeout(e,i):e()},_showAxisTooltip:function(t,e){var i=this._ecModel,o=this._tooltipModel,a=[e.offsetX,e.offsetY],r=[],s=[],l=kv([e.tooltipOption,o]),u=this._renderMode,h=this._newLine,c={};hN(t,function(t){hN(t.dataByAxis,function(t){var e=i.getComponent(t.axisDim+"Axis",t.axisIndex),o=t.value,a=[];if(e&&null!=o){var l=Im(o,e.axis,i,t.seriesDataIndices,t.valueLabelOpt);d(t.seriesDataIndices,function(r){var h=i.getSeriesByIndex(r.seriesIndex),d=r.dataIndexInside,f=h&&h.getDataParams(d);if(f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=Xl(e.axis,o),f.axisValueLabel=l,f){s.push(f);var p,g=h.formatTooltip(d,!0,null,u);if(w(g)){p=g.html;var m=g.markers;n(c,m)}else p=g;a.push(p)}});var f=l;"html"!==u?r.push(a.join(h)):r.push((f?ia(f)+h:"")+a.join(h))}})},this),r.reverse(),r=r.join(this._newLine+this._newLine);var f=e.position;this._showOrMove(l,function(){this._updateContentNotChangedOnAxis(t)?this._updatePosition(l,f,a[0],a[1],this._tooltipContent,s):this._showTooltipContent(l,r,s,Math.random(),a[0],a[1],f,void 0,c)})},_showSeriesItemTooltip:function(t,e,i){var n=this._ecModel,o=e.seriesIndex,a=n.getSeriesByIndex(o),r=e.dataModel||a,s=e.dataIndex,l=e.dataType,u=r.getData(),h=kv([u.getItemModel(s),r,a&&(a.coordinateSystem||{}).model,this._tooltipModel]),c=h.get("trigger");if(null==c||"item"===c){var d,f,p=r.getDataParams(s,l),g=r.formatTooltip(s,!1,l,this._renderMode);w(g)?(d=g.html,f=g.markers):(d=g,f=null);var m="item_"+r.name+"_"+s;this._showOrMove(h,function(){this._showTooltipContent(h,d,p,m,t.offsetX,t.offsetY,t.position,t.target,f)}),i({type:"showTip",dataIndexInside:s,dataIndex:u.getRawIndex(s),seriesIndex:o,from:this.uid})}},_showComponentItemTooltip:function(t,e,i){var n=e.tooltip;if("string"==typeof n){var o=n;n={content:o,formatter:o}}var a=new No(n,this._tooltipModel,this._ecModel),r=a.get("content"),s=Math.random();this._showOrMove(a,function(){this._showTooltipContent(a,r,a.get("formatterParams")||{},s,t.offsetX,t.offsetY,t.position,e)}),i({type:"showTip",from:this.uid})},_showTooltipContent:function(t,e,i,n,o,a,r,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent,h=t.get("formatter");r=r||t.get("position");var c=e;if(h&&"string"==typeof h)c=na(h,i,!0);else if("function"==typeof h){var d=uN(function(e,n){e===this._ticket&&(u.setContent(n,l,t),this._updatePosition(t,r,o,a,u,i,s))},this);this._ticket=n,c=h(i,n,d)}u.setContent(c,l,t),u.show(t),this._updatePosition(t,r,o,a,u,i,s)}},_updatePosition:function(t,e,i,n,o,a,r){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=o.getSize(),h=t.get("align"),c=t.get("verticalAlign"),d=r&&r.getBoundingRect().clone();if(r&&d.applyTransform(r.transform),"function"==typeof e&&(e=e([i,n],a,o.el,d,{viewSize:[s,l],contentSize:u.slice()})),y(e))i=cN(e[0],s),n=cN(e[1],l);else if(w(e)){e.width=u[0],e.height=u[1];var f=ca(e,{width:s,height:l});i=f.x,n=f.y,h=null,c=null}else"string"==typeof e&&r?(i=(p=Ev(e,d,u))[0],n=p[1]):(i=(p=Nv(i,n,o,s,l,h?null:20,c?null:20))[0],n=p[1]);if(h&&(i-=Rv(h)?u[0]/2:"right"===h?u[0]:0),c&&(n-=Rv(c)?u[1]/2:"bottom"===c?u[1]:0),t.get("confine")){var p=Ov(i,n,o,s,l);i=p[0],n=p[1]}o.moveTo(i,n)},_updateContentNotChangedOnAxis:function(t){var e=this._lastDataByCoordSys,i=!!e&&e.length===t.length;return i&&hN(e,function(e,n){var o=e.dataByAxis||{},a=(t[n]||{}).dataByAxis||[];(i&=o.length===a.length)&&hN(o,function(t,e){var n=a[e]||{},o=t.seriesDataIndices||[],r=n.seriesDataIndices||[];(i&=t.value===n.value&&t.axisType===n.axisType&&t.axisId===n.axisId&&o.length===r.length)&&hN(o,function(t,e){var n=r[e];i&=t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})})}),this._lastDataByCoordSys=t,!!i},_hide:function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},dispose:function(t,e){U_.node||(this._tooltipContent.hide(),gm("itemTooltip",e))}}),Es({type:"showTip",event:"showTip",update:"tooltip:manuallyShowTip"},function(){}),Es({type:"hideTip",event:"hideTip",update:"tooltip:manuallyHideTip"},function(){}),Gv.prototype={constructor:Gv,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToRadius:aD.prototype.dataToCoord,radiusToData:aD.prototype.coordToData},u(Gv,aD);var fN=Bi();Fv.prototype={constructor:Fv,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToAngle:aD.prototype.dataToCoord,angleToData:aD.prototype.coordToData,calculateCategoryInterval:function(){var t=this,e=t.getLabelModel(),i=t.scale,n=i.getExtent(),o=i.count();if(n[1]-n[0]<1)return 0;var a=n[0],r=t.dataToCoord(a+1)-t.dataToCoord(a),s=Math.abs(r),l=ke(a,e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var h=Math.max(0,Math.floor(u)),c=fN(t.model),d=c.lastAutoInterval,f=c.lastTickCount;return null!=d&&null!=f&&Math.abs(d-h)<=1&&Math.abs(f-o)<=1&&d>h?h=d:(c.lastTickCount=o,c.lastAutoInterval=h),h}},u(Fv,aD);var pN=function(t){this.name=t||"",this.cx=0,this.cy=0,this._radiusAxis=new Gv,this._angleAxis=new Fv,this._radiusAxis.polar=this._angleAxis.polar=this};pN.prototype={type:"polar",axisPointerEnabled:!0,constructor:pN,dimensions:["radius","angle"],model:null,containPoint:function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},containData:function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},getAxis:function(t){return this["_"+t+"Axis"]},getAxes:function(){return[this._radiusAxis,this._angleAxis]},getAxesByScale:function(t){var e=[],i=this._angleAxis,n=this._radiusAxis;return i.scale.type===t&&e.push(i),n.scale.type===t&&e.push(n),e},getAngleAxis:function(){return this._angleAxis},getRadiusAxis:function(){return this._radiusAxis},getOtherAxis:function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},getBaseAxis:function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},getTooltipAxes:function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},dataToPoint:function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},pointToData:function(t,e){var i=this.pointToCoord(t);return[this._radiusAxis.radiusToData(i[0],e),this._angleAxis.angleToData(i[1],e)]},pointToCoord:function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=this.getAngleAxis(),o=n.getExtent(),a=Math.min(o[0],o[1]),r=Math.max(o[0],o[1]);n.inverse?a=r-360:r=a+360;var s=Math.sqrt(e*e+i*i);e/=s,i/=s;for(var l=Math.atan2(-i,e)/Math.PI*180,u=lr;)l+=360*u;return[s,l]},coordToPoint:function(t){var e=t[0],i=t[1]/180*Math.PI;return[Math.cos(i)*e+this.cx,-Math.sin(i)*e+this.cy]}};var gN=lI.extend({type:"polarAxis",axis:null,getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"polar",index:this.option.polarIndex,id:this.option.polarId})[0]}});n(gN.prototype,UA);var mN={angle:{startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:!1}},radius:{splitNumber:5}};ED("angle",gN,Wv,mN.angle),ED("radius",gN,Wv,mN.radius),Fs({type:"polar",dependencies:["polarAxis","angleAxis"],coordinateSystem:null,findAxisModel:function(t){var e;return this.ecModel.eachComponent(t,function(t){t.getCoordSysModel()===this&&(e=t)},this),e},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"80%"}});var vN={dimensions:pN.prototype.dimensions,create:function(t,e){var i=[];return t.eachComponent("polar",function(t,n){var o=new pN(n);o.update=Zv;var a=o.getRadiusAxis(),r=o.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");Uv(a,s),Uv(r,l),Hv(o,t,e),i.push(o),t.coordinateSystem=o,o.model=t}),t.eachSeries(function(e){if("polar"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"polar",index:e.get("polarIndex"),id:e.get("polarId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}};Fa.register("polar",vN);var yN=["axisLine","axisLabel","axisTick","splitLine","splitArea"];XD.extend({type:"angleAxis",axisPointerClass:"PolarAxisPointer",render:function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,o=n.polar,a=o.getRadiusAxis().getExtent(),r=n.getTicksCoords(),s=f(n.getViewLabels(),function(t){return(t=i(t)).coord=n.dataToCoord(t.tickValue),t});Yv(s),Yv(r),d(yN,function(e){!t.get(e+".show")||n.scale.isBlank()&&"axisLine"!==e||this["_"+e](t,o,r,a,s)},this)}},_axisLine:function(t,e,i,n){var o=t.getModel("axisLine.lineStyle"),a=new sM({shape:{cx:e.cx,cy:e.cy,r:n[jv(e)]},style:o.getLineStyle(),z2:1,silent:!0});a.style.fill=null,this.group.add(a)},_axisTick:function(t,e,i,n){var o=t.getModel("axisTick"),a=(o.get("inside")?-1:1)*o.get("length"),s=n[jv(e)],l=f(i,function(t){return new _M({shape:Xv(e,[s,s+a],t.coord)})});this.group.add(OM(l,{style:r(o.getModel("lineStyle").getLineStyle(),{stroke:t.get("axisLine.lineStyle.color")})}))},_axisLabel:function(t,e,i,n,o){var a=t.getCategories(!0),r=t.getModel("axisLabel"),s=r.get("margin");d(o,function(i,o){var l=r,u=i.tickValue,h=n[jv(e)],c=e.coordToPoint([h+s,i.coord]),d=e.cx,f=e.cy,p=Math.abs(c[0]-d)/h<.3?"center":c[0]>d?"left":"right",g=Math.abs(c[1]-f)/h<.3?"middle":c[1]>f?"top":"bottom";a&&a[u]&&a[u].textStyle&&(l=new No(a[u].textStyle,r,r.ecModel));var m=new rM({silent:!0});this.group.add(m),mo(m.style,l,{x:c[0],y:c[1],textFill:l.getTextColor()||t.get("axisLine.lineStyle.color"),text:i.formattedLabel,textAlign:p,textVerticalAlign:g})},this)},_splitLine:function(t,e,i,n){var o=t.getModel("splitLine").getModel("lineStyle"),a=o.get("color"),s=0;a=a instanceof Array?a:[a];for(var l=[],u=0;u=0?"p":"n",M=y;v&&(n[r][b]||(n[r][b]={p:y,n:y}),M=n[r][b][S]);var I,T,A,D;if("radius"===h.dim){var C=h.dataToRadius(w)-y,L=a.dataToAngle(b);Math.abs(C)=0},kN.findTargetInfo=function(t,e){for(var i=this._targetInfoList,n=dy(e,t),o=0;o=0||AN(n,t.getAxis("y").model)>=0)&&a.push(t)}),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:a[0],coordSyses:a,getPanelRect:ON.grid,xAxisDeclared:r[t.id],yAxisDeclared:s[t.id]})}))},geo:function(t,e){TN(t.geoModels,function(t){var i=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:i,coordSyses:[i],getPanelRect:ON.geo})})}},NN=[function(t,e){var i=t.xAxisModel,n=t.yAxisModel,o=t.gridModel;return!o&&i&&(o=i.axis.grid.model),!o&&n&&(o=n.axis.grid.model),o&&o===e.gridModel},function(t,e){var i=t.geoModel;return i&&i===e.geoModel}],ON={grid:function(){return this.coordSys.grid.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(Ao(t)),e}},EN={lineX:DN(fy,0),lineY:DN(fy,1),rect:function(t,e,i){var n=e[CN[t]]([i[0][0],i[1][0]]),o=e[CN[t]]([i[0][1],i[1][1]]),a=[cy([n[0],o[0]]),cy([n[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,i){var n=[[1/0,-1/0],[1/0,-1/0]];return{values:f(i,function(i){var o=e[CN[t]](i);return n[0][0]=Math.min(n[0][0],o[0]),n[1][0]=Math.min(n[1][0],o[1]),n[0][1]=Math.max(n[0][1],o[0]),n[1][1]=Math.max(n[1][1],o[1]),o}),xyMinMax:n}}},RN={lineX:DN(py,0),lineY:DN(py,1),rect:function(t,e,i){return[[t[0][0]-i[0]*e[0][0],t[0][1]-i[0]*e[0][1]],[t[1][0]-i[1]*e[1][0],t[1][1]-i[1]*e[1][1]]]},polygon:function(t,e,i){return f(t,function(t,n){return[t[0]-i[0]*e[n][0],t[1]-i[1]*e[n][1]]})}},zN=["inBrush","outOfBrush"],BN="__ecBrushSelect",VN="__ecInBrushSelectEvent",GN=VT.VISUAL.BRUSH;zs(GN,function(t,e,i){t.eachComponent({mainType:"brush"},function(e){i&&"takeGlobalCursor"===i.type&&e.setBrushOption("brush"===i.key?i.brushOption:{brushType:!1}),(e.brushTargetManager=new hy(e.option,t)).setInputRanges(e.areas,t)})}),Bs(GN,function(t,e,n){var o,a,s=[];t.eachComponent({mainType:"brush"},function(e,n){function l(t){return"all"===m||v[t]}function u(t){return!!t.length}function h(t,e){var i=t.coordinateSystem;w|=i.hasAxisBrushed(),l(e)&&i.eachActiveState(t.getData(),function(t,e){"active"===t&&(x[e]=1)})}function c(i,n,o){var a=_y(i);if(a&&!wy(e,n)&&(d(b,function(n){a[n.brushType]&&e.brushTargetManager.controlSeries(n,i,t)&&o.push(n),w|=u(o)}),l(n)&&u(o))){var r=i.getData();r.each(function(t){xy(a,o,r,t)&&(x[t]=1)})}}var p={brushId:e.id,brushIndex:n,brushName:e.name,areas:i(e.areas),selected:[]};s.push(p);var g=e.option,m=g.brushLink,v=[],x=[],_=[],w=0;n||(o=g.throttleType,a=g.throttleDelay);var b=f(e.areas,function(t){return by(r({boundingRect:FN[t.brushType](t)},t))}),S=ty(e.option,zN,function(t){t.mappingMethod="fixed"});y(m)&&d(m,function(t){v[t]=1}),t.eachSeries(function(t,e){var i=_[e]=[];"parallel"===t.subType?h(t,e):c(t,e,i)}),t.eachSeries(function(t,e){var i={seriesId:t.id,seriesIndex:e,seriesName:t.name,dataIndex:[]};p.selected.push(i);var n=_y(t),o=_[e],a=t.getData(),r=l(e)?function(t){return x[t]?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"}:function(t){return xy(n,o,a,t)?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"};(l(e)?w:u(o))&&iy(zN,S,a,r)})}),vy(e,o,a,s,n)});var FN={lineX:B,lineY:B,rect:function(t){return Sy(t.range)},polygon:function(t){for(var e,i=t.range,n=0,o=i.length;ne[0][1]&&(e[0][1]=a[0]),a[1]e[1][1]&&(e[1][1]=a[1])}return e&&Sy(e)}},WN=["#ddd"];Fs({type:"brush",dependencies:["geo","grid","xAxis","yAxis","parallel","series"],defaultOption:{toolbox:null,brushLink:null,seriesIndex:"all",geoIndex:null,xAxisIndex:null,yAxisIndex:null,brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(120,140,180,0.3)",borderColor:"rgba(120,140,180,0.8)"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},areas:[],brushType:null,brushOption:{},coordInfoList:[],optionUpdated:function(t,e){var i=this.option;!e&&ey(i,t,["inBrush","outOfBrush"]);var n=i.inBrush=i.inBrush||{};i.outOfBrush=i.outOfBrush||{color:WN},n.hasOwnProperty("liftZ")||(n.liftZ=5)},setAreas:function(t){t&&(this.areas=f(t,function(t){return My(this.option,t)},this))},setBrushOption:function(t){this.brushOption=My(this.option,t),this.brushType=this.brushOption.brushType}});Ws({type:"brush",init:function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new zf(e.getZr())).on("brush",m(this._onBrush,this)).mount()},render:function(t){return this.model=t,Iy.apply(this,arguments)},updateTransform:Iy,updateView:Iy,dispose:function(){this._brushController.dispose()},_onBrush:function(t,e){var n=this.model.id;this.model.brushTargetManager.setOutputRanges(t,this.ecModel),(!e.isEnd||e.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:n,areas:i(t),$from:n})}}),Es({type:"brush",event:"brush"},function(t,e){e.eachComponent({mainType:"brush",query:t},function(e){e.setAreas(t.areas)})}),Es({type:"brushSelect",event:"brushSelected",update:"none"},function(){});var HN={},ZN=rT.toolbox.brush;Dy.defaultOption={show:!0,type:["rect","polygon","lineX","lineY","keep","clear"],icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:i(ZN.title)};var UN=Dy.prototype;UN.render=UN.updateView=function(t,e,i){var n,o,a;e.eachComponent({mainType:"brush"},function(t){n=t.brushType,o=t.brushOption.brushMode||"single",a|=t.areas.length}),this._brushType=n,this._brushMode=o,d(t.get("type",!0),function(e){t.setIconStatus(e,("keep"===e?"multiple"===o:"clear"===e?a:e===n)?"emphasis":"normal")})},UN.getIcons=function(){var t=this.model,e=t.get("icon",!0),i={};return d(t.get("type",!0),function(t){e[t]&&(i[t]=e[t])}),i},UN.onclick=function(t,e,i){var n=this._brushType,o=this._brushMode;"clear"===i?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===i?n:n!==i&&i,brushMode:"keep"===i?"multiple"===o?"single":"multiple":o}})},Ty("brush",Dy),Ns(function(t,e){var i=t&&t.brush;if(y(i)||(i=i?[i]:[]),i.length){var n=[];d(i,function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(n=n.concat(e))});var o=t&&t.toolbox;y(o)&&(o=o[0]),o||(o={feature:{}},t.toolbox=[o]);var a=o.feature||(o.feature={}),r=a.brush||(a.brush={}),s=r.type||(r.type=[]);s.push.apply(s,n),Jv(s),e&&!s.length&&s.push.apply(s,SN)}});Cy.prototype={constructor:Cy,type:"calendar",dimensions:["time","value"],getDimensionsInfo:function(){return[{name:"time",type:"time"},"value"]},getRangeInfo:function(){return this._rangeInfo},getModel:function(){return this._model},getRect:function(){return this._rect},getCellWidth:function(){return this._sw},getCellHeight:function(){return this._sh},getOrient:function(){return this._orient},getFirstDayOfWeek:function(){return this._firstDayOfWeek},getDateInfo:function(t){var e=(t=Yo(t)).getFullYear(),i=t.getMonth()+1;i=i<10?"0"+i:i;var n=t.getDate();n=n<10?"0"+n:n;var o=t.getDay();return o=Math.abs((o+7-this.getFirstDayOfWeek())%7),{y:e,m:i,d:n,day:o,time:t.getTime(),formatedDate:e+"-"+i+"-"+n,date:t}},getNextNDay:function(t,e){return 0===(e=e||0)?this.getDateInfo(t):((t=new Date(this.getDateInfo(t).time)).setDate(t.getDate()+e),this.getDateInfo(t))},update:function(t,e){function i(t,e){return null!=t[e]&&"auto"!==t[e]}this._firstDayOfWeek=+this._model.getModel("dayLabel").get("firstDay"),this._orient=this._model.get("orient"),this._lineWidth=this._model.getModel("itemStyle").getItemStyle().lineWidth||0,this._rangeInfo=this._getRangeInfo(this._initRangeOption());var n=this._rangeInfo.weeks||1,o=["width","height"],a=this._model.get("cellSize").slice(),r=this._model.getBoxLayoutParams(),s="horizontal"===this._orient?[n,7]:[7,n];d([0,1],function(t){i(a,t)&&(r[o[t]]=a[t]*s[t])});var l={width:e.getWidth(),height:e.getHeight()},u=this._rect=ca(r,l);d([0,1],function(t){i(a,t)||(a[t]=u[o[t]]/s[t])}),this._sw=a[0],this._sh=a[1]},dataToPoint:function(t,e){y(t)&&(t=t[0]),null==e&&(e=!0);var i=this.getDateInfo(t),n=this._rangeInfo,o=i.formatedDate;if(e&&!(i.time>=n.start.time&&i.timea.end.time&&t.reverse(),t},_getRangeInfo:function(t){var e;(t=[this.getDateInfo(t[0]),this.getDateInfo(t[1])])[0].time>t[1].time&&(e=!0,t.reverse());var i=Math.floor(t[1].time/864e5)-Math.floor(t[0].time/864e5)+1,n=new Date(t[0].time),o=n.getDate(),a=t[1].date.getDate();if(n.setDate(o+i-1),n.getDate()!==a)for(var r=n.getTime()-t[1].time>0?1:-1;n.getDate()!==a&&(n.getTime()-t[1].time)*r>0;)i-=r,n.setDate(o+i-1);var s=Math.floor((i+t[0].day+6)/7),l=e?1-s:s-1;return e&&t.reverse(),{range:[t[0].formatedDate,t[1].formatedDate],start:t[0],end:t[1],allDay:i,weeks:s,nthWeek:l,fweek:t[0].day,lweek:t[1].day}},_getDateByWeeksAndDay:function(t,e,i){var n=this._getRangeInfo(i);if(t>n.weeks||0===t&&en.lweek)return!1;var o=7*(t-1)-n.fweek+e,a=new Date(n.start.time);return a.setDate(n.start.d+o),this.getDateInfo(a)}},Cy.dimensions=Cy.prototype.dimensions,Cy.getDimensionsInfo=Cy.prototype.getDimensionsInfo,Cy.create=function(t,e){var i=[];return t.eachComponent("calendar",function(n){var o=new Cy(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeries(function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])}),i},Fa.register("calendar",Cy);var XN=lI.extend({type:"calendar",coordinateSystem:null,defaultOption:{zlevel:0,z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",nameMap:"en",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",nameMap:"en",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},init:function(t,e,i,n){var o=ga(t);XN.superApply(this,"init",arguments),ky(t,o)},mergeOption:function(t,e){XN.superApply(this,"mergeOption",arguments),ky(this.option,t)}}),jN={EN:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],CN:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},YN={EN:["S","M","T","W","T","F","S"],CN:["日","一","二","三","四","五","六"]};Ws({type:"calendar",_tlpoints:null,_blpoints:null,_firstDayOfMonth:null,_firstDayPoints:null,render:function(t,e,i){var n=this.group;n.removeAll();var o=t.coordinateSystem,a=o.getRangeInfo(),r=o.getOrient();this._renderDayRect(t,a,n),this._renderLines(t,a,r,n),this._renderYearText(t,a,r,n),this._renderMonthText(t,r,n),this._renderWeekText(t,a,r,n)},_renderDayRect:function(t,e,i){for(var n=t.coordinateSystem,o=t.getModel("itemStyle").getItemStyle(),a=n.getCellWidth(),r=n.getCellHeight(),s=e.start.time;s<=e.end.time;s=n.getNextNDay(s,1).time){var l=n.dataToRect([s],!1).tl,u=new yM({shape:{x:l[0],y:l[1],width:a,height:r},cursor:"default",style:o});i.add(u)}},_renderLines:function(t,e,i,n){function o(e){a._firstDayOfMonth.push(r.getDateInfo(e)),a._firstDayPoints.push(r.dataToRect([e],!1).tl);var o=a._getLinePointsOfOneWeek(t,e,i);a._tlpoints.push(o[0]),a._blpoints.push(o[o.length-1]),l&&a._drawSplitline(o,s,n)}var a=this,r=t.coordinateSystem,s=t.getModel("splitLine.lineStyle").getLineStyle(),l=t.get("splitLine.show"),u=s.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var h=e.start,c=0;h.time<=e.end.time;c++){o(h.formatedDate),0===c&&(h=r.getDateInfo(e.start.y+"-"+e.start.m));var d=h.date;d.setMonth(d.getMonth()+1),h=r.getDateInfo(d)}o(r.getNextNDay(e.end.time,1).formatedDate),l&&this._drawSplitline(a._getEdgesPoints(a._tlpoints,u,i),s,n),l&&this._drawSplitline(a._getEdgesPoints(a._blpoints,u,i),s,n)},_getEdgesPoints:function(t,e,i){var n=[t[0].slice(),t[t.length-1].slice()],o="horizontal"===i?0:1;return n[0][o]=n[0][o]-e/2,n[1][o]=n[1][o]+e/2,n},_drawSplitline:function(t,e,i){var n=new gM({z2:20,shape:{points:t},style:e});i.add(n)},_getLinePointsOfOneWeek:function(t,e,i){var n=t.coordinateSystem;e=n.getDateInfo(e);for(var o=[],a=0;a<7;a++){var r=n.getNextNDay(e.time,a),s=n.dataToRect([r.time],!1);o[2*r.day]=s.tl,o[2*r.day+1]=s["horizontal"===i?"bl":"tr"]}return o},_formatterLabel:function(t,e){return"string"==typeof t&&t?oa(t,e):"function"==typeof t?t(e):e.nameMap},_yearTextPositionControl:function(t,e,i,n,o){e=e.slice();var a=["center","bottom"];"bottom"===n?(e[1]+=o,a=["center","top"]):"left"===n?e[0]-=o:"right"===n?(e[0]+=o,a=["center","top"]):e[1]-=o;var r=0;return"left"!==n&&"right"!==n||(r=Math.PI/2),{rotation:r,position:e,style:{textAlign:a[0],textVerticalAlign:a[1]}}},_renderYearText:function(t,e,i,n){var o=t.getModel("yearLabel");if(o.get("show")){var a=o.get("margin"),r=o.get("position");r||(r="horizontal"!==i?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===i?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},d=e.start.y;+e.end.y>+e.start.y&&(d=d+"-"+e.end.y);var f=o.get("formatter"),p={start:e.start.y,end:e.end.y,nameMap:d},g=this._formatterLabel(f,p),m=new rM({z2:30});mo(m.style,o,{text:g}),m.attr(this._yearTextPositionControl(m,c[r],i,r,a)),n.add(m)}},_monthTextPositionControl:function(t,e,i,n,o){var a="left",r="top",s=t[0],l=t[1];return"horizontal"===i?(l+=o,e&&(a="center"),"start"===n&&(r="bottom")):(s+=o,e&&(r="middle"),"start"===n&&(a="right")),{x:s,y:l,textAlign:a,textVerticalAlign:r}},_renderMonthText:function(t,e,i){var n=t.getModel("monthLabel");if(n.get("show")){var o=n.get("nameMap"),r=n.get("margin"),s=n.get("position"),l=n.get("align"),u=[this._tlpoints,this._blpoints];_(o)&&(o=jN[o.toUpperCase()]||[]);var h="start"===s?0:1,c="horizontal"===e?0:1;r="start"===s?-r:r;for(var d="center"===l,f=0;f=r[0]&&t<=r[1]}if(t===this._dataZoomModel){var n=this._dimName,o=this.getTargetSeriesModels(),a=t.get("filterMode"),r=this._valueWindow;"none"!==a&&$N(o,function(t){var e=t.getData(),o=e.mapDimension(n,!0);o.length&&("weakFilter"===a?e.filterSelf(function(t){for(var i,n,a,s=0;sr[1];if(u&&!h&&!c)return!0;u&&(a=!0),h&&(i=!0),c&&(n=!0)}return a&&i&&n}):$N(o,function(n){if("empty"===a)t.setData(e.map(n,function(t){return i(t)?t:NaN}));else{var o={};o[n]=r,e.selectRange(o)}}),$N(o,function(t){e.setApproximateExtent(r,t)}))})}}};var tO=d,eO=KN,iO=Fs({type:"dataZoom",dependencies:["xAxis","yAxis","zAxis","radiusAxis","angleAxis","singleAxis","series"],defaultOption:{zlevel:0,z:4,orient:null,xAxisIndex:null,yAxisIndex:null,filterMode:"filter",throttle:null,start:0,end:100,startValue:null,endValue:null,minSpan:null,maxSpan:null,minValueSpan:null,maxValueSpan:null,rangeMode:null},init:function(t,e,i){this._dataIntervalByAxis={},this._dataInfo={},this._axisProxies={},this.textStyleModel,this._autoThrottle=!0,this._rangePropMode=["percent","percent"];var n=By(t);this.mergeDefaultAndTheme(t,i),this.doInit(n)},mergeOption:function(t){var e=By(t);n(this.option,t,!0),this.doInit(e)},doInit:function(t){var e=this.option;U_.canvasSupported||(e.realtime=!1),this._setDefaultThrottle(t),Vy(this,t),tO([["start","startValue"],["end","endValue"]],function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=null)},this),this.textStyleModel=this.getModel("textStyle"),this._resetTarget(),this._giveAxisProxies()},_giveAxisProxies:function(){var t=this._axisProxies;this.eachTargetAxis(function(e,i,n,o){var a=this.dependentModels[e.axis][i],r=a.__dzAxisProxy||(a.__dzAxisProxy=new QN(e.name,i,this,o));t[e.name+"_"+i]=r},this)},_resetTarget:function(){var t=this.option,e=this._judgeAutoMode();eO(function(e){var i=e.axisIndex;t[i]=Di(t[i])},this),"axisIndex"===e?this._autoSetAxisIndex():"orient"===e&&this._autoSetOrient()},_judgeAutoMode:function(){var t=this.option,e=!1;eO(function(i){null!=t[i.axisIndex]&&(e=!0)},this);var i=t.orient;return null==i&&e?"orient":e?void 0:(null==i&&(t.orient="horizontal"),"axisIndex")},_autoSetAxisIndex:function(){var t=!0,e=this.get("orient",!0),i=this.option,n=this.dependentModels;if(t){var o="vertical"===e?"y":"x";n[o+"Axis"].length?(i[o+"AxisIndex"]=[0],t=!1):tO(n.singleAxis,function(n){t&&n.get("orient",!0)===e&&(i.singleAxisIndex=[n.componentIndex],t=!1)})}t&&eO(function(e){if(t){var n=[],o=this.dependentModels[e.axis];if(o.length&&!n.length)for(var a=0,r=o.length;a0?100:20}},getFirstTargetAxisModel:function(){var t;return eO(function(e){if(null==t){var i=this.get(e.axisIndex);i.length&&(t=this.dependentModels[e.axis][i[0]])}},this),t},eachTargetAxis:function(t,e){var i=this.ecModel;eO(function(n){tO(this.get(n.axisIndex),function(o){t.call(e,n,o,this,i)},this)},this)},getAxisProxy:function(t,e){return this._axisProxies[t+"_"+e]},getAxisModel:function(t,e){var i=this.getAxisProxy(t,e);return i&&i.getAxisModel()},setRawRange:function(t,e){var i=this.option;tO([["start","startValue"],["end","endValue"]],function(e){null==t[e[0]]&&null==t[e[1]]||(i[e[0]]=t[e[0]],i[e[1]]=t[e[1]])},this),!e&&Vy(this,t)},getPercentRange:function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},getValueRange:function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var i=this.findRepresentativeAxisProxy();return i?i.getDataValueWindow():void 0},findRepresentativeAxisProxy:function(t){if(t)return t.__dzAxisProxy;var e=this._axisProxies;for(var i in e)if(e.hasOwnProperty(i)&&e[i].hostedBy(this))return e[i];for(var i in e)if(e.hasOwnProperty(i)&&!e[i].hostedBy(this))return e[i]},getRangePropMode:function(){return this._rangePropMode.slice()}}),nO=qI.extend({type:"dataZoom",render:function(t,e,i,n){this.dataZoomModel=t,this.ecModel=e,this.api=i},getTargetCoordInfo:function(){function t(t,e,i,n){for(var o,a=0;a0&&e%g)p+=f;else{var i=null==t||isNaN(t)||""===t,n=i?0:aO(t,a,u,!0);i&&!l&&e?(c.push([c[c.length-1][0],0]),d.push([d[d.length-1][0],0])):!i&&l&&(c.push([p,0]),d.push([p,0])),c.push([p,n]),d.push([p,n]),p+=f,l=i}});var m=this.dataZoomModel;this._displayables.barGroup.add(new pM({shape:{points:c},style:r({fill:m.get("dataBackgroundColor")},m.getModel("dataBackground.areaStyle").getAreaStyle()),silent:!0,z2:-20})),this._displayables.barGroup.add(new gM({shape:{points:d},style:m.getModel("dataBackground.lineStyle").getLineStyle(),silent:!0,z2:-19}))}}},_prepareDataShadowInfo:function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var i,n=this.ecModel;return t.eachTargetAxis(function(o,a){d(t.getAxisProxy(o.name,a).getTargetSeriesModels(),function(t){if(!(i||!0!==e&&l(cO,t.get("type"))<0)){var r,s=n.getComponent(o.axis,a).axis,u=Gy(o.name),h=t.coordinateSystem;null!=u&&h.getOtherAxis&&(r=h.getOtherAxis(s).inverse),u=t.getData().mapDimension(u),i={thisAxis:s,series:t,thisDim:o.name,otherDim:u,otherAxisInverse:r}}},this)},this),i}},_renderHandle:function(){var t=this._displayables,e=t.handles=[],i=t.handleLabels=[],n=this._displayables.barGroup,o=this._size,a=this.dataZoomModel;n.add(t.filler=new oO({draggable:!0,cursor:Fy(this._orient),drift:sO(this._onDragMove,this,"all"),onmousemove:function(t){mw(t.event)},ondragstart:sO(this._showDataInfo,this,!0),ondragend:sO(this._onDragEnd,this),onmouseover:sO(this._showDataInfo,this,!0),onmouseout:sO(this._showDataInfo,this,!1),style:{fill:a.get("fillerColor"),textPosition:"inside"}})),n.add(new oO($n({silent:!0,shape:{x:0,y:0,width:o[0],height:o[1]},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}}))),lO([0,1],function(t){var o=Po(a.get("handleIcon"),{cursor:Fy(this._orient),draggable:!0,drift:sO(this._onDragMove,this,t),onmousemove:function(t){mw(t.event)},ondragend:sO(this._onDragEnd,this),onmouseover:sO(this._showDataInfo,this,!0),onmouseout:sO(this._showDataInfo,this,!1)},{x:-1,y:0,width:2,height:2}),r=o.getBoundingRect();this._handleHeight=Vo(a.get("handleSize"),this._size[1]),this._handleWidth=r.width/r.height*this._handleHeight,o.setStyle(a.getModel("handleStyle").getItemStyle());var s=a.get("handleColor");null!=s&&(o.style.fill=s),n.add(e[t]=o);var l=a.textStyleModel;this.group.add(i[t]=new rM({silent:!0,invisible:!0,style:{x:0,y:0,text:"",textVerticalAlign:"middle",textAlign:"center",textFill:l.getTextColor(),textFont:l.getFont()},z2:10}))},this)},_resetInterval:function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[aO(t[0],[0,100],e,!0),aO(t[1],[0,100],e,!0)]},_updateInterval:function(t,e){var i=this.dataZoomModel,n=this._handleEnds,o=this._getViewExtent(),a=i.findRepresentativeAxisProxy().getMinMaxSpan(),r=[0,100];QL(e,n,o,i.get("zoomLock")?"all":t,null!=a.minSpan?aO(a.minSpan,r,o,!0):null,null!=a.maxSpan?aO(a.maxSpan,r,o,!0):null);var s=this._range,l=this._range=rO([aO(n[0],o,r,!0),aO(n[1],o,r,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},_updateView:function(t){var e=this._displayables,i=this._handleEnds,n=rO(i.slice()),o=this._size;lO([0,1],function(t){var n=e.handles[t],a=this._handleHeight;n.attr({scale:[a/2,a/2],position:[i[t],o[1]/2-a/2]})},this),e.filler.setShape({x:n[0],y:0,width:n[1]-n[0],height:o[1]}),this._updateDataInfo(t)},_updateDataInfo:function(t){function e(t){var e=Ao(n.handles[t].parent,this.group),i=Co(0===t?"right":"left",e),s=this._handleWidth/2+hO,l=Do([c[t]+(0===t?-s:s),this._size[1]/2],e);o[t].setStyle({x:l[0],y:l[1],textVerticalAlign:a===uO?"middle":i,textAlign:a===uO?i:"center",text:r[t]})}var i=this.dataZoomModel,n=this._displayables,o=n.handleLabels,a=this._orient,r=["",""];if(i.get("showDetail")){var s=i.findRepresentativeAxisProxy();if(s){var l=s.getAxisModel().axis,u=this._range,h=t?s.calculateDataWindow({start:u[0],end:u[1]}).valueWindow:s.getDataValueWindow();r=[this._formatLabel(h[0],l),this._formatLabel(h[1],l)]}}var c=rO(this._handleEnds.slice());e.call(this,0),e.call(this,1)},_formatLabel:function(t,e){var i=this.dataZoomModel,n=i.get("labelFormatter"),o=i.get("labelPrecision");null!=o&&"auto"!==o||(o=e.getPixelPrecision());var a=null==t||isNaN(t)?"":"category"===e.type||"time"===e.type?e.scale.getLabel(Math.round(t)):t.toFixed(Math.min(o,20));return x(n)?n(t,a):_(n)?n.replace("{value}",a):a},_showDataInfo:function(t){t=this._dragging||t;var e=this._displayables.handleLabels;e[0].attr("invisible",!t),e[1].attr("invisible",!t)},_onDragMove:function(t,e,i){this._dragging=!0;var n=Do([e,i],this._displayables.barGroup.getLocalTransform(),!0),o=this._updateInterval(t,n[0]),a=this.dataZoomModel.get("realtime");this._updateView(!a),o&&a&&this._dispatchZoomAction()},_onDragEnd:function(){this._dragging=!1,this._showDataInfo(!1),!this.dataZoomModel.get("realtime")&&this._dispatchZoomAction()},_onClickPanelClick:function(t){var e=this._size,i=this._displayables.barGroup.transformCoordToLocal(t.offsetX,t.offsetY);if(!(i[0]<0||i[0]>e[0]||i[1]<0||i[1]>e[1])){var n=this._handleEnds,o=(n[0]+n[1])/2,a=this._updateInterval("all",i[0]-o);this._updateView(),a&&this._dispatchZoomAction()}},_dispatchZoomAction:function(){var t=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,start:t[0],end:t[1]})},_findCoordRect:function(){var t;if(lO(this.getTargetCoordInfo(),function(e){if(!t&&e.length){var i=e[0].model.coordinateSystem;t=i.getRect&&i.getRect()}}),!t){var e=this.api.getWidth(),i=this.api.getHeight();t={x:.2*e,y:.2*i,width:.6*e,height:.6*i}}return t}});iO.extend({type:"dataZoom.inside",defaultOption:{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}});var fO="\0_ec_dataZoom_roams",pO=m,gO=nO.extend({type:"dataZoom.inside",init:function(t,e){this._range},render:function(t,e,i,n){gO.superApply(this,"render",arguments),this._range=t.getPercentRange(),d(this.getTargetCoordInfo(),function(e,n){var o=f(e,function(t){return Zy(t.model)});d(e,function(e){var a=e.model,r={};d(["pan","zoom","scrollMove"],function(t){r[t]=pO(mO[t],this,e,n)},this),Wy(i,{coordId:Zy(a),allCoordIds:o,containsPoint:function(t,e,i){return a.coordinateSystem.containPoint([e,i])},dataZoomId:t.id,dataZoomModel:t,getRange:r})},this)},this)},dispose:function(){Hy(this.api,this.dataZoomModel.id),gO.superApply(this,"dispose",arguments),this._range=null}}),mO={zoom:function(t,e,i,n){var o=this._range,a=o.slice(),r=t.axisModels[0];if(r){var s=vO[e](null,[n.originX,n.originY],r,i,t),l=(s.signal>0?s.pixelStart+s.pixelLength-s.pixel:s.pixel-s.pixelStart)/s.pixelLength*(a[1]-a[0])+a[0],u=Math.max(1/n.scale,0);a[0]=(a[0]-l)*u+l,a[1]=(a[1]-l)*u+l;var h=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return QL(0,a,[0,100],0,h.minSpan,h.maxSpan),this._range=a,o[0]!==a[0]||o[1]!==a[1]?a:void 0}},pan:Ky(function(t,e,i,n,o,a){var r=vO[n]([a.oldX,a.oldY],[a.newX,a.newY],e,o,i);return r.signal*(t[1]-t[0])*r.pixel/r.pixelLength}),scrollMove:Ky(function(t,e,i,n,o,a){return vO[n]([0,0],[a.scrollDelta,a.scrollDelta],e,o,i).signal*(t[1]-t[0])*a.scrollDelta})},vO={grid:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem.getRect();return t=t||[0,0],"x"===a.dim?(r.pixel=e[0]-t[0],r.pixelLength=s.width,r.pixelStart=s.x,r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=s.height,r.pixelStart=s.y,r.signal=a.inverse?-1:1),r},polar:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===i.mainType?(r.pixel=e[0]-t[0],r.pixelLength=l[1]-l[0],r.pixelStart=l[0],r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=u[1]-u[0],r.pixelStart=u[0],r.signal=a.inverse?-1:1),r},singleAxis:function(t,e,i,n,o){var a=i.axis,r=o.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===a.orient?(s.pixel=e[0]-t[0],s.pixelLength=r.width,s.pixelStart=r.x,s.signal=a.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=r.height,s.pixelStart=r.y,s.signal=a.inverse?-1:1),s}};Os({getTargetSeries:function(t){var e=R();return t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){d(n.getAxisProxy(t.name,i).getTargetSeriesModels(),function(t){e.set(t.uid,t)})})}),e},modifyOutputEnd:!0,overallReset:function(t,e){t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).reset(n,e)}),t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).filterData(n,e)})}),t.eachComponent("dataZoom",function(t){var e=t.findRepresentativeAxisProxy(),i=e.getDataPercentWindow(),n=e.getDataValueWindow();t.setRawRange({start:i[0],end:i[1],startValue:n[0],endValue:n[1]},!0)})}}),Es("dataZoom",function(t,e){var i=Ny(m(e.eachComponent,e,"dataZoom"),KN,function(t,e){return t.get(e.axisIndex)}),n=[];e.eachComponent({mainType:"dataZoom",query:t},function(t,e){n.push.apply(n,i(t).nodes)}),d(n,function(e,i){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})})});var yO=d,xO=function(t){var e=t&&t.visualMap;y(e)||(e=e?[e]:[]),yO(e,function(t){if(t){$y(t,"splitList")&&!$y(t,"pieces")&&(t.pieces=t.splitList,delete t.splitList);var e=t.pieces;e&&y(e)&&yO(e,function(t){w(t)&&($y(t,"start")&&!$y(t,"min")&&(t.min=t.start),$y(t,"end")&&!$y(t,"max")&&(t.max=t.end))})}})};lI.registerSubTypeDefaulter("visualMap",function(t){return t.categories||(t.pieces?t.pieces.length>0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"});var _O=VT.VISUAL.COMPONENT;Bs(_O,{createOnAllSeries:!0,reset:function(t,e){var i=[];return e.eachComponent("visualMap",function(e){var n=t.pipelineContext;!e.isTargetSeries(t)||n&&n.large||i.push(ny(e.stateList,e.targetVisuals,m(e.getValueState,e),e.getDataDimension(t.getData())))}),i}}),Bs(_O,{createOnAllSeries:!0,reset:function(t,e){var i=t.getData(),n=[];e.eachComponent("visualMap",function(e){if(e.isTargetSeries(t)){var o=e.getVisualMeta(m(Jy,null,t,e))||{stops:[],outerColors:[]},a=e.getDataDimension(i),r=i.getDimensionInfo(a);null!=r&&(o.dimension=r.index,n.push(o))}}),t.getData().setVisual("visualMeta",n)}});var wO={get:function(t,e,n){var o=i((bO[t]||{})[e]);return n&&y(o)?o[o.length-1]:o}},bO={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},SO=hL.mapVisual,MO=hL.eachVisual,IO=y,TO=d,AO=Fo,DO=Bo,CO=B,LO=Fs({type:"visualMap",dependencies:["series"],stateList:["inRange","outOfRange"],replacableOptionKeys:["inRange","outOfRange","target","controller","color"],dataBound:[-1/0,1/0],layoutMode:{type:"box",ignoreSize:!0},defaultOption:{show:!0,zlevel:0,z:4,seriesIndex:"all",min:0,max:200,dimension:null,inRange:null,outOfRange:null,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,color:null,formatter:null,text:null,textStyle:{color:"#333"}},init:function(t,e,i){this._dataExtent,this.targetVisuals={},this.controllerVisuals={},this.textStyleModel,this.itemSize,this.mergeDefaultAndTheme(t,i)},optionUpdated:function(t,e){var i=this.option;U_.canvasSupported||(i.realtime=!1),!e&&ey(i,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},resetVisual:function(t){var e=this.stateList;t=m(t,this),this.controllerVisuals=ty(this.option.controller,e,t),this.targetVisuals=ty(this.option.target,e,t)},getTargetSeriesIndices:function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries(function(t,i){e.push(i)}):e=Di(t),e},eachTargetSeries:function(t,e){d(this.getTargetSeriesIndices(),function(i){t.call(e,this.ecModel.getSeriesByIndex(i))},this)},isTargetSeries:function(t){var e=!1;return this.eachTargetSeries(function(i){i===t&&(e=!0)}),e},formatValueText:function(t,e,i){function n(t){return t===l[0]?"min":t===l[1]?"max":(+t).toFixed(Math.min(s,20))}var o,a,r=this.option,s=r.precision,l=this.dataBound,u=r.formatter;return i=i||["<",">"],y(t)&&(t=t.slice(),o=!0),a=e?t:o?[n(t[0]),n(t[1])]:n(t),_(u)?u.replace("{value}",o?a[0]:a).replace("{value2}",o?a[1]:a):x(u)?o?u(t[0],t[1]):u(t):o?t[0]===l[0]?i[0]+" "+a[1]:t[1]===l[1]?i[1]+" "+a[0]:a[0]+" - "+a[1]:a},resetExtent:function(){var t=this.option,e=AO([t.min,t.max]);this._dataExtent=e},getDataDimension:function(t){var e=this.option.dimension,i=t.dimensions;if(null!=e||i.length){if(null!=e)return t.getDimension(e);for(var n=t.dimensions,o=n.length-1;o>=0;o--){var a=n[o];if(!t.getDimensionInfo(a).isCalculationCoord)return a}}},getExtent:function(){return this._dataExtent.slice()},completeVisualOption:function(){function t(t){IO(o.color)&&!t.inRange&&(t.inRange={color:o.color.slice().reverse()}),t.inRange=t.inRange||{color:e.get("gradientColor")},TO(this.stateList,function(e){var i=t[e];if(_(i)){var n=wO.get(i,"active",l);n?(t[e]={},t[e][i]=n):delete t[e]}},this)}var e=this.ecModel,o=this.option,a={inRange:o.inRange,outOfRange:o.outOfRange},r=o.target||(o.target={}),s=o.controller||(o.controller={});n(r,a),n(s,a);var l=this.isCategory();t.call(this,r),t.call(this,s),function(t,e,i){var n=t[e],o=t[i];n&&!o&&(o=t[i]={},TO(n,function(t,e){if(hL.isValidType(e)){var i=wO.get(e,"inactive",l);null!=i&&(o[e]=i,"color"!==e||o.hasOwnProperty("opacity")||o.hasOwnProperty("colorAlpha")||(o.opacity=[0,0]))}}))}.call(this,r,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,o=this.get("inactiveColor");TO(this.stateList,function(a){var r=this.itemSize,s=t[a];s||(s=t[a]={color:l?o:[o]}),null==s.symbol&&(s.symbol=e&&i(e)||(l?"roundRect":["roundRect"])),null==s.symbolSize&&(s.symbolSize=n&&i(n)||(l?r[0]:[r[0],r[0]])),s.symbol=SO(s.symbol,function(t){return"none"===t||"square"===t?"roundRect":t});var u=s.symbolSize;if(null!=u){var h=-1/0;MO(u,function(t){t>h&&(h=t)}),s.symbolSize=SO(u,function(t){return DO(t,[0,h],[0,r[0]],!0)})}},this)}.call(this,s)},resetItemSize:function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},isCategory:function(){return!!this.option.categories},setSelected:CO,getValueState:CO,getVisualMeta:CO}),kO=[20,140],PO=LO.extend({type:"visualMap.continuous",defaultOption:{align:"auto",calculable:!1,range:null,realtime:!0,itemHeight:null,itemWidth:null,hoverLink:!0,hoverLinkDataSize:null,hoverLinkOnHandle:null},optionUpdated:function(t,e){PO.superApply(this,"optionUpdated",arguments),this.resetExtent(),this.resetVisual(function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()}),this._resetRange()},resetItemSize:function(){PO.superApply(this,"resetItemSize",arguments);var t=this.itemSize;"horizontal"===this._orient&&t.reverse(),(null==t[0]||isNaN(t[0]))&&(t[0]=kO[0]),(null==t[1]||isNaN(t[1]))&&(t[1]=kO[1])},_resetRange:function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},completeVisualOption:function(){LO.prototype.completeVisualOption.apply(this,arguments),d(this.stateList,function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=0)},this)},setSelected:function(t){this.option.range=t.slice(),this._resetRange()},getSelected:function(){var t=this.getExtent(),e=Fo((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=i[1]||t<=e[1])?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){t[0]<=e&&e<=t[1]&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getVisualMeta:function(t){function e(e,i){o.push({value:e,color:t(e,i)})}for(var i=Qy(0,0,this.getExtent()),n=Qy(0,0,this.option.range.slice()),o=[],a=0,r=0,s=n.length,l=i.length;rt[1])break;i.push({color:this.getControllerVisual(a,"color",e),offset:o/100})}return i.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),i},_createBarPoints:function(t,e){var i=this.visualMapModel.itemSize;return[[i[0]-e[0],t[0]],[i[0],t[0]],[i[0],t[1]],[i[0]-e[1],t[1]]]},_createBarGroup:function(t){var e=this._orient,i=this.visualMapModel.get("inverse");return new tb("horizontal"!==e||i?"horizontal"===e&&i?{scale:"bottom"===t?[-1,1]:[1,1],rotation:-Math.PI/2}:"vertical"!==e||i?{scale:"left"===t?[1,1]:[-1,1]}:{scale:"left"===t?[1,-1]:[-1,-1]}:{scale:"bottom"===t?[1,1]:[-1,1],rotation:Math.PI/2})},_updateHandle:function(t,e){if(this._useHandle){var i=this._shapes,n=this.visualMapModel,o=i.handleThumbs,a=i.handleLabels;EO([0,1],function(r){var s=o[r];s.setStyle("fill",e.handlesColor[r]),s.position[1]=t[r];var l=Do(i.handleLabelPoints[r],Ao(s,this.group));a[r].setStyle({x:l[0],y:l[1],text:n.formatValueText(this._dataInterval[r]),textVerticalAlign:"middle",textAlign:this._applyTransform("horizontal"===this._orient?0===r?"bottom":"top":"left",i.barGroup)})},this)}},_showIndicator:function(t,e,i,n){var o=this.visualMapModel,a=o.getExtent(),r=o.itemSize,s=[0,r[1]],l=OO(t,a,s,!0),u=this._shapes,h=u.indicator;if(h){h.position[1]=l,h.attr("invisible",!1),h.setShape("points",ox(!!i,n,l,r[1]));var c={convertOpacityToAlpha:!0},d=this.getControllerVisual(t,"color",c);h.setStyle("fill",d);var f=Do(u.indicatorLabelPoint,Ao(h,this.group)),p=u.indicatorLabel;p.attr("invisible",!1);var g=this._applyTransform("left",u.barGroup),m=this._orient;p.setStyle({text:(i||"")+o.formatValueText(e),textVerticalAlign:"horizontal"===m?g:"middle",textAlign:"horizontal"===m?"center":g,x:f[0],y:f[1]})}},_enableHoverLinkToSeries:function(){var t=this;this._shapes.barGroup.on("mousemove",function(e){if(t._hovering=!0,!t._dragging){var i=t.visualMapModel.itemSize,n=t._applyTransform([e.offsetX,e.offsetY],t._shapes.barGroup,!0,!0);n[1]=RO(zO(0,n[1]),i[1]),t._doHoverLinkToSeries(n[1],0<=n[0]&&n[0]<=i[0])}}).on("mouseout",function(){t._hovering=!1,!t._dragging&&t._clearHoverLinkToSeries()})},_enableHoverLinkFromSeries:function(){var t=this.api.getZr();this.visualMapModel.option.hoverLink?(t.on("mouseover",this._hoverLinkFromSeriesMouseOver,this),t.on("mouseout",this._hideIndicator,this)):this._clearHoverLinkFromSeries()},_doHoverLinkToSeries:function(t,e){var i=this.visualMapModel,n=i.itemSize;if(i.option.hoverLink){var o=[0,n[1]],a=i.getExtent();t=RO(zO(o[0],t),o[1]);var r=ax(i,a,o),s=[t-r,t+r],l=OO(t,o,a,!0),u=[OO(s[0],o,a,!0),OO(s[1],o,a,!0)];s[0]o[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",r):u[1]===1/0?this._showIndicator(l,u[0],"> ",r):this._showIndicator(l,l,"≈ ",r));var h=this._hoverLinkDataIndices,c=[];(e||rx(i))&&(c=this._hoverLinkDataIndices=i.findTargetDataIndices(u));var d=Ri(h,c);this._dispatchHighDown("downplay",ex(d[0])),this._dispatchHighDown("highlight",ex(d[1]))}},_hoverLinkFromSeriesMouseOver:function(t){var e=t.target,i=this.visualMapModel;if(e&&null!=e.dataIndex){var n=this.ecModel.getSeriesByIndex(e.seriesIndex);if(i.isTargetSeries(n)){var o=n.getData(e.dataType),a=o.get(i.getDataDimension(o),e.dataIndex,!0);isNaN(a)||this._showIndicator(a,a)}}},_hideIndicator:function(){var t=this._shapes;t.indicator&&t.indicator.attr("invisible",!0),t.indicatorLabel&&t.indicatorLabel.attr("invisible",!0)},_clearHoverLinkToSeries:function(){this._hideIndicator();var t=this._hoverLinkDataIndices;this._dispatchHighDown("downplay",ex(t)),t.length=0},_clearHoverLinkFromSeries:function(){this._hideIndicator();var t=this.api.getZr();t.off("mouseover",this._hoverLinkFromSeriesMouseOver),t.off("mouseout",this._hideIndicator)},_applyTransform:function(t,e,i,n){var o=Ao(e,n?null:this.group);return zM[y(t)?"applyTransform":"transformDirection"](t,o,i)},_dispatchHighDown:function(t,e){e&&e.length&&this.api.dispatchAction({type:t,batch:e})},dispose:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()},remove:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()}});Es({type:"selectDataRange",event:"dataRangeSelected",update:"update"},function(t,e){e.eachComponent({mainType:"visualMap",query:t},function(e){e.setSelected(t.selected)})}),Ns(xO);var FO=LO.extend({type:"visualMap.piecewise",defaultOption:{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieceList:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0,showLabel:null},optionUpdated:function(t,e){FO.superApply(this,"optionUpdated",arguments),this._pieceList=[],this.resetExtent();var n=this._mode=this._determineMode();WO[this._mode].call(this),this._resetSelected(t,e);var o=this.option.categories;this.resetVisual(function(t,e){"categories"===n?(t.mappingMethod="category",t.categories=i(o)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=f(this._pieceList,function(t){var t=i(t);return"inRange"!==e&&(t.visual=null),t}))})},completeVisualOption:function(){function t(t,e,i){return t&&t[e]&&(w(t[e])?t[e].hasOwnProperty(i):t[e]===i)}var e=this.option,i={},n=hL.listVisualTypes(),o=this.isCategory();d(e.pieces,function(t){d(n,function(e){t.hasOwnProperty(e)&&(i[e]=1)})}),d(i,function(i,n){var a=0;d(this.stateList,function(i){a|=t(e,i,n)||t(e.target,i,n)},this),!a&&d(this.stateList,function(t){(e[t]||(e[t]={}))[n]=wO.get(n,"inRange"===t?"active":"inactive",o)})},this),LO.prototype.completeVisualOption.apply(this,arguments)},_resetSelected:function(t,e){var i=this.option,n=this._pieceList,o=(e?i:t).selected||{};if(i.selected=o,d(n,function(t,e){var i=this.getSelectedMapKey(t);o.hasOwnProperty(i)||(o[i]=!0)},this),"single"===i.selectedMode){var a=!1;d(n,function(t,e){var i=this.getSelectedMapKey(t);o[i]&&(a?o[i]=!1:a=!0)},this)}},getSelectedMapKey:function(t){return"categories"===this._mode?t.value+"":t.index+""},getPieceList:function(){return this._pieceList},_determineMode:function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},setSelected:function(t){this.option.selected=i(t)},getValueState:function(t){var e=hL.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){hL.findPieceIndex(e,this._pieceList)===t&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getRepresentValue:function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var i=t.interval||[];e=i[0]===-1/0&&i[1]===1/0?0:(i[0]+i[1])/2}return e},getVisualMeta:function(t){function e(e,a){var r=o.getRepresentValue({interval:e});a||(a=o.getValueState(r));var s=t(r,a);e[0]===-1/0?n[0]=s:e[1]===1/0?n[1]=s:i.push({value:e[0],color:s},{value:e[1],color:s})}if(!this.isCategory()){var i=[],n=[],o=this,a=this._pieceList.slice();if(a.length){var r=a[0].interval[0];r!==-1/0&&a.unshift({interval:[-1/0,r]}),(r=a[a.length-1].interval[1])!==1/0&&a.push({interval:[r,1/0]})}else a.push({interval:[-1/0,1/0]});var s=-1/0;return d(a,function(t){var i=t.interval;i&&(i[0]>s&&e([s,i[0]],"outOfRange"),e(i.slice()),s=i[1])},this),{stops:i,outerColors:n}}}}),WO={splitNumber:function(){var t=this.option,e=this._pieceList,i=Math.min(t.precision,20),n=this.getExtent(),o=t.splitNumber;o=Math.max(parseInt(o,10),1),t.splitNumber=o;for(var a=(n[1]-n[0])/o;+a.toFixed(i)!==a&&i<5;)i++;t.precision=i,a=+a.toFixed(i);var r=0;t.minOpen&&e.push({index:r++,interval:[-1/0,n[0]],close:[0,0]});for(var s=n[0],l=r+o;r","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,i)},this)}};NO.extend({type:"visualMap.piecewise",doRender:function(){var t=this.group;t.removeAll();var e=this.visualMapModel,i=e.get("textGap"),n=e.textStyleModel,o=n.getFont(),a=n.getTextColor(),r=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=T(e.get("showLabel",!0),!u);u&&this._renderEndsText(t,u[0],s,h,r),d(l.viewPieceList,function(n){var l=n.piece,u=new tb;u.onclick=m(this._onItemClick,this,l),this._enableHoverLink(u,n.indexInModelPieceList);var c=e.getRepresentValue(l);if(this._createItemSymbol(u,c,[0,0,s[0],s[1]]),h){var d=this.visualMapModel.getValueState(c);u.add(new rM({style:{x:"right"===r?-i:s[0]+i,y:s[1]/2,text:l.text,textVerticalAlign:"middle",textAlign:r,textFont:o,textFill:a,opacity:"outOfRange"===d?.5:1}}))}t.add(u)},this),u&&this._renderEndsText(t,u[1],s,h,r),aI(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},_enableHoverLink:function(t,e){function i(t){var i=this.visualMapModel;i.option.hoverLink&&this.api.dispatchAction({type:t,batch:ex(i.findTargetDataIndices(e))})}t.on("mouseover",m(i,this,"highlight")).on("mouseout",m(i,this,"downplay"))},_getItemAlign:function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return tx(t,this.api,t.itemSize);var i=e.align;return i&&"auto"!==i||(i="left"),i},_renderEndsText:function(t,e,i,n,o){if(e){var a=new tb,r=this.visualMapModel.textStyleModel;a.add(new rM({style:{x:n?"right"===o?i[0]:0:i[0]/2,y:i[1]/2,textVerticalAlign:"middle",textAlign:n?o:"center",text:e,textFont:r.getFont(),textFill:r.getTextColor()}})),t.add(a)}},_getViewData:function(){var t=this.visualMapModel,e=f(t.getPieceList(),function(t,e){return{piece:t,indexInModelPieceList:e}}),i=t.get("text"),n=t.get("orient"),o=t.get("inverse");return("horizontal"===n?o:!o)?e.reverse():i&&(i=i.slice().reverse()),{viewPieceList:e,endsText:i}},_createItemSymbol:function(t,e,i){t.add(Jl(this.getControllerVisual(e,"symbol"),i[0],i[1],i[2],i[3],this.getControllerVisual(e,"color")))},_onItemClick:function(t){var e=this.visualMapModel,n=e.option,o=i(n.selected),a=e.getSelectedMapKey(t);"single"===n.selectedMode?(o[a]=!0,d(o,function(t,e){o[e]=e===a})):o[a]=!o[a],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:o})}});Ns(xO);var HO=ta,ZO=ia,UO=Fs({type:"marker",dependencies:["series","grid","polar","geo"],init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i),this.mergeOption(t,i,n.createdBySelf,!0)},isAnimationEnabled:function(){if(U_.node)return!1;var t=this.__hostSeries;return this.getShallow("animation")&&t&&t.isAnimationEnabled()},mergeOption:function(t,e,i,n){var o=this.constructor,r=this.mainType+"Model";i||e.eachSeries(function(t){var i=t.get(this.mainType,!0),s=t[r];i&&i.data?(s?s.mergeOption(i,e,!0):(n&&ux(i),d(i.data,function(t){t instanceof Array?(ux(t[0]),ux(t[1])):ux(t)}),a(s=new o(i,this,e),{mainType:this.mainType,seriesIndex:t.seriesIndex,name:t.name,createdBySelf:!0}),s.__hostSeries=t),t[r]=s):t[r]=null},this)},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=y(i)?f(i,HO).join(", "):HO(i),o=e.getName(t),a=ZO(this.name);return(null!=i||o)&&(a+="
"),o&&(a+=ZO(o),null!=i&&(a+=" : ")),null!=i&&(a+=ZO(n)),a},getData:function(){return this._data},setData:function(t){this._data=t}});h(UO,ZI),UO.extend({type:"markPoint",defaultOption:{zlevel:0,z:5,symbol:"pin",symbolSize:50,tooltip:{trigger:"item"},label:{show:!0,position:"inside"},itemStyle:{borderWidth:2},emphasis:{label:{show:!0}}}});var XO=l,jO=v,YO={min:jO(dx,"min"),max:jO(dx,"max"),average:jO(dx,"average")},qO=Ws({type:"marker",init:function(){this.markerGroupMap=R()},render:function(t,e,i){var n=this.markerGroupMap;n.each(function(t){t.__keep=!1});var o=this.type+"Model";e.eachSeries(function(t){var n=t[o];n&&this.renderSeries(t,n,e,i)},this),n.each(function(t){!t.__keep&&this.group.remove(t.group)},this)},renderSeries:function(){}});qO.extend({type:"markPoint",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markPointModel;e&&(xx(e.getData(),t,i),this.markerGroupMap.get(t.id).updateLayout(e))},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,r=t.getData(),s=this.markerGroupMap,l=s.get(a)||s.set(a,new Du),u=_x(o,t,e);e.setData(u),xx(e.getData(),t,n),u.each(function(t){var i=u.getItemModel(t),n=i.getShallow("symbolSize");"function"==typeof n&&(n=n(e.getRawValue(t),e.getDataParams(t))),u.setItemVisual(t,{symbolSize:n,color:i.get("itemStyle.color")||r.getVisual("color"),symbol:i.getShallow("symbol")})}),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl(function(t){t.traverse(function(t){t.dataModel=e})}),l.__keep=!0,l.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markPoint=t.markPoint||{}}),UO.extend({type:"markLine",defaultOption:{zlevel:0,z:5,symbol:["circle","arrow"],symbolSize:[8,16],precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end"},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"}});var KO=function(t,e,o,r){var s=t.getData(),l=r.type;if(!y(r)&&("min"===l||"max"===l||"average"===l||"median"===l||null!=r.xAxis||null!=r.yAxis)){var u,h;if(null!=r.yAxis||null!=r.xAxis)u=null!=r.yAxis?"y":"x",e.getAxis(u),h=T(r.yAxis,r.xAxis);else{var c=px(r,s,e,t);u=c.valueDataDim,c.valueAxis,h=yx(s,u,l)}var d="x"===u?0:1,f=1-d,p=i(r),g={};p.type=null,p.coord=[],g.coord=[],p.coord[f]=-1/0,g.coord[f]=1/0;var m=o.get("precision");m>=0&&"number"==typeof h&&(h=+h.toFixed(Math.min(m,20))),p.coord[d]=g.coord[d]=h,r=[p,g,{type:l,valueIndex:r.valueIndex,value:h}]}return r=[fx(t,r[0]),fx(t,r[1]),a({},r[2])],r[2].type=r[2].type||"",n(r[2],r[0]),n(r[2],r[1]),r};qO.extend({type:"markLine",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markLineModel;if(e){var n=e.getData(),o=e.__from,a=e.__to;o.each(function(e){Ix(o,e,!0,t,i),Ix(a,e,!1,t,i)}),n.each(function(t){n.setItemLayout(t,[o.getItemLayout(t),a.getItemLayout(t)])}),this.markerGroupMap.get(t.id).updateLayout()}},this)},renderSeries:function(t,e,i,n){function o(e,i,o){var a=e.getItemModel(i);Ix(e,i,o,t,n),e.setItemVisual(i,{symbolSize:a.get("symbolSize")||g[o?0:1],symbol:a.get("symbol",!0)||p[o?0:1],color:a.get("itemStyle.color")||s.getVisual("color")})}var a=t.coordinateSystem,r=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(r)||l.set(r,new sf);this.group.add(u.group);var h=Tx(a,t,e),c=h.from,d=h.to,f=h.line;e.__from=c,e.__to=d,e.setData(f);var p=e.get("symbol"),g=e.get("symbolSize");y(p)||(p=[p,p]),"number"==typeof g&&(g=[g,g]),h.from.each(function(t){o(c,t,!0),o(d,t,!1)}),f.each(function(t){var e=f.getItemModel(t).get("lineStyle.color");f.setItemVisual(t,{color:e||c.getItemVisual(t,"color")}),f.setItemLayout(t,[c.getItemLayout(t),d.getItemLayout(t)]),f.setItemVisual(t,{fromSymbolSize:c.getItemVisual(t,"symbolSize"),fromSymbol:c.getItemVisual(t,"symbol"),toSymbolSize:d.getItemVisual(t,"symbolSize"),toSymbol:d.getItemVisual(t,"symbol")})}),u.updateData(f),h.line.eachItemGraphicEl(function(t,i){t.traverse(function(t){t.dataModel=e})}),u.__keep=!0,u.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markLine=t.markLine||{}}),UO.extend({type:"markArea",defaultOption:{zlevel:0,z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}}});var $O=function(t,e,i,n){var a=fx(t,n[0]),r=fx(t,n[1]),s=T,l=a.coord,u=r.coord;l[0]=s(l[0],-1/0),l[1]=s(l[1],-1/0),u[0]=s(u[0],1/0),u[1]=s(u[1],1/0);var h=o([{},a,r]);return h.coord=[a.coord,r.coord],h.x0=a.x,h.y0=a.y,h.x1=r.x,h.y1=r.y,h},JO=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]];qO.extend({type:"markArea",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markAreaModel;if(e){var n=e.getData();n.each(function(e){var o=f(JO,function(o){return Lx(n,e,o,t,i)});n.setItemLayout(e,o),n.getItemGraphicEl(e).setShape("points",o)})}},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(a)||l.set(a,{group:new tb});this.group.add(u.group),u.__keep=!0;var h=kx(o,t,e);e.setData(h),h.each(function(e){h.setItemLayout(e,f(JO,function(i){return Lx(h,e,i,t,n)})),h.setItemVisual(e,{color:s.getVisual("color")})}),h.diff(u.__data).add(function(t){var e=new pM({shape:{points:h.getItemLayout(t)}});h.setItemGraphicEl(t,e),u.group.add(e)}).update(function(t,i){var n=u.__data.getItemGraphicEl(i);Io(n,{shape:{points:h.getItemLayout(t)}},e,t),u.group.add(n),h.setItemGraphicEl(t,n)}).remove(function(t){var e=u.__data.getItemGraphicEl(t);u.group.remove(e)}).execute(),h.eachItemGraphicEl(function(t,i){var n=h.getItemModel(i),o=n.getModel("label"),a=n.getModel("emphasis.label"),s=h.getItemVisual(i,"color");t.useStyle(r(n.getModel("itemStyle").getItemStyle(),{fill:Yt(s,.4),stroke:s})),t.hoverStyle=n.getModel("emphasis.itemStyle").getItemStyle(),go(t.style,t.hoverStyle,o,a,{labelFetcher:e,labelDataIndex:i,defaultText:h.getName(i)||"",isRectText:!0,autoColor:s}),fo(t,{}),t.dataModel=e}),u.__data=h,u.group.silent=e.get("silent")||t.get("silent")}}),Ns(function(t){t.markArea=t.markArea||{}});lI.registerSubTypeDefaulter("timeline",function(){return"slider"}),Es({type:"timelineChange",event:"timelineChanged",update:"prepareAndUpdate"},function(t,e){var i=e.getComponent("timeline");return i&&null!=t.currentIndex&&(i.setCurrentIndex(t.currentIndex),!i.get("loop",!0)&&i.isIndexMax()&&i.setPlayState(!1)),e.resetOption("timeline"),r({currentIndex:i.option.currentIndex},t)}),Es({type:"timelinePlayChange",event:"timelinePlayChanged",update:"update"},function(t,e){var i=e.getComponent("timeline");i&&null!=t.playState&&i.setPlayState(t.playState)});var QO=lI.extend({type:"timeline",layoutMode:"box",defaultOption:{zlevel:0,z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},init:function(t,e,i){this._data,this._names,this.mergeDefaultAndTheme(t,i),this._initData()},mergeOption:function(t){QO.superApply(this,"mergeOption",arguments),this._initData()},setCurrentIndex:function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},getCurrentIndex:function(){return this.option.currentIndex},isIndexMax:function(){return this.getCurrentIndex()>=this._data.count()-1},setPlayState:function(t){this.option.autoPlay=!!t},getPlayState:function(){return!!this.option.autoPlay},_initData:function(){var t=this.option,e=t.data||[],n=t.axisType,o=this._names=[];if("category"===n){var a=[];d(e,function(t,e){var n,r=Li(t);w(t)?(n=i(t)).value=e:n=e,a.push(n),_(r)||null!=r&&!isNaN(r)||(r=""),o.push(r+"")}),e=a}var r={category:"ordinal",time:"time"}[n]||"number";(this._data=new vA([{name:"value",type:r}],this)).initData(e,o)},getData:function(){return this._data},getCategories:function(){if("category"===this.get("axisType"))return this._names.slice()}});h(QO.extend({type:"timeline.slider",defaultOption:{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"emptyCircle",symbolSize:10,lineStyle:{show:!0,width:2,color:"#304654"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#304654"},itemStyle:{color:"#304654",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:13,color:"#c23531",borderWidth:5,borderColor:"rgba(194,53,49, 0.5)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:22,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z",prevIcon:"path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z",color:"#304654",borderColor:"#304654",borderWidth:1},emphasis:{label:{show:!0,color:"#c23531"},itemStyle:{color:"#c23531"},controlStyle:{color:"#c23531",borderColor:"#c23531",borderWidth:2}},data:[]}}),ZI);var tE=qI.extend({type:"timeline"}),eE=function(t,e,i,n){aD.call(this,t,e,i),this.type=n||"value",this.model=null};eE.prototype={constructor:eE,getLabelModel:function(){return this.model.getModel("label")},isHorizontal:function(){return"horizontal"===this.model.get("orient")}},u(eE,aD);var iE=m,nE=d,oE=Math.PI;tE.extend({type:"timeline.slider",init:function(t,e){this.api=e,this._axis,this._viewRect,this._timer,this._currentPointer,this._mainGroup,this._labelGroup},render:function(t,e,i,n){if(this.model=t,this.api=i,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var o=this._layout(t,i),a=this._createGroup("mainGroup"),r=this._createGroup("labelGroup"),s=this._axis=this._createAxis(o,t);t.formatTooltip=function(t){return ia(s.scale.getLabel(t))},nE(["AxisLine","AxisTick","Control","CurrentPointer"],function(e){this["_render"+e](o,a,s,t)},this),this._renderAxisLabel(o,r,s,t),this._position(o,t)}this._doPlayStop()},remove:function(){this._clearTimer(),this.group.removeAll()},dispose:function(){this._clearTimer()},_layout:function(t,e){var i=t.get("label.position"),n=t.get("orient"),o=Ex(t,e);null==i||"auto"===i?i="horizontal"===n?o.y+o.height/2=0||"+"===i?"left":"right"},r={horizontal:i>=0||"+"===i?"top":"bottom",vertical:"middle"},s={horizontal:0,vertical:oE/2},l="vertical"===n?o.height:o.width,u=t.getModel("controlStyle"),h=u.get("show",!0),c=h?u.get("itemSize"):0,d=h?u.get("itemGap"):0,f=c+d,p=t.get("label.rotate")||0;p=p*oE/180;var g,m,v,y,x=u.get("position",!0),_=h&&u.get("showPlayBtn",!0),w=h&&u.get("showPrevBtn",!0),b=h&&u.get("showNextBtn",!0),S=0,M=l;return"left"===x||"bottom"===x?(_&&(g=[0,0],S+=f),w&&(m=[S,0],S+=f),b&&(v=[M-c,0],M-=f)):(_&&(g=[M-c,0],M-=f),w&&(m=[0,0],S+=f),b&&(v=[M-c,0],M-=f)),y=[S,M],t.get("inverse")&&y.reverse(),{viewRect:o,mainLength:l,orient:n,rotation:s[n],labelRotation:p,labelPosOpt:i,labelAlign:t.get("label.align")||a[n],labelBaseline:t.get("label.verticalAlign")||t.get("label.baseline")||r[n],playPosition:g,prevBtnPosition:m,nextBtnPosition:v,axisExtent:y,controlSize:c,controlGap:d}},_position:function(t,e){function i(t){var e=t.position;t.origin=[c[0][0]-e[0],c[1][0]-e[1]]}function n(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function o(t,e,i,n,o){t[n]+=i[n][o]-e[n][o]}var a=this._mainGroup,r=this._labelGroup,s=t.viewRect;if("vertical"===t.orient){var l=xt(),u=s.x,h=s.y+s.height;St(l,l,[-u,-h]),Mt(l,l,-oE/2),St(l,l,[u,h]),(s=s.clone()).applyTransform(l)}var c=n(s),d=n(a.getBoundingRect()),f=n(r.getBoundingRect()),p=a.position,g=r.position;g[0]=p[0]=c[0][0];var m=t.labelPosOpt;if(isNaN(m))o(p,d,c,1,v="+"===m?0:1),o(g,f,c,1,1-v);else{var v=m>=0?0:1;o(p,d,c,1,v),g[1]=p[1]+m}a.attr("position",p),r.attr("position",g),a.rotation=r.rotation=t.rotation,i(a),i(r)},_createAxis:function(t,e){var i=e.getData(),n=e.get("axisType"),o=Hl(e,n);o.getTicks=function(){return i.mapArray(["value"],function(t){return t})};var a=i.getDataExtent("value");o.setExtent(a[0],a[1]),o.niceTicks();var r=new eE("value",o,t.axisExtent,n);return r.model=e,r},_createGroup:function(t){var e=this["_"+t]=new tb;return this.group.add(e),e},_renderAxisLine:function(t,e,i,n){var o=i.getExtent();n.get("lineStyle.show")&&e.add(new _M({shape:{x1:o[0],y1:0,x2:o[1],y2:0},style:a({lineCap:"round"},n.getModel("lineStyle").getLineStyle()),silent:!0,z2:1}))},_renderAxisTick:function(t,e,i,n){var o=n.getData(),a=i.scale.getTicks();nE(a,function(t){var a=i.dataToCoord(t),r=o.getItemModel(t),s=r.getModel("itemStyle"),l=r.getModel("emphasis.itemStyle"),u={position:[a,0],onclick:iE(this._changeTimeline,this,t)},h=zx(r,s,e,u);fo(h,l.getItemStyle()),r.get("tooltip")?(h.dataIndex=t,h.dataModel=n):h.dataIndex=h.dataModel=null},this)},_renderAxisLabel:function(t,e,i,n){if(i.getLabelModel().get("show")){var o=n.getData(),a=i.getViewLabels();nE(a,function(n){var a=n.tickValue,r=o.getItemModel(a),s=r.getModel("label"),l=r.getModel("emphasis.label"),u=i.dataToCoord(n.tickValue),h=new rM({position:[u,0],rotation:t.labelRotation-t.rotation,onclick:iE(this._changeTimeline,this,a),silent:!1});mo(h.style,s,{text:n.formattedLabel,textAlign:t.labelAlign,textVerticalAlign:t.labelBaseline}),e.add(h),fo(h,mo({},l))},this)}},_renderControl:function(t,e,i,n){function o(t,i,o,h){if(t){var c=Rx(n,i,u,{position:t,origin:[a/2,0],rotation:h?-r:0,rectHover:!0,style:s,onclick:o});e.add(c),fo(c,l)}}var a=t.controlSize,r=t.rotation,s=n.getModel("controlStyle").getItemStyle(),l=n.getModel("emphasis.controlStyle").getItemStyle(),u=[0,-a/2,a,a],h=n.getPlayState(),c=n.get("inverse",!0);o(t.nextBtnPosition,"controlStyle.nextIcon",iE(this._changeTimeline,this,c?"-":"+")),o(t.prevBtnPosition,"controlStyle.prevIcon",iE(this._changeTimeline,this,c?"+":"-")),o(t.playPosition,"controlStyle."+(h?"stopIcon":"playIcon"),iE(this._handlePlayClick,this,!h),!0)},_renderCurrentPointer:function(t,e,i,n){var o=n.getData(),a=n.getCurrentIndex(),r=o.getItemModel(a).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=iE(s._handlePointerDrag,s),t.ondragend=iE(s._handlePointerDragend,s),Bx(t,a,i,n,!0)},onUpdate:function(t){Bx(t,a,i,n)}};this._currentPointer=zx(r,r,this._mainGroup,{},this._currentPointer,l)},_handlePlayClick:function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},_handlePointerDrag:function(t,e,i){this._clearTimer(),this._pointerChangeTimeline([i.offsetX,i.offsetY])},_handlePointerDragend:function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},_pointerChangeTimeline:function(t,e){var i=this._toAxisCoord(t)[0],n=Fo(this._axis.getExtent().slice());i>n[1]&&(i=n[1]),ii.getHeight()&&(n.textPosition="top",l=!0);var u=l?-5-o.height:s+8;a+o.width/2>i.getWidth()?(n.textPosition=["100%",u],n.textAlign="right"):a-o.width/2<0&&(n.textPosition=[0,u],n.textAlign="left")}})}},updateView:function(t,e,i,n){d(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,n)})},remove:function(t,e){d(this._features,function(i){i.remove&&i.remove(t,e)}),this.group.removeAll()},dispose:function(t,e){d(this._features,function(i){i.dispose&&i.dispose(t,e)})}});var rE=rT.toolbox.saveAsImage;Gx.defaultOption={show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:rE.title,type:"png",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:rE.lang.slice()},Gx.prototype.unusable=!U_.canvasSupported,Gx.prototype.onclick=function(t,e){var i=this.model,n=i.get("name")||t.get("title.0.text")||"echarts",o=document.createElement("a"),a=i.get("type",!0)||"png";o.download=n+"."+a,o.target="_blank";var r=e.getConnectedDataURL({type:a,backgroundColor:i.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",excludeComponents:i.get("excludeComponents"),pixelRatio:i.get("pixelRatio")});if(o.href=r,"function"!=typeof MouseEvent||U_.browser.ie||U_.browser.edge)if(window.navigator.msSaveOrOpenBlob){for(var s=atob(r.split(",")[1]),l=s.length,u=new Uint8Array(l);l--;)u[l]=s.charCodeAt(l);var h=new Blob([u]);window.navigator.msSaveOrOpenBlob(h,n+"."+a)}else{var c=i.get("lang"),d='';window.open().document.write(d)}else{var f=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1});o.dispatchEvent(f)}},Ty("saveAsImage",Gx);var sE=rT.toolbox.magicType;Fx.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z",tiled:"M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z"},title:i(sE.title),option:{},seriesIndex:{}};var lE=Fx.prototype;lE.getIcons=function(){var t=this.model,e=t.get("icon"),i={};return d(t.get("type"),function(t){e[t]&&(i[t]=e[t])}),i};var uE={line:function(t,e,i,o){if("bar"===t)return n({id:e,type:"line",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.line")||{},!0)},bar:function(t,e,i,o){if("line"===t)return n({id:e,type:"bar",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.bar")||{},!0)},stack:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:"__ec_magicType_stack__"},o.get("option.stack")||{},!0)},tiled:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:""},o.get("option.tiled")||{},!0)}},hE=[["line","bar"],["stack","tiled"]];lE.onclick=function(t,e,i){var n=this.model,o=n.get("seriesIndex."+i);if(uE[i]){var a={series:[]};d(hE,function(t){l(t,i)>=0&&d(t,function(t){n.setIconStatus(t,"normal")})}),n.setIconStatus(i,"emphasis"),t.eachComponent({mainType:"series",query:null==o?null:{seriesIndex:o}},function(e){var o=e.subType,s=e.id,l=uE[i](o,s,e,n);l&&(r(l,e.option),a.series.push(l));var u=e.coordinateSystem;if(u&&"cartesian2d"===u.type&&("line"===i||"bar"===i)){var h=u.getAxesByScale("ordinal")[0];if(h){var c=h.dim+"Axis",d=t.queryComponents({mainType:c,index:e.get(name+"Index"),id:e.get(name+"Id")})[0].componentIndex;a[c]=a[c]||[];for(var f=0;f<=d;f++)a[c][d]=a[c][d]||{};a[c][d].boundaryGap="bar"===i}}}),e.dispatchAction({type:"changeMagicType",currentType:i,newOption:a})}},Es({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),Ty("magicType",Fx);var cE=rT.toolbox.dataView,dE=new Array(60).join("-"),fE="\t",pE=new RegExp("["+fE+"]+","g");$x.defaultOption={show:!0,readOnly:!1,optionToContent:null,contentToOption:null,icon:"M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28",title:i(cE.title),lang:i(cE.lang),backgroundColor:"#fff",textColor:"#000",textareaColor:"#fff",textareaBorderColor:"#333",buttonColor:"#c23531",buttonTextColor:"#fff"},$x.prototype.onclick=function(t,e){function i(){n.removeChild(a),x._dom=null}var n=e.getDom(),o=this.model;this._dom&&n.removeChild(this._dom);var a=document.createElement("div");a.style.cssText="position:absolute;left:5px;top:5px;bottom:5px;right:5px;",a.style.backgroundColor=o.get("backgroundColor")||"#fff";var r=document.createElement("h4"),s=o.get("lang")||[];r.innerHTML=s[0]||o.get("title"),r.style.cssText="margin: 10px 20px;",r.style.color=o.get("textColor");var l=document.createElement("div"),u=document.createElement("textarea");l.style.cssText="display:block;width:100%;overflow:auto;";var h=o.get("optionToContent"),c=o.get("contentToOption"),d=Ux(t);if("function"==typeof h){var f=h(e.getOption());"string"==typeof f?l.innerHTML=f:M(f)&&l.appendChild(f)}else l.appendChild(u),u.readOnly=o.get("readOnly"),u.style.cssText="width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;",u.style.color=o.get("textColor"),u.style.borderColor=o.get("textareaBorderColor"),u.style.backgroundColor=o.get("textareaColor"),u.value=d.value;var p=d.meta,g=document.createElement("div");g.style.cssText="position:absolute;bottom:0;left:0;right:0;";var m="float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px",v=document.createElement("div"),y=document.createElement("div");m+=";background-color:"+o.get("buttonColor"),m+=";color:"+o.get("buttonTextColor");var x=this;ht(v,"click",i),ht(y,"click",function(){var t;try{t="function"==typeof c?c(l,e.getOption()):Kx(u.value,p)}catch(t){throw i(),new Error("Data view format error "+t)}t&&e.dispatchAction({type:"changeDataView",newOption:t}),i()}),v.innerHTML=s[1],y.innerHTML=s[2],y.style.cssText=m,v.style.cssText=m,!o.get("readOnly")&&g.appendChild(y),g.appendChild(v),ht(u,"keydown",function(t){if(9===(t.keyCode||t.which)){var e=this.value,i=this.selectionStart,n=this.selectionEnd;this.value=e.substring(0,i)+fE+e.substring(n),this.selectionStart=this.selectionEnd=i+1,mw(t)}}),a.appendChild(r),a.appendChild(l),a.appendChild(g),l.style.height=n.clientHeight-80+"px",n.appendChild(a),this._dom=a},$x.prototype.remove=function(t,e){this._dom&&e.getDom().removeChild(this._dom)},$x.prototype.dispose=function(t,e){this.remove(t,e)},Ty("dataView",$x),Es({type:"changeDataView",event:"dataViewChanged",update:"prepareAndUpdate"},function(t,e){var i=[];d(t.newOption.series,function(t){var n=e.getSeriesByName(t.name)[0];if(n){var o=n.get("data");i.push({name:t.name,data:Jx(t.data,o)})}else i.push(a({type:"scatter"},t))}),e.mergeOption(r({series:i},t.newOption))});var gE=d,mE="\0_ec_hist_store";iO.extend({type:"dataZoom.select"}),nO.extend({type:"dataZoom.select"});var vE=rT.toolbox.dataZoom,yE=d,xE="\0_ec_\0toolbox-dataZoom_";o_.defaultOption={show:!0,icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:i(vE.title)};var _E=o_.prototype;_E.render=function(t,e,i,n){this.model=t,this.ecModel=e,this.api=i,s_(t,e,this,n,i),r_(t,e)},_E.onclick=function(t,e,i){wE[i].call(this)},_E.remove=function(t,e){this._brushController.unmount()},_E.dispose=function(t,e){this._brushController.dispose()};var wE={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(t_(this.ecModel))}};_E._onBrush=function(t,e){function i(t,e,i){var r=e.getAxis(t),s=r.model,l=n(t,s,a),u=l.findRepresentativeAxisProxy(s).getMinMaxSpan();null==u.minValueSpan&&null==u.maxValueSpan||(i=QL(0,i.slice(),r.scale.getExtent(),0,u.minValueSpan,u.maxValueSpan)),l&&(o[l.id]={dataZoomId:l.id,startValue:i[0],endValue:i[1]})}function n(t,e,i){var n;return i.eachComponent({mainType:"dataZoom",subType:"select"},function(i){i.getAxisModel(t,e.componentIndex)&&(n=i)}),n}if(e.isEnd&&t.length){var o={},a=this.ecModel;this._brushController.updateCovers([]),new hy(a_(this.model.option),a,{include:["grid"]}).matchOutputRanges(t,a,function(t,e,n){if("cartesian2d"===n.type){var o=t.brushType;"rect"===o?(i("x",n,e[0]),i("y",n,e[1])):i({lineX:"x",lineY:"y"}[o],n,e)}}),Qx(a,o),this._dispatchZoomAction(o)}},_E._dispatchZoomAction=function(t){var e=[];yE(t,function(t,n){e.push(i(t))}),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},Ty("dataZoom",o_),Ns(function(t){function e(t,e){if(e){var o=t+"Index",a=e[o];null==a||"all"===a||y(a)||(a=!1===a||"none"===a?[]:[a]),i(t,function(e,i){if(null==a||"all"===a||-1!==l(a,i)){var r={type:"select",$fromToolbox:!0,id:xE+t+i};r[o]=i,n.push(r)}})}}function i(e,i){var n=t[e];y(n)||(n=n?[n]:[]),yE(n,i)}if(t){var n=t.dataZoom||(t.dataZoom=[]);y(n)||(t.dataZoom=n=[n]);var o=t.toolbox;if(o&&(y(o)&&(o=o[0]),o&&o.feature)){var a=o.feature.dataZoom;e("xAxis",a),e("yAxis",a)}}});var bE=rT.toolbox.restore;l_.defaultOption={show:!0,icon:"M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5",title:bE.title},l_.prototype.onclick=function(t,e,i){e_(t),e.dispatchAction({type:"restore",from:this.uid})},Ty("restore",l_),Es({type:"restore",event:"restore",update:"prepareAndUpdate"},function(t,e){e.resetOption("recreate")});var SE,ME="urn:schemas-microsoft-com:vml",IE="undefined"==typeof window?null:window,TE=!1,AE=IE&&IE.document;if(AE&&!U_.canvasSupported)try{!AE.namespaces.zrvml&&AE.namespaces.add("zrvml",ME),SE=function(t){return AE.createElement("')}}catch(t){SE=function(t){return AE.createElement("<"+t+' xmlns="'+ME+'" class="zrvml">')}}var DE=ES.CMD,CE=Math.round,LE=Math.sqrt,kE=Math.abs,PE=Math.cos,NE=Math.sin,OE=Math.max;if(!U_.canvasSupported){var EE=21600,RE=EE/2,zE=function(t){t.style.cssText="position:absolute;left:0;top:0;width:1px;height:1px;",t.coordsize=EE+","+EE,t.coordorigin="0,0"},BE=function(t){return String(t).replace(/&/g,"&").replace(/"/g,""")},VE=function(t,e,i){return"rgb("+[t,e,i].join(",")+")"},GE=function(t,e){e&&t&&e.parentNode!==t&&t.appendChild(e)},FE=function(t,e){e&&t&&e.parentNode===t&&t.removeChild(e)},WE=function(t,e,i){return 1e5*(parseFloat(t)||0)+1e3*(parseFloat(e)||0)+i},HE=function(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t},ZE=function(t,e,i){var n=Gt(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=VE(n[0],n[1],n[2]),t.opacity=i*n[3])},UE=function(t){var e=Gt(t);return[VE(e[0],e[1],e[2]),e[3]]},XE=function(t,e,i){var n=e.fill;if(null!=n)if(n instanceof IM){var o,a=0,r=[0,0],s=0,l=1,u=i.getBoundingRect(),h=u.width,c=u.height;if("linear"===n.type){o="gradient";var d=i.transform,f=[n.x*h,n.y*c],p=[n.x2*h,n.y2*c];d&&(Q(f,f,d),Q(p,p,d));var g=p[0]-f[0],m=p[1]-f[1];(a=180*Math.atan2(g,m)/Math.PI)<0&&(a+=360),a<1e-6&&(a=0)}else{o="gradientradial";var f=[n.x*h,n.y*c],d=i.transform,v=i.scale,y=h,x=c;r=[(f[0]-u.x)/y,(f[1]-u.y)/x],d&&Q(f,f,d),y/=v[0]*EE,x/=v[1]*EE;var _=OE(y,x);s=0/_,l=2*n.r/_-s}var w=n.colorStops.slice();w.sort(function(t,e){return t.offset-e.offset});for(var b=w.length,S=[],M=[],I=0;I=2){var D=S[0][0],C=S[1][0],L=S[0][1]*e.opacity,k=S[1][1]*e.opacity;t.type=o,t.method="none",t.focus="100%",t.angle=a,t.color=D,t.color2=C,t.colors=M.join(","),t.opacity=k,t.opacity2=L}"radial"===o&&(t.focusposition=r.join(","))}else ZE(t,n,e.opacity)},jE=function(t,e){null!=e.lineDash&&(t.dashstyle=e.lineDash.join(" ")),null==e.stroke||e.stroke instanceof IM||ZE(t,e.stroke,e.opacity)},YE=function(t,e,i,n){var o="fill"===e,a=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(o||!o&&i.lineWidth)?(t[o?"filled":"stroked"]="true",i[e]instanceof IM&&FE(t,a),a||(a=u_(e)),o?XE(a,i,n):jE(a,i),GE(t,a)):(t[o?"filled":"stroked"]="false",FE(t,a))},qE=[[],[],[]],KE=function(t,e){var i,n,o,a,r,s,l=DE.M,u=DE.C,h=DE.L,c=DE.A,d=DE.Q,f=[],p=t.data,g=t.len();for(a=0;a.01?N&&(O+=.0125):Math.abs(E-D)<1e-4?N&&OA?x-=.0125:x+=.0125:N&&ED?y+=.0125:y-=.0125),f.push(R,CE(((A-C)*M+b)*EE-RE),",",CE(((D-L)*I+S)*EE-RE),",",CE(((A+C)*M+b)*EE-RE),",",CE(((D+L)*I+S)*EE-RE),",",CE((O*M+b)*EE-RE),",",CE((E*I+S)*EE-RE),",",CE((y*M+b)*EE-RE),",",CE((x*I+S)*EE-RE)),r=y,s=x;break;case DE.R:var z=qE[0],B=qE[1];z[0]=p[a++],z[1]=p[a++],B[0]=z[0]+p[a++],B[1]=z[1]+p[a++],e&&(Q(z,z,e),Q(B,B,e)),z[0]=CE(z[0]*EE-RE),B[0]=CE(B[0]*EE-RE),z[1]=CE(z[1]*EE-RE),B[1]=CE(B[1]*EE-RE),f.push(" m ",z[0],",",z[1]," l ",B[0],",",z[1]," l ",B[0],",",B[1]," l ",z[0],",",B[1]);break;case DE.Z:f.push(" x ")}if(i>0){f.push(n);for(var V=0;V100&&(tR=0,QE={});var i,n=eR.style;try{n.font=t,i=n.fontFamily.split(",")[0]}catch(t){}e={style:n.fontStyle||"normal",variant:n.fontVariant||"normal",weight:n.fontWeight||"normal",size:0|parseFloat(n.fontSize||12),family:i||"Microsoft YaHei"},QE[t]=e,tR++}return e};!function(t,e){bb[t]=e}("measureText",function(t,e){var i=AE;JE||((JE=i.createElement("div")).style.cssText="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;",AE.body.appendChild(JE));try{JE.style.font=e}catch(t){}return JE.innerHTML="",JE.appendChild(i.createTextNode(t)),{width:JE.offsetWidth}});for(var nR=new de,oR=[Db,di,fi,Pn,rM],aR=0;aR=o&&u+1>=a){for(var h=[],c=0;c=o&&c+1>=a)return T_(0,s.components);l[i]=s}else l[i]=void 0}r++}();if(d)return d}},pushComponent:function(t,e,i){var n=t[t.length-1];n&&n.added===e&&n.removed===i?t[t.length-1]={count:n.count+1,added:e,removed:i}:t.push({count:1,added:e,removed:i})},extractCommon:function(t,e,i,n){for(var o=e.length,a=i.length,r=t.newPos,s=r-n,l=0;r+1=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},D_.prototype.update=function(t,e){if(t){var i=this.getDefs(!1);if(t[this._domName]&&i.contains(t[this._domName]))"function"==typeof e&&e(t);else{var n=this.add(t);n&&(t[this._domName]=n)}}},D_.prototype.addDom=function(t){this.getDefs(!0).appendChild(t)},D_.prototype.removeDom=function(t){var e=this.getDefs(!1);e&&t[this._domName]&&(e.removeChild(t[this._domName]),t[this._domName]=null)},D_.prototype.getDoms=function(){var t=this.getDefs(!1);if(!t)return[];var e=[];return d(this._tagNames,function(i){var n=t.getElementsByTagName(i);e=e.concat([].slice.call(n))}),e},D_.prototype.markAllUnused=function(){var t=this;d(this.getDoms(),function(e){e[t._markLabel]="0"})},D_.prototype.markUsed=function(t){t&&(t[this._markLabel]="1")},D_.prototype.removeUnused=function(){var t=this.getDefs(!1);if(t){var e=this;d(this.getDoms(),function(i){"1"!==i[e._markLabel]&&t.removeChild(i)})}},D_.prototype.getSvgProxy=function(t){return t instanceof Pn?yR:t instanceof fi?xR:t instanceof rM?_R:yR},D_.prototype.getTextSvgElement=function(t){return t.__textSvgEl},D_.prototype.getSvgElement=function(t){return t.__svgEl},u(C_,D_),C_.prototype.addWithoutUpdate=function(t,e){if(e&&e.style){var i=this;d(["fill","stroke"],function(n){if(e.style[n]&&("linear"===e.style[n].type||"radial"===e.style[n].type)){var o,a=e.style[n],r=i.getDefs(!0);a._dom?(o=a._dom,r.contains(a._dom)||i.addDom(o)):o=i.add(a),i.markUsed(e);var s=o.getAttribute("id");t.setAttribute(n,"url(#"+s+")")}})}},C_.prototype.add=function(t){var e;if("linear"===t.type)e=this.createElement("linearGradient");else{if("radial"!==t.type)return Yw("Illegal gradient type."),null;e=this.createElement("radialGradient")}return t.id=t.id||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-gradient-"+t.id),this.updateDom(t,e),this.addDom(e),e},C_.prototype.update=function(t){var e=this;D_.prototype.update.call(this,t,function(){var i=t.type,n=t._dom.tagName;"linear"===i&&"linearGradient"===n||"radial"===i&&"radialGradient"===n?e.updateDom(t,t._dom):(e.removeDom(t),e.add(t))})},C_.prototype.updateDom=function(t,e){if("linear"===t.type)e.setAttribute("x1",t.x),e.setAttribute("y1",t.y),e.setAttribute("x2",t.x2),e.setAttribute("y2",t.y2);else{if("radial"!==t.type)return void Yw("Illegal gradient type.");e.setAttribute("cx",t.x),e.setAttribute("cy",t.y),e.setAttribute("r",t.r)}t.global?e.setAttribute("gradientUnits","userSpaceOnUse"):e.setAttribute("gradientUnits","objectBoundingBox"),e.innerHTML="";for(var i=t.colorStops,n=0,o=i.length;n0){var n,o,a=this.getDefs(!0),r=e[0],s=i?"_textDom":"_dom";r[s]?(o=r[s].getAttribute("id"),n=r[s],a.contains(n)||a.appendChild(n)):(o="zr"+this._zrId+"-clip-"+this.nextId,++this.nextId,(n=this.createElement("clipPath")).setAttribute("id",o),a.appendChild(n),r[s]=n);var l=this.getSvgProxy(r);if(r.transform&&r.parent.invTransform&&!i){var u=Array.prototype.slice.call(r.transform);bt(r.transform,r.parent.invTransform,r.transform),l.brush(r),r.transform=u}else l.brush(r);var h=this.getSvgElement(r);n.innerHTML="",n.appendChild(h.cloneNode()),t.setAttribute("clip-path","url(#"+o+")"),e.length>1&&this.updateDom(n,e.slice(1),i)}else t&&t.setAttribute("clip-path","none")},L_.prototype.markUsed=function(t){var e=this;t.__clipPaths&&t.__clipPaths.length>0&&d(t.__clipPaths,function(t){t._dom&&D_.prototype.markUsed.call(e,t._dom),t._textDom&&D_.prototype.markUsed.call(e,t._textDom)})},u(k_,D_),k_.prototype.addWithoutUpdate=function(t,e){if(e&&P_(e.style)){var i,n=e.style;n._shadowDom?(i=n._shadowDom,this.getDefs(!0).contains(n._shadowDom)||this.addDom(i)):i=this.add(e),this.markUsed(e);var o=i.getAttribute("id");t.style.filter="url(#"+o+")"}},k_.prototype.add=function(t){var e=this.createElement("filter"),i=t.style;return i._shadowDomId=i._shadowDomId||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-shadow-"+i._shadowDomId),this.updateDom(t,e),this.addDom(e),e},k_.prototype.update=function(t,e){var i=e.style;if(P_(i)){var n=this;D_.prototype.update.call(this,e,function(t){n.updateDom(e,t._shadowDom)})}else this.remove(t,i)},k_.prototype.remove=function(t,e){null!=e._shadowDomId&&(this.removeDom(e),t.style.filter="")},k_.prototype.updateDom=function(t,e){var i=e.getElementsByTagName("feDropShadow");i=0===i.length?this.createElement("feDropShadow"):i[0];var n,o,a,r,s=t.style,l=t.scale?t.scale[0]||1:1,u=t.scale?t.scale[1]||1:1;if(s.shadowBlur||s.shadowOffsetX||s.shadowOffsetY)n=s.shadowOffsetX||0,o=s.shadowOffsetY||0,a=s.shadowBlur,r=s.shadowColor;else{if(!s.textShadowBlur)return void this.removeDom(e,s);n=s.textShadowOffsetX||0,o=s.textShadowOffsetY||0,a=s.textShadowBlur,r=s.textShadowColor}i.setAttribute("dx",n/l),i.setAttribute("dy",o/u),i.setAttribute("flood-color",r);var h=a/2/l+" "+a/2/u;i.setAttribute("stdDeviation",h),e.setAttribute("x","-100%"),e.setAttribute("y","-100%"),e.setAttribute("width",Math.ceil(a/2*200)+"%"),e.setAttribute("height",Math.ceil(a/2*200)+"%"),e.appendChild(i),s._shadowDom=e},k_.prototype.markUsed=function(t){var e=t.style;e&&e._shadowDom&&D_.prototype.markUsed.call(this,e._shadowDom)};var IR=function(t,e,i,n){this.root=t,this.storage=e,this._opts=i=a({},i||{});var o=p_("svg");o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("version","1.1"),o.setAttribute("baseProfile","full"),o.style.cssText="user-select:none;position:absolute;left:0;top:0;",this.gradientManager=new C_(n,o),this.clipPathManager=new L_(n,o),this.shadowManager=new k_(n,o);var r=document.createElement("div");r.style.cssText="overflow:hidden;position:relative",this._svgRoot=o,this._viewport=r,t.appendChild(r),r.appendChild(o),this.resize(i.width,i.height),this._visibleList=[]};IR.prototype={constructor:IR,getType:function(){return"svg"},getViewportRoot:function(){return this._viewport},getViewportRootOffset:function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},refresh:function(){var t=this.storage.getDisplayList(!0);this._paintList(t)},setBackgroundColor:function(t){this._viewport.style.background=t},_paintList:function(t){this.gradientManager.markAllUnused(),this.clipPathManager.markAllUnused(),this.shadowManager.markAllUnused();var e,i=this._svgRoot,n=this._visibleList,o=t.length,a=[];for(e=0;e=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},resize:function(t,e){var i=this._viewport;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n.height=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!==t||this._height!==e){this._width=t,this._height=e;var o=i.style;o.width=t+"px",o.height=e+"px";var a=this._svgRoot;a.setAttribute("width",t),a.setAttribute("height",e)}},getWidth:function(){return this._width},getHeight:function(){return this._height},_getSize:function(t){var e=this._opts,i=["width","height"][t],n=["clientWidth","clientHeight"][t],o=["paddingLeft","paddingTop"][t],a=["paddingRight","paddingBottom"][t];if(null!=e[i]&&"auto"!==e[i])return parseFloat(e[i]);var r=this.root,s=document.defaultView.getComputedStyle(r);return(r[n]||N_(s[i])||N_(r.style[i]))-(N_(s[o])||0)-(N_(s[a])||0)|0},dispose:function(){this.root.innerHTML="",this._svgRoot=this._viewport=this.storage=null},clear:function(){this._viewport&&this.root.removeChild(this._viewport)},pathToDataUrl:function(){return this.refresh(),"data:image/svg+xml;charset=UTF-8,"+this._svgRoot.outerHTML}},d(["getLayer","insertLayer","eachLayer","eachBuiltinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","toDataURL","pathToImage"],function(t){IR.prototype[t]=F_(t)}),Ti("svg",IR),t.version="4.2.1",t.dependencies=ET,t.PRIORITY=VT,t.init=function(t,e,i){var n=ks(t);if(n)return n;var o=new us(t,e,i);return o.id="ec_"+iA++,tA[o.id]=o,Fi(t,oA,o.id),Cs(o),o},t.connect=function(t){if(y(t)){var e=t;t=null,kT(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+nA++,kT(e,function(e){e.group=t})}return eA[t]=!0,t},t.disConnect=Ls,t.disconnect=aA,t.dispose=function(t){"string"==typeof t?t=tA[t]:t instanceof us||(t=ks(t)),t instanceof us&&!t.isDisposed()&&t.dispose()},t.getInstanceByDom=ks,t.getInstanceById=function(t){return tA[t]},t.registerTheme=Ps,t.registerPreprocessor=Ns,t.registerProcessor=Os,t.registerPostUpdate=function(t){KT.push(t)},t.registerAction=Es,t.registerCoordinateSystem=Rs,t.getCoordinateSystemDimensions=function(t){var e=Fa.get(t);if(e)return e.getDimensionsInfo?e.getDimensionsInfo():e.dimensions.slice()},t.registerLayout=zs,t.registerVisual=Bs,t.registerLoading=Gs,t.extendComponentModel=Fs,t.extendComponentView=Ws,t.extendSeriesModel=Hs,t.extendChartView=Zs,t.setCanvasCreator=function(t){e("createCanvas",t)},t.registerMap=function(t,e,i){DT.registerMap(t,e,i)},t.getMap=function(t){var e=DT.retrieveMap(t);return e&&e[0]&&{geoJson:e[0].geoJSON,specialAreas:e[0].specialAreas}},t.dataTool=rA,t.zrender=Hb,t.number=YM,t.format=eI,t.throttle=Pr,t.helper=tD,t.matrix=Sw,t.vector=cw,t.color=Ww,t.parseGeoJSON=iD,t.parseGeoJson=rD,t.util=sD,t.graphic=lD,t.List=vA,t.Model=No,t.Axis=aD,t.env=U_}); \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-badge/changelog.md b/alpha/admin/uni_modules/uni-badge/changelog.md new file mode 100644 index 0000000..e352c60 --- /dev/null +++ b/alpha/admin/uni_modules/uni-badge/changelog.md @@ -0,0 +1,33 @@ +## 1.2.2(2023-01-28) +- 修复 运行/打包 控制台警告问题 +## 1.2.1(2022-09-05) +- 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473) +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-badge](https://uniapp.dcloud.io/component/uniui/uni-badge) +## 1.1.7(2021-11-08) +- 优化 升级ui +- 修改 size 属性默认值调整为 small +- 修改 type 属性,默认值调整为 error,info 替换 default +## 1.1.6(2021-09-22) +- 修复 在字节小程序上样式不生效的 bug +## 1.1.5(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.4(2021-07-29) +- 修复 去掉 nvue 不支持css 的 align-self 属性,nvue 下不暂支持 absolute 属性 +## 1.1.3(2021-06-24) +- 优化 示例项目 +## 1.1.1(2021-05-12) +- 新增 组件示例地址 +## 1.1.0(2021-05-12) +- 新增 uni-badge 的 absolute 属性,支持定位 +- 新增 uni-badge 的 offset 属性,支持定位偏移 +- 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点 +- 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+ +- 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式 +## 1.0.7(2021-05-07) +- 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug +- 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug +- 新增 uni-badge 属性 custom-style, 支持自定义样式 +## 1.0.6(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-badge/components/uni-badge/uni-badge.vue b/alpha/admin/uni_modules/uni-badge/components/uni-badge/uni-badge.vue new file mode 100644 index 0000000..956354b --- /dev/null +++ b/alpha/admin/uni_modules/uni-badge/components/uni-badge/uni-badge.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-badge/package.json b/alpha/admin/uni_modules/uni-badge/package.json new file mode 100644 index 0000000..b0bac93 --- /dev/null +++ b/alpha/admin/uni_modules/uni-badge/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-badge", + "displayName": "uni-badge 数字角标", + "version": "1.2.2", + "description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。", + "keywords": [ + "", + "badge", + "uni-ui", + "uniui", + "数字角标", + "徽章" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-badge/readme.md b/alpha/admin/uni_modules/uni-badge/readme.md new file mode 100644 index 0000000..bdf175d --- /dev/null +++ b/alpha/admin/uni_modules/uni-badge/readme.md @@ -0,0 +1,10 @@ +## Badge 数字角标 +> **组件名:uni-badge** +> 代码块: `uBadge` + +数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景, + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-badge) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-breadcrumb/changelog.md b/alpha/admin/uni_modules/uni-breadcrumb/changelog.md new file mode 100644 index 0000000..016e6ce --- /dev/null +++ b/alpha/admin/uni_modules/uni-breadcrumb/changelog.md @@ -0,0 +1,6 @@ +## 0.1.2(2022-06-08) +- 修复 微信小程序 separator 不显示问题 +## 0.1.1(2022-06-02) +- 新增 支持 uni.scss 修改颜色 +## 0.1.0(2022-04-21) +- 初始化 diff --git a/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue b/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue new file mode 100644 index 0000000..b9edbd6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue @@ -0,0 +1,121 @@ + + + diff --git a/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue b/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue new file mode 100644 index 0000000..94493a2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue @@ -0,0 +1,41 @@ + + + diff --git a/alpha/admin/uni_modules/uni-breadcrumb/package.json b/alpha/admin/uni_modules/uni-breadcrumb/package.json new file mode 100644 index 0000000..e5f33e8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-breadcrumb/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-breadcrumb", + "displayName": "uni-breadcrumb 面包屑", + "version": "0.1.2", + "description": "Breadcrumb 面包屑", + "keywords": [ + "uni-breadcrumb", + "breadcrumb", + "uni-ui", + "面包屑导航", + "面包屑" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-breadcrumb/readme.md b/alpha/admin/uni_modules/uni-breadcrumb/readme.md new file mode 100644 index 0000000..6976b8d --- /dev/null +++ b/alpha/admin/uni_modules/uni-breadcrumb/readme.md @@ -0,0 +1,66 @@ + +## breadcrumb 面包屑导航 +> **组件名:uni-breadcrumb** +> 代码块: `ubreadcrumb` + +显示当前页面的路径,快速返回之前的任意页面。 + +### 安装方式 + +本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 + +如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) + +### 基本用法 + +在 ``template`` 中使用组件 + +```html + + {{route.name}} + +``` + +```js +export default { + name: "uni-stat-breadcrumb", + data() { + return { + routes: [{ + to: '/A', + name: 'A页面' + }, { + to: '/B', + name: 'B页面' + }, { + to: '/C', + name: 'C页面' + }] + }; + } + } +``` + + +## API + +### Breadcrumb Props + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|separator |String |斜杠'/' |分隔符 | +|separatorClass |String | |图标分隔符 class | + +### Breadcrumb Item Props + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|to |String | |路由跳转页面路径 | +|replace|Boolean | |在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录(仅 h5 支持) | + + + + +## 组件示例 + +点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb](https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb) \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-captcha/changelog.md b/alpha/admin/uni_modules/uni-captcha/changelog.md new file mode 100644 index 0000000..fdfea67 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/changelog.md @@ -0,0 +1,37 @@ +## 0.6.4(2023-01-16) +- 修复 部分情况下APP端无法获取验证码的问题 +## 0.6.3(2023-01-11) +- 修复 抖音小程序无法显示的Bug +- 修复 刷新时兼容 device_uuid +## 0.6.1(2022-06-23) +- 修复:部分返回值,不符合响应体规范的问题 +## 0.6.0(2022-05-27) +- 新增:支持在`uni-config-center`中根据场景值配置 +- 修复:弹窗式验证码,输入内容后点击取消,重新打开验证码的值仍然存在的问题 +## 0.5.2(2022-05-19) +- 修复在Vue3的兼容问题 +## 0.5.1(2022-05-18) +- 修复在某些情况下微信小程序端验证码显示错误的问题 +## 0.5.0(2022-05-17) +- 新增支持在`uni-captcha-co`->`config`配置验证码 +## 0.4.1(2022-05-16) +- 新增示例项目 +## 0.4.0(2022-05-16) +- 集成创建、刷新、显示验证码的云端一体验证码组件 +- 云对象`uni-captcha-co`集成获取验证码的api,`getImageCaptcha` +## 0.3.1(2022-05-13) +- 新增 返回值符合响应体规范 +## 0.3.0(2022-05-13) +- 新增 支持 uni-config-center 配置 +## 0.2.2(2022-04-25) +- 修复 0.2.1 版本引起的使用 image 组件验证码不显示的Bug +## 0.2.1(2022-04-18) +- 更新 优化字体 +## 0.2.0(2022-04-14) +- 新增 使用 svg 表现形式更好 +- 新增 使用字体,可以任意替换默认字体 +- 新增 支持设置字体大小 +- 新增 支持忽略某些字符 +- 注意 更新之后请重新上传公共模块 +## 0.1.0(2021-03-01) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue b/alpha/admin/uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue new file mode 100644 index 0000000..3d33343 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue @@ -0,0 +1,167 @@ + + + + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue b/alpha/admin/uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue new file mode 100644 index 0000000..b89b003 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-captcha/package.json b/alpha/admin/uni_modules/uni-captcha/package.json new file mode 100644 index 0000000..ea5c89d --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/package.json @@ -0,0 +1,81 @@ +{ + "id": "uni-captcha", + "displayName": "uni-captcha", + "version": "0.6.4", + "description": "云端一体图形验证码组件", + "keywords": [ + "captcha", + "图形验证码", + "人机验证", + "防刷", + "防脚本" +], + "repository": "https://gitee.com/dcloud/uni-captcha", + "engines": { + "HBuilderX": "^3.1.0" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "unicloud-template-function" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "u" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-captcha/readme.md b/alpha/admin/uni_modules/uni-captcha/readme.md new file mode 100644 index 0000000..d929f63 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/readme.md @@ -0,0 +1,3 @@ +

+文档已移至 uni-captcha文档 +

\ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/LICENSE.md b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/LICENSE.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/fonts/font.ttf b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/fonts/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a60ce88613704bc7fe02dbff52043c3757a0c9d7 GIT binary patch literal 7080 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js new file mode 100644 index 0000000..6e5c3c8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js @@ -0,0 +1 @@ +"use strict";var e=require("assert"),t=require("path");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),r=n(t);const s={10001:"uni-captcha-create-fail",10002:"uni-captcha-verify-fail",10003:"uni-captcha-refresh-fail",10101:"uni-captcha-deviceId-required",10102:"uni-captcha-text-required",10103:"uni-captcha-verify-overdue",10104:"uni-captcha-verify-fail",50403:"uni-captcha-interior-fail"};function a(e){const t=.2*Math.random()-.1;switch(e.type){case"M":case"L":e.x+=t,e.y+=t;break;case"Q":case"C":e.x+=t,e.y+=t,e.x1+=t,e.y1+=t}return e}function i(e,t,n,o,r,s,a){let i,l,c,u,p,h;if(e<=0||e>=1)throw RangeError("spliteCurveAt requires position > 0 && position < 1");return u=[],p=0,i={},l={},c={},i.x=t,i.y=n,l.x=o,l.y=r,c.x=s,c.y=a,h=e,u[p++]=i.x,u[p++]=i.y,u[p++]=i.x+=(l.x-i.x)*h,u[p++]=i.y+=(l.y-i.y)*h,l.x+=(c.x-l.x)*h,l.y+=(c.y-l.y)*h,u[p++]=i.x+(l.x-i.x)*h,u[p++]=i.y+(l.y-i.y)*h,u[p++]=l.x,u[p++]=l.y,u[p++]=c.x,u[p++]=c.y,u}function l(e,t){return Math.random()*(t-e)+e}var c=function(e,t){const n=e[0];o.default(n,"expect a string");const r=t.fontSize,s=r/t.font.unitsPerEm,c=t.font.charToGlyph(n),u=c.advanceWidth?c.advanceWidth*s:0,p=t.x-u/2,h=(t.ascender+t.descender)*s,f=t.y+h/2,d=c.getPath(p,f,r);d.commands.forEach(a),d.commands=function(e,t){const n=[];for(let o=0;ot.truncateLineProbability){const e=l(-.1,.1);n.push(r),n.push({type:"L",x:(r.x+s.x)/2+e,y:(r.y+s.y)/2+e})}else n.push(r)}else if("Q"===r.type&&o>=1){const s=e[o-1];if(("L"===s.type||"M"===s.type)&&Math.random()>t.truncateCurveProbability){const e=s.x,o=s.y,a=l(-.1,.1),c=r.x1+a,u=r.y1+a,p=r.x+a,h=r.y+a,f=i(l(t.truncateCurvePositionMin,t.truncateCurvePositionMax),e,o,c,u,p,h),d={type:"Q",x1:f[2],y1:f[3],x:f[4],y:f[5]},g={type:"L",x:f[4],y:f[5]},m={type:"Q",x1:f[6],y1:f[7],x:f[8],y:f[9]},y={type:"L",x:f[8],y:f[9]};n.push(d),n.push(g),n.push(m),n.push(y)}}else n.push(r)}return n}(d.commands,t);return d.toPathData()};function u(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function p(e,t){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=t,this.destLen=0,this.ltree=new u,this.dtree=new u}var h=new u,f=new u,d=new Uint8Array(30),g=new Uint16Array(30),m=new Uint8Array(30),y=new Uint16Array(30),v=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),b=new u,S=new Uint8Array(320);function x(e,t,n,o){var r,s;for(r=0;r>>=1,t}function O(e,t,n){if(!t)return n;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-t;return e.tag>>>=t,e.bitcount-=t,o+n}function w(e,t){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++r,n+=t.table[r],o-=t.table[r]}while(o>=0);return e.tag=s,e.bitcount-=r,t.trans[n+o]}function k(e,t,n){var o,r,s,a,i,l;for(o=O(e,5,257),r=O(e,5,1),s=O(e,4,4),a=0;a<19;++a)S[a]=0;for(a=0;a8;)e.sourceIndex--,e.bitcount-=8;if((t=256*(t=e.source[e.sourceIndex+1])+e.source[e.sourceIndex])!==(65535&~(256*e.source[e.sourceIndex+3]+e.source[e.sourceIndex+2])))return-3;for(e.sourceIndex+=4,n=t;n;--n)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,0}!function(e,t){var n;for(n=0;n<7;++n)e.table[n]=0;for(e.table[7]=24,e.table[8]=152,e.table[9]=112,n=0;n<24;++n)e.trans[n]=256+n;for(n=0;n<144;++n)e.trans[24+n]=n;for(n=0;n<8;++n)e.trans[168+n]=280+n;for(n=0;n<112;++n)e.trans[176+n]=144+n;for(n=0;n<5;++n)t.table[n]=0;for(t.table[5]=32,n=0;n<32;++n)t.trans[n]=n}(h,f),x(d,g,4,3),x(m,y,2,1),d[28]=0,g[28]=258;var C=function(e,t){var n,o,r=new p(e,t);do{switch(n=E(r),O(r,2,0)){case 0:o=D(r);break;case 1:o=R(r,h,f);break;case 2:k(r,r.ltree,r.dtree),o=R(r,r.ltree,r.dtree);break;default:o=-3}if(0!==o)throw new Error("Data error")}while(!n);return r.destLenthis.x2&&(this.x2=e)),"number"==typeof t&&((isNaN(this.y1)||isNaN(this.y2))&&(this.y1=t,this.y2=t),tthis.y2&&(this.y2=t))},I.prototype.addX=function(e){this.addPoint(e,null)},I.prototype.addY=function(e){this.addPoint(null,e)},I.prototype.addBezier=function(e,t,n,o,r,s,a,i){const l=[e,t],c=[n,o],u=[r,s],p=[a,i];this.addPoint(e,t),this.addPoint(a,i);for(let e=0;e<=1;e++){const t=6*l[e]-12*c[e]+6*u[e],n=-3*l[e]+9*c[e]-9*u[e]+3*p[e],o=3*c[e]-3*l[e];if(0===n){if(0===t)continue;const n=-o/t;0=0&&n>0&&(e+=" "),e+=t(o)}return e}e=void 0!==e?e:2;let o="";for(let e=0;e=0&&e<=255,"Byte value should be between 0 and 255."),[e]},F.BYTE=H(1),A.CHAR=function(e){return[e.charCodeAt(0)]},F.CHAR=H(1),A.CHARARRAY=function(e){const t=[];for(let n=0;n>8&255,255&e]},F.USHORT=H(2),A.SHORT=function(e){return e>=32768&&(e=-(65536-e)),[e>>8&255,255&e]},F.SHORT=H(2),A.UINT24=function(e){return[e>>16&255,e>>8&255,255&e]},F.UINT24=H(3),A.ULONG=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]},F.ULONG=H(4),A.LONG=function(e){return e>=2147483648&&(e=-(4294967296-e)),[e>>24&255,e>>16&255,e>>8&255,255&e]},F.LONG=H(4),A.FIXED=A.ULONG,F.FIXED=F.ULONG,A.FWORD=A.SHORT,F.FWORD=F.SHORT,A.UFWORD=A.USHORT,F.UFWORD=F.USHORT,A.LONGDATETIME=function(e){return[0,0,0,0,e>>24&255,e>>16&255,e>>8&255,255&e]},F.LONGDATETIME=H(8),A.TAG=function(e){return N.argument(4===e.length,"Tag should be exactly 4 ASCII characters."),[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]},F.TAG=H(4),A.Card8=A.BYTE,F.Card8=F.BYTE,A.Card16=A.USHORT,F.Card16=F.USHORT,A.OffSize=A.BYTE,F.OffSize=F.BYTE,A.SID=A.USHORT,F.SID=F.USHORT,A.NUMBER=function(e){return e>=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?A.NUMBER16(e):A.NUMBER32(e)},F.NUMBER=function(e){return A.NUMBER(e).length},A.NUMBER16=function(e){return[28,e>>8&255,255&e]},F.NUMBER16=H(3),A.NUMBER32=function(e){return[29,e>>24&255,e>>16&255,e>>8&255,255&e]},F.NUMBER32=H(5),A.REAL=function(e){let t=e.toString();const n=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(n){const o=parseFloat("1e"+((n[2]?+n[2]:0)+n[1].length));t=(Math.round(e*o)/o).toString()}let o="";for(let e=0,n=t.length;e>8&255,t[t.length]=255&o}return t},F.UTF16=function(e){return 2*e.length};const z={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"};P.MACSTRING=function(e,t,n,o){const r=z[o];if(void 0===r)return;let s="";for(let o=0;o=-128&&e<=127}function X(e,t,n){let o=0;const r=e.length;for(;t>8&255,t+256&255)}return s}A.MACSTRING=function(e,t){const n=function(e){if(!W){W={};for(let e in z)W[e]=new String(e)}const t=W[e];if(void 0===t)return;if(_){const e=_.get(t);if(void 0!==e)return e}const n=z[e];if(void 0===n)return;const o={};for(let e=0;e=128&&(r=n[r],void 0===r))return;o[t]=r}return o},F.MACSTRING=function(e,t){const n=A.MACSTRING(e,t);return void 0!==n?n.length:0},A.VARDELTAS=function(e){let t=0;const n=[];for(;t=-128&&o<=127?V(e,t,n):j(e,t,n)}return n},A.INDEX=function(e){let t=1;const n=[t],o=[];for(let r=0;r>8,t[s+1]=255&a,t=t.concat(o[n])}return t},F.TABLE=function(e){let t=0;const n=e.fields.length;for(let o=0;o0)return new ce(this.data,this.offset+t).parseStruct(e)},ce.prototype.parseListOfLists=function(e){const t=this.parseOffset16List(),n=t.length,o=this.relativeOffset,r=new Array(n);for(let o=0;o=0;r-=1){const n=pe.getUShort(e,t+4+8*r),s=pe.getUShort(e,t+4+8*r+2);if(3===n&&(0===s||1===s||10===s)){o=pe.getULong(e,t+4+8*r+4);break}}if(-1===o)throw new Error("No valid cmap sub-tables found.");const r=new pe.Parser(e,t+o);if(n.format=r.parseUShort(),12===n.format)!function(e,t){let n;t.parseUShort(),e.length=t.parseULong(),e.language=t.parseULong(),e.groupCount=n=t.parseULong(),e.glyphIndexMap={};for(let o=0;o>1,t.skip("uShort",3),e.glyphIndexMap={};const a=new pe.Parser(n,o+r+14),i=new pe.Parser(n,o+r+16+2*s),l=new pe.Parser(n,o+r+16+4*s),c=new pe.Parser(n,o+r+16+6*s);let u=o+r+16+8*s;for(let t=0;t0?(s=e.parseByte(),0==(t&r)&&(s=-s),s=n+s):s=(t&r)>0?n:n+e.parseShort(),s}function Ee(e,t,n){const o=new pe.Parser(t,n);let r,s;if(e.numberOfContours=o.parseShort(),e._xMin=o.parseShort(),e._yMin=o.parseShort(),e._xMax=o.parseShort(),e._yMax=o.parseShort(),e.numberOfContours>0){const t=e.endPointIndices=[];for(let n=0;n0){const t=o.parseByte();for(let n=0;n0){const a=[];let i;if(n>0){for(let e=0;e=0,a.push(i);let e=0;for(let t=0;t0?(2&r)>0?(n.dx=o.parseShort(),n.dy=o.parseShort()):n.matchedPoints=[o.parseUShort(),o.parseUShort()]:(2&r)>0?(n.dx=o.parseChar(),n.dy=o.parseChar()):n.matchedPoints=[o.parseByte(),o.parseByte()],(8&r)>0?n.xScale=n.yScale=o.parseF2Dot14():(64&r)>0?(n.xScale=o.parseF2Dot14(),n.yScale=o.parseF2Dot14()):(128&r)>0&&(n.xScale=o.parseF2Dot14(),n.scale01=o.parseF2Dot14(),n.scale10=o.parseF2Dot14(),n.yScale=o.parseF2Dot14()),e.components.push(n),t=!!(32&r)}if(256&r){e.instructionLength=o.parseUShort(),e.instructions=[];for(let t=0;tt.points.length-1||o.matchedPoints[1]>r.points.length-1)throw Error("Matched points out of range in "+t.name);const n=t.points[o.matchedPoints[0]];let s=r.points[o.matchedPoints[1]];const a={xScale:o.xScale,scale01:o.scale01,scale10:o.scale10,yScale:o.yScale,dx:0,dy:0};s=Oe([s],a)[0],a.dx=n.x-s.x,a.dy=n.y-s.y,e=Oe(r.points,a)}t.points=t.points.concat(e)}}return we(t.points)}var Re={getPath:we,parse:function(e,t,n,o){const r=new Ie.GlyphSet(o);for(let s=0;s>4,s=15&o;if(15===r)break;if(t+=n[r],15===s)break;t+=n[s]}return parseFloat(t)}(e);if(t>=32&&t<=246)return t-139;if(t>=247&&t<=250)return n=e.parseByte(),256*(t-247)+n+108;if(t>=251&&t<=254)return n=e.parseByte(),256*-(t-251)-n-108;throw new Error("Invalid b0 "+t)}function Pe(e,t,n){t=void 0!==t?t:0;const o=new pe.Parser(e,t),r=[];let s=[];for(n=void 0!==n?n:e.length;o.relativeOffset>1,l.length=0,d=!0}return function n(p){let x,U,T,E,O,w,k,R,D,C,L,I,M=0;for(;M1&&!d&&(v=l.shift()+h,d=!0),y+=l.pop(),b(m,y);break;case 5:for(;l.length>0;)m+=l.shift(),y+=l.shift(),i.lineTo(m,y);break;case 6:for(;l.length>0&&(m+=l.shift(),i.lineTo(m,y),0!==l.length);)y+=l.shift(),i.lineTo(m,y);break;case 7:for(;l.length>0&&(y+=l.shift(),i.lineTo(m,y),0!==l.length);)m+=l.shift(),i.lineTo(m,y);break;case 8:for(;l.length>0;)o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 10:O=l.pop()+u,w=c[O],w&&n(w);break;case 11:return;case 12:switch(B=p[M],M+=1,B){case 35:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a+l.shift(),D=k+l.shift(),C=R+l.shift(),L=D+l.shift(),I=C+l.shift(),m=L+l.shift(),y=I+l.shift(),l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 34:o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a,D=k+l.shift(),C=a,L=D+l.shift(),I=y,m=L+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 36:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a,D=k+l.shift(),C=a,L=D+l.shift(),I=C+l.shift(),m=L+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 37:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a+l.shift(),D=k+l.shift(),C=R+l.shift(),L=D+l.shift(),I=C+l.shift(),Math.abs(L-m)>Math.abs(I-y)?m=L+l.shift():y=I+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;default:console.log("Glyph "+t.index+": unknown operator 1200"+B),l.length=0}break;case 14:l.length>0&&!d&&(v=l.shift()+h,d=!0),g&&(i.closePath(),g=!1);break;case 18:S();break;case 19:case 20:S(),M+=f+7>>3;break;case 21:l.length>2&&!d&&(v=l.shift()+h,d=!0),y+=l.pop(),m+=l.pop(),b(m,y);break;case 22:l.length>1&&!d&&(v=l.shift()+h,d=!0),m+=l.pop(),b(m,y);break;case 23:S();break;case 24:for(;l.length>2;)o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);m+=l.shift(),y+=l.shift(),i.lineTo(m,y);break;case 25:for(;l.length>6;)m+=l.shift(),y+=l.shift(),i.lineTo(m,y);o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 26:for(l.length%2&&(m+=l.shift());l.length>0;)o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s,y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 27:for(l.length%2&&(y+=l.shift());l.length>0;)o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a,i.curveTo(o,r,s,a,m,y);break;case 28:x=p[M],U=p[M+1],l.push((x<<24|U<<16)>>16),M+=2;break;case 29:O=l.pop()+e.gsubrsBias,w=e.gsubrs[O],w&&n(w);break;case 30:for(;l.length>0&&(o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y),0!==l.length);)o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),y=a+l.shift(),m=s+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y);break;case 31:for(;l.length>0&&(o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),y=a+l.shift(),m=s+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y),0!==l.length);)o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y);break;default:B<32?console.log("Glyph "+t.index+": unknown operator "+B):B<247?l.push(B-139):B<251?(x=p[M],M+=1,l.push(256*(B-247)+x+108)):B<255?(x=p[M],M+=1,l.push(256*-(B-251)-x-108)):(x=p[M],U=p[M+1],T=p[M+2],E=p[M+3],M+=4,l.push((x<<24|U<<16|T<<8|E)/65536))}}}(n),t.advanceWidth=v,i}function Ve(e,t){let n,o=de.indexOf(e);return o>=0&&(n=o),o=t.indexOf(e),o>=0?n=o+de.length:(n=de.length+t.length,t.push(e)),n}function je(e,t,n){const o={};for(let r=0;r=o)throw new Error("CFF table CID Font FDSelect has bad FD index value "+s+" (FD count "+o+")");r.push(s)}else{if(3!==i)throw new Error("CFF Table CID Font FDSelect table has unsupported format "+i);{const e=a.parseCard16();let t,i=a.parseCard16();if(0!==i)throw new Error("CFF Table CID Font FDSelect format 3 range has bad initial GID "+i);for(let l=0;l=o)throw new Error("CFF table CID Font FDSelect has bad FD index value "+s+" (FD count "+o+")");if(t>n)throw new Error("CFF Table CID Font FDSelect format 3 range has bad GID "+t);for(;i=1&&(n.ulCodePageRange1=o.parseULong(),n.ulCodePageRange2=o.parseULong()),n.version>=2&&(n.sxHeight=o.parseShort(),n.sCapHeight=o.parseShort(),n.usDefaultChar=o.parseUShort(),n.usBreakChar=o.parseUShort(),n.usMaxContent=o.parseUShort()),n},make:function(e){return new oe.Table("OS/2",[{name:"version",type:"USHORT",value:3},{name:"xAvgCharWidth",type:"SHORT",value:0},{name:"usWeightClass",type:"USHORT",value:0},{name:"usWidthClass",type:"USHORT",value:0},{name:"fsType",type:"USHORT",value:0},{name:"ySubscriptXSize",type:"SHORT",value:650},{name:"ySubscriptYSize",type:"SHORT",value:699},{name:"ySubscriptXOffset",type:"SHORT",value:0},{name:"ySubscriptYOffset",type:"SHORT",value:140},{name:"ySuperscriptXSize",type:"SHORT",value:650},{name:"ySuperscriptYSize",type:"SHORT",value:699},{name:"ySuperscriptXOffset",type:"SHORT",value:0},{name:"ySuperscriptYOffset",type:"SHORT",value:479},{name:"yStrikeoutSize",type:"SHORT",value:49},{name:"yStrikeoutPosition",type:"SHORT",value:258},{name:"sFamilyClass",type:"SHORT",value:0},{name:"bFamilyType",type:"BYTE",value:0},{name:"bSerifStyle",type:"BYTE",value:0},{name:"bWeight",type:"BYTE",value:0},{name:"bProportion",type:"BYTE",value:0},{name:"bContrast",type:"BYTE",value:0},{name:"bStrokeVariation",type:"BYTE",value:0},{name:"bArmStyle",type:"BYTE",value:0},{name:"bLetterform",type:"BYTE",value:0},{name:"bMidline",type:"BYTE",value:0},{name:"bXHeight",type:"BYTE",value:0},{name:"ulUnicodeRange1",type:"ULONG",value:0},{name:"ulUnicodeRange2",type:"ULONG",value:0},{name:"ulUnicodeRange3",type:"ULONG",value:0},{name:"ulUnicodeRange4",type:"ULONG",value:0},{name:"achVendID",type:"CHARARRAY",value:"XXXX"},{name:"fsSelection",type:"USHORT",value:0},{name:"usFirstCharIndex",type:"USHORT",value:0},{name:"usLastCharIndex",type:"USHORT",value:0},{name:"sTypoAscender",type:"SHORT",value:0},{name:"sTypoDescender",type:"SHORT",value:0},{name:"sTypoLineGap",type:"SHORT",value:0},{name:"usWinAscent",type:"USHORT",value:0},{name:"usWinDescent",type:"USHORT",value:0},{name:"ulCodePageRange1",type:"ULONG",value:0},{name:"ulCodePageRange2",type:"ULONG",value:0},{name:"sxHeight",type:"SHORT",value:0},{name:"sCapHeight",type:"SHORT",value:0},{name:"usDefaultChar",type:"USHORT",value:0},{name:"usBreakChar",type:"USHORT",value:0},{name:"usMaxContext",type:"USHORT",value:0}],e)},unicodeRanges:gt,getUnicodeRange:function(e){for(let t=0;t=n.begin&&e=ye.length){const e=o.parseChar();n.names.push(o.parseString(e))}break;case 2.5:n.numberOfGlyphs=o.parseUShort(),n.offset=new Array(n.numberOfGlyphs);for(let e=0;et.value.tag?1:-1})),t.fields=t.fields.concat(o),t.fields=t.fields.concat(r),t}function kt(e,t,n){for(let n=0;n0){return e.glyphs.get(o).getMetrics()}}return n}function Rt(e){let t=0;for(let n=0;nm||void 0===l)&&m>0&&(l=m),c 123 are reserved for internal usage");f|=1<0?tt.make(w):void 0,D=yt.make(),C=$e.make(e.glyphs,{version:e.getEnglishName("version"),fullName:T,familyName:x,weightName:U,postScriptName:E,unitsPerEm:e.unitsPerEm,fontBBox:[0,d.yMin,d.ascender,d.advanceWidthMax]}),L=e.metas&&Object.keys(e.metas).length>0?Ut.make(e.metas):void 0,I=[g,m,y,v,k,S,D,C,b];R&&I.push(R),e.tables.gsub&&I.push(xt.make(e.tables.gsub)),L&&I.push(L);const M=wt(I),B=Et(M.encode()),G=M.fields;let N=!1;for(let e=0;e>>1,s=e[r].tag;if(s===t)return r;s>>1,s=e[r];if(s===t)return r;s=0)return o[r].script;if(t){const t={tag:e,script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}};return o.splice(-1-r,0,t),t.script}}},getLangSysTable:function(e,t,n){const o=this.getScriptTable(e,n);if(o){if(!t||"dflt"===t||"DFLT"===t)return o.defaultLangSys;const e=Ct(o.langSysRecords,t);if(e>=0)return o.langSysRecords[e].langSys;if(n){const n={tag:t,langSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]}};return o.langSysRecords.splice(-1-e,0,n),n.langSys}}},getFeatureTable:function(e,t,n,o){const r=this.getLangSysTable(e,t,o);if(r){let e;const t=r.featureIndexes,s=this.font.tables[this.tableName].features;for(let o=0;o=s[o-1].tag,"Features must be added in alphabetical order."),e={tag:n,feature:{params:0,lookupListIndexes:[]}},s.push(e),t.push(o),e.feature}}},getLookupTables:function(e,t,n,o,r){const s=this.getFeatureTable(e,t,n,r),a=[];if(s){let e;const t=s.lookupListIndexes,n=this.font.tables[this.tableName].lookups;for(let r=0;r=0){const e=s.ligatureSets[c];for(let t=0;t0&&e<0?n:o<0&&e>0?-n:e*o},Zt={x:1,y:0,axis:"x",distance:function(e,t,n,o){return(n?e.xo:e.x)-(o?t.xo:t.x)},interpolate:function(e,t,n,o){let r,s,a,i,l,c,u;if(!o||o===this)return r=e.xo-t.xo,s=e.xo-n.xo,l=t.x-t.xo,c=n.x-n.xo,a=Math.abs(r),i=Math.abs(s),u=a+i,0===u?void(e.x=e.xo+(l+c)/2):void(e.x=e.xo+(l*i+c*a)/u);r=o.distance(e,t,!0,!0),s=o.distance(e,n,!0,!0),l=o.distance(t,t,!1,!0),c=o.distance(n,n,!1,!0),a=Math.abs(r),i=Math.abs(s),u=a+i,0!==u?Zt.setRelative(e,e,(l*i+c*a)/u,o,!0):Zt.setRelative(e,e,(l+c)/2,o,!0)},normalSlope:Number.NEGATIVE_INFINITY,setRelative:function(e,t,n,o,r){if(!o||o===this)return void(e.x=(r?t.xo:t.x)+n);const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y;e.x=i+(e.y-l)/o.normalSlope},slope:0,touch:function(e){e.xTouched=!0},touched:function(e){return e.xTouched},untouch:function(e){e.xTouched=!1}},Qt={x:0,y:1,axis:"y",distance:function(e,t,n,o){return(n?e.yo:e.y)-(o?t.yo:t.y)},interpolate:function(e,t,n,o){let r,s,a,i,l,c,u;if(!o||o===this)return r=e.yo-t.yo,s=e.yo-n.yo,l=t.y-t.yo,c=n.y-n.yo,a=Math.abs(r),i=Math.abs(s),u=a+i,0===u?void(e.y=e.yo+(l+c)/2):void(e.y=e.yo+(l*i+c*a)/u);r=o.distance(e,t,!0,!0),s=o.distance(e,n,!0,!0),l=o.distance(t,t,!1,!0),c=o.distance(n,n,!1,!0),a=Math.abs(r),i=Math.abs(s),u=a+i,0!==u?Qt.setRelative(e,e,(l*i+c*a)/u,o,!0):Qt.setRelative(e,e,(l+c)/2,o,!0)},normalSlope:0,setRelative:function(e,t,n,o,r){if(!o||o===this)return void(e.y=(r?t.yo:t.y)+n);const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y;e.y=l+o.normalSlope*(e.x-i)},slope:Number.POSITIVE_INFINITY,touch:function(e){e.yTouched=!0},touched:function(e){return e.yTouched},untouch:function(e){e.yTouched=!1}};function $t(e,t){this.x=e,this.y=t,this.axis=void 0,this.slope=t/e,this.normalSlope=-e/t,Object.freeze(this)}function Kt(e,t){const n=Math.sqrt(e*e+t*t);return t/=n,1===(e/=n)&&0===t?Zt:0===e&&1===t?Qt:new $t(e,t)}function Jt(e,t,n,o){this.x=this.xo=Math.round(64*e)/64,this.y=this.yo=Math.round(64*t)/64,this.lastPointOfContour=n,this.onCurve=o,this.prevPointOnContour=void 0,this.nextPointOnContour=void 0,this.xTouched=!1,this.yTouched=!1,Object.preventExtensions(this)}Object.freeze(Zt),Object.freeze(Qt),$t.prototype.distance=function(e,t,n,o){return this.x*Zt.distance(e,t,n,o)+this.y*Qt.distance(e,t,n,o)},$t.prototype.interpolate=function(e,t,n,o){let r,s,a,i,l,c,u;a=o.distance(e,t,!0,!0),i=o.distance(e,n,!0,!0),r=o.distance(t,t,!1,!0),s=o.distance(n,n,!1,!0),l=Math.abs(a),c=Math.abs(i),u=l+c,0!==u?this.setRelative(e,e,(r*c+s*l)/u,o,!0):this.setRelative(e,e,(r+s)/2,o,!0)},$t.prototype.setRelative=function(e,t,n,o,r){o=o||this;const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y,c=o.normalSlope,u=this.slope,p=e.x,h=e.y;e.x=(u*p-c*i+l-h)/(u-c),e.y=u*(e.x-p)+h},$t.prototype.touch=function(e){e.xTouched=!0,e.yTouched=!0},Jt.prototype.nextTouched=function(e){let t=this.nextPointOnContour;for(;!e.touched(t)&&t!==this;)t=t.nextPointOnContour;return t},Jt.prototype.prevTouched=function(e){let t=this.prevPointOnContour;for(;!e.touched(t)&&t!==this;)t=t.prevPointOnContour;return t};const en=Object.freeze(new Jt(0,0)),tn={cvCutIn:17/16,deltaBase:9,deltaShift:.125,loop:1,minDis:1,autoFlip:!0};function nn(e,t){switch(this.env=e,this.stack=[],this.prog=t,e){case"glyf":this.zp0=this.zp1=this.zp2=1,this.rp0=this.rp1=this.rp2=0;case"prep":this.fv=this.pv=this.dpv=Zt,this.round=Wt}}function on(e){const t=e.tZone=new Array(e.gZone.length);for(let e=0;e=176&&o<=183)r+=o-176+1;else if(o>=184&&o<=191)r+=2*(o-184+1);else if(t&&1===s&&27===o)break}while(s>0);e.ip=r}function sn(e,t){exports.DEBUG&&console.log(t.step,"SVTCA["+e.axis+"]"),t.fv=t.pv=t.dpv=e}function an(e,t){exports.DEBUG&&console.log(t.step,"SPVTCA["+e.axis+"]"),t.pv=t.dpv=e}function ln(e,t){exports.DEBUG&&console.log(t.step,"SFVTCA["+e.axis+"]"),t.fv=e}function cn(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SPVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.pv=t.dpv=Kt(i,l)}function un(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SFVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.fv=Kt(i,l)}function pn(e){exports.DEBUG&&console.log(e.step,"POP[]"),e.stack.pop()}function hn(e,t){const n=t.stack.pop(),o=t.z0[n],r=t.fv,s=t.pv;exports.DEBUG&&console.log(t.step,"MDAP["+e+"]",n);let a=s.distance(o,en);e&&(a=t.round(a)),r.setRelative(o,en,a,s),r.touch(o),t.rp0=t.rp1=n}function fn(e,t){const n=t.z2,o=n.length-2;let r,s,a;exports.DEBUG&&console.log(t.step,"IUP["+e.axis+"]");for(let t=0;t1?"loop "+(t.loop-i)+": ":"")+"SHP["+(e?"rp1":"rp2")+"]",o)}t.loop=1}function gn(e,t){const n=t.stack,o=e?t.rp1:t.rp2,r=(e?t.z0:t.z1)[o],s=t.fv,a=t.pv,i=n.pop(),l=t.z2[t.contours[i]];let c=l;exports.DEBUG&&console.log(t.step,"SHC["+e+"]",i);const u=a.distance(r,r,!1,!0);do{c!==r&&s.setRelative(c,c,u,a),c=c.nextPointOnContour}while(c!==l)}function mn(e,t){const n=t.stack,o=e?t.rp1:t.rp2,r=(e?t.z0:t.z1)[o],s=t.fv,a=t.pv,i=n.pop();let l,c;switch(exports.DEBUG&&console.log(t.step,"SHZ["+e+"]",i),i){case 0:l=t.tZone;break;case 1:l=t.gZone;break;default:throw new Error("Invalid zone")}const u=a.distance(r,r,!1,!0),p=l.length-2;for(let e=0;e",i),t.stack.push(Math.round(64*i))}function xn(e,t){const n=t.stack,o=n.pop(),r=t.fv,s=t.pv,a=t.ppem,i=t.deltaBase+16*(e-1),l=t.deltaShift,c=t.z0;exports.DEBUG&&console.log(t.step,"DELTAP["+e+"]",o,n);for(let e=0;e>4)!==a)continue;let u=(15&o)-8;u>=0&&u++,exports.DEBUG&&console.log(t.step,"DELTAPFIX",e,"by",u*l);const p=c[e];r.setRelative(p,p,u*l,s)}}function Un(e,t){const n=t.stack,o=n.pop();exports.DEBUG&&console.log(t.step,"ROUND[]"),n.push(64*t.round(o/64))}function Tn(e,t){const n=t.stack,o=n.pop(),r=t.ppem,s=t.deltaBase+16*(e-1),a=t.deltaShift;exports.DEBUG&&console.log(t.step,"DELTAC["+e+"]",o,n);for(let e=0;e>4)!==r)continue;let i=(15&o)-8;i>=0&&i++;const l=i*a;exports.DEBUG&&console.log(t.step,"DELTACFIX",e,"by",l),t.cvt[e]+=l}}function En(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SDPVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.dpv=Kt(i,l)}function On(e,t){const n=t.stack,o=t.prog;let r=t.ip;exports.DEBUG&&console.log(t.step,"PUSHB["+e+"]");for(let t=0;t=0?1:-1,m=Math.abs(m),e&&(v=s.cvt[i],o&&Math.abs(m-v)":"_")+(o?"R":"_")+(0===r?"Gr":1===r?"Bl":2===r?"Wh":"")+"]",e?i+"("+s.cvt[i]+","+v+")":"",l,"(d =",g,"->",y*m,")"),s.rp1=s.rp0,s.rp2=l,t&&(s.rp0=l)}function Rn(e){(e=e||{}).empty||(Nt(e.familyName,"When creating a new Font object, familyName is required."),Nt(e.styleName,"When creating a new Font object, styleName is required."),Nt(e.unitsPerEm,"When creating a new Font object, unitsPerEm is required."),Nt(e.ascender,"When creating a new Font object, ascender is required."),Nt(e.descender,"When creating a new Font object, descender is required."),Nt(e.descender<0,"Descender should be negative (e.g. -512)."),this.names={fontFamily:{en:e.familyName||" "},fontSubfamily:{en:e.styleName||" "},fullName:{en:e.fullName||e.familyName+" "+e.styleName},postScriptName:{en:e.postScriptName||e.familyName+e.styleName},designer:{en:e.designer||" "},designerURL:{en:e.designerURL||" "},manufacturer:{en:e.manufacturer||" "},manufacturerURL:{en:e.manufacturerURL||" "},license:{en:e.license||" "},licenseURL:{en:e.licenseURL||" "},version:{en:e.version||"Version 0.1"},description:{en:e.description||" "},copyright:{en:e.copyright||" "},trademark:{en:e.trademark||" "}},this.unitsPerEm=e.unitsPerEm||1e3,this.ascender=e.ascender,this.descender=e.descender,this.createdTimestamp=e.createdTimestamp,this.tables={os2:{usWeightClass:e.weightClass||this.usWeightClasses.MEDIUM,usWidthClass:e.widthClass||this.usWidthClasses.MEDIUM,fsSelection:e.fsSelection||this.fsSelectionValues.REGULAR}}),this.supported=!0,this.glyphs=new Ie.GlyphSet(this,e.glyphs||[]),this.encoding=new ve(this),this.substitution=new It(this),this.tables=this.tables||{},Object.defineProperty(this,"hinting",{get:function(){return this._hinting?this._hinting:"truetype"===this.outlinesFormat?this._hinting=new zt(this):void 0}})}function Dn(e,t){const n=JSON.stringify(e);let o=256;for(let e in t){let r=parseInt(e);if(r&&!(r<256)){if(JSON.stringify(t[e])===n)return r;o<=r&&(o=r+1)}}return t[o]=e,o}function Cn(e,t,n){const o=Dn(t.name,n);return[{name:"tag_"+e,type:"TAG",value:t.tag},{name:"minValue_"+e,type:"FIXED",value:t.minValue<<16},{name:"defaultValue_"+e,type:"FIXED",value:t.defaultValue<<16},{name:"maxValue_"+e,type:"FIXED",value:t.maxValue<<16},{name:"flags_"+e,type:"USHORT",value:0},{name:"nameID_"+e,type:"USHORT",value:o}]}function Ln(e,t,n){const o={},r=new pe.Parser(e,t);return o.tag=r.parseTag(),o.minValue=r.parseFixed(),o.defaultValue=r.parseFixed(),o.maxValue=r.parseFixed(),r.skip("uShort",1),o.name=n[r.parseUShort()]||{},o}function In(e,t,n,o){const r=[{name:"nameID_"+e,type:"USHORT",value:Dn(t.name,o)},{name:"flags_"+e,type:"USHORT",value:0}];for(let o=0;o2)return;const n=this.font;let o=this._prepState;if(!o||o.ppem!==t){let e=this._fpgmState;if(!e){nn.prototype=tn,e=this._fpgmState=new nn("fpgm",n.tables.fpgm),e.funcs=[],e.font=n,exports.DEBUG&&(console.log("---EXEC FPGM---"),e.step=-1);try{At(e)}catch(e){return console.log("Hinting error in FPGM:"+e),void(this._errorState=3)}}nn.prototype=e,o=this._prepState=new nn("prep",n.tables.prep),o.ppem=t;const r=n.tables.cvt;if(r){const e=o.cvt=new Array(r.length),s=t/n.unitsPerEm;for(let t=0;t1))try{return Ft(e,o)}catch(e){return this._errorState<1&&(console.log("Hinting error:"+e),console.log("Note: further hinting errors are silenced")),void(this._errorState=1)}},Ft=function(e,t){const n=t.ppem/t.font.unitsPerEm,o=n;let r,s,a,i=e.components;if(nn.prototype=t,i){const l=t.font;s=[],r=[];for(let e=0;e1?"loop "+(e.loop-n)+": ":"")+"SHPIX[]",a,r),o.setRelative(i,i,r),o.touch(i)}e.loop=1},function(e){const t=e.stack,n=e.rp1,o=e.rp2;let r=e.loop;const s=e.z0[n],a=e.z1[o],i=e.fv,l=e.dpv,c=e.z2;for(;r--;){const u=t.pop(),p=c[u];exports.DEBUG&&console.log(e.step,(e.loop>1?"loop "+(e.loop-r)+": ":"")+"IP[]",u,n,"<->",o),i.interpolate(p,s,a,l),i.touch(p)}e.loop=1},yn.bind(void 0,0),yn.bind(void 0,1),function(e){const t=e.stack,n=e.rp0,o=e.z0[n];let r=e.loop;const s=e.fv,a=e.pv,i=e.z1;for(;r--;){const n=t.pop(),l=i[n];exports.DEBUG&&console.log(e.step,(e.loop>1?"loop "+(e.loop-r)+": ":"")+"ALIGNRP[]",n),s.setRelative(l,o,0,a),s.touch(l)}e.loop=1},function(e){exports.DEBUG&&console.log(e.step,"RTDG[]"),e.round=qt},vn.bind(void 0,0),vn.bind(void 0,1),function(e){const t=e.prog;let n=e.ip;const o=e.stack,r=t[++n];exports.DEBUG&&console.log(e.step,"NPUSHB[]",r);for(let e=0;en?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"GTEQ[]",n,o),t.push(o>=n?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"EQ[]",n,o),t.push(n===o?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"NEQ[]",n,o),t.push(n!==o?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"ODD[]",n),t.push(Math.trunc(n)%2?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"EVEN[]",n),t.push(Math.trunc(n)%2?0:1)},function(e){let t=e.stack.pop();exports.DEBUG&&console.log(e.step,"IF[]",t),t||(rn(e,!0),exports.DEBUG&&console.log(e.step,"EIF[]"))},function(e){exports.DEBUG&&console.log(e.step,"EIF[]")},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"AND[]",n,o),t.push(n&&o?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"OR[]",n,o),t.push(n||o?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"NOT[]",n),t.push(n?0:1)},xn.bind(void 0,1),function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SDB[]",t),e.deltaBase=t},function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SDS[]",t),e.deltaShift=Math.pow(.5,t)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"ADD[]",n,o),t.push(o+n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"SUB[]",n,o),t.push(o-n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"DIV[]",n,o),t.push(64*o/n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MUL[]",n,o),t.push(o*n/64)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"ABS[]",n),t.push(Math.abs(n))},function(e){const t=e.stack;let n=t.pop();exports.DEBUG&&console.log(e.step,"NEG[]",n),t.push(-n)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"FLOOR[]",n),t.push(64*Math.floor(n/64))},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"CEILING[]",n),t.push(64*Math.ceil(n/64))},Un.bind(void 0,0),Un.bind(void 0,1),Un.bind(void 0,2),Un.bind(void 0,3),void 0,void 0,void 0,void 0,function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"WCVTF[]",n,o),e.cvt[o]=n*e.ppem/e.font.unitsPerEm},xn.bind(void 0,2),xn.bind(void 0,3),Tn.bind(void 0,1),Tn.bind(void 0,2),Tn.bind(void 0,3),function(e){let t,n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"SROUND[]",n),e.round=Yt,192&n){case 0:t=.5;break;case 64:t=1;break;case 128:t=2;break;default:throw new Error("invalid SROUND value")}switch(e.srPeriod=t,48&n){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*t;break;case 32:e.srPhase=.5*t;break;case 48:e.srPhase=.75*t;break;default:throw new Error("invalid SROUND value")}n&=15,e.srThreshold=0===n?0:(n/8-.5)*t},function(e){let t,n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"S45ROUND[]",n),e.round=Yt,192&n){case 0:t=Math.sqrt(2)/2;break;case 64:t=Math.sqrt(2);break;case 128:t=2*Math.sqrt(2);break;default:throw new Error("invalid S45ROUND value")}switch(e.srPeriod=t,48&n){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*t;break;case 32:e.srPhase=.5*t;break;case 48:e.srPhase=.75*t;break;default:throw new Error("invalid S45ROUND value")}n&=15,e.srThreshold=0===n?0:(n/8-.5)*t},void 0,void 0,function(e){exports.DEBUG&&console.log(e.step,"ROFF[]"),e.round=_t},void 0,function(e){exports.DEBUG&&console.log(e.step,"RUTG[]"),e.round=Vt},function(e){exports.DEBUG&&console.log(e.step,"RDTG[]"),e.round=jt},pn,pn,void 0,void 0,void 0,void 0,void 0,function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SCANCTRL[]",t)},En.bind(void 0,0),En.bind(void 0,1),function(e){const t=e.stack,n=t.pop();let o=0;exports.DEBUG&&console.log(e.step,"GETINFO[]",n),1&n&&(o=35),32&n&&(o|=4096),t.push(o)},void 0,function(e){const t=e.stack,n=t.pop(),o=t.pop(),r=t.pop();exports.DEBUG&&console.log(e.step,"ROLL[]"),t.push(o),t.push(n),t.push(r)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MAX[]",n,o),t.push(Math.max(o,n))},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MIN[]",n,o),t.push(Math.min(o,n))},function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SCANTYPE[]",t)},function(e){const t=e.stack.pop();let n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"INSTCTRL[]",t,n),t){case 1:return void(e.inhibitGridFit=!!n);case 2:return void(e.ignoreCvt=!!n);default:throw new Error("invalid INSTCTRL[] selector")}},void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,On.bind(void 0,1),On.bind(void 0,2),On.bind(void 0,3),On.bind(void 0,4),On.bind(void 0,5),On.bind(void 0,6),On.bind(void 0,7),On.bind(void 0,8),wn.bind(void 0,1),wn.bind(void 0,2),wn.bind(void 0,3),wn.bind(void 0,4),wn.bind(void 0,5),wn.bind(void 0,6),wn.bind(void 0,7),wn.bind(void 0,8),kn.bind(void 0,0,0,0,0,0),kn.bind(void 0,0,0,0,0,1),kn.bind(void 0,0,0,0,0,2),kn.bind(void 0,0,0,0,0,3),kn.bind(void 0,0,0,0,1,0),kn.bind(void 0,0,0,0,1,1),kn.bind(void 0,0,0,0,1,2),kn.bind(void 0,0,0,0,1,3),kn.bind(void 0,0,0,1,0,0),kn.bind(void 0,0,0,1,0,1),kn.bind(void 0,0,0,1,0,2),kn.bind(void 0,0,0,1,0,3),kn.bind(void 0,0,0,1,1,0),kn.bind(void 0,0,0,1,1,1),kn.bind(void 0,0,0,1,1,2),kn.bind(void 0,0,0,1,1,3),kn.bind(void 0,0,1,0,0,0),kn.bind(void 0,0,1,0,0,1),kn.bind(void 0,0,1,0,0,2),kn.bind(void 0,0,1,0,0,3),kn.bind(void 0,0,1,0,1,0),kn.bind(void 0,0,1,0,1,1),kn.bind(void 0,0,1,0,1,2),kn.bind(void 0,0,1,0,1,3),kn.bind(void 0,0,1,1,0,0),kn.bind(void 0,0,1,1,0,1),kn.bind(void 0,0,1,1,0,2),kn.bind(void 0,0,1,1,0,3),kn.bind(void 0,0,1,1,1,0),kn.bind(void 0,0,1,1,1,1),kn.bind(void 0,0,1,1,1,2),kn.bind(void 0,0,1,1,1,3),kn.bind(void 0,1,0,0,0,0),kn.bind(void 0,1,0,0,0,1),kn.bind(void 0,1,0,0,0,2),kn.bind(void 0,1,0,0,0,3),kn.bind(void 0,1,0,0,1,0),kn.bind(void 0,1,0,0,1,1),kn.bind(void 0,1,0,0,1,2),kn.bind(void 0,1,0,0,1,3),kn.bind(void 0,1,0,1,0,0),kn.bind(void 0,1,0,1,0,1),kn.bind(void 0,1,0,1,0,2),kn.bind(void 0,1,0,1,0,3),kn.bind(void 0,1,0,1,1,0),kn.bind(void 0,1,0,1,1,1),kn.bind(void 0,1,0,1,1,2),kn.bind(void 0,1,0,1,1,3),kn.bind(void 0,1,1,0,0,0),kn.bind(void 0,1,1,0,0,1),kn.bind(void 0,1,1,0,0,2),kn.bind(void 0,1,1,0,0,3),kn.bind(void 0,1,1,0,1,0),kn.bind(void 0,1,1,0,1,1),kn.bind(void 0,1,1,0,1,2),kn.bind(void 0,1,1,0,1,3),kn.bind(void 0,1,1,1,0,0),kn.bind(void 0,1,1,1,0,1),kn.bind(void 0,1,1,1,0,2),kn.bind(void 0,1,1,1,0,3),kn.bind(void 0,1,1,1,1,0),kn.bind(void 0,1,1,1,1,1),kn.bind(void 0,1,1,1,1,2),kn.bind(void 0,1,1,1,1,3)],Rn.prototype.hasChar=function(e){return null!==this.encoding.charToGlyphIndex(e)},Rn.prototype.charToGlyphIndex=function(e){return this.encoding.charToGlyphIndex(e)},Rn.prototype.charToGlyph=function(e){const t=this.charToGlyphIndex(e);let n=this.glyphs.get(t);return n||(n=this.glyphs.get(0)),n},Rn.prototype.stringToGlyphs=function(e,t){t=t||this.defaultRenderOptions;const n=[];for(let t=0;t>1;e1&&console.warn("Only the first kern subtable is supported."),e.skip("uLong");const n=255&e.parseUShort();if(e.skip("uShort"),0===n){const n=e.parseUShort();e.skip("uShort",3);for(let o=0;o{const t=jn.loadSync(e);Qn.font=t,Qn.ascender=t.ascender,Qn.descender=t.descender}};const Kn=$n.options,Jn=function(e,t){return Math.round(e+Math.random()*(t-e))};const eo=function(e,t){return{text:(e+t).toString(),equation:e+"+"+t}},to=function(e,t){return{text:(e-t).toString(),equation:e+"-"+t}};function no(e,t,n){return 6*(n=(n+1)%1)<1?e+(t-e)*n*6:2*n<1?t:3*n<2?e+(t-e)*(2/3-n)*6:e}var oo={int:Jn,greyColor:function(e,t){const n=Jn(e=e||1,t=t||9).toString(16);return`#${n}${n}${n}`},captchaText:function(e){"number"==typeof e&&(e={size:e});const t=(e=e||{}).size||4,n=e.ignoreChars||"";let o=-1,r="",s=e.charPreset||Kn.charPreset;n&&(s=function(e,t){return e.split("").filter(e=>-1===t.indexOf(e))}(s,n));const a=s.length-1;for(;++o>16,o=t>>8&255,r=255&t,s=Math.max(n,o,r),a=Math.min(n,o,r);return(s+a)/510}(e):1;let r,s;o>=.5?(r=Math.round(100*o)-45,s=Math.round(100*o)-25):(r=Math.round(100*o)+25,s=Math.round(100*o)+45);const a=Jn(r,s)/100,i=a<.5?a*(a+n):a+n-a*n,l=2*a-i,c=Math.floor(255*no(l,i,t+1/3)),u=Math.floor(255*no(l,i,t));return"#"+(Math.floor(255*no(l,i,t-1/3))|u<<8|c<<16|1<<24).toString(16).slice(1)}};const ro=$n.options,so=function(e,t){e=e||oo.captchaText();const n=(t=Object.assign({},ro,t)).width,o=t.height,r=t.background||t.backgroundColor;r&&(t.color=!0);const s=r?``:"",a=[].concat(function(e,t,n){const o=n.color,r=[],s=n.inverse?7:1,a=n.inverse?15:9;let i=-1;for(;++i`)}return r}(n,o,t)).concat(function(e,t,n,o,r){const s=e.length,a=(t-2)/(s+1),i=o.inverse?10:0,l=o.inverse?14:4;let u=-1;const p=[],h=r||o.color?oo.color(o.background):oo.greyColor(i,l);for(;++u`)}return p}(e,n,o,t)).sort(()=>Math.random()-.5).join("");return`${``}${s}${a}`};var ao=so,io=oo.captchaText,lo=function(e){const t=e.text||oo.captchaText(e);return{text:t,data:so(t,e)}},co=function(e){const t=oo.mathExpr(e.mathMin,e.mathMax,e.mathOperator);return{text:t.text,data:so(t.equation,e)}},uo=ro,po=$n.loadFont;ao.randomText=io,ao.create=lo,ao.createMathExpr=co,ao.options=uo,ao.loadFont=po;var ho=ao;const fo=Object.prototype.toString;function go(e){return"[object Object]"===fo.call(e)}function mo(){"development"===process.env.NODE_ENV&&console.log(...arguments)}const yo=async function(){};function vo(e){return yo.constructor===e.constructor?async function(){const t=await e.apply(this,arguments);return go(t)&&(t.msg&&(t.message=t.msg,t.errMsg=t.msg),0===t.code?t.errCode=t.code:t.errCode=s[t.code]||t.code),t}:function(){const t=e.apply(this,arguments);return go(t)&&(t.msg&&(t.message=t.msg,t.errMsg=t.msg),0===t.code?t.errCode=t.code:t.errCode=s[t.code]||t.code),t}}const bo=uniCloud.database(),So=bo.collection("opendb-verify-codes");class xo{async setVerifyCode({clientIP:e,deviceId:t,code:n,expiresDate:o,scene:r}){if(!t)return{code:10101,msg:"deviceId不可为空"};if(!n)return{code:10102,msg:"验证码不可为空"};o||(o=180);const s=Date.now(),a={device_uuid:t,scene:r,code:n.toLocaleLowerCase(),state:0,ip:e,created_date:s,expired_date:s+1e3*o};return mo("addRes",await So.add(a)),{code:0,deviceId:t}}async verifyCode({deviceId:e,code:t,scene:n}){if(!e)return{code:10101,msg:"deviceId不可为空"};if(!t)return{code:10102,msg:"验证码不可为空"};const o=Date.now(),r={device_uuid:e,scene:n,code:t.toLocaleLowerCase(),state:0},s=await So.where(r).orderBy("created_date","desc").limit(1).get();if(mo("verifyRecord:",s),s&&s.data&&s.data.length>0){const e=s.data[0];if(e.expired_date{e.scene&&delete e.scene,this.pluginConfig.scene[n]=Object.assign({},t,e[n])})}}}{constructor(){super(),this.DEVICEID2opts={}}mergeConfig(e){const t=go(this.pluginConfig.scene)?this.pluginConfig.scene[e.scene]:e.scene;return Object.assign({},go(t)?t:this.pluginConfig,e)}async create(e={}){if(!e.scene)throw new Error("scene验证码场景不可为空");e=this.mergeConfig(e);let{scene:t,expiresDate:n,deviceId:o,clientIP:r,...s}=e;if(o=o||__ctx__.DEVICEID,r=r||__ctx__.CLIENTIP,!o)throw new Error("deviceId不可为空");const a=new xo;try{const{text:i,base64:l}=function(e={}){const{uniPlatform:t=""}=e;let n;n=e.mathExpr?ho.createMathExpr(e):ho.create(e);let o="data:image/svg+xml;utf8,"+n.data.replace(/#/g,"%23");return(!t||["mp-toutiao","h5","web","app","app-plus"].indexOf(t)>-1)&&(o=o.replace(/"/g,"'").replace(//g,"%3E")),{text:n.text,base64:o}}(s),c=await a.setVerifyCode({clientIP:r,deviceId:o,code:i,expiresDate:n,scene:t});return c.code>0?{...c,code:10001}:(this.DEVICEID2opts[o]=e,{code:0,msg:"验证码获取成功",captchaBase64:l})}catch(e){return{code:10001,msg:"验证码生成失败:"+e.message}}}async verify({deviceId:e,captcha:t,scene:n}){if(!(e=e||__ctx__.DEVICEID))throw new Error("deviceId不可为空");if(!n)throw new Error("scene验证码场景不可为空");const o=new xo;try{const r=await o.verifyCode({deviceId:e,code:t,scene:n});return r.code>0?r:{code:0,msg:"验证码通过"}}catch(e){return{code:10002,msg:"验证码校验失败:"+e.message}}}async refresh(e={}){let{scene:t,expiresDate:n,deviceId:o,...r}=e;if(o=o||__ctx__.DEVICEID,!o)throw new Error("deviceId不可为空");if(!t)throw new Error("scene验证码场景不可为空");const s=await So.where(bo.command.or([{device_uuid:o,scene:t},{deviceId:o,scene:t}])).orderBy("created_date","desc").limit(1).get();if(s&&s.data&&s.data.length>0){const e=s.data[0];await So.doc(e._id).update({state:2}),Object.keys(r).length>0&&(this.DEVICEID2opts[o]=Object.assign({},this.DEVICEID2opts[o],r));let a={};try{a=await this.create(Object.assign({},this.DEVICEID2opts[o],{deviceId:o,scene:t,expiresDate:n}))}catch(e){return{code:50403,msg:e.message}}return a.code>0?{...a,code:50403}:{code:0,msg:"验证码刷新成功",captchaBase64:a.captchaBase64}}return{code:10003,msg:`验证码刷新失败:无此设备在 ${t} 场景信息,请重新获取`}}}const Eo=new xo;Object.keys(Eo).forEach(e=>{To.prototype[e]=vo(Eo[e])});const Oo=new To,wo=new Proxy(Oo,{get(e,t){if(t in e)return"function"==typeof e[t]?vo(e[t]).bind(wo):e[t]}});module.exports=wo; diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t uni-config-center + return await uniCaptcha[action]({ + scene, //来源客户端传递,表示:使用场景值,用于防止不同功能的验证码混用 + uniPlatform: platform + }) + } +} diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/package.json b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/package.json new file mode 100644 index 0000000..b5188c3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/package.json @@ -0,0 +1,10 @@ +{ + "name": "uni-captcha-co", + "dependencies": { + "uni-captcha": "file:../common/uni-captcha", + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "extensions": { + "uni-cloud-jql": {} + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-captcha/uniCloud/database/opendb-verify-codes.schema.json b/alpha/admin/uni_modules/uni-captcha/uniCloud/database/opendb-verify-codes.schema.json new file mode 100644 index 0000000..1f3be59 --- /dev/null +++ b/alpha/admin/uni_modules/uni-captcha/uniCloud/database/opendb-verify-codes.schema.json @@ -0,0 +1,45 @@ +{ + "bsonType": "object", + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "code": { + "bsonType": "string", + "description": "验证码" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间" + }, + "device_uuid": { + "bsonType": "string", + "description": "设备UUID,常用于图片验证码" + }, + "email": { + "bsonType": "string", + "description": "邮箱" + }, + "expired_date": { + "bsonType": "timestamp", + "description": "过期时间" + }, + "ip": { + "bsonType": "string", + "description": "请求时客户端IP地址" + }, + "mobile": { + "bsonType": "string", + "description": "手机号码" + }, + "scene": { + "bsonType": "string", + "description": "使用验证码的场景,如:login, bind, unbind, pay" + }, + "state": { + "bsonType": "int", + "description": "验证状态:0 未验证、1 已验证、2 已作废" + } + }, + "required": [] +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-card/changelog.md b/alpha/admin/uni_modules/uni-card/changelog.md new file mode 100644 index 0000000..c3cd8c4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-card/changelog.md @@ -0,0 +1,26 @@ +## 1.3.1(2021-12-20) +- 修复 在vue页面下略缩图显示不正常的bug +## 1.3.0(2021-11-19) +- 重构插槽的用法 ,header 替换为 title +- 新增 actions 插槽 +- 新增 cover 封面图属性和插槽 +- 新增 padding 内容默认内边距离 +- 新增 margin 卡片默认外边距离 +- 新增 spacing 卡片默认内边距 +- 新增 shadow 卡片阴影属性 +- 取消 mode 属性,可使用组合插槽代替 +- 取消 note 属性 ,使用actions插槽代替 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card) +## 1.2.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.2.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.8(2021-07-01) +- 优化 图文卡片无图片加载时,提供占位图标 +- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持) +- 修复 thumbnail 不存在仍然占位的 bug +## 1.1.7(2021-05-12) +- 新增 组件示例地址 +## 1.1.6(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-card/components/uni-card/uni-card.vue b/alpha/admin/uni_modules/uni-card/components/uni-card/uni-card.vue new file mode 100644 index 0000000..38cf594 --- /dev/null +++ b/alpha/admin/uni_modules/uni-card/components/uni-card/uni-card.vue @@ -0,0 +1,270 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-card/package.json b/alpha/admin/uni_modules/uni-card/package.json new file mode 100644 index 0000000..f16224d --- /dev/null +++ b/alpha/admin/uni_modules/uni-card/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-card", + "displayName": "uni-card 卡片", + "version": "1.3.1", + "description": "Card 组件,提供常见的卡片样式。", + "keywords": [ + "uni-ui", + "uniui", + "card", + "", + "卡片" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [ + "uni-icons", + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-card/readme.md b/alpha/admin/uni_modules/uni-card/readme.md new file mode 100644 index 0000000..7434e71 --- /dev/null +++ b/alpha/admin/uni_modules/uni-card/readme.md @@ -0,0 +1,12 @@ + + +## Card 卡片 +> **组件名:uni-card** +> 代码块: `uCard` + +卡片视图组件。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-cloud-router/changelog.md b/alpha/admin/uni_modules/uni-cloud-router/changelog.md new file mode 100644 index 0000000..e3ff73b --- /dev/null +++ b/alpha/admin/uni_modules/uni-cloud-router/changelog.md @@ -0,0 +1,4 @@ +## 1.0.3(2021-02-02) +- 修复 package.json 丢失 +## 1.0.2(2021-02-02) +- 支持 uni_modules diff --git a/alpha/admin/uni_modules/uni-cloud-router/package.json b/alpha/admin/uni_modules/uni-cloud-router/package.json new file mode 100644 index 0000000..8609e8f --- /dev/null +++ b/alpha/admin/uni_modules/uni-cloud-router/package.json @@ -0,0 +1,80 @@ +{ + "id": "uni-cloud-router", + "name": "uni-cloud-router", + "displayName": "uni-cloud-router", + "version": "1.0.3", + "description": " 基于 koa 风格的 uniCloud 云函数路由库,同时支持 uniCloud 客户端及 URL", + "keywords": [ + "云函数路由", + "uniCloud", + "uni-cloud-router" + ], + "repository": "https://gitee.com/dcloud/uni-cloud-router", + "engines": { + "HBuilderX": "^3.1.0" + }, + "files": ["uniCloud", "changelog.md", "readme.md"], + "dcloudext": { + "category": [ + "uniCloud", + "云函数模板" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/uni-cloud-router" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-cloud-router/readme.md b/alpha/admin/uni_modules/uni-cloud-router/readme.md new file mode 100644 index 0000000..0bf1eda --- /dev/null +++ b/alpha/admin/uni_modules/uni-cloud-router/readme.md @@ -0,0 +1 @@ +## 文档已迁移至[uni-cloud-router 文档](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-router) \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-combox/changelog.md b/alpha/admin/uni_modules/uni-combox/changelog.md new file mode 100644 index 0000000..23c2748 --- /dev/null +++ b/alpha/admin/uni_modules/uni-combox/changelog.md @@ -0,0 +1,15 @@ +## 1.0.1(2021-11-23) +- 优化 label、label-width 属性 +## 1.0.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-combox](https://uniapp.dcloud.io/component/uniui/uni-combox) +## 0.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 0.0.6(2021-05-12) +- 新增 组件示例地址 +## 0.0.5(2021-04-21) +- 优化 添加依赖 uni-icons, 导入后自动下载依赖 +## 0.0.4(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 0.0.3(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-combox/components/uni-combox/uni-combox.vue b/alpha/admin/uni_modules/uni-combox/components/uni-combox/uni-combox.vue new file mode 100644 index 0000000..3d70647 --- /dev/null +++ b/alpha/admin/uni_modules/uni-combox/components/uni-combox/uni-combox.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-combox/package.json b/alpha/admin/uni_modules/uni-combox/package.json new file mode 100644 index 0000000..4a05c3f --- /dev/null +++ b/alpha/admin/uni_modules/uni-combox/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-combox", + "displayName": "uni-combox 组合框", + "version": "1.0.1", + "description": "可以选择也可以输入的表单项 ", + "keywords": [ + "uni-ui", + "uniui", + "combox", + "组合框", + "select" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-combox/readme.md b/alpha/admin/uni_modules/uni-combox/readme.md new file mode 100644 index 0000000..ffa2cc8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-combox/readme.md @@ -0,0 +1,11 @@ + + +## Combox 组合框 +> **组件名:uni-combox** +> 代码块: `uCombox` + + +组合框组件。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-config-center/changelog.md b/alpha/admin/uni_modules/uni-config-center/changelog.md new file mode 100644 index 0000000..57dbcb5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-config-center/changelog.md @@ -0,0 +1,6 @@ +## 0.0.3(2022-11-11) +- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug +## 0.0.2(2021-04-16) +- 修改插件package信息 +## 0.0.1(2021-03-15) +- 初始化项目 diff --git a/alpha/admin/uni_modules/uni-config-center/package.json b/alpha/admin/uni_modules/uni-config-center/package.json new file mode 100644 index 0000000..bace866 --- /dev/null +++ b/alpha/admin/uni_modules/uni-config-center/package.json @@ -0,0 +1,81 @@ +{ + "id": "uni-config-center", + "displayName": "uni-config-center", + "version": "0.0.3", + "description": "uniCloud 配置中心", + "keywords": [ + "配置", + "配置中心" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "unicloud-template-function" + }, + "directories": { + "example": "../../../scripts/dist" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "u" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-config-center/readme.md b/alpha/admin/uni_modules/uni-config-center/readme.md new file mode 100644 index 0000000..03f7fc2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-config-center/readme.md @@ -0,0 +1,93 @@ +# 为什么使用uni-config-center + +实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构 + +```bash +cloudfunctions +└─────common 公共模块 + ├─plugin-a // 插件A对应的目录 + │ ├─index.js + │ ├─config.json // plugin-a对应的配置文件 + │ └─other-file.cert // plugin-a依赖的其他文件 + └─plugin-b // plugin-b对应的目录 + ├─index.js + └─config.json // plugin-b对应的配置文件 +``` + +假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。 + +uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下 + +```bash +cloudfunctions +└─────common 公共模块 + ├─plugin-a // 插件A对应的目录 + │ └─index.js + ├─plugin-b // plugin-b对应的目录 + │ └─index.js + └─uni-config-center + ├─index.js // config-center入口文件 + ├─plugin-a + │ ├─config.json // plugin-a对应的配置文件 + │ └─other-file.cert // plugin-a依赖的其他文件 + └─plugin-b + └─config.json // plugin-b对应的配置文件 +``` + +使用uni-config-center后的优势 + +- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便 +- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持) + +# 用法 + +在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common) + +```js +const createConfig = require('uni-config-center') + +const uniIdConfig = createConfig({ + pluginId: 'uni-id', // 插件id + defaultConfig: { // 默认配置 + tokenExpiresIn: 7200, + tokenExpiresThreshold: 600, + }, + customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并 + // defaudltConfig 默认配置 + // userConfig 用户配置 + return Object.assign(defaultConfig, userConfig) + } +}) + + +// 以如下配置为例 +// { +// "tokenExpiresIn": 7200, +// "passwordErrorLimit": 6, +// "bindTokenToDevice": false, +// "passwordErrorRetryTime": 3600, +// "app-plus": { +// "tokenExpiresIn": 2592000 +// }, +// "service": { +// "sms": { +// "codeExpiresIn": 300 +// } +// } +// } + +// 获取配置 +uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象 +uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200 +uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300 +uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600 + +// 获取文件绝对路径 +uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径 + +// 引用文件(require) +uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。 + +// 判断是否包含某文件 +uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在 +``` \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js b/alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t { + var al = [] + attrs.forEach(key => { + al.push(this[key]) + }) + return al + }, (newValue, oldValue) => { + this.paginationInternal.pageSize = this.pageSize + + let needReset = false + for (let i = 2; i < newValue.length; i++) { + if (newValue[i] != oldValue[i]) { + needReset = true + break + } + } + if (needReset) { + this.clear() + this.reset() + } + if (newValue[0] != oldValue[0]) { + this.paginationInternal.current = this.pageCurrent + } + + this._execLoadData() + }) + + // #ifdef H5 + if (process.env.NODE_ENV === 'development') { + this._debugDataList = [] + if (!window.unidev) { + window.unidev = { + clientDB: { + data: [] + } + } + } + unidev.clientDB.data.push(this._debugDataList) + } + // #endif + + // #ifdef MP-TOUTIAO + let changeName + let events = this.$scope.dataset.eventOpts + for (var i = 0; i < events.length; i++) { + let event = events[i] + if (event[0].includes('^load')) { + changeName = event[1][0][0] + } + } + if (changeName) { + let parent = this.$parent + let maxDepth = 16 + this._changeDataFunction = null + while (parent && maxDepth > 0) { + let fun = parent[changeName] + if (fun && typeof fun === 'function') { + this._changeDataFunction = fun + maxDepth = 0 + break + } + parent = parent.$parent + maxDepth--; + } + } + // #endif + + // if (!this.manual) { + // this.loadData() + // } + }, + // #ifdef H5 + beforeDestroy() { + if (process.env.NODE_ENV === 'development' && window.unidev) { + var cd = this._debugDataList + var dl = unidev.clientDB.data + for (var i = dl.length - 1; i >= 0; i--) { + if (dl[i] === cd) { + dl.splice(i, 1) + break + } + } + } + }, + // #endif + methods: { + loadData(args1, args2) { + let callback = null + if (typeof args1 === 'object') { + if (args1.clear) { + this.clear() + this.reset() + } + if (args1.current !== undefined) { + this.paginationInternal.current = args1.current + } + if (typeof args2 === 'function') { + callback = args2 + } + } else if (typeof args1 === 'function') { + callback = args1 + } + + this._execLoadData(callback) + }, + loadMore() { + if (this._isEnded) { + return + } + this._execLoadData() + }, + refresh() { + this.clear() + this._execLoadData() + }, + clear() { + this._isEnded = false + this.listData = [] + }, + reset() { + this.paginationInternal.current = 1 + }, + remove(id, { + action, + callback, + confirmTitle, + confirmContent + } = {}) { + if (!id || !id.length) { + return + } + uni.showModal({ + title: confirmTitle || '提示', + content: confirmContent || '是否删除该数据', + showCancel: true, + success: (res) => { + if (!res.confirm) { + return + } + this._execRemove(id, action, callback) + } + }) + }, + _execLoadData(callback) { + if (this.loading) { + return + } + this.loading = true + this.errorMessage = '' + + this._getExec().then((res) => { + this.loading = false + const { + data, + count + } = res.result + this._isEnded = data.length < this.pageSize + + callback && callback(data, this._isEnded) + this._dispatchEvent(events.load, data) + + if (this.getone) { + this.listData = data.length ? data[0] : undefined + } else if (this.pageData === pageMode.add) { + this.listData.push(...data) + if (this.listData.length) { + this.paginationInternal.current++ + } + } else if (this.pageData === pageMode.replace) { + this.listData = data + this.paginationInternal.count = count + } + + // #ifdef H5 + if (process.env.NODE_ENV === 'development') { + this._debugDataList.length = 0 + this._debugDataList.push(...JSON.parse(JSON.stringify(this.listData))) + } + // #endif + }).catch((err) => { + this.loading = false + this.errorMessage = err + callback && callback() + this.$emit(events.error, err) + }) + }, + _getExec() { + let exec = this.db + if (this.action) { + exec = exec.action(this.action) + } + + exec = exec.collection(this.collection) + + if (!(!this.where || !Object.keys(this.where).length)) { + exec = exec.where(this.where) + } + if (this.field) { + exec = exec.field(this.field) + } + if (this.orderby) { + exec = exec.orderBy(this.orderby) + } + + const { + current, + size + } = this.paginationInternal + exec = exec.skip(size * (current - 1)).limit(size).get({ + getCount: this.getcount + }) + + return exec + }, + _execRemove(id, action, callback) { + if (!this.collection || !id) { + return + } + + const ids = Array.isArray(id) ? id : [id] + if (!ids.length) { + return + } + + uni.showLoading({ + mask: true + }) + + let exec = this.db + if (action) { + exec = exec.action(action) + } + + exec.collection(this.collection).where({ + _id: dbCmd.in(ids) + }).remove().then((res) => { + callback && callback(res.result) + if (this.pageData === pageMode.replace) { + this.refresh() + } else { + this.removeData(ids) + } + }).catch((err) => { + uni.showModal({ + content: err.message, + showCancel: false + }) + }).finally(() => { + uni.hideLoading() + }) + }, + removeData(ids) { + let il = ids.slice(0) + let dl = this.listData + for (let i = dl.length - 1; i >= 0; i--) { + let index = il.indexOf(dl[i]._id) + if (index >= 0) { + dl.splice(i, 1) + il.splice(index, 1) + } + } + }, + _dispatchEvent(type, data) { + if (this._changeDataFunction) { + this._changeDataFunction(data, this._isEnded) + } else { + this.$emit(type, data, this._isEnded) + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue b/alpha/admin/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue new file mode 100644 index 0000000..3c75d9f --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue @@ -0,0 +1,821 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-data-checkbox/package.json b/alpha/admin/uni_modules/uni-data-checkbox/package.json new file mode 100644 index 0000000..113c350 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-checkbox/package.json @@ -0,0 +1,84 @@ +{ + "id": "uni-data-checkbox", + "displayName": "uni-data-checkbox 数据选择器", + "version": "1.0.3", + "description": "通过数据驱动的单选框和复选框", + "keywords": [ + "uni-ui", + "checkbox", + "单选", + "多选", + "单选多选" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.1.1" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-load-more","uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-data-checkbox/readme.md b/alpha/admin/uni_modules/uni-data-checkbox/readme.md new file mode 100644 index 0000000..6eb253d --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-checkbox/readme.md @@ -0,0 +1,18 @@ + + +## DataCheckbox 数据驱动的单选复选框 +> **组件名:uni-data-checkbox** +> 代码块: `uDataCheckbox` + + +本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括: + +1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能 +2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验 +3. 本组件合并了单选多选 +4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性 + +在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-data-picker/changelog.md b/alpha/admin/uni_modules/uni-data-picker/changelog.md new file mode 100644 index 0000000..7edcd87 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/changelog.md @@ -0,0 +1,68 @@ +## 1.0.9(2022-11-30) +- 修复 v-for 为使用 key 值控制台 warning +## 1.0.8(2022-09-16) +- 可以使用 uni-scss 控制主题色 +## 1.0.7(2022-07-06) +- 优化 pc端图标位置不正确的问题 +## 1.0.6(2022-07-05) +- 优化 显示样式 +## 1.0.5(2022-07-04) +- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug +## 1.0.4(2022-04-19) +- 修复 字节小程序 本地数据无法选择下一级的Bug +## 1.0.3(2022-02-25) +- 修复 nvue 不支持的 v-show 的 bug +## 1.0.2(2022-02-25) +- 修复 条件编译 nvue 不支持的 css 样式 +## 1.0.1(2021-11-23) +- 修复 由上个版本引发的map、v-model等属性不生效的bug +## 1.0.0(2021-11-19) +- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker) +## 0.4.9(2021-10-28) +- 修复 VUE2 v-model 概率无效的 bug +## 0.4.8(2021-10-27) +- 修复 v-model 概率无效的 bug +## 0.4.7(2021-10-25) +- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+ +- 修复 树型 uniCloud 数据类型为 int 时报错的 bug +## 0.4.6(2021-10-19) +- 修复 非 VUE3 v-model 为 0 时无法选中的 bug +## 0.4.5(2021-09-26) +- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效 +- 修复 readonly 为 true 时报错的 bug +## 0.4.4(2021-09-26) +- 修复 上一版本造成的 map 属性失效的 bug +- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略 +## 0.4.3(2021-09-24) +- 修复 某些情况下级联未触发的 bug +## 0.4.2(2021-09-23) +- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用 +- 新增 选项内容过长自动添加省略号 +## 0.4.1(2021-09-15) +- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段 +## 0.4.0(2021-07-13) +- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 0.3.5(2021-06-04) +- 修复 无法加载云端数据的问题 +## 0.3.4(2021-05-28) +- 修复 v-model 无效问题 +- 修复 loaddata 为空数据组时加载时间过长问题 +- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点 +## 0.3.3(2021-05-12) +- 新增 组件示例地址 +## 0.3.2(2021-04-22) +- 修复 非树形数据有 where 属性查询报错的问题 +## 0.3.1(2021-04-15) +- 修复 本地数据概率无法回显时问题 +## 0.3.0(2021-04-07) +- 新增 支持云端非树形表结构数据 +- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题 +## 0.2.0(2021-03-15) +- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题 +## 0.1.9(2021-03-09) +- 修复 微信小程序某些情况下无法选择的问题 +## 0.1.8(2021-02-05) +- 优化 部分样式在 nvue 上的兼容表现 +## 0.1.7(2021-02-05) +- 调整为 uni_modules 目录规范 diff --git a/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js new file mode 100644 index 0000000..6ef26a2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + this.$once('hook:beforeDestroy', () => { + document.removeEventListener('keyup', listener) + }) + }, + render: () => {} +} +// #endif diff --git a/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue new file mode 100644 index 0000000..4553627 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue @@ -0,0 +1,554 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js new file mode 100644 index 0000000..c12fd54 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js @@ -0,0 +1,563 @@ +export default { + props: { + localdata: { + type: [Array, Object], + default () { + return [] + } + }, + spaceInfo: { + type: Object, + default () { + return {} + } + }, + collection: { + type: String, + default: '' + }, + action: { + type: String, + default: '' + }, + field: { + type: String, + default: '' + }, + orderby: { + type: String, + default: '' + }, + where: { + type: [String, Object], + default: '' + }, + pageData: { + type: String, + default: 'add' + }, + pageCurrent: { + type: Number, + default: 1 + }, + pageSize: { + type: Number, + default: 20 + }, + getcount: { + type: [Boolean, String], + default: false + }, + getone: { + type: [Boolean, String], + default: false + }, + gettree: { + type: [Boolean, String], + default: false + }, + manual: { + type: Boolean, + default: false + }, + value: { + type: [Array, String, Number], + default () { + return [] + } + }, + modelValue: { + type: [Array, String, Number], + default () { + return [] + } + }, + preload: { + type: Boolean, + default: false + }, + stepSearh: { + type: Boolean, + default: true + }, + selfField: { + type: String, + default: '' + }, + parentField: { + type: String, + default: '' + }, + multiple: { + type: Boolean, + default: false + }, + map: { + type: Object, + default() { + return { + text: "text", + value: "value" + } + } + } + }, + data() { + return { + loading: false, + errorMessage: '', + loadMore: { + contentdown: '', + contentrefresh: '', + contentnomore: '' + }, + dataList: [], + selected: [], + selectedIndex: 0, + page: { + current: this.pageCurrent, + size: this.pageSize, + count: 0 + } + } + }, + computed: { + isLocaldata() { + return !this.collection.length + }, + postField() { + let fields = [this.field]; + if (this.parentField) { + fields.push(`${this.parentField} as parent_value`); + } + return fields.join(','); + }, + dataValue() { + let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null || this.modelValue !== undefined) + return isModelValue ? this.modelValue : this.value + }, + hasValue() { + if (typeof this.dataValue === 'number') { + return true + } + return (this.dataValue != null) && (this.dataValue.length > 0) + } + }, + created() { + this.$watch(() => { + var al = []; + ['pageCurrent', + 'pageSize', + 'spaceInfo', + 'value', + 'modelValue', + 'localdata', + 'collection', + 'action', + 'field', + 'orderby', + 'where', + 'getont', + 'getcount', + 'gettree' + ].forEach(key => { + al.push(this[key]) + }); + return al + }, (newValue, oldValue) => { + let needReset = false + for (let i = 2; i < newValue.length; i++) { + if (newValue[i] != oldValue[i]) { + needReset = true + break + } + } + if (newValue[0] != oldValue[0]) { + this.page.current = this.pageCurrent + } + this.page.size = this.pageSize + + this.onPropsChange() + }) + this._treeData = [] + }, + methods: { + onPropsChange() { + this._treeData = [] + }, + getCommand(options = {}) { + /* eslint-disable no-undef */ + let db = uniCloud.database(this.spaceInfo) + + const action = options.action || this.action + if (action) { + db = db.action(action) + } + + const collection = options.collection || this.collection + db = db.collection(collection) + + const where = options.where || this.where + if (!(!where || !Object.keys(where).length)) { + db = db.where(where) + } + + const field = options.field || this.field + if (field) { + db = db.field(field) + } + + const orderby = options.orderby || this.orderby + if (orderby) { + db = db.orderBy(orderby) + } + + const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current + const size = options.pageSize !== undefined ? options.pageSize : this.page.size + const getCount = options.getcount !== undefined ? options.getcount : this.getcount + const getTree = options.gettree !== undefined ? options.gettree : this.gettree + + const getOptions = { + getCount, + getTree + } + if (options.getTreePath) { + getOptions.getTreePath = options.getTreePath + } + + db = db.skip(size * (current - 1)).limit(size).get(getOptions) + + return db + }, + getNodeData(callback) { + if (this.loading) { + return + } + this.loading = true + this.getCommand({ + field: this.postField, + where: this._pathWhere() + }).then((res) => { + this.loading = false + this.selected = res.result.data + callback && callback() + }).catch((err) => { + this.loading = false + this.errorMessage = err + }) + }, + getTreePath(callback) { + if (this.loading) { + return + } + this.loading = true + + this.getCommand({ + field: this.postField, + getTreePath: { + startWith: `${this.selfField}=='${this.dataValue}'` + } + }).then((res) => { + this.loading = false + let treePath = [] + this._extractTreePath(res.result.data, treePath) + this.selected = treePath + callback && callback() + }).catch((err) => { + this.loading = false + this.errorMessage = err + }) + }, + loadData() { + if (this.isLocaldata) { + this._processLocalData() + return + } + + if (this.dataValue != null) { + this._loadNodeData((data) => { + this._treeData = data + this._updateBindData() + this._updateSelected() + }) + return + } + + if (this.stepSearh) { + this._loadNodeData((data) => { + this._treeData = data + this._updateBindData() + }) + } else { + this._loadAllData((data) => { + this._treeData = [] + this._extractTree(data, this._treeData, null) + this._updateBindData() + }) + } + }, + _loadAllData(callback) { + if (this.loading) { + return + } + this.loading = true + + this.getCommand({ + field: this.postField, + gettree: true, + startwith: `${this.selfField}=='${this.dataValue}'` + }).then((res) => { + this.loading = false + callback(res.result.data) + this.onDataChange() + }).catch((err) => { + this.loading = false + this.errorMessage = err + }) + }, + _loadNodeData(callback, pw) { + if (this.loading) { + return + } + this.loading = true + + this.getCommand({ + field: this.postField, + where: pw || this._postWhere(), + pageSize: 500 + }).then((res) => { + this.loading = false + callback(res.result.data) + this.onDataChange() + }).catch((err) => { + this.loading = false + this.errorMessage = err + }) + }, + _pathWhere() { + let result = [] + let where_field = this._getParentNameByField(); + if (where_field) { + result.push(`${where_field} == '${this.dataValue}'`) + } + + if (this.where) { + return `(${this.where}) && (${result.join(' || ')})` + } + + return result.join(' || ') + }, + _postWhere() { + let result = [] + let selected = this.selected + let parentField = this.parentField + if (parentField) { + result.push(`${parentField} == null || ${parentField} == ""`) + } + if (selected.length) { + for (var i = 0; i < selected.length - 1; i++) { + result.push(`${parentField} == '${selected[i].value}'`) + } + } + + let where = [] + if (this.where) { + where.push(`(${this.where})`) + } + if (result.length) { + where.push(`(${result.join(' || ')})`) + } + + return where.join(' && ') + }, + _nodeWhere() { + let result = [] + let selected = this.selected + if (selected.length) { + result.push(`${this.parentField} == '${selected[selected.length - 1].value}'`) + } + + if (this.where) { + return `(${this.where}) && (${result.join(' || ')})` + } + + return result.join(' || ') + }, + _getParentNameByField() { + const fields = this.field.split(','); + let where_field = null; + for (let i = 0; i < fields.length; i++) { + const items = fields[i].split('as'); + if (items.length < 2) { + continue; + } + if (items[1].trim() === 'value') { + where_field = items[0].trim(); + break; + } + } + return where_field + }, + _isTreeView() { + return (this.parentField && this.selfField) + }, + _updateSelected() { + var dl = this.dataList + var sl = this.selected + let textField = this.map.text + let valueField = this.map.value + for (var i = 0; i < sl.length; i++) { + var value = sl[i].value + var dl2 = dl[i] + for (var j = 0; j < dl2.length; j++) { + var item2 = dl2[j] + if (item2[valueField] === value) { + sl[i].text = item2[textField] + break + } + } + } + }, + _updateBindData(node) { + const { + dataList, + hasNodes + } = this._filterData(this._treeData, this.selected) + + let isleaf = this._stepSearh === false && !hasNodes + + if (node) { + node.isleaf = isleaf + } + + this.dataList = dataList + this.selectedIndex = dataList.length - 1 + + if (!isleaf && this.selected.length < dataList.length) { + this.selected.push({ + value: null, + text: "请选择" + }) + } + + return { + isleaf, + hasNodes + } + }, + _filterData(data, paths) { + let dataList = [] + let hasNodes = true + + dataList.push(data.filter((item) => { + return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '') + })) + for (let i = 0; i < paths.length; i++) { + var value = paths[i].value + var nodes = data.filter((item) => { + return item.parent_value === value + }) + + if (nodes.length) { + dataList.push(nodes) + } else { + hasNodes = false + } + } + + return { + dataList, + hasNodes + } + }, + _extractTree(nodes, result, parent_value) { + let list = result || [] + let valueField = this.map.value + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i] + + let child = {} + for (let key in node) { + if (key !== 'children') { + child[key] = node[key] + } + } + if (parent_value !== null && parent_value !== undefined && parent_value !== '') { + child.parent_value = parent_value + } + result.push(child) + + let children = node.children + if (children) { + this._extractTree(children, result, node[valueField]) + } + } + }, + _extractTreePath(nodes, result) { + let list = result || [] + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i] + + let child = {} + for (let key in node) { + if (key !== 'children') { + child[key] = node[key] + } + } + result.push(child) + + let children = node.children + if (children) { + this._extractTreePath(children, result) + } + } + }, + _findNodePath(key, nodes, path = []) { + let textField = this.map.text + let valueField = this.map.value + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i] + let children = node.children + let text = node[textField] + let value = node[valueField] + + path.push({ + value, + text + }) + + if (value === key) { + return path + } + + if (children) { + const p = this._findNodePath(key, children, path) + if (p.length) { + return p + } + } + + path.pop() + } + return [] + }, + _processLocalData() { + this._treeData = [] + this._extractTree(this.localdata, this._treeData) + + var inputValue = this.dataValue + if (inputValue === undefined) { + return + } + + if (Array.isArray(inputValue)) { + inputValue = inputValue[inputValue.length - 1] + if (typeof inputValue === 'object' && inputValue[this.map.value]) { + inputValue = inputValue[this.map.value] + } + } + + this.selected = this._findNodePath(inputValue, this.localdata) + } + } +} diff --git a/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue new file mode 100644 index 0000000..e0aa590 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue @@ -0,0 +1,335 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-data-picker/package.json b/alpha/admin/uni_modules/uni-data-picker/package.json new file mode 100644 index 0000000..04b4610 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-data-picker", + "displayName": "uni-data-picker 数据驱动的picker选择器", + "version": "1.0.9", + "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景", + "keywords": [ + "uni-ui", + "uniui", + "picker", + "级联", + "省市区", + "" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-load-more", + "uni-icons", + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-data-picker/readme.md b/alpha/admin/uni_modules/uni-data-picker/readme.md new file mode 100644 index 0000000..6cda224 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-picker/readme.md @@ -0,0 +1,22 @@ +## DataPicker 级联选择 +> **组件名:uni-data-picker** +> 代码块: `uDataPicker` +> 关联组件:`uni-data-pickerview`、`uni-load-more`。 + + +`` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。 + +支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。 + +候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。 + +`` 组件尤其适用于地址选择、分类选择等选择类。 + +`` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。 + +`` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。 + +在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-data-select/changelog.md b/alpha/admin/uni_modules/uni-data-select/changelog.md new file mode 100644 index 0000000..2e077a9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-select/changelog.md @@ -0,0 +1,31 @@ +## 1.0.4(2023-02-02) +优化 查询条件短期内多次变更只查询最后一次变更后的结果 +调整 内部缓存键名调整为 uni-data-select-lastSelectedValue +## 1.0.3(2023-01-16) +- 修复 不关联服务空间报错的问题 +## 1.0.2(2023-01-14) +- 新增 属性 `format` 可用于格式化显示选项内容 +## 1.0.1(2022-12-06) +- 修复 当where变化时,数据不会自动更新的问题 +## 0.1.9(2022-09-05) +- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框 +## 0.1.8(2022-08-29) +- 修复 点击的位置不准确 +## 0.1.7(2022-08-12) +- 新增 支持 disabled 属性 +## 0.1.6(2022-07-06) +- 修复 pc端宽度异常的bug +## 0.1.5 +- 修复 pc端宽度异常的bug +## 0.1.4(2022-07-05) +- 优化 显示样式 +## 0.1.3(2022-06-02) +- 修复 localdata 赋值不生效的 bug +- 新增 支持 uni.scss 修改颜色 +- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用) +## 0.1.2(2022-05-08) +- 修复 当 value 为 0 时选择不生效的 bug +## 0.1.1(2022-05-07) +- 新增 记住上次的选项(仅 collection 存在时有效) +## 0.1.0(2022-04-22) +- 初始化 diff --git a/alpha/admin/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue b/alpha/admin/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue new file mode 100644 index 0000000..eec5a1b --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue @@ -0,0 +1,502 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-data-select/package.json b/alpha/admin/uni_modules/uni-data-select/package.json new file mode 100644 index 0000000..fdb48ba --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-select/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-data-select", + "displayName": "uni-data-select 下拉框选择器", + "version": "1.0.4", + "description": "通过数据驱动的下拉框选择器", + "keywords": [ + "uni-ui", + "select", + "uni-data-select", + "下拉框", + "下拉选" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.1.1" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-load-more"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "u", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-data-select/readme.md b/alpha/admin/uni_modules/uni-data-select/readme.md new file mode 100644 index 0000000..eb58de3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-data-select/readme.md @@ -0,0 +1,8 @@ +## DataSelect 下拉框选择器 +> **组件名:uni-data-select** +> 代码块: `uDataSelect` + +当选项过多时,使用下拉菜单展示并选择内容 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 diff --git a/alpha/admin/uni_modules/uni-dateformat/changelog.md b/alpha/admin/uni_modules/uni-dateformat/changelog.md new file mode 100644 index 0000000..d551d7b --- /dev/null +++ b/alpha/admin/uni_modules/uni-dateformat/changelog.md @@ -0,0 +1,10 @@ +## 1.0.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-dateformat](https://uniapp.dcloud.io/component/uniui/uni-dateformat) +## 0.0.5(2021-07-08) +- 调整 默认时间不再是当前时间,而是显示'-'字符 +## 0.0.4(2021-05-12) +- 新增 组件示例地址 +## 0.0.3(2021-02-04) +- 调整为uni_modules目录规范 +- 修复 iOS 平台日期格式化出错的问题 diff --git a/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js b/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js new file mode 100644 index 0000000..e00d559 --- /dev/null +++ b/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js @@ -0,0 +1,200 @@ +// yyyy-MM-dd hh:mm:ss.SSS 所有支持的类型 +function pad(str, length = 2) { + str += '' + while (str.length < length) { + str = '0' + str + } + return str.slice(-length) +} + +const parser = { + yyyy: (dateObj) => { + return pad(dateObj.year, 4) + }, + yy: (dateObj) => { + return pad(dateObj.year) + }, + MM: (dateObj) => { + return pad(dateObj.month) + }, + M: (dateObj) => { + return dateObj.month + }, + dd: (dateObj) => { + return pad(dateObj.day) + }, + d: (dateObj) => { + return dateObj.day + }, + hh: (dateObj) => { + return pad(dateObj.hour) + }, + h: (dateObj) => { + return dateObj.hour + }, + mm: (dateObj) => { + return pad(dateObj.minute) + }, + m: (dateObj) => { + return dateObj.minute + }, + ss: (dateObj) => { + return pad(dateObj.second) + }, + s: (dateObj) => { + return dateObj.second + }, + SSS: (dateObj) => { + return pad(dateObj.millisecond, 3) + }, + S: (dateObj) => { + return dateObj.millisecond + }, +} + +// 这都n年了iOS依然不认识2020-12-12,需要转换为2020/12/12 +function getDate(time) { + if (time instanceof Date) { + return time + } + switch (typeof time) { + case 'string': + { + // 2020-12-12T12:12:12.000Z、2020-12-12T12:12:12.000 + if (time.indexOf('T') > -1) { + return new Date(time) + } + return new Date(time.replace(/-/g, '/')) + } + default: + return new Date(time) + } +} + +export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') { + if (!date && date !== 0) { + return '' + } + date = getDate(date) + const dateObj = { + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + millisecond: date.getMilliseconds() + } + const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/ + let flag = true + let result = format + while (flag) { + flag = false + result = result.replace(tokenRegExp, function(matched) { + flag = true + return parser[matched](dateObj) + }) + } + return result +} + +export function friendlyDate(time, { + locale = 'zh', + threshold = [60000, 3600000], + format = 'yyyy/MM/dd hh:mm:ss' +}) { + if (time === '-') { + return time + } + if (!time && time !== 0) { + return '' + } + const localeText = { + zh: { + year: '年', + month: '月', + day: '天', + hour: '小时', + minute: '分钟', + second: '秒', + ago: '前', + later: '后', + justNow: '刚刚', + soon: '马上', + template: '{num}{unit}{suffix}' + }, + en: { + year: 'year', + month: 'month', + day: 'day', + hour: 'hour', + minute: 'minute', + second: 'second', + ago: 'ago', + later: 'later', + justNow: 'just now', + soon: 'soon', + template: '{num} {unit} {suffix}' + } + } + const text = localeText[locale] || localeText.zh + let date = getDate(time) + let ms = date.getTime() - Date.now() + let absMs = Math.abs(ms) + if (absMs < threshold[0]) { + return ms < 0 ? text.justNow : text.soon + } + if (absMs >= threshold[1]) { + return formatDate(date, format) + } + let num + let unit + let suffix = text.later + if (ms < 0) { + suffix = text.ago + ms = -ms + } + const seconds = Math.floor((ms) / 1000) + const minutes = Math.floor(seconds / 60) + const hours = Math.floor(minutes / 60) + const days = Math.floor(hours / 24) + const months = Math.floor(days / 30) + const years = Math.floor(months / 12) + switch (true) { + case years > 0: + num = years + unit = text.year + break + case months > 0: + num = months + unit = text.month + break + case days > 0: + num = days + unit = text.day + break + case hours > 0: + num = hours + unit = text.hour + break + case minutes > 0: + num = minutes + unit = text.minute + break + default: + num = seconds + unit = text.second + break + } + + if (locale === 'en') { + if (num === 1) { + num = 'a' + } else { + unit += 's' + } + } + + return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g, + suffix) +} diff --git a/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue b/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue new file mode 100644 index 0000000..c5ed030 --- /dev/null +++ b/alpha/admin/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-dateformat/package.json b/alpha/admin/uni_modules/uni-dateformat/package.json new file mode 100644 index 0000000..786a670 --- /dev/null +++ b/alpha/admin/uni_modules/uni-dateformat/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-dateformat", + "displayName": "uni-dateformat 日期格式化", + "version": "1.0.0", + "description": "日期格式化组件,可以将日期格式化为1分钟前、刚刚等形式", + "keywords": [ + "uni-ui", + "uniui", + "日期格式化", + "时间格式化", + "格式化时间", + "" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-dateformat/readme.md b/alpha/admin/uni_modules/uni-dateformat/readme.md new file mode 100644 index 0000000..37ddb6e --- /dev/null +++ b/alpha/admin/uni_modules/uni-dateformat/readme.md @@ -0,0 +1,11 @@ + + +### DateFormat 日期格式化 +> **组件名:uni-dateformat** +> 代码块: `uDateformat` + + +日期格式化组件。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-dateformat) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-datetime-picker/changelog.md b/alpha/admin/uni_modules/uni-datetime-picker/changelog.md new file mode 100644 index 0000000..1f1a554 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/changelog.md @@ -0,0 +1,133 @@ +## 2.2.22(2023-03-30) +- 修复 日历 picker 修改年月后,自动选中当月1日 [详情](https://ask.dcloud.net.cn/question/165937) +- 修复 小程序端 低版本 ios NaN [详情](https://ask.dcloud.net.cn/question/162979) +## 2.2.21(2023-02-20) +- 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362) +## 2.2.20(2023-02-17) +- 优化 值为空依然选中当天问题 +- 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间 +- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间 +- 优化 字节小程序日期时间范围选择,底部日期换行问题 +## 2.2.19(2023-02-09) +- 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686) +## 2.2.18(2023-02-08) +- 修复 移动端范围选择change事件触发异常的Bug [详情](https://github.com/dcloudio/uni-ui/issues/684) +- 优化 PC端输入日期格式错误时返回当前日期时间 +- 优化 PC端输入日期时间超出 start、end 限制的Bug +- 优化 移动端日期时间范围用法时间展示不完整问题 +## 2.2.17(2023-02-04) +- 修复 小程序端绑定 Date 类型报错的Bug [详情](https://github.com/dcloudio/uni-ui/issues/679) +- 修复 vue3 time-picker 无法显示绑定时分秒的Bug +## 2.2.16(2023-02-02) +- 修复 字节小程序报错的Bug +## 2.2.15(2023-02-02) +- 修复 某些情况切换月份错误的Bug +## 2.2.14(2023-01-30) +- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/162033) +## 2.2.13(2023-01-10) +- 修复 多次加载组件造成内存占用的Bug +## 2.2.12(2022-12-01) +- 修复 vue3 下 i18n 国际化初始值不正确的Bug +## 2.2.11(2022-09-19) +- 修复 支付宝小程序样式错乱的Bug [详情](https://github.com/dcloudio/uni-app/issues/3861) +## 2.2.10(2022-09-19) +- 修复 反向选择日期范围,日期显示异常的Bug [详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false) +## 2.2.9(2022-09-16) +- 可以使用 uni-scss 控制主题色 +## 2.2.8(2022-09-08) +- 修复 close事件无效的Bug +## 2.2.7(2022-09-05) +- 修复 移动端 maskClick 无效的Bug [详情](https://ask.dcloud.net.cn/question/140824) +## 2.2.6(2022-06-30) +- 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致 +## 2.2.5(2022-06-24) +- 修复 日历顶部年月及底部确认未国际化的Bug +## 2.2.4(2022-03-31) +- 修复 Vue3 下动态赋值,单选类型未响应的Bug +## 2.2.3(2022-03-28) +- 修复 Vue3 下动态赋值未响应的Bug +## 2.2.2(2021-12-10) +- 修复 clear-icon 属性在小程序平台不生效的Bug +## 2.2.1(2021-12-10) +- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的Bug +## 2.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源 [详情](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移 [https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) +## 2.1.5(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 2.1.4(2021-09-10) +- 修复 hide-second 在移动端的Bug +- 修复 单选赋默认值时,赋值日期未高亮的Bug +- 修复 赋默认值时,移动端未正确显示时间的Bug +## 2.1.3(2021-09-09) +- 新增 hide-second 属性,支持只使用时分,隐藏秒 +## 2.1.2(2021-09-03) +- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次 +- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法 +- 优化 调整字号大小,美化日历界面 +- 修复 因国际化导致的 placeholder 失效的Bug +## 2.1.1(2021-08-24) +- 新增 支持国际化 +- 优化 范围选择器在 pc 端过宽的问题 +## 2.1.0(2021-08-09) +- 新增 适配 vue3 +## 2.0.19(2021-08-09) +- 新增 支持作为 uni-forms 子组件相关功能 +- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的Bug +## 2.0.18(2021-08-05) +- 修复 type 属性动态赋值无效的Bug +- 修复 ‘确认’按钮被 tabbar 遮盖 bug +- 修复 组件未赋值时范围选左、右日历相同的Bug +## 2.0.17(2021-08-04) +- 修复 范围选未正确显示当前值的Bug +- 修复 h5 平台(移动端)报错 'cale' of undefined 的Bug +## 2.0.16(2021-07-21) +- 新增 return-type 属性支持返回 date 日期对象 +## 2.0.15(2021-07-14) +- 修复 单选日期类型,初始赋值后不在当前日历的Bug +- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效) +- 优化 移动端移除显示框的清空按钮,无实际用途 +## 2.0.14(2021-07-14) +- 修复 组件赋值为空,界面未更新的Bug +- 修复 start 和 end 不能动态赋值的Bug +- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的Bug +## 2.0.13(2021-07-08) +- 修复 范围选择不能动态赋值的Bug +## 2.0.12(2021-07-08) +- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug +## 2.0.11(2021-07-08) +- 优化 弹出层在超出视窗边缘定位不准确的问题 +## 2.0.10(2021-07-08) +- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的Bug +- 优化 弹出层在超出视窗边缘被遮盖的问题 +## 2.0.9(2021-07-07) +- 新增 maskClick 事件 +- 修复 特殊情况日历 rpx 布局错误的Bug,rpx -> px +- 修复 范围选择时清空返回值不合理的bug,['', ''] -> [] +## 2.0.8(2021-07-07) +- 新增 日期时间显示框支持插槽 +## 2.0.7(2021-07-01) +- 优化 添加 uni-icons 依赖 +## 2.0.6(2021-05-22) +- 修复 图标在小程序上不显示的Bug +- 优化 重命名引用组件,避免潜在组件命名冲突 +## 2.0.5(2021-05-20) +- 优化 代码目录扁平化 +## 2.0.4(2021-05-12) +- 新增 组件示例地址 +## 2.0.3(2021-05-10) +- 修复 ios 下不识别 '-' 日期格式的Bug +- 优化 pc 下弹出层添加边框和阴影 +## 2.0.2(2021-05-08) +- 修复 在 admin 中获取弹出层定位错误的bug +## 2.0.1(2021-05-08) +- 修复 type 属性向下兼容,默认值从 date 变更为 datetime +## 2.0.0(2021-04-30) +- 支持日历形式的日期+时间的范围选择 + > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker) +## 1.0.6(2021-03-18) +- 新增 hide-second 属性,时间支持仅选择时、分 +- 修复 选择跟显示的日期不一样的Bug +- 修复 chang事件触发2次的Bug +- 修复 分、秒 end 范围错误的Bug +- 优化 更好的 nvue 适配 diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue new file mode 100644 index 0000000..dba9887 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.js b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.js new file mode 100644 index 0000000..b8d7d6f --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.js @@ -0,0 +1,546 @@ +/** +* @1900-2100区间内的公历、农历互转 +* @charset UTF-8 +* @github https://github.com/jjonline/calendar.js +* @Author Jea杨(JJonline@JJonline.Cn) +* @Time 2014-7-21 +* @Time 2016-8-13 Fixed 2033hex、Attribution Annals +* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug +* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year +* @Version 1.0.3 +* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] +* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] +*/ +/* eslint-disable */ +var calendar = { + + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 + /** Add By JJonline@JJonline.Cn**/ + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 + 0x0d520], // 2100 + + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], + + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], + + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], + + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], + + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], + + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], + + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], + + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], + + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:var count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function (y) { + var i; var sum = 348 + for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } + return (sum + this.leapDays(y)) + }, + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function (y) { // 闰字编码 \u95f0 + return (this.lunarInfo[y - 1900] & 0xf) + }, + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function (y) { + if (this.leapMonth(y)) { + return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) + } + return (0) + }, + + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function (y, m) { + if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 + return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) + }, + + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function (y, m) { + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var ms = m - 1 + if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) + } else { + return (this.solarMonth[ms]) + } + }, + + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function (lYear) { + var ganKey = (lYear - 3) % 10 + var zhiKey = (lYear - 3) % 12 + if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 + return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] + }, + + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function (cMonth, cDay) { + var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' + var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 + }, + + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function (offset) { + return this.Gan[offset % 10] + this.Zhi[offset % 12] + }, + + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function (y, n) { + if (y < 1900 || y > 2100) { return -1 } + if (n < 1 || n > 24) { return -1 } + var _table = this.sTermInfo[y - 1900] + var _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ] + var _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2) + ] + return parseInt(_calday[n - 1]) + }, + + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function (m) { // 月 => \u6708 + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var s = this.nStr3[m - 1] + s += '\u6708'// 加上月字 + return s + }, + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function (d) { // 日 => \u65e5 + var s + switch (d) { + case 10: + s = '\u521d\u5341'; break + case 20: + s = '\u4e8c\u5341'; break + break + case 30: + s = '\u4e09\u5341'; break + break + default : + s = this.nStr2[Math.floor(d / 10)] + s += this.nStr1[d % 10] + } + return (s) + }, + + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function (y) { + return this.Animals[(y - 4) % 12] + }, + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 + // 年份限定、上限 + if (y < 1900 || y > 2100) { + return -1// undefined转换为数字变为NaN + } + // 公历传参最下限 + if (y == 1900 && m == 1 && d < 31) { + return -1 + } + // 未传参 获得当天 + if (!y) { + var objDate = new Date() + } else { + var objDate = new Date(y, parseInt(m) - 1, d) + } + var i; var leap = 0; var temp = 0 + // 修正ymd参数 + var y = objDate.getFullYear() + var m = objDate.getMonth() + 1 + var d = objDate.getDate() + var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = this.lYearDays(i) + offset -= temp + } + if (offset < 0) { + offset += temp; i-- + } + + // 是否今天 + var isTodayObj = new Date() + var isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + // 星期几 + var nWeek = objDate.getDay() + var cWeek = this.nStr1[nWeek] + // 数字表示周几顺应天朝周一开始的惯例 + if (nWeek == 0) { + nWeek = 7 + } + // 农历年 + var year = i + var leap = this.leapMonth(i) // 闰哪个月 + var isLeap = false + + // 效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + // 闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i + isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 + } else { + temp = this.monthDays(year, i)// 计算农历普通月天数 + } + // 解除闰月 + if (isLeap == true && i == (leap + 1)) { isLeap = false } + offset -= temp + } + // 闰月导致数组下标重叠取反 + if (offset == 0 && leap > 0 && i == leap + 1) { + if (isLeap) { + isLeap = false + } else { + isLeap = true; --i + } + } + if (offset < 0) { + offset += temp; --i + } + // 农历月 + var month = i + // 农历日 + var day = offset + 1 + // 天干地支处理 + var sm = m - 1 + var gzY = this.toGanZhiYear(year) + + // 当月的两个节气 + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` + var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 + var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 + + // 依据12节气修正干支月 + var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) + if (d >= firstNode) { + gzM = this.toGanZhi((y - 1900) * 12 + m + 12) + } + + // 传入的日期的节气与否 + var isTerm = false + var Term = null + if (firstNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 2] + } + if (secondNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 1] + } + // 日柱 当月一日与 1900/1/1 相差天数 + var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 + var gzD = this.toGanZhi(dayCyclical + d - 1) + // 该日期所属的星座 + var astro = this.toAstro(m, d) + + return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } + }, + + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 + var isLeapMonth = !!isLeapMonth + var leapOffset = 0 + var leapMonth = this.leapMonth(y) + var leapDay = this.leapDays(y) + if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 + var day = this.monthDays(y, m) + var _day = day + // bugFix 2016-9-25 + // if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = this.leapDays(y, m) + } + if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 + + // 计算农历的时间差 + var offset = 0 + for (var i = 1900; i < y; i++) { + offset += this.lYearDays(i) + } + var leap = 0; var isAdd = false + for (var i = 1; i < m; i++) { + leap = this.leapMonth(y) + if (!isAdd) { // 处理闰月 + if (leap <= i && leap > 0) { + offset += this.leapDays(y); isAdd = true + } + } + offset += this.monthDays(y, i) + } + // 转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { offset += day } + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) + var calObj = new Date((offset + d - 31) * 86400000 + stmap) + var cY = calObj.getUTCFullYear() + var cM = calObj.getUTCMonth() + 1 + var cD = calObj.getUTCDate() + + return this.solar2lunar(cY, cM, cD) + } +} + +export default calendar diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue new file mode 100644 index 0000000..3418f49 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue @@ -0,0 +1,928 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json new file mode 100644 index 0000000..024f22f --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json @@ -0,0 +1,22 @@ +{ + "uni-datetime-picker.selectDate": "select date", + "uni-datetime-picker.selectTime": "select time", + "uni-datetime-picker.selectDateTime": "select date and time", + "uni-datetime-picker.startDate": "start date", + "uni-datetime-picker.endDate": "end date", + "uni-datetime-picker.startTime": "start time", + "uni-datetime-picker.endTime": "end time", + "uni-datetime-picker.ok": "ok", + "uni-datetime-picker.clear": "clear", + "uni-datetime-picker.cancel": "cancel", + "uni-datetime-picker.year": "-", + "uni-datetime-picker.month": "", + "uni-calender.MON": "MON", + "uni-calender.TUE": "TUE", + "uni-calender.WED": "WED", + "uni-calender.THU": "THU", + "uni-calender.FRI": "FRI", + "uni-calender.SAT": "SAT", + "uni-calender.SUN": "SUN", + "uni-calender.confirm": "confirm" +} diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json new file mode 100644 index 0000000..d2df5e7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json @@ -0,0 +1,22 @@ +{ + "uni-datetime-picker.selectDate": "选择日期", + "uni-datetime-picker.selectTime": "选择时间", + "uni-datetime-picker.selectDateTime": "选择日期时间", + "uni-datetime-picker.startDate": "开始日期", + "uni-datetime-picker.endDate": "结束日期", + "uni-datetime-picker.startTime": "开始时间", + "uni-datetime-picker.endTime": "结束时间", + "uni-datetime-picker.ok": "确定", + "uni-datetime-picker.clear": "清除", + "uni-datetime-picker.cancel": "取消", + "uni-datetime-picker.year": "年", + "uni-datetime-picker.month": "月", + "uni-calender.SUN": "日", + "uni-calender.MON": "一", + "uni-calender.TUE": "二", + "uni-calender.WED": "三", + "uni-calender.THU": "四", + "uni-calender.FRI": "五", + "uni-calender.SAT": "六", + "uni-calender.confirm": "确认" +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json new file mode 100644 index 0000000..d23fa3c --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json @@ -0,0 +1,22 @@ +{ + "uni-datetime-picker.selectDate": "選擇日期", + "uni-datetime-picker.selectTime": "選擇時間", + "uni-datetime-picker.selectDateTime": "選擇日期時間", + "uni-datetime-picker.startDate": "開始日期", + "uni-datetime-picker.endDate": "結束日期", + "uni-datetime-picker.startTime": "開始时间", + "uni-datetime-picker.endTime": "結束时间", + "uni-datetime-picker.ok": "確定", + "uni-datetime-picker.clear": "清除", + "uni-datetime-picker.cancel": "取消", + "uni-datetime-picker.year": "年", + "uni-datetime-picker.month": "月", + "uni-calender.SUN": "日", + "uni-calender.MON": "一", + "uni-calender.TUE": "二", + "uni-calender.WED": "三", + "uni-calender.THU": "四", + "uni-calender.FRI": "五", + "uni-calender.SAT": "六", + "uni-calender.confirm": "確認" +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js new file mode 100644 index 0000000..9601aba --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + this.$once('hook:beforeDestroy', () => { + document.removeEventListener('keyup', listener) + }) + }, + render: () => {} +} +// #endif \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue new file mode 100644 index 0000000..81a042a --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue @@ -0,0 +1,934 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue new file mode 100644 index 0000000..bd96488 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue @@ -0,0 +1,1026 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js new file mode 100644 index 0000000..7dc34c4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js @@ -0,0 +1,403 @@ +class Calendar { + constructor({ + selected, + startDate, + endDate, + range, + } = {}) { + // 当前日期 + this.date = this.getDateObj(new Date()) // 当前初入日期 + // 打点信息 + this.selected = selected || []; + // 起始时间 + this.startDate = startDate + // 终止时间 + this.endDate = endDate + // 是否范围选择 + this.range = range + // 多选状态 + this.cleanMultipleStatus() + // 每周日期 + this.weeks = {} + this.lastHover = false + } + /** + * 设置日期 + * @param {Object} date + */ + setDate(date) { + const selectDate = this.getDateObj(date) + this.getWeeks(selectDate.fullDate) + } + + /** + * 清理多选状态 + */ + cleanMultipleStatus() { + this.multipleStatus = { + before: '', + after: '', + data: [] + } + } + + setStartDate(startDate) { + this.startDate = startDate + } + + setEndDate(endDate) { + this.endDate = endDate + } + + getPreMonthObj(date){ + date = fixIosDateFormat(date) + date = new Date(date) + + const oldMonth = date.getMonth() + date.setMonth(oldMonth - 1) + const newMonth = date.getMonth() + if(oldMonth !== 0 && newMonth - oldMonth === 0){ + date.setMonth(newMonth - 1) + } + return this.getDateObj(date) + } + getNextMonthObj(date){ + date = fixIosDateFormat(date) + date = new Date(date) + + const oldMonth = date.getMonth() + date.setMonth(oldMonth + 1) + const newMonth = date.getMonth() + if(newMonth - oldMonth > 1){ + date.setMonth(newMonth - 1) + } + return this.getDateObj(date) + } + + /** + * 获取指定格式Date对象 + */ + getDateObj(date) { + date = fixIosDateFormat(date) + date = new Date(date) + + return { + fullDate: getDate(date), + year: date.getFullYear(), + month: addZero(date.getMonth() + 1), + date: addZero(date.getDate()), + day: date.getDay() + } + } + + /** + * 获取上一个月日期集合 + */ + getPreMonthDays(amount, dateObj) { + const result = [] + for (let i = amount - 1; i >= 0; i--) { + const month = dateObj.month - 1 + result.push({ + date: new Date(dateObj.year, month, -i).getDate(), + month, + disable: true + }) + } + return result + } + /** + * 获取本月日期集合 + */ + getCurrentMonthDays(amount, dateObj) { + const result = [] + const fullDate = this.date.fullDate + for (let i = 1; i <= amount; i++) { + const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}` + const isToday = fullDate === currentDate + // 获取打点信息 + const info = this.selected && this.selected.find((item) => { + if (this.dateEqual(currentDate, item.date)) { + return item + } + }) + + // 日期禁用 + let disableBefore = true + let disableAfter = true + if (this.startDate) { + disableBefore = dateCompare(this.startDate, currentDate) + } + + if (this.endDate) { + disableAfter = dateCompare(currentDate, this.endDate) + } + + let multiples = this.multipleStatus.data + let multiplesStatus = -1 + if (this.range && multiples) { + multiplesStatus = multiples.findIndex((item) => { + return this.dateEqual(item, currentDate) + }) + } + const checked = multiplesStatus !== -1 + + result.push({ + fullDate: currentDate, + year: dateObj.year, + date: i, + multiple: this.range ? checked : false, + beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after), + afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after), + month: dateObj.month, + disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(currentDate,this.endDate)), + isToday, + userChecked: false, + extraInfo: info + }) + } + return result + } + /** + * 获取下一个月日期集合 + */ + _getNextMonthDays(amount, dateObj) { + const result = [] + const month = dateObj.month + 1 + for (let i = 1; i <= amount; i++) { + result.push({ + date: i, + month, + disable: true + }) + } + return result + } + + /** + * 获取当前日期详情 + * @param {Object} date + */ + getInfo(date) { + if (!date) { + date = new Date() + } + + return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate) + } + + /** + * 比较时间是否相等 + */ + dateEqual(before, after) { + before = new Date(fixIosDateFormat(before)) + after = new Date(fixIosDateFormat(after)) + return before.valueOf() === after.valueOf() + } + + /** + * 比较真实起始日期 + */ + + isLogicBefore(currentDate, before, after) { + let logicBefore = before + if (before && after) { + logicBefore = dateCompare(before, after) ? before : after + } + return this.dateEqual(logicBefore, currentDate) + } + + isLogicAfter(currentDate, before, after) { + let logicAfter = after + if (before && after) { + logicAfter = dateCompare(before, after) ? after : before + } + return this.dateEqual(logicAfter, currentDate) + } + + /** + * 获取日期范围内所有日期 + * @param {Object} begin + * @param {Object} end + */ + geDateAll(begin, end) { + var arr = [] + var ab = begin.split('-') + var ae = end.split('-') + var db = new Date() + db.setFullYear(ab[0], ab[1] - 1, ab[2]) + var de = new Date() + de.setFullYear(ae[0], ae[1] - 1, ae[2]) + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 + for (var k = unixDb; k <= unixDe;) { + k = k + 24 * 60 * 60 * 1000 + arr.push(this.getDateObj(new Date(parseInt(k))).fullDate) + } + return arr + } + + /** + * 获取多选状态 + */ + setMultiple(fullDate) { + if (!this.range) return + + let { + before, + after + } = this.multipleStatus + if (before && after) { + if (!this.lastHover) { + this.lastHover = true + return + } + this.multipleStatus.before = fullDate + this.multipleStatus.after = '' + this.multipleStatus.data = [] + this.multipleStatus.fulldate = '' + this.lastHover = false + } else { + if (!before) { + this.multipleStatus.before = fullDate + this.lastHover = false + } else { + this.multipleStatus.after = fullDate + if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus + .after); + } else { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus + .before); + } + this.lastHover = true + } + } + this.getWeeks(fullDate) + } + + /** + * 鼠标 hover 更新多选状态 + */ + setHoverMultiple(fullDate) { + if (!this.range || this.lastHover) return + + const { before } = this.multipleStatus + + if (!before) { + this.multipleStatus.before = fullDate + } else { + this.multipleStatus.after = fullDate + if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); + } else { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); + } + } + this.getWeeks(fullDate) + } + + /** + * 更新默认值多选状态 + */ + setDefaultMultiple(before, after) { + this.multipleStatus.before = before + this.multipleStatus.after = after + if (before && after) { + if (dateCompare(before, after)) { + this.multipleStatus.data = this.geDateAll(before, after); + this.getWeeks(after) + } else { + this.multipleStatus.data = this.geDateAll(after, before); + this.getWeeks(before) + } + } + } + + /** + * 获取每周数据 + * @param {Object} dateData + */ + getWeeks(dateData) { + const { + year, + month, + } = this.getDateObj(dateData) + + const preMonthDayAmount = new Date(year, month - 1, 1).getDay() + const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData)) + + const currentMonthDayAmount = new Date(year, month, 0).getDate() + const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData)) + + const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount + const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData)) + + const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays] + + const weeks = new Array(6) + for (let i = 0; i < calendarDays.length; i++) { + const index = Math.floor(i / 7) + if(!weeks[index]){ + weeks[index] = new Array(7) + } + weeks[index][i % 7] = calendarDays[i] + } + + this.calendar = calendarDays + this.weeks = weeks + } +} + +function getDateTime(date, hideSecond){ + return `${getDate(date)} ${getTime(date, hideSecond)}` +} + +function getDate(date) { + date = fixIosDateFormat(date) + date = new Date(date) + const year = date.getFullYear() + const month = date.getMonth()+1 + const day = date.getDate() + return `${year}-${addZero(month)}-${addZero(day)}` +} + +function getTime(date, hideSecond){ + date = fixIosDateFormat(date) + date = new Date(date) + const hour = date.getHours() + const minute = date.getMinutes() + const second = date.getSeconds() + return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}` +} + +function addZero(num) { + if(num < 10){ + num = `0${num}` + } + return num +} + +function getDefaultSecond(hideSecond) { + return hideSecond ? '00:00' : '00:00:00' +} + +function dateCompare(startDate, endDate) { + startDate = new Date(fixIosDateFormat(startDate)) + endDate = new Date(fixIosDateFormat(endDate)) + return startDate <= endDate +} + +function checkDate(date){ + const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g + return date.match(dateReg) +} + +const dateTimeReg = /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])( [0-5][0-9]:[0-5][0-9]:[0-5][0-9])?$/ +function fixIosDateFormat(value) { + if (typeof value === 'string' && dateTimeReg.test(value)) { + value = value.replace(/-/g, '/') + } + return value +} + +export {Calendar, getDateTime, getDate, getTime, addZero, getDefaultSecond, dateCompare, checkDate, fixIosDateFormat} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-datetime-picker/package.json b/alpha/admin/uni_modules/uni-datetime-picker/package.json new file mode 100644 index 0000000..8abed63 --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-datetime-picker", + "displayName": "uni-datetime-picker 日期选择器", + "version": "2.2.22", + "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择", + "keywords": [ + "uni-datetime-picker", + "uni-ui", + "uniui", + "日期时间选择器", + "日期时间" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-datetime-picker/readme.md b/alpha/admin/uni_modules/uni-datetime-picker/readme.md new file mode 100644 index 0000000..162fbef --- /dev/null +++ b/alpha/admin/uni_modules/uni-datetime-picker/readme.md @@ -0,0 +1,21 @@ + + +> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护` + +## DatetimePicker 时间选择器 + +> **组件名:uni-datetime-picker** +> 代码块: `uDatetimePicker` + + +该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。 + +若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。 + +**_点击 picker 默认值规则:_** + +- 若设置初始值 value, 会显示在 picker 显示框中 +- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-drawer/changelog.md b/alpha/admin/uni_modules/uni-drawer/changelog.md new file mode 100644 index 0000000..6d2488c --- /dev/null +++ b/alpha/admin/uni_modules/uni-drawer/changelog.md @@ -0,0 +1,13 @@ +## 1.2.1(2021-11-22) +- 修复 vue3中个别scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-drawer](https://uniapp.dcloud.io/component/uniui/uni-drawer) +## 1.1.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/keypress.js b/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/keypress.js new file mode 100644 index 0000000..62dda46 --- /dev/null +++ b/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + // this.$once('hook:beforeDestroy', () => { + // document.removeEventListener('keyup', listener) + // }) + }, + render: () => {} +} +// #endif diff --git a/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue b/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue new file mode 100644 index 0000000..2471521 --- /dev/null +++ b/alpha/admin/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-drawer/package.json b/alpha/admin/uni_modules/uni-drawer/package.json new file mode 100644 index 0000000..dd056e4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-drawer/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-drawer", + "displayName": "uni-drawer 抽屉", + "version": "1.2.1", + "description": "抽屉式导航,用于展示侧滑菜单,侧滑导航。", + "keywords": [ + "uni-ui", + "uniui", + "drawer", + "抽屉", + "侧滑导航" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-drawer/readme.md b/alpha/admin/uni_modules/uni-drawer/readme.md new file mode 100644 index 0000000..dcf6e6b --- /dev/null +++ b/alpha/admin/uni_modules/uni-drawer/readme.md @@ -0,0 +1,10 @@ + + +## Drawer 抽屉 +> **组件名:uni-drawer** +> 代码块: `uDrawer` + +抽屉侧滑菜单。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-drawer) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-easyinput/changelog.md b/alpha/admin/uni_modules/uni-easyinput/changelog.md new file mode 100644 index 0000000..5f5a55d --- /dev/null +++ b/alpha/admin/uni_modules/uni-easyinput/changelog.md @@ -0,0 +1,91 @@ +## 1.1.6(2023-01-28) +- 新增 keyboardheightchange 事件,可监听键盘高度变化 +## 1.1.5(2022-11-29) +- 优化 主题样式 +## 1.1.4(2022-10-27) +- 修复 props 中背景颜色无默认值的bug +## 1.1.0(2022-06-30) + +- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容 +- 新增 clear 事件,点击右侧叉号图标触发 +- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发 +- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等 + +## 1.0.5(2022-06-07) + +- 优化 clearable 显示策略 + +## 1.0.4(2022-06-07) + +- 优化 clearable 显示策略 + +## 1.0.3(2022-05-20) + +- 修复 关闭图标某些情况下无法取消的 bug + +## 1.0.2(2022-04-12) + +- 修复 默认值不生效的 bug + +## 1.0.1(2022-04-02) + +- 修复 value 不能为 0 的 bug + +## 1.0.0(2021-11-19) + +- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput) + +## 0.1.4(2021-08-20) + +- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug + +## 0.1.3(2021-08-11) + +- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题 + +## 0.1.2(2021-07-30) + +- 优化 vue3 下事件警告的问题 + +## 0.1.1 + +- 优化 errorMessage 属性支持 Boolean 类型 + +## 0.1.0(2021-07-13) + +- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) + +## 0.0.16(2021-06-29) + +- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug + +## 0.0.15(2021-06-21) + +- 修复 passwordIcon 属性拼写错误的 bug + +## 0.0.14(2021-06-18) + +- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标 +- 修复 confirmType 属性不生效的问题 + +## 0.0.13(2021-06-04) + +- 修复 disabled 状态可清出内容的 bug + +## 0.0.12(2021-05-12) + +- 新增 组件示例地址 + +## 0.0.11(2021-05-07) + +- 修复 input-border 属性不生效的问题 + +## 0.0.10(2021-04-30) + +- 修复 ios 遮挡文字、显示一半的问题 + +## 0.0.9(2021-02-05) + +- 调整为 uni_modules 目录规范 +- 优化 兼容 nvue 页面 diff --git a/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/common.js b/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/common.js new file mode 100644 index 0000000..df9abe1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/common.js @@ -0,0 +1,56 @@ +/** + * @desc 函数防抖 + * @param func 目标函数 + * @param wait 延迟执行毫秒数 + * @param immediate true - 立即执行, false - 延迟执行 + */ +export const debounce = function(func, wait = 1000, immediate = true) { + let timer; + console.log(1); + return function() { + console.log(123); + let context = this, + args = arguments; + if (timer) clearTimeout(timer); + if (immediate) { + let callNow = !timer; + timer = setTimeout(() => { + timer = null; + }, wait); + if (callNow) func.apply(context, args); + } else { + timer = setTimeout(() => { + func.apply(context, args); + }, wait) + } + } +} +/** + * @desc 函数节流 + * @param func 函数 + * @param wait 延迟执行毫秒数 + * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发 + */ +export const throttle = (func, wait = 1000, type = 1) => { + let previous = 0; + let timeout; + return function() { + let context = this; + let args = arguments; + if (type === 1) { + let now = Date.now(); + + if (now - previous > wait) { + func.apply(context, args); + previous = now; + } + } else if (type === 2) { + if (!timeout) { + timeout = setTimeout(() => { + timeout = null; + func.apply(context, args) + }, wait) + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue new file mode 100644 index 0000000..4511fb1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue @@ -0,0 +1,650 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-easyinput/package.json b/alpha/admin/uni_modules/uni-easyinput/package.json new file mode 100644 index 0000000..657771a --- /dev/null +++ b/alpha/admin/uni_modules/uni-easyinput/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-easyinput", + "displayName": "uni-easyinput 增强输入框", + "version": "1.1.6", + "description": "Easyinput 组件是对原生input组件的增强", + "keywords": [ + "uni-ui", + "uniui", + "input", + "uni-easyinput", + "输入框" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-easyinput/readme.md b/alpha/admin/uni_modules/uni-easyinput/readme.md new file mode 100644 index 0000000..f1faf8f --- /dev/null +++ b/alpha/admin/uni_modules/uni-easyinput/readme.md @@ -0,0 +1,11 @@ + + +### Easyinput 增强输入框 +> **组件名:uni-easyinput** +> 代码块: `uEasyinput` + + +easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-feedback/changelog.md b/alpha/admin/uni_modules/uni-feedback/changelog.md new file mode 100644 index 0000000..9ba4692 --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/changelog.md @@ -0,0 +1,8 @@ +## 1.1.0(2022-07-13) +新增,应用[pages_init](https://uniapp.dcloud.io/plugin/publish.html#pages-init)当导入插件到项目工程时,自动合并本插件的页面路由到项目的pages.json +## 1.0.5(2022-07-13) +新增,应用[pages_init](https://uniapp.dcloud.io/plugin/publish.html#pages-init)当导入插件到项目工程时,自动合并本插件的页面路由到项目的pages.json +## 1.0.4(2021-09-26) +为了数据安全,`opendb-feedback`表的`permission`中`delete`,`update`的值默认为`false` +## 1.0.3(2021-08-26) +删除多余的云函数test2 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-feedback/js_sdk/validator/opendb-feedback.js b/alpha/admin/uni_modules/uni-feedback/js_sdk/validator/opendb-feedback.js new file mode 100644 index 0000000..be3d330 --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/js_sdk/validator/opendb-feedback.js @@ -0,0 +1,98 @@ +// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema + + +const validator = { + "content": { + "rules": [ + { + "required": true + }, + { + "format": "string" + } + ], + "label": "留言内容/回复内容" + }, + "imgs": { + "rules": [ + { + "format": "array" + }, + { + "arrayType": "file" + }, + { + "maxLength": 6 + } + ], + "label": "图片列表" + }, + "contact": { + "rules": [ + { + "format": "string" + } + ], + "label": "联系人" + }, + "mobile": { + "rules": [ + { + "format": "string" + }, + { + "pattern": "^\\+?[0-9-]{3,20}$" + } + ], + "label": "联系电话" + } +} + +const enumConverter = {} + +function filterToWhere(filter, command) { + let where = {} + for (let field in filter) { + let { type, value } = filter[field] + switch (type) { + case "search": + if (typeof value === 'string' && value.length) { + where[field] = new RegExp(value) + } + break; + case "select": + if (value.length) { + let selectValue = [] + for (let s of value) { + selectValue.push(command.eq(s)) + } + where[field] = command.or(selectValue) + } + break; + case "range": + if (value.length) { + let gt = value[0] + let lt = value[1] + where[field] = command.and([command.gte(gt), command.lte(lt)]) + } + break; + case "date": + if (value.length) { + let [s, e] = value + let startDate = new Date(s) + let endDate = new Date(e) + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + case "timestamp": + if (value.length) { + let [startDate, endDate] = value + where[field] = command.and([command.gte(startDate), command.lte(endDate)]) + } + break; + } + } + return where +} + +export { validator, enumConverter, filterToWhere } diff --git a/alpha/admin/uni_modules/uni-feedback/package.json b/alpha/admin/uni_modules/uni-feedback/package.json new file mode 100644 index 0000000..8d1818f --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/package.json @@ -0,0 +1,92 @@ +{ + "id": "uni-feedback", + "displayName": "问题反馈页面模板", + "version": "1.1.0", + "description": "问题反馈页面模板,方便开发者快速搭建问题反馈界面", + "keywords": [ + "问题反馈页面模板" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "uniCloud", + "云端一体页面模板" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uni-forms", + "uni-file-picker", + "uni-easyinput", + "uni-load-more", + "uni-list", + "uni-fab", + "uni-link" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "u", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/detail.vue b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/detail.vue new file mode 100644 index 0000000..fa28fca --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/detail.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/edit.vue b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/edit.vue new file mode 100644 index 0000000..bd65125 --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/edit.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/list.vue b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/list.vue new file mode 100644 index 0000000..1131edb --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/list.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/opendb-feedback.vue b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/opendb-feedback.vue new file mode 100644 index 0000000..f8bc77e --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/pages/opendb-feedback/opendb-feedback.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-feedback/readme.md b/alpha/admin/uni_modules/uni-feedback/readme.md new file mode 100644 index 0000000..65d9192 --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/readme.md @@ -0,0 +1 @@ +这是一个问题反馈客户端插件,admin端插件:[https://ext.dcloud.net.cn/plugin?id=4992](https://ext.dcloud.net.cn/plugin?id=4992) \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-feedback/uniCloud/database/opendb-feedback.schema.json b/alpha/admin/uni_modules/uni-feedback/uniCloud/database/opendb-feedback.schema.json new file mode 100644 index 0000000..e426955 --- /dev/null +++ b/alpha/admin/uni_modules/uni-feedback/uniCloud/database/opendb-feedback.schema.json @@ -0,0 +1,53 @@ +{ + "bsonType": "object", + "required": [ + "user_id", + "content" + ], + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "user_id": { + "bsonType": "string", + "description": "留言反馈用户ID/回复留言用户ID,参考uni-id-users表", + "foreignKey": "uni-id-users._id" + }, + "create_date": { + "bsonType": "timestamp", + "description": "留言时间/回复留言时间" + }, + "content": { + "bsonType": "string", + "description": "留言内容/回复内容", + "trim": "right" + }, + "imgs": { + "bsonType": "array", + "description": "图片列表" + }, + "is_reply": { + "bsonType": "bool", + "description": "是否是回复类型" + }, + "feedback_id": { + "bsonType": "string", + "description": "被回复留言ID" + }, + "contact": { + "bsonType": "string", + "description": "联系人", + "trim": "both" + }, + "mobile": { + "bsonType": "string", + "description": "联系电话", + "trim": "both" + }, + "reply_count": { + "bsonType": "int", + "description": "被回复条数" + } + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-file-picker/changelog.md b/alpha/admin/uni_modules/uni-file-picker/changelog.md new file mode 100644 index 0000000..e1621c3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/changelog.md @@ -0,0 +1,65 @@ +## 1.0.3(2022-12-21) +- 新增 sourceType 属性, 可以自定义图片和视频选择的来源 +## 1.0.2(2022-07-04) +- 修复 在uni-forms下样式不生效的bug +## 1.0.1(2021-11-23) +- 修复 参数为对象的情况下,url在某些情况显示错误的bug +## 1.0.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-file-picker](https://uniapp.dcloud.io/component/uniui/uni-file-picker) +## 0.2.16(2021-11-08) +- 修复 传入空对象 ,显示错误的Bug +## 0.2.15(2021-08-30) +- 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug +## 0.2.14(2021-08-23) +- 新增 参数中返回 fileID 字段 +## 0.2.13(2021-08-23) +- 修复 腾讯云传入fileID 不能回显的bug +- 修复 选择图片后,不能放大的问题 +## 0.2.12(2021-08-17) +- 修复 由于 0.2.11 版本引起的不能回显图片的Bug +## 0.2.11(2021-08-16) +- 新增 clearFiles(index) 方法,可以手动删除指定文件 +- 修复 v-model 值设为 null 报错的Bug +## 0.2.10(2021-08-13) +- 修复 return-type="object" 时,无法删除文件的Bug +## 0.2.9(2021-08-03) +- 修复 auto-upload 属性失效的Bug +## 0.2.8(2021-07-31) +- 修复 fileExtname属性不指定值报错的Bug +## 0.2.7(2021-07-31) +- 修复 在某种场景下图片不回显的Bug +## 0.2.6(2021-07-30) +- 修复 return-type为object下,返回值不正确的Bug +## 0.2.5(2021-07-30) +- 修复(重要) H5 平台下如果和uni-forms组件一同使用导致页面卡死的问题 +## 0.2.3(2021-07-28) +- 优化 调整示例代码 +## 0.2.2(2021-07-27) +- 修复 vue3 下赋值错误的Bug +- 优化 h5平台下上传文件导致页面卡死的问题 +## 0.2.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 0.1.1(2021-07-02) +- 修复 sourceType 缺少默认值导致 ios 无法选择文件 +## 0.1.0(2021-06-30) +- 优化 解耦与uniCloud的强绑定关系 ,如不绑定服务空间,默认autoUpload为false且不可更改 +## 0.0.11(2021-06-30) +- 修复 由 0.0.10 版本引发的 returnType 属性失效的问题 +## 0.0.10(2021-06-29) +- 优化 文件上传后进度条消失时机 +## 0.0.9(2021-06-29) +- 修复 在uni-forms 中,删除文件 ,获取的值不对的Bug +## 0.0.8(2021-06-15) +- 修复 删除文件时无法触发 v-model 的Bug +## 0.0.7(2021-05-12) +- 新增 组件示例地址 +## 0.0.6(2021-04-09) +- 修复 选择的文件非 file-extname 字段指定的扩展名报错的Bug +## 0.0.5(2021-04-09) +- 优化 更新组件示例 +## 0.0.4(2021-04-09) +- 优化 file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔 +## 0.0.3(2021-02-05) +- 调整为uni_modules目录规范 +- 修复 微信小程序不指定 fileExtname 属性选择失败的Bug diff --git a/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js new file mode 100644 index 0000000..aff0864 --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js @@ -0,0 +1,224 @@ +'use strict'; + +const ERR_MSG_OK = 'chooseAndUploadFile:ok'; +const ERR_MSG_FAIL = 'chooseAndUploadFile:fail'; + +function chooseImage(opts) { + const { + count, + sizeType = ['original', 'compressed'], + sourceType, + extension + } = opts + return new Promise((resolve, reject) => { + uni.chooseImage({ + count, + sizeType, + sourceType, + extension, + success(res) { + resolve(normalizeChooseAndUploadFileRes(res, 'image')); + }, + fail(res) { + reject({ + errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL), + }); + }, + }); + }); +} + +function chooseVideo(opts) { + const { + camera, + compressed, + maxDuration, + sourceType, + extension + } = opts; + return new Promise((resolve, reject) => { + uni.chooseVideo({ + camera, + compressed, + maxDuration, + sourceType, + extension, + success(res) { + const { + tempFilePath, + duration, + size, + height, + width + } = res; + resolve(normalizeChooseAndUploadFileRes({ + errMsg: 'chooseVideo:ok', + tempFilePaths: [tempFilePath], + tempFiles: [ + { + name: (res.tempFile && res.tempFile.name) || '', + path: tempFilePath, + size, + type: (res.tempFile && res.tempFile.type) || '', + width, + height, + duration, + fileType: 'video', + cloudPath: '', + }, ], + }, 'video')); + }, + fail(res) { + reject({ + errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL), + }); + }, + }); + }); +} + +function chooseAll(opts) { + const { + count, + extension + } = opts; + return new Promise((resolve, reject) => { + let chooseFile = uni.chooseFile; + if (typeof wx !== 'undefined' && + typeof wx.chooseMessageFile === 'function') { + chooseFile = wx.chooseMessageFile; + } + if (typeof chooseFile !== 'function') { + return reject({ + errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。', + }); + } + chooseFile({ + type: 'all', + count, + extension, + success(res) { + resolve(normalizeChooseAndUploadFileRes(res)); + }, + fail(res) { + reject({ + errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL), + }); + }, + }); + }); +} + +function normalizeChooseAndUploadFileRes(res, fileType) { + res.tempFiles.forEach((item, index) => { + if (!item.name) { + item.name = item.path.substring(item.path.lastIndexOf('/') + 1); + } + if (fileType) { + item.fileType = fileType; + } + item.cloudPath = + Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.')); + }); + if (!res.tempFilePaths) { + res.tempFilePaths = res.tempFiles.map((file) => file.path); + } + return res; +} + +function uploadCloudFiles(files, max = 5, onUploadProgress) { + files = JSON.parse(JSON.stringify(files)) + const len = files.length + let count = 0 + let self = this + return new Promise(resolve => { + while (count < max) { + next() + } + + function next() { + let cur = count++ + if (cur >= len) { + !files.find(item => !item.url && !item.errMsg) && resolve(files) + return + } + const fileItem = files[cur] + const index = self.files.findIndex(v => v.uuid === fileItem.uuid) + fileItem.url = '' + delete fileItem.errMsg + + uniCloud + .uploadFile({ + filePath: fileItem.path, + cloudPath: fileItem.cloudPath, + fileType: fileItem.fileType, + onUploadProgress: res => { + res.index = index + onUploadProgress && onUploadProgress(res) + } + }) + .then(res => { + fileItem.url = res.fileID + fileItem.index = index + if (cur < len) { + next() + } + }) + .catch(res => { + fileItem.errMsg = res.errMsg || res.message + fileItem.index = index + if (cur < len) { + next() + } + }) + } + }) +} + + + + + +function uploadFiles(choosePromise, { + onChooseFile, + onUploadProgress +}) { + return choosePromise + .then((res) => { + if (onChooseFile) { + const customChooseRes = onChooseFile(res); + if (typeof customChooseRes !== 'undefined') { + return Promise.resolve(customChooseRes).then((chooseRes) => typeof chooseRes === 'undefined' ? + res : chooseRes); + } + } + return res; + }) + .then((res) => { + if (res === false) { + return { + errMsg: ERR_MSG_OK, + tempFilePaths: [], + tempFiles: [], + }; + } + return res + }) +} + +function chooseAndUploadFile(opts = { + type: 'all' +}) { + if (opts.type === 'image') { + return uploadFiles(chooseImage(opts), opts); + } + else if (opts.type === 'video') { + return uploadFiles(chooseVideo(opts), opts); + } + return uploadFiles(chooseAll(opts), opts); +} + +export { + chooseAndUploadFile, + uploadCloudFiles +}; diff --git a/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue new file mode 100644 index 0000000..9bb9829 --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue @@ -0,0 +1,663 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue new file mode 100644 index 0000000..625d92e --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue @@ -0,0 +1,325 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue new file mode 100644 index 0000000..2a29bc2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/utils.js b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/utils.js new file mode 100644 index 0000000..60aaa3e --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/components/uni-file-picker/utils.js @@ -0,0 +1,109 @@ +/** + * 获取文件名和后缀 + * @param {String} name + */ +export const get_file_ext = (name) => { + const last_len = name.lastIndexOf('.') + const len = name.length + return { + name: name.substring(0, last_len), + ext: name.substring(last_len + 1, len) + } +} + +/** + * 获取扩展名 + * @param {Array} fileExtname + */ +export const get_extname = (fileExtname) => { + if (!Array.isArray(fileExtname)) { + let extname = fileExtname.replace(/(\[|\])/g, '') + return extname.split(',') + } else { + return fileExtname + } + return [] +} + +/** + * 获取文件和检测是否可选 + */ +export const get_files_and_is_max = (res, _extname) => { + let filePaths = [] + let files = [] + if(!_extname || _extname.length === 0){ + return { + filePaths, + files + } + } + res.tempFiles.forEach(v => { + let fileFullName = get_file_ext(v.name) + const extname = fileFullName.ext.toLowerCase() + if (_extname.indexOf(extname) !== -1) { + files.push(v) + filePaths.push(v.path) + } + }) + if (files.length !== res.tempFiles.length) { + uni.showToast({ + title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`, + icon: 'none', + duration: 5000 + }) + } + + return { + filePaths, + files + } +} + + +/** + * 获取图片信息 + * @param {Object} filepath + */ +export const get_file_info = (filepath) => { + return new Promise((resolve, reject) => { + uni.getImageInfo({ + src: filepath, + success(res) { + resolve(res) + }, + fail(err) { + reject(err) + } + }) + }) +} +/** + * 获取封装数据 + */ +export const get_file_data = async (files, type = 'image') => { + // 最终需要上传数据库的数据 + let fileFullName = get_file_ext(files.name) + const extname = fileFullName.ext.toLowerCase() + let filedata = { + name: files.name, + uuid: files.uuid, + extname: extname || '', + cloudPath: files.cloudPath, + fileType: files.fileType, + url: files.path || files.path, + size: files.size, //单位是字节 + image: {}, + path: files.path, + video: {} + } + if (type === 'image') { + const imageinfo = await get_file_info(files.path) + delete filedata.video + filedata.image.width = imageinfo.width + filedata.image.height = imageinfo.height + filedata.image.location = imageinfo.path + } else { + delete filedata.image + } + return filedata +} diff --git a/alpha/admin/uni_modules/uni-file-picker/package.json b/alpha/admin/uni_modules/uni-file-picker/package.json new file mode 100644 index 0000000..8d5227b --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-file-picker", + "displayName": "uni-file-picker 文件选择上传", + "version": "1.0.3", + "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间", + "keywords": [ + "uni-ui", + "uniui", + "图片上传", + "文件上传" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-file-picker/readme.md b/alpha/admin/uni_modules/uni-file-picker/readme.md new file mode 100644 index 0000000..c8399a5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-file-picker/readme.md @@ -0,0 +1,11 @@ + +## FilePicker 文件选择上传 + +> **组件名:uni-file-picker** +> 代码块: `uFilePicker` + + +文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-file-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-forms/changelog.md b/alpha/admin/uni_modules/uni-forms/changelog.md new file mode 100644 index 0000000..c358a21 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/changelog.md @@ -0,0 +1,90 @@ +## 1.4.8(2022-08-23) +- 优化 根据 rules 自动添加 required 的问题 +## 1.4.7(2022-08-22) +- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540) +## 1.4.6(2022-07-13) +- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug +## 1.4.5(2022-07-05) +- 新增 更多表单示例 +- 优化 子表单组件过期提示的问题 +- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式 +## 1.4.4(2022-07-04) +- 更新 删除组件日志 +## 1.4.3(2022-07-04) +- 修复 由 1.4.0 引发的 label 插槽不生效的bug +## 1.4.2(2022-07-04) +- 修复 子组件找不到 setValue 报错的bug +## 1.4.1(2022-07-04) +- 修复 uni-data-picker 在 uni-forms-item 中报错的bug +- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug +## 1.4.0(2022-06-30) +- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题 +- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力 +- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃 +- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效 +- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法 +- 新增 子表单的 setRules 方法,配合自定义校验函数使用 +- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则 +- 优化 动态表单校验方式,废弃拼接name的方式 +## 1.3.3(2022-06-22) +- 修复 表单校验顺序无序问题 +## 1.3.2(2021-12-09) +- +## 1.3.1(2021-11-19) +- 修复 label 插槽不生效的bug +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms) +## 1.2.7(2021-08-13) +- 修复 没有添加校验规则的字段依然报错的Bug +## 1.2.6(2021-08-11) +- 修复 重置表单错误信息无法清除的问题 +## 1.2.5(2021-08-11) +- 优化 组件文档 +## 1.2.4(2021-08-11) +- 修复 表单验证只生效一次的问题 +## 1.2.3(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.2.2(2021-07-26) +- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug +- 修复 1.2.1 引起的示例在小程序平台报错的Bug +## 1.2.1(2021-07-22) +- 修复 动态校验表单,默认值为空的情况下校验失效的Bug +- 修复 不指定name属性时,运行报错的Bug +- 优化 label默认宽度从65调整至70,使required为true且四字时不换行 +- 优化 组件示例,新增动态校验示例代码 +- 优化 组件文档,使用方式更清晰 +## 1.2.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.2(2021-06-25) +- 修复 pattern 属性在微信小程序平台无效的问题 +## 1.1.1(2021-06-22) +- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug +## 1.1.0(2021-06-22) +- 修复 只写setRules方法而导致校验不生效的Bug +- 修复 由上个办法引发的错误提示文字错位的Bug +## 1.0.48(2021-06-21) +- 修复 不设置 label 属性 ,无法设置label插槽的问题 +## 1.0.47(2021-06-21) +- 修复 不设置label属性,label-width属性不生效的bug +- 修复 setRules 方法与rules属性冲突的问题 +## 1.0.46(2021-06-04) +- 修复 动态删减数据导致报错的问题 +## 1.0.45(2021-06-04) +- 新增 modelValue 属性 ,value 即将废弃 +## 1.0.44(2021-06-02) +- 新增 uni-forms-item 可以设置单独的 rules +- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤 +- 优化 submit 事件重命名为 validate +## 1.0.43(2021-05-12) +- 新增 组件示例地址 +## 1.0.42(2021-04-30) +- 修复 自定义检验器失效的问题 +## 1.0.41(2021-03-05) +- 更新 校验器 +- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug +## 1.0.40(2021-03-04) +- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug +## 1.0.39(2021-02-05) +- 调整为uni_modules目录规范 +- 修复 校验器传入 int 等类型 ,返回String类型的Bug diff --git a/alpha/admin/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue b/alpha/admin/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue new file mode 100644 index 0000000..ce7c460 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue @@ -0,0 +1,631 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-forms/components/uni-forms/uni-forms.vue b/alpha/admin/uni_modules/uni-forms/components/uni-forms/uni-forms.vue new file mode 100644 index 0000000..ed2f6d9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/components/uni-forms/uni-forms.vue @@ -0,0 +1,397 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-forms/components/uni-forms/utils.js b/alpha/admin/uni_modules/uni-forms/components/uni-forms/utils.js new file mode 100644 index 0000000..6da2421 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/components/uni-forms/utils.js @@ -0,0 +1,293 @@ +/** + * 简单处理对象拷贝 + * @param {Obejct} 被拷贝对象 + * @@return {Object} 拷贝对象 + */ +export const deepCopy = (val) => { + return JSON.parse(JSON.stringify(val)) +} +/** + * 过滤数字类型 + * @param {String} format 数字类型 + * @@return {Boolean} 返回是否为数字类型 + */ +export const typeFilter = (format) => { + return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp'; +} + +/** + * 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined + * @param {String} key 字段名 + * @param {any} value 字段值 + * @param {Object} rules 表单校验规则 + */ +export const getValue = (key, value, rules) => { + const isRuleNumType = rules.find(val => val.format && typeFilter(val.format)); + const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool'); + // 输入类型为 number + if (!!isRuleNumType) { + if (!value && value !== 0) { + value = null + } else { + value = isNumber(Number(value)) ? Number(value) : value + } + } + + // 输入类型为 boolean + if (!!isRuleBoolType) { + value = isBoolean(value) ? value : false + } + + return value; +} + +/** + * 获取表单数据 + * @param {String|Array} name 真实名称,需要使用 realName 获取 + * @param {Object} data 原始数据 + * @param {any} value 需要设置的值 + */ +export const setDataValue = (field, formdata, value) => { + formdata[field] = value + return value || '' +} + +/** + * 获取表单数据 + * @param {String|Array} field 真实名称,需要使用 realName 获取 + * @param {Object} data 原始数据 + */ +export const getDataValue = (field, data) => { + return objGet(data, field) +} + +/** + * 获取表单类型 + * @param {String|Array} field 真实名称,需要使用 realName 获取 + */ +export const getDataValueType = (field, data) => { + const value = getDataValue(field, data) + return { + type: type(value), + value + } +} + +/** + * 获取表单可用的真实name + * @param {String|Array} name 表单name + * @@return {String} 表单可用的真实name + */ +export const realName = (name, data = {}) => { + const base_name = _basePath(name) + if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) { + const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_') + return realname + } + return base_name[0] || name +} + +/** + * 判断是否表单可用的真实name + * @param {String|Array} name 表单name + * @@return {String} 表单可用的真实name + */ +export const isRealName = (name) => { + const reg = /^_formdata_#*/ + return reg.test(name) +} + +/** + * 获取表单数据的原始格式 + * @@return {Object|Array} object 需要解析的数据 + */ +export const rawData = (object = {}, name) => { + let newData = JSON.parse(JSON.stringify(object)) + let formData = {} + for(let i in newData){ + let path = name2arr(i) + objSet(formData,path,newData[i]) + } + return formData +} + +/** + * 真实name还原为 array + * @param {*} name + */ +export const name2arr = (name) => { + let field = name.replace('_formdata_#', '') + field = field.split('#').map(v => (isNumber(v) ? Number(v) : v)) + return field +} + +/** + * 对象中设置值 + * @param {Object|Array} object 源数据 + * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] + * @param {String} value 需要设置的值 + */ +export const objSet = (object, path, value) => { + if (typeof object !== 'object') return object; + _basePath(path).reduce((o, k, i, _) => { + if (i === _.length - 1) { + // 若遍历结束直接赋值 + o[k] = value + return null + } else if (k in o) { + // 若存在对应路径,则返回找到的对象,进行下一次遍历 + return o[k] + } else { + // 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象 + o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {} + return o[k] + } + }, object) + // 返回object + return object; +} + +// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用 +function _basePath(path) { + // 若是数组,则直接返回 + if (Array.isArray(path)) return path + // 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']' + return path.replace(/\[/g, '.').replace(/\]/g, '').split('.') +} + +/** + * 从对象中获取值 + * @param {Object|Array} object 源数据 + * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] + * @param {String} defaultVal 如果无法从调用链中获取值的默认值 + */ +export const objGet = (object, path, defaultVal = 'undefined') => { + // 先将path处理成统一格式 + let newPath = _basePath(path) + // 递归处理,返回最后结果 + let val = newPath.reduce((o, k) => { + return (o || {})[k] + }, object); + return !val || val !== undefined ? val : defaultVal +} + + +/** + * 是否为 number 类型 + * @param {any} num 需要判断的值 + * @return {Boolean} 是否为 number + */ +export const isNumber = (num) => { + return !isNaN(Number(num)) +} + +/** + * 是否为 boolean 类型 + * @param {any} bool 需要判断的值 + * @return {Boolean} 是否为 boolean + */ +export const isBoolean = (bool) => { + return (typeof bool === 'boolean') +} +/** + * 是否有必填字段 + * @param {Object} rules 规则 + * @return {Boolean} 是否有必填字段 + */ +export const isRequiredField = (rules) => { + let isNoField = false; + for (let i = 0; i < rules.length; i++) { + const ruleData = rules[i]; + if (ruleData.required) { + isNoField = true; + break; + } + } + return isNoField; +} + + +/** + * 获取数据类型 + * @param {Any} obj 需要获取数据类型的值 + */ +export const type = (obj) => { + var class2type = {}; + + // 生成class2type映射 + "Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) { + class2type["[object " + item + "]"] = item.toLowerCase(); + }) + if (obj == null) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[Object.prototype.toString.call(obj)] || "object" : + typeof obj; +} + +/** + * 判断两个值是否相等 + * @param {any} a 值 + * @param {any} b 值 + * @return {Boolean} 是否相等 + */ +export const isEqual = (a, b) => { + //如果a和b本来就全等 + if (a === b) { + //判断是否为0和-0 + return a !== 0 || 1 / a === 1 / b; + } + //判断是否为null和undefined + if (a == null || b == null) { + return a === b; + } + //接下来判断a和b的数据类型 + var classNameA = toString.call(a), + classNameB = toString.call(b); + //如果数据类型不相等,则返回false + if (classNameA !== classNameB) { + return false; + } + //如果数据类型相等,再根据不同数据类型分别判断 + switch (classNameA) { + case '[object RegExp]': + case '[object String]': + //进行字符串转换比较 + return '' + a === '' + b; + case '[object Number]': + //进行数字转换比较,判断是否为NaN + if (+a !== +a) { + return +b !== +b; + } + //判断是否为0或-0 + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + return +a === +b; + } + //如果是对象类型 + if (classNameA == '[object Object]') { + //获取a和b的属性长度 + var propsA = Object.getOwnPropertyNames(a), + propsB = Object.getOwnPropertyNames(b); + if (propsA.length != propsB.length) { + return false; + } + for (var i = 0; i < propsA.length; i++) { + var propName = propsA[i]; + //如果对应属性对应值不相等,则返回false + if (a[propName] !== b[propName]) { + return false; + } + } + return true; + } + //如果是数组类型 + if (classNameA == '[object Array]') { + if (a.toString() == b.toString()) { + return true; + } + return false; + } +} diff --git a/alpha/admin/uni_modules/uni-forms/components/uni-forms/validate.js b/alpha/admin/uni_modules/uni-forms/components/uni-forms/validate.js new file mode 100644 index 0000000..1834c6c --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/components/uni-forms/validate.js @@ -0,0 +1,486 @@ +var pattern = { + email: /^\S+?@\S+?\.\S+?$/, + idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, + url: new RegExp( + "^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$", + 'i') +}; + +const FORMAT_MAPPING = { + "int": 'integer', + "bool": 'boolean', + "double": 'number', + "long": 'number', + "password": 'string' + // "fileurls": 'array' +} + +function formatMessage(args, resources = '') { + var defaultMessage = ['label'] + defaultMessage.forEach((item) => { + if (args[item] === undefined) { + args[item] = '' + } + }) + + let str = resources + for (let key in args) { + let reg = new RegExp('{' + key + '}') + str = str.replace(reg, args[key]) + } + return str +} + +function isEmptyValue(value, type) { + if (value === undefined || value === null) { + return true; + } + + if (typeof value === 'string' && !value) { + return true; + } + + if (Array.isArray(value) && !value.length) { + return true; + } + + if (type === 'object' && !Object.keys(value).length) { + return true; + } + + return false; +} + +const types = { + integer(value) { + return types.number(value) && parseInt(value, 10) === value; + }, + string(value) { + return typeof value === 'string'; + }, + number(value) { + if (isNaN(value)) { + return false; + } + return typeof value === 'number'; + }, + "boolean": function(value) { + return typeof value === 'boolean'; + }, + "float": function(value) { + return types.number(value) && !types.integer(value); + }, + array(value) { + return Array.isArray(value); + }, + object(value) { + return typeof value === 'object' && !types.array(value); + }, + date(value) { + return value instanceof Date; + }, + timestamp(value) { + if (!this.integer(value) || Math.abs(value).toString().length > 16) { + return false + } + return true; + }, + file(value) { + return typeof value.url === 'string'; + }, + email(value) { + return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255; + }, + url(value) { + return typeof value === 'string' && !!value.match(pattern.url); + }, + pattern(reg, value) { + try { + return new RegExp(reg).test(value); + } catch (e) { + return false; + } + }, + method(value) { + return typeof value === 'function'; + }, + idcard(value) { + return typeof value === 'string' && !!value.match(pattern.idcard); + }, + 'url-https'(value) { + return this.url(value) && value.startsWith('https://'); + }, + 'url-scheme'(value) { + return value.startsWith('://'); + }, + 'url-web'(value) { + return false; + } +} + +class RuleValidator { + + constructor(message) { + this._message = message + } + + async validateRule(fieldKey, fieldValue, value, data, allData) { + var result = null + + let rules = fieldValue.rules + + let hasRequired = rules.findIndex((item) => { + return item.required + }) + if (hasRequired < 0) { + if (value === null || value === undefined) { + return result + } + if (typeof value === 'string' && !value.length) { + return result + } + } + + var message = this._message + + if (rules === undefined) { + return message['default'] + } + + for (var i = 0; i < rules.length; i++) { + let rule = rules[i] + let vt = this._getValidateType(rule) + + Object.assign(rule, { + label: fieldValue.label || `["${fieldKey}"]` + }) + + if (RuleValidatorHelper[vt]) { + result = RuleValidatorHelper[vt](rule, value, message) + if (result != null) { + break + } + } + + if (rule.validateExpr) { + let now = Date.now() + let resultExpr = rule.validateExpr(value, allData, now) + if (resultExpr === false) { + result = this._getMessage(rule, rule.errorMessage || this._message['default']) + break + } + } + + if (rule.validateFunction) { + result = await this.validateFunction(rule, value, data, allData, vt) + if (result !== null) { + break + } + } + } + + if (result !== null) { + result = message.TAG + result + } + + return result + } + + async validateFunction(rule, value, data, allData, vt) { + let result = null + try { + let callbackMessage = null + const res = await rule.validateFunction(rule, value, allData || data, (message) => { + callbackMessage = message + }) + if (callbackMessage || (typeof res === 'string' && res) || res === false) { + result = this._getMessage(rule, callbackMessage || res, vt) + } + } catch (e) { + result = this._getMessage(rule, e.message, vt) + } + return result + } + + _getMessage(rule, message, vt) { + return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default']) + } + + _getValidateType(rule) { + var result = '' + if (rule.required) { + result = 'required' + } else if (rule.format) { + result = 'format' + } else if (rule.arrayType) { + result = 'arrayTypeFormat' + } else if (rule.range) { + result = 'range' + } else if (rule.maximum !== undefined || rule.minimum !== undefined) { + result = 'rangeNumber' + } else if (rule.maxLength !== undefined || rule.minLength !== undefined) { + result = 'rangeLength' + } else if (rule.pattern) { + result = 'pattern' + } else if (rule.validateFunction) { + result = 'validateFunction' + } + return result + } +} + +const RuleValidatorHelper = { + required(rule, value, message) { + if (rule.required && isEmptyValue(value, rule.format || typeof value)) { + return formatMessage(rule, rule.errorMessage || message.required); + } + + return null + }, + + range(rule, value, message) { + const { + range, + errorMessage + } = rule; + + let list = new Array(range.length); + for (let i = 0; i < range.length; i++) { + const item = range[i]; + if (types.object(item) && item.value !== undefined) { + list[i] = item.value; + } else { + list[i] = item; + } + } + + let result = false + if (Array.isArray(value)) { + result = (new Set(value.concat(list)).size === list.length); + } else { + if (list.indexOf(value) > -1) { + result = true; + } + } + + if (!result) { + return formatMessage(rule, errorMessage || message['enum']); + } + + return null + }, + + rangeNumber(rule, value, message) { + if (!types.number(value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + let { + minimum, + maximum, + exclusiveMinimum, + exclusiveMaximum + } = rule; + let min = exclusiveMinimum ? value <= minimum : value < minimum; + let max = exclusiveMaximum ? value >= maximum : value > maximum; + + if (minimum !== undefined && min) { + return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ? + 'exclusiveMinimum' : 'minimum' + ]) + } else if (maximum !== undefined && max) { + return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ? + 'exclusiveMaximum' : 'maximum' + ]) + } else if (minimum !== undefined && maximum !== undefined && (min || max)) { + return formatMessage(rule, rule.errorMessage || message['number'].range) + } + + return null + }, + + rangeLength(rule, value, message) { + if (!types.string(value) && !types.array(value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + let min = rule.minLength; + let max = rule.maxLength; + let val = value.length; + + if (min !== undefined && val < min) { + return formatMessage(rule, rule.errorMessage || message['length'].minLength) + } else if (max !== undefined && val > max) { + return formatMessage(rule, rule.errorMessage || message['length'].maxLength) + } else if (min !== undefined && max !== undefined && (val < min || val > max)) { + return formatMessage(rule, rule.errorMessage || message['length'].range) + } + + return null + }, + + pattern(rule, value, message) { + if (!types['pattern'](rule.pattern, value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + return null + }, + + format(rule, value, message) { + var customTypes = Object.keys(types); + var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType); + + if (customTypes.indexOf(format) > -1) { + if (!types[format](value)) { + return formatMessage(rule, rule.errorMessage || message.typeError); + } + } + + return null + }, + + arrayTypeFormat(rule, value, message) { + if (!Array.isArray(value)) { + return formatMessage(rule, rule.errorMessage || message.typeError); + } + + for (let i = 0; i < value.length; i++) { + const element = value[i]; + let formatResult = this.format(rule, element, message) + if (formatResult !== null) { + return formatResult + } + } + + return null + } +} + +class SchemaValidator extends RuleValidator { + + constructor(schema, options) { + super(SchemaValidator.message); + + this._schema = schema + this._options = options || null + } + + updateSchema(schema) { + this._schema = schema + } + + async validate(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidate(data, false, allData) + } + return result.length ? result[0] : null + } + + async validateAll(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidate(data, true, allData) + } + return result + } + + async validateUpdate(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidateUpdate(data, false, allData) + } + return result.length ? result[0] : null + } + + async invokeValidate(data, all, allData) { + let result = [] + let schema = this._schema + for (let key in schema) { + let value = schema[key] + let errorMessage = await this.validateRule(key, value, data[key], data, allData) + if (errorMessage != null) { + result.push({ + key, + errorMessage + }) + if (!all) break + } + } + return result + } + + async invokeValidateUpdate(data, all, allData) { + let result = [] + for (let key in data) { + let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData) + if (errorMessage != null) { + result.push({ + key, + errorMessage + }) + if (!all) break + } + } + return result + } + + _checkFieldInSchema(data) { + var keys = Object.keys(data) + var keys2 = Object.keys(this._schema) + if (new Set(keys.concat(keys2)).size === keys2.length) { + return '' + } + + var noExistFields = keys.filter((key) => { + return keys2.indexOf(key) < 0; + }) + var errorMessage = formatMessage({ + field: JSON.stringify(noExistFields) + }, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid']) + return [{ + key: 'invalid', + errorMessage + }] + } +} + +function Message() { + return { + TAG: "", + default: '验证错误', + defaultInvalid: '提交的字段{field}在数据库中并不存在', + validateFunction: '验证无效', + required: '{label}必填', + 'enum': '{label}超出范围', + timestamp: '{label}格式无效', + whitespace: '{label}不能为空', + typeError: '{label}类型无效', + date: { + format: '{label}日期{value}格式无效', + parse: '{label}日期无法解析,{value}无效', + invalid: '{label}日期{value}无效' + }, + length: { + minLength: '{label}长度不能少于{minLength}', + maxLength: '{label}长度不能超过{maxLength}', + range: '{label}必须介于{minLength}和{maxLength}之间' + }, + number: { + minimum: '{label}不能小于{minimum}', + maximum: '{label}不能大于{maximum}', + exclusiveMinimum: '{label}不能小于等于{minimum}', + exclusiveMaximum: '{label}不能大于等于{maximum}', + range: '{label}必须介于{minimum}and{maximum}之间' + }, + pattern: { + mismatch: '{label}格式不匹配' + } + }; +} + + +SchemaValidator.message = new Message(); + +export default SchemaValidator diff --git a/alpha/admin/uni_modules/uni-forms/package.json b/alpha/admin/uni_modules/uni-forms/package.json new file mode 100644 index 0000000..e3736c4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-forms", + "displayName": "uni-forms 表单", + "version": "1.4.8", + "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据", + "keywords": [ + "uni-ui", + "表单", + "校验", + "表单校验", + "表单验证" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-forms/readme.md b/alpha/admin/uni_modules/uni-forms/readme.md new file mode 100644 index 0000000..63d5a04 --- /dev/null +++ b/alpha/admin/uni_modules/uni-forms/readme.md @@ -0,0 +1,23 @@ + + +## Forms 表单 + +> **组件名:uni-forms** +> 代码块: `uForms`、`uni-forms-item` +> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。 + + +uni-app的内置组件已经有了 `
`组件,用于提交表单内容。 + +然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 ``组件封装了 ``组件,内置了表单验证功能。 + +`` 提供了 `rules`属性来描述校验规则、``子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。 + +每个要校验的表单项,不管input还是checkbox,都必须放在``组件中,且一个``组件只能放置一个表单项。 + +``组件内部预留了显示error message的区域,默认是在表单项的底部。 + +另外,``组件下面的各个表单项,可以通过``包裹为不同的分组。同一``下的不同表单项目将聚拢在一起,同其他group保持垂直间距。``仅影响视觉效果。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-group/changelog.md b/alpha/admin/uni_modules/uni-group/changelog.md new file mode 100644 index 0000000..a7024fd --- /dev/null +++ b/alpha/admin/uni_modules/uni-group/changelog.md @@ -0,0 +1,16 @@ +## 1.2.2(2022-05-30) +- 新增 stat属性,是否开启uni统计功能 +## 1.2.1(2021-11-22) +- 修复 vue3中某些scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-group](https://uniapp.dcloud.io/component/uniui/uni-group) +## 1.1.7(2021-11-08) +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +- 优化 组件文档 +## 1.0.3(2021-05-12) +- 新增 组件示例地址 +## 1.0.2(2021-02-05) +- 调整为uni_modules目录规范 +- 优化 兼容 nvue 页面 diff --git a/alpha/admin/uni_modules/uni-group/components/uni-group/uni-group.vue b/alpha/admin/uni_modules/uni-group/components/uni-group/uni-group.vue new file mode 100644 index 0000000..3425ecd --- /dev/null +++ b/alpha/admin/uni_modules/uni-group/components/uni-group/uni-group.vue @@ -0,0 +1,134 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-group/package.json b/alpha/admin/uni_modules/uni-group/package.json new file mode 100644 index 0000000..ea00a08 --- /dev/null +++ b/alpha/admin/uni_modules/uni-group/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-group", + "displayName": "uni-group 分组", + "version": "1.2.2", + "description": "分组组件可用于将组件用于分组,添加间隔,以产生明显的区块", + "keywords": [ + "uni-ui", + "uniui", + "group", + "分组", + "" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-group/readme.md b/alpha/admin/uni_modules/uni-group/readme.md new file mode 100644 index 0000000..bae67f4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-group/readme.md @@ -0,0 +1,9 @@ + +## Group 分组 +> **组件名:uni-group** +> 代码块: `uGroup` + +分组组件可用于将组件分组,添加间隔,以产生明显的区块。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-group) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-icons/changelog.md b/alpha/admin/uni_modules/uni-icons/changelog.md new file mode 100644 index 0000000..6449885 --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/changelog.md @@ -0,0 +1,22 @@ +## 1.3.5(2022-01-24) +- 优化 size 属性可以传入不带单位的字符串数值 +## 1.3.4(2022-01-24) +- 优化 size 支持其他单位 +## 1.3.3(2022-01-17) +- 修复 nvue 有些图标不显示的bug,兼容老版本图标 +## 1.3.2(2021-12-01) +- 优化 示例可复制图标名称 +## 1.3.1(2021-11-23) +- 优化 兼容旧组件 type 值 +## 1.3.0(2021-11-19) +- 新增 更多图标 +- 优化 自定义图标使用方式 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons) +## 1.1.7(2021-11-08) +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.5(2021-05-12) +- 新增 组件示例地址 +## 1.1.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-icons/components/uni-icons/icons.js b/alpha/admin/uni_modules/uni-icons/components/uni-icons/icons.js new file mode 100644 index 0000000..7889936 --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/components/uni-icons/icons.js @@ -0,0 +1,1169 @@ +export default { + "id": "2852637", + "name": "uniui图标库", + "font_family": "uniicons", + "css_prefix_text": "uniui-", + "description": "", + "glyphs": [ + { + "icon_id": "25027049", + "name": "yanse", + "font_class": "color", + "unicode": "e6cf", + "unicode_decimal": 59087 + }, + { + "icon_id": "25027048", + "name": "wallet", + "font_class": "wallet", + "unicode": "e6b1", + "unicode_decimal": 59057 + }, + { + "icon_id": "25015720", + "name": "settings-filled", + "font_class": "settings-filled", + "unicode": "e6ce", + "unicode_decimal": 59086 + }, + { + "icon_id": "25015434", + "name": "shimingrenzheng-filled", + "font_class": "auth-filled", + "unicode": "e6cc", + "unicode_decimal": 59084 + }, + { + "icon_id": "24934246", + "name": "shop-filled", + "font_class": "shop-filled", + "unicode": "e6cd", + "unicode_decimal": 59085 + }, + { + "icon_id": "24934159", + "name": "staff-filled-01", + "font_class": "staff-filled", + "unicode": "e6cb", + "unicode_decimal": 59083 + }, + { + "icon_id": "24932461", + "name": "VIP-filled", + "font_class": "vip-filled", + "unicode": "e6c6", + "unicode_decimal": 59078 + }, + { + "icon_id": "24932462", + "name": "plus_circle_fill", + "font_class": "plus-filled", + "unicode": "e6c7", + "unicode_decimal": 59079 + }, + { + "icon_id": "24932463", + "name": "folder_add-filled", + "font_class": "folder-add-filled", + "unicode": "e6c8", + "unicode_decimal": 59080 + }, + { + "icon_id": "24932464", + "name": "yanse-filled", + "font_class": "color-filled", + "unicode": "e6c9", + "unicode_decimal": 59081 + }, + { + "icon_id": "24932465", + "name": "tune-filled", + "font_class": "tune-filled", + "unicode": "e6ca", + "unicode_decimal": 59082 + }, + { + "icon_id": "24932455", + "name": "a-rilidaka-filled", + "font_class": "calendar-filled", + "unicode": "e6c0", + "unicode_decimal": 59072 + }, + { + "icon_id": "24932456", + "name": "notification-filled", + "font_class": "notification-filled", + "unicode": "e6c1", + "unicode_decimal": 59073 + }, + { + "icon_id": "24932457", + "name": "wallet-filled", + "font_class": "wallet-filled", + "unicode": "e6c2", + "unicode_decimal": 59074 + }, + { + "icon_id": "24932458", + "name": "paihangbang-filled", + "font_class": "medal-filled", + "unicode": "e6c3", + "unicode_decimal": 59075 + }, + { + "icon_id": "24932459", + "name": "gift-filled", + "font_class": "gift-filled", + "unicode": "e6c4", + "unicode_decimal": 59076 + }, + { + "icon_id": "24932460", + "name": "fire-filled", + "font_class": "fire-filled", + "unicode": "e6c5", + "unicode_decimal": 59077 + }, + { + "icon_id": "24928001", + "name": "refreshempty", + "font_class": "refreshempty", + "unicode": "e6bf", + "unicode_decimal": 59071 + }, + { + "icon_id": "24926853", + "name": "location-ellipse", + "font_class": "location-filled", + "unicode": "e6af", + "unicode_decimal": 59055 + }, + { + "icon_id": "24926735", + "name": "person-filled", + "font_class": "person-filled", + "unicode": "e69d", + "unicode_decimal": 59037 + }, + { + "icon_id": "24926703", + "name": "personadd-filled", + "font_class": "personadd-filled", + "unicode": "e698", + "unicode_decimal": 59032 + }, + { + "icon_id": "24923351", + "name": "back", + "font_class": "back", + "unicode": "e6b9", + "unicode_decimal": 59065 + }, + { + "icon_id": "24923352", + "name": "forward", + "font_class": "forward", + "unicode": "e6ba", + "unicode_decimal": 59066 + }, + { + "icon_id": "24923353", + "name": "arrowthinright", + "font_class": "arrow-right", + "unicode": "e6bb", + "unicode_decimal": 59067 + }, + { + "icon_id": "24923353", + "name": "arrowthinright", + "font_class": "arrowthinright", + "unicode": "e6bb", + "unicode_decimal": 59067 + }, + { + "icon_id": "24923354", + "name": "arrowthinleft", + "font_class": "arrow-left", + "unicode": "e6bc", + "unicode_decimal": 59068 + }, + { + "icon_id": "24923354", + "name": "arrowthinleft", + "font_class": "arrowthinleft", + "unicode": "e6bc", + "unicode_decimal": 59068 + }, + { + "icon_id": "24923355", + "name": "arrowthinup", + "font_class": "arrow-up", + "unicode": "e6bd", + "unicode_decimal": 59069 + }, + { + "icon_id": "24923355", + "name": "arrowthinup", + "font_class": "arrowthinup", + "unicode": "e6bd", + "unicode_decimal": 59069 + }, + { + "icon_id": "24923356", + "name": "arrowthindown", + "font_class": "arrow-down", + "unicode": "e6be", + "unicode_decimal": 59070 + },{ + "icon_id": "24923356", + "name": "arrowthindown", + "font_class": "arrowthindown", + "unicode": "e6be", + "unicode_decimal": 59070 + }, + { + "icon_id": "24923349", + "name": "arrowdown", + "font_class": "bottom", + "unicode": "e6b8", + "unicode_decimal": 59064 + },{ + "icon_id": "24923349", + "name": "arrowdown", + "font_class": "arrowdown", + "unicode": "e6b8", + "unicode_decimal": 59064 + }, + { + "icon_id": "24923346", + "name": "arrowright", + "font_class": "right", + "unicode": "e6b5", + "unicode_decimal": 59061 + }, + { + "icon_id": "24923346", + "name": "arrowright", + "font_class": "arrowright", + "unicode": "e6b5", + "unicode_decimal": 59061 + }, + { + "icon_id": "24923347", + "name": "arrowup", + "font_class": "top", + "unicode": "e6b6", + "unicode_decimal": 59062 + }, + { + "icon_id": "24923347", + "name": "arrowup", + "font_class": "arrowup", + "unicode": "e6b6", + "unicode_decimal": 59062 + }, + { + "icon_id": "24923348", + "name": "arrowleft", + "font_class": "left", + "unicode": "e6b7", + "unicode_decimal": 59063 + }, + { + "icon_id": "24923348", + "name": "arrowleft", + "font_class": "arrowleft", + "unicode": "e6b7", + "unicode_decimal": 59063 + }, + { + "icon_id": "24923334", + "name": "eye", + "font_class": "eye", + "unicode": "e651", + "unicode_decimal": 58961 + }, + { + "icon_id": "24923335", + "name": "eye-filled", + "font_class": "eye-filled", + "unicode": "e66a", + "unicode_decimal": 58986 + }, + { + "icon_id": "24923336", + "name": "eye-slash", + "font_class": "eye-slash", + "unicode": "e6b3", + "unicode_decimal": 59059 + }, + { + "icon_id": "24923337", + "name": "eye-slash-filled", + "font_class": "eye-slash-filled", + "unicode": "e6b4", + "unicode_decimal": 59060 + }, + { + "icon_id": "24923305", + "name": "info-filled", + "font_class": "info-filled", + "unicode": "e649", + "unicode_decimal": 58953 + }, + { + "icon_id": "24923299", + "name": "reload-01", + "font_class": "reload", + "unicode": "e6b2", + "unicode_decimal": 59058 + }, + { + "icon_id": "24923195", + "name": "mic_slash_fill", + "font_class": "micoff-filled", + "unicode": "e6b0", + "unicode_decimal": 59056 + }, + { + "icon_id": "24923165", + "name": "map-pin-ellipse", + "font_class": "map-pin-ellipse", + "unicode": "e6ac", + "unicode_decimal": 59052 + }, + { + "icon_id": "24923166", + "name": "map-pin", + "font_class": "map-pin", + "unicode": "e6ad", + "unicode_decimal": 59053 + }, + { + "icon_id": "24923167", + "name": "location", + "font_class": "location", + "unicode": "e6ae", + "unicode_decimal": 59054 + }, + { + "icon_id": "24923064", + "name": "starhalf", + "font_class": "starhalf", + "unicode": "e683", + "unicode_decimal": 59011 + }, + { + "icon_id": "24923065", + "name": "star", + "font_class": "star", + "unicode": "e688", + "unicode_decimal": 59016 + }, + { + "icon_id": "24923066", + "name": "star-filled", + "font_class": "star-filled", + "unicode": "e68f", + "unicode_decimal": 59023 + }, + { + "icon_id": "24899646", + "name": "a-rilidaka", + "font_class": "calendar", + "unicode": "e6a0", + "unicode_decimal": 59040 + }, + { + "icon_id": "24899647", + "name": "fire", + "font_class": "fire", + "unicode": "e6a1", + "unicode_decimal": 59041 + }, + { + "icon_id": "24899648", + "name": "paihangbang", + "font_class": "medal", + "unicode": "e6a2", + "unicode_decimal": 59042 + }, + { + "icon_id": "24899649", + "name": "font", + "font_class": "font", + "unicode": "e6a3", + "unicode_decimal": 59043 + }, + { + "icon_id": "24899650", + "name": "gift", + "font_class": "gift", + "unicode": "e6a4", + "unicode_decimal": 59044 + }, + { + "icon_id": "24899651", + "name": "link", + "font_class": "link", + "unicode": "e6a5", + "unicode_decimal": 59045 + }, + { + "icon_id": "24899652", + "name": "notification", + "font_class": "notification", + "unicode": "e6a6", + "unicode_decimal": 59046 + }, + { + "icon_id": "24899653", + "name": "staff", + "font_class": "staff", + "unicode": "e6a7", + "unicode_decimal": 59047 + }, + { + "icon_id": "24899654", + "name": "VIP", + "font_class": "vip", + "unicode": "e6a8", + "unicode_decimal": 59048 + }, + { + "icon_id": "24899655", + "name": "folder_add", + "font_class": "folder-add", + "unicode": "e6a9", + "unicode_decimal": 59049 + }, + { + "icon_id": "24899656", + "name": "tune", + "font_class": "tune", + "unicode": "e6aa", + "unicode_decimal": 59050 + }, + { + "icon_id": "24899657", + "name": "shimingrenzheng", + "font_class": "auth", + "unicode": "e6ab", + "unicode_decimal": 59051 + }, + { + "icon_id": "24899565", + "name": "person", + "font_class": "person", + "unicode": "e699", + "unicode_decimal": 59033 + }, + { + "icon_id": "24899566", + "name": "email-filled", + "font_class": "email-filled", + "unicode": "e69a", + "unicode_decimal": 59034 + }, + { + "icon_id": "24899567", + "name": "phone-filled", + "font_class": "phone-filled", + "unicode": "e69b", + "unicode_decimal": 59035 + }, + { + "icon_id": "24899568", + "name": "phone", + "font_class": "phone", + "unicode": "e69c", + "unicode_decimal": 59036 + }, + { + "icon_id": "24899570", + "name": "email", + "font_class": "email", + "unicode": "e69e", + "unicode_decimal": 59038 + }, + { + "icon_id": "24899571", + "name": "personadd", + "font_class": "personadd", + "unicode": "e69f", + "unicode_decimal": 59039 + }, + { + "icon_id": "24899558", + "name": "chatboxes-filled", + "font_class": "chatboxes-filled", + "unicode": "e692", + "unicode_decimal": 59026 + }, + { + "icon_id": "24899559", + "name": "contact", + "font_class": "contact", + "unicode": "e693", + "unicode_decimal": 59027 + }, + { + "icon_id": "24899560", + "name": "chatbubble-filled", + "font_class": "chatbubble-filled", + "unicode": "e694", + "unicode_decimal": 59028 + }, + { + "icon_id": "24899561", + "name": "contact-filled", + "font_class": "contact-filled", + "unicode": "e695", + "unicode_decimal": 59029 + }, + { + "icon_id": "24899562", + "name": "chatboxes", + "font_class": "chatboxes", + "unicode": "e696", + "unicode_decimal": 59030 + }, + { + "icon_id": "24899563", + "name": "chatbubble", + "font_class": "chatbubble", + "unicode": "e697", + "unicode_decimal": 59031 + }, + { + "icon_id": "24881290", + "name": "upload-filled", + "font_class": "upload-filled", + "unicode": "e68e", + "unicode_decimal": 59022 + }, + { + "icon_id": "24881292", + "name": "upload", + "font_class": "upload", + "unicode": "e690", + "unicode_decimal": 59024 + }, + { + "icon_id": "24881293", + "name": "weixin", + "font_class": "weixin", + "unicode": "e691", + "unicode_decimal": 59025 + }, + { + "icon_id": "24881274", + "name": "compose", + "font_class": "compose", + "unicode": "e67f", + "unicode_decimal": 59007 + }, + { + "icon_id": "24881275", + "name": "qq", + "font_class": "qq", + "unicode": "e680", + "unicode_decimal": 59008 + }, + { + "icon_id": "24881276", + "name": "download-filled", + "font_class": "download-filled", + "unicode": "e681", + "unicode_decimal": 59009 + }, + { + "icon_id": "24881277", + "name": "pengyouquan", + "font_class": "pyq", + "unicode": "e682", + "unicode_decimal": 59010 + }, + { + "icon_id": "24881279", + "name": "sound", + "font_class": "sound", + "unicode": "e684", + "unicode_decimal": 59012 + }, + { + "icon_id": "24881280", + "name": "trash-filled", + "font_class": "trash-filled", + "unicode": "e685", + "unicode_decimal": 59013 + }, + { + "icon_id": "24881281", + "name": "sound-filled", + "font_class": "sound-filled", + "unicode": "e686", + "unicode_decimal": 59014 + }, + { + "icon_id": "24881282", + "name": "trash", + "font_class": "trash", + "unicode": "e687", + "unicode_decimal": 59015 + }, + { + "icon_id": "24881284", + "name": "videocam-filled", + "font_class": "videocam-filled", + "unicode": "e689", + "unicode_decimal": 59017 + }, + { + "icon_id": "24881285", + "name": "spinner-cycle", + "font_class": "spinner-cycle", + "unicode": "e68a", + "unicode_decimal": 59018 + }, + { + "icon_id": "24881286", + "name": "weibo", + "font_class": "weibo", + "unicode": "e68b", + "unicode_decimal": 59019 + }, + { + "icon_id": "24881288", + "name": "videocam", + "font_class": "videocam", + "unicode": "e68c", + "unicode_decimal": 59020 + }, + { + "icon_id": "24881289", + "name": "download", + "font_class": "download", + "unicode": "e68d", + "unicode_decimal": 59021 + }, + { + "icon_id": "24879601", + "name": "help", + "font_class": "help", + "unicode": "e679", + "unicode_decimal": 59001 + }, + { + "icon_id": "24879602", + "name": "navigate-filled", + "font_class": "navigate-filled", + "unicode": "e67a", + "unicode_decimal": 59002 + }, + { + "icon_id": "24879603", + "name": "plusempty", + "font_class": "plusempty", + "unicode": "e67b", + "unicode_decimal": 59003 + }, + { + "icon_id": "24879604", + "name": "smallcircle", + "font_class": "smallcircle", + "unicode": "e67c", + "unicode_decimal": 59004 + }, + { + "icon_id": "24879605", + "name": "minus-filled", + "font_class": "minus-filled", + "unicode": "e67d", + "unicode_decimal": 59005 + }, + { + "icon_id": "24879606", + "name": "micoff", + "font_class": "micoff", + "unicode": "e67e", + "unicode_decimal": 59006 + }, + { + "icon_id": "24879588", + "name": "closeempty", + "font_class": "closeempty", + "unicode": "e66c", + "unicode_decimal": 58988 + }, + { + "icon_id": "24879589", + "name": "clear", + "font_class": "clear", + "unicode": "e66d", + "unicode_decimal": 58989 + }, + { + "icon_id": "24879590", + "name": "navigate", + "font_class": "navigate", + "unicode": "e66e", + "unicode_decimal": 58990 + }, + { + "icon_id": "24879591", + "name": "minus", + "font_class": "minus", + "unicode": "e66f", + "unicode_decimal": 58991 + }, + { + "icon_id": "24879592", + "name": "image", + "font_class": "image", + "unicode": "e670", + "unicode_decimal": 58992 + }, + { + "icon_id": "24879593", + "name": "mic", + "font_class": "mic", + "unicode": "e671", + "unicode_decimal": 58993 + }, + { + "icon_id": "24879594", + "name": "paperplane", + "font_class": "paperplane", + "unicode": "e672", + "unicode_decimal": 58994 + }, + { + "icon_id": "24879595", + "name": "close", + "font_class": "close", + "unicode": "e673", + "unicode_decimal": 58995 + }, + { + "icon_id": "24879596", + "name": "help-filled", + "font_class": "help-filled", + "unicode": "e674", + "unicode_decimal": 58996 + }, + { + "icon_id": "24879597", + "name": "plus-filled", + "font_class": "paperplane-filled", + "unicode": "e675", + "unicode_decimal": 58997 + }, + { + "icon_id": "24879598", + "name": "plus", + "font_class": "plus", + "unicode": "e676", + "unicode_decimal": 58998 + }, + { + "icon_id": "24879599", + "name": "mic-filled", + "font_class": "mic-filled", + "unicode": "e677", + "unicode_decimal": 58999 + }, + { + "icon_id": "24879600", + "name": "image-filled", + "font_class": "image-filled", + "unicode": "e678", + "unicode_decimal": 59000 + }, + { + "icon_id": "24855900", + "name": "locked-filled", + "font_class": "locked-filled", + "unicode": "e668", + "unicode_decimal": 58984 + }, + { + "icon_id": "24855901", + "name": "info", + "font_class": "info", + "unicode": "e669", + "unicode_decimal": 58985 + }, + { + "icon_id": "24855903", + "name": "locked", + "font_class": "locked", + "unicode": "e66b", + "unicode_decimal": 58987 + }, + { + "icon_id": "24855884", + "name": "camera-filled", + "font_class": "camera-filled", + "unicode": "e658", + "unicode_decimal": 58968 + }, + { + "icon_id": "24855885", + "name": "chat-filled", + "font_class": "chat-filled", + "unicode": "e659", + "unicode_decimal": 58969 + }, + { + "icon_id": "24855886", + "name": "camera", + "font_class": "camera", + "unicode": "e65a", + "unicode_decimal": 58970 + }, + { + "icon_id": "24855887", + "name": "circle", + "font_class": "circle", + "unicode": "e65b", + "unicode_decimal": 58971 + }, + { + "icon_id": "24855888", + "name": "checkmarkempty", + "font_class": "checkmarkempty", + "unicode": "e65c", + "unicode_decimal": 58972 + }, + { + "icon_id": "24855889", + "name": "chat", + "font_class": "chat", + "unicode": "e65d", + "unicode_decimal": 58973 + }, + { + "icon_id": "24855890", + "name": "circle-filled", + "font_class": "circle-filled", + "unicode": "e65e", + "unicode_decimal": 58974 + }, + { + "icon_id": "24855891", + "name": "flag", + "font_class": "flag", + "unicode": "e65f", + "unicode_decimal": 58975 + }, + { + "icon_id": "24855892", + "name": "flag-filled", + "font_class": "flag-filled", + "unicode": "e660", + "unicode_decimal": 58976 + }, + { + "icon_id": "24855893", + "name": "gear-filled", + "font_class": "gear-filled", + "unicode": "e661", + "unicode_decimal": 58977 + }, + { + "icon_id": "24855894", + "name": "home", + "font_class": "home", + "unicode": "e662", + "unicode_decimal": 58978 + }, + { + "icon_id": "24855895", + "name": "home-filled", + "font_class": "home-filled", + "unicode": "e663", + "unicode_decimal": 58979 + }, + { + "icon_id": "24855896", + "name": "gear", + "font_class": "gear", + "unicode": "e664", + "unicode_decimal": 58980 + }, + { + "icon_id": "24855897", + "name": "smallcircle-filled", + "font_class": "smallcircle-filled", + "unicode": "e665", + "unicode_decimal": 58981 + }, + { + "icon_id": "24855898", + "name": "map-filled", + "font_class": "map-filled", + "unicode": "e666", + "unicode_decimal": 58982 + }, + { + "icon_id": "24855899", + "name": "map", + "font_class": "map", + "unicode": "e667", + "unicode_decimal": 58983 + }, + { + "icon_id": "24855825", + "name": "refresh-filled", + "font_class": "refresh-filled", + "unicode": "e656", + "unicode_decimal": 58966 + }, + { + "icon_id": "24855826", + "name": "refresh", + "font_class": "refresh", + "unicode": "e657", + "unicode_decimal": 58967 + }, + { + "icon_id": "24855808", + "name": "cloud-upload", + "font_class": "cloud-upload", + "unicode": "e645", + "unicode_decimal": 58949 + }, + { + "icon_id": "24855809", + "name": "cloud-download-filled", + "font_class": "cloud-download-filled", + "unicode": "e646", + "unicode_decimal": 58950 + }, + { + "icon_id": "24855810", + "name": "cloud-download", + "font_class": "cloud-download", + "unicode": "e647", + "unicode_decimal": 58951 + }, + { + "icon_id": "24855811", + "name": "cloud-upload-filled", + "font_class": "cloud-upload-filled", + "unicode": "e648", + "unicode_decimal": 58952 + }, + { + "icon_id": "24855813", + "name": "redo", + "font_class": "redo", + "unicode": "e64a", + "unicode_decimal": 58954 + }, + { + "icon_id": "24855814", + "name": "images-filled", + "font_class": "images-filled", + "unicode": "e64b", + "unicode_decimal": 58955 + }, + { + "icon_id": "24855815", + "name": "undo-filled", + "font_class": "undo-filled", + "unicode": "e64c", + "unicode_decimal": 58956 + }, + { + "icon_id": "24855816", + "name": "more", + "font_class": "more", + "unicode": "e64d", + "unicode_decimal": 58957 + }, + { + "icon_id": "24855817", + "name": "more-filled", + "font_class": "more-filled", + "unicode": "e64e", + "unicode_decimal": 58958 + }, + { + "icon_id": "24855818", + "name": "undo", + "font_class": "undo", + "unicode": "e64f", + "unicode_decimal": 58959 + }, + { + "icon_id": "24855819", + "name": "images", + "font_class": "images", + "unicode": "e650", + "unicode_decimal": 58960 + }, + { + "icon_id": "24855821", + "name": "paperclip", + "font_class": "paperclip", + "unicode": "e652", + "unicode_decimal": 58962 + }, + { + "icon_id": "24855822", + "name": "settings", + "font_class": "settings", + "unicode": "e653", + "unicode_decimal": 58963 + }, + { + "icon_id": "24855823", + "name": "search", + "font_class": "search", + "unicode": "e654", + "unicode_decimal": 58964 + }, + { + "icon_id": "24855824", + "name": "redo-filled", + "font_class": "redo-filled", + "unicode": "e655", + "unicode_decimal": 58965 + }, + { + "icon_id": "24841702", + "name": "list", + "font_class": "list", + "unicode": "e644", + "unicode_decimal": 58948 + }, + { + "icon_id": "24841489", + "name": "mail-open-filled", + "font_class": "mail-open-filled", + "unicode": "e63a", + "unicode_decimal": 58938 + }, + { + "icon_id": "24841491", + "name": "hand-thumbsdown-filled", + "font_class": "hand-down-filled", + "unicode": "e63c", + "unicode_decimal": 58940 + }, + { + "icon_id": "24841492", + "name": "hand-thumbsdown", + "font_class": "hand-down", + "unicode": "e63d", + "unicode_decimal": 58941 + }, + { + "icon_id": "24841493", + "name": "hand-thumbsup-filled", + "font_class": "hand-up-filled", + "unicode": "e63e", + "unicode_decimal": 58942 + }, + { + "icon_id": "24841494", + "name": "hand-thumbsup", + "font_class": "hand-up", + "unicode": "e63f", + "unicode_decimal": 58943 + }, + { + "icon_id": "24841496", + "name": "heart-filled", + "font_class": "heart-filled", + "unicode": "e641", + "unicode_decimal": 58945 + }, + { + "icon_id": "24841498", + "name": "mail-open", + "font_class": "mail-open", + "unicode": "e643", + "unicode_decimal": 58947 + }, + { + "icon_id": "24841488", + "name": "heart", + "font_class": "heart", + "unicode": "e639", + "unicode_decimal": 58937 + }, + { + "icon_id": "24839963", + "name": "loop", + "font_class": "loop", + "unicode": "e633", + "unicode_decimal": 58931 + }, + { + "icon_id": "24839866", + "name": "pulldown", + "font_class": "pulldown", + "unicode": "e632", + "unicode_decimal": 58930 + }, + { + "icon_id": "24813798", + "name": "scan", + "font_class": "scan", + "unicode": "e62a", + "unicode_decimal": 58922 + }, + { + "icon_id": "24813786", + "name": "bars", + "font_class": "bars", + "unicode": "e627", + "unicode_decimal": 58919 + }, + { + "icon_id": "24813788", + "name": "cart-filled", + "font_class": "cart-filled", + "unicode": "e629", + "unicode_decimal": 58921 + }, + { + "icon_id": "24813790", + "name": "checkbox", + "font_class": "checkbox", + "unicode": "e62b", + "unicode_decimal": 58923 + }, + { + "icon_id": "24813791", + "name": "checkbox-filled", + "font_class": "checkbox-filled", + "unicode": "e62c", + "unicode_decimal": 58924 + }, + { + "icon_id": "24813794", + "name": "shop", + "font_class": "shop", + "unicode": "e62f", + "unicode_decimal": 58927 + }, + { + "icon_id": "24813795", + "name": "headphones", + "font_class": "headphones", + "unicode": "e630", + "unicode_decimal": 58928 + }, + { + "icon_id": "24813796", + "name": "cart", + "font_class": "cart", + "unicode": "e631", + "unicode_decimal": 58929 + } + ] +} diff --git a/alpha/admin/uni_modules/uni-icons/components/uni-icons/uni-icons.vue b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uni-icons.vue new file mode 100644 index 0000000..86e7444 --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uni-icons.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-icons/components/uni-icons/uni.ttf b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uni.ttf new file mode 100644 index 0000000000000000000000000000000000000000..60a1968d08cc6056c70b5402b2effac43c6f96a3 GIT binary patch literal 26164 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.css b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.css new file mode 100644 index 0000000..2f56eab --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.css @@ -0,0 +1,663 @@ +.uniui-color:before { + content: "\e6cf"; +} + +.uniui-wallet:before { + content: "\e6b1"; +} + +.uniui-settings-filled:before { + content: "\e6ce"; +} + +.uniui-auth-filled:before { + content: "\e6cc"; +} + +.uniui-shop-filled:before { + content: "\e6cd"; +} + +.uniui-staff-filled:before { + content: "\e6cb"; +} + +.uniui-vip-filled:before { + content: "\e6c6"; +} + +.uniui-plus-filled:before { + content: "\e6c7"; +} + +.uniui-folder-add-filled:before { + content: "\e6c8"; +} + +.uniui-color-filled:before { + content: "\e6c9"; +} + +.uniui-tune-filled:before { + content: "\e6ca"; +} + +.uniui-calendar-filled:before { + content: "\e6c0"; +} + +.uniui-notification-filled:before { + content: "\e6c1"; +} + +.uniui-wallet-filled:before { + content: "\e6c2"; +} + +.uniui-medal-filled:before { + content: "\e6c3"; +} + +.uniui-gift-filled:before { + content: "\e6c4"; +} + +.uniui-fire-filled:before { + content: "\e6c5"; +} + +.uniui-refreshempty:before { + content: "\e6bf"; +} + +.uniui-location-filled:before { + content: "\e6af"; +} + +.uniui-person-filled:before { + content: "\e69d"; +} + +.uniui-personadd-filled:before { + content: "\e698"; +} + +.uniui-back:before { + content: "\e6b9"; +} + +.uniui-forward:before { + content: "\e6ba"; +} + +.uniui-arrow-right:before { + content: "\e6bb"; +} + +.uniui-arrowthinright:before { + content: "\e6bb"; +} + +.uniui-arrow-left:before { + content: "\e6bc"; +} + +.uniui-arrowthinleft:before { + content: "\e6bc"; +} + +.uniui-arrow-up:before { + content: "\e6bd"; +} + +.uniui-arrowthinup:before { + content: "\e6bd"; +} + +.uniui-arrow-down:before { + content: "\e6be"; +} + +.uniui-arrowthindown:before { + content: "\e6be"; +} + +.uniui-bottom:before { + content: "\e6b8"; +} + +.uniui-arrowdown:before { + content: "\e6b8"; +} + +.uniui-right:before { + content: "\e6b5"; +} + +.uniui-arrowright:before { + content: "\e6b5"; +} + +.uniui-top:before { + content: "\e6b6"; +} + +.uniui-arrowup:before { + content: "\e6b6"; +} + +.uniui-left:before { + content: "\e6b7"; +} + +.uniui-arrowleft:before { + content: "\e6b7"; +} + +.uniui-eye:before { + content: "\e651"; +} + +.uniui-eye-filled:before { + content: "\e66a"; +} + +.uniui-eye-slash:before { + content: "\e6b3"; +} + +.uniui-eye-slash-filled:before { + content: "\e6b4"; +} + +.uniui-info-filled:before { + content: "\e649"; +} + +.uniui-reload:before { + content: "\e6b2"; +} + +.uniui-micoff-filled:before { + content: "\e6b0"; +} + +.uniui-map-pin-ellipse:before { + content: "\e6ac"; +} + +.uniui-map-pin:before { + content: "\e6ad"; +} + +.uniui-location:before { + content: "\e6ae"; +} + +.uniui-starhalf:before { + content: "\e683"; +} + +.uniui-star:before { + content: "\e688"; +} + +.uniui-star-filled:before { + content: "\e68f"; +} + +.uniui-calendar:before { + content: "\e6a0"; +} + +.uniui-fire:before { + content: "\e6a1"; +} + +.uniui-medal:before { + content: "\e6a2"; +} + +.uniui-font:before { + content: "\e6a3"; +} + +.uniui-gift:before { + content: "\e6a4"; +} + +.uniui-link:before { + content: "\e6a5"; +} + +.uniui-notification:before { + content: "\e6a6"; +} + +.uniui-staff:before { + content: "\e6a7"; +} + +.uniui-vip:before { + content: "\e6a8"; +} + +.uniui-folder-add:before { + content: "\e6a9"; +} + +.uniui-tune:before { + content: "\e6aa"; +} + +.uniui-auth:before { + content: "\e6ab"; +} + +.uniui-person:before { + content: "\e699"; +} + +.uniui-email-filled:before { + content: "\e69a"; +} + +.uniui-phone-filled:before { + content: "\e69b"; +} + +.uniui-phone:before { + content: "\e69c"; +} + +.uniui-email:before { + content: "\e69e"; +} + +.uniui-personadd:before { + content: "\e69f"; +} + +.uniui-chatboxes-filled:before { + content: "\e692"; +} + +.uniui-contact:before { + content: "\e693"; +} + +.uniui-chatbubble-filled:before { + content: "\e694"; +} + +.uniui-contact-filled:before { + content: "\e695"; +} + +.uniui-chatboxes:before { + content: "\e696"; +} + +.uniui-chatbubble:before { + content: "\e697"; +} + +.uniui-upload-filled:before { + content: "\e68e"; +} + +.uniui-upload:before { + content: "\e690"; +} + +.uniui-weixin:before { + content: "\e691"; +} + +.uniui-compose:before { + content: "\e67f"; +} + +.uniui-qq:before { + content: "\e680"; +} + +.uniui-download-filled:before { + content: "\e681"; +} + +.uniui-pyq:before { + content: "\e682"; +} + +.uniui-sound:before { + content: "\e684"; +} + +.uniui-trash-filled:before { + content: "\e685"; +} + +.uniui-sound-filled:before { + content: "\e686"; +} + +.uniui-trash:before { + content: "\e687"; +} + +.uniui-videocam-filled:before { + content: "\e689"; +} + +.uniui-spinner-cycle:before { + content: "\e68a"; +} + +.uniui-weibo:before { + content: "\e68b"; +} + +.uniui-videocam:before { + content: "\e68c"; +} + +.uniui-download:before { + content: "\e68d"; +} + +.uniui-help:before { + content: "\e679"; +} + +.uniui-navigate-filled:before { + content: "\e67a"; +} + +.uniui-plusempty:before { + content: "\e67b"; +} + +.uniui-smallcircle:before { + content: "\e67c"; +} + +.uniui-minus-filled:before { + content: "\e67d"; +} + +.uniui-micoff:before { + content: "\e67e"; +} + +.uniui-closeempty:before { + content: "\e66c"; +} + +.uniui-clear:before { + content: "\e66d"; +} + +.uniui-navigate:before { + content: "\e66e"; +} + +.uniui-minus:before { + content: "\e66f"; +} + +.uniui-image:before { + content: "\e670"; +} + +.uniui-mic:before { + content: "\e671"; +} + +.uniui-paperplane:before { + content: "\e672"; +} + +.uniui-close:before { + content: "\e673"; +} + +.uniui-help-filled:before { + content: "\e674"; +} + +.uniui-paperplane-filled:before { + content: "\e675"; +} + +.uniui-plus:before { + content: "\e676"; +} + +.uniui-mic-filled:before { + content: "\e677"; +} + +.uniui-image-filled:before { + content: "\e678"; +} + +.uniui-locked-filled:before { + content: "\e668"; +} + +.uniui-info:before { + content: "\e669"; +} + +.uniui-locked:before { + content: "\e66b"; +} + +.uniui-camera-filled:before { + content: "\e658"; +} + +.uniui-chat-filled:before { + content: "\e659"; +} + +.uniui-camera:before { + content: "\e65a"; +} + +.uniui-circle:before { + content: "\e65b"; +} + +.uniui-checkmarkempty:before { + content: "\e65c"; +} + +.uniui-chat:before { + content: "\e65d"; +} + +.uniui-circle-filled:before { + content: "\e65e"; +} + +.uniui-flag:before { + content: "\e65f"; +} + +.uniui-flag-filled:before { + content: "\e660"; +} + +.uniui-gear-filled:before { + content: "\e661"; +} + +.uniui-home:before { + content: "\e662"; +} + +.uniui-home-filled:before { + content: "\e663"; +} + +.uniui-gear:before { + content: "\e664"; +} + +.uniui-smallcircle-filled:before { + content: "\e665"; +} + +.uniui-map-filled:before { + content: "\e666"; +} + +.uniui-map:before { + content: "\e667"; +} + +.uniui-refresh-filled:before { + content: "\e656"; +} + +.uniui-refresh:before { + content: "\e657"; +} + +.uniui-cloud-upload:before { + content: "\e645"; +} + +.uniui-cloud-download-filled:before { + content: "\e646"; +} + +.uniui-cloud-download:before { + content: "\e647"; +} + +.uniui-cloud-upload-filled:before { + content: "\e648"; +} + +.uniui-redo:before { + content: "\e64a"; +} + +.uniui-images-filled:before { + content: "\e64b"; +} + +.uniui-undo-filled:before { + content: "\e64c"; +} + +.uniui-more:before { + content: "\e64d"; +} + +.uniui-more-filled:before { + content: "\e64e"; +} + +.uniui-undo:before { + content: "\e64f"; +} + +.uniui-images:before { + content: "\e650"; +} + +.uniui-paperclip:before { + content: "\e652"; +} + +.uniui-settings:before { + content: "\e653"; +} + +.uniui-search:before { + content: "\e654"; +} + +.uniui-redo-filled:before { + content: "\e655"; +} + +.uniui-list:before { + content: "\e644"; +} + +.uniui-mail-open-filled:before { + content: "\e63a"; +} + +.uniui-hand-down-filled:before { + content: "\e63c"; +} + +.uniui-hand-down:before { + content: "\e63d"; +} + +.uniui-hand-up-filled:before { + content: "\e63e"; +} + +.uniui-hand-up:before { + content: "\e63f"; +} + +.uniui-heart-filled:before { + content: "\e641"; +} + +.uniui-mail-open:before { + content: "\e643"; +} + +.uniui-heart:before { + content: "\e639"; +} + +.uniui-loop:before { + content: "\e633"; +} + +.uniui-pulldown:before { + content: "\e632"; +} + +.uniui-scan:before { + content: "\e62a"; +} + +.uniui-bars:before { + content: "\e627"; +} + +.uniui-cart-filled:before { + content: "\e629"; +} + +.uniui-checkbox:before { + content: "\e62b"; +} + +.uniui-checkbox-filled:before { + content: "\e62c"; +} + +.uniui-shop:before { + content: "\e62f"; +} + +.uniui-headphones:before { + content: "\e630"; +} + +.uniui-cart:before { + content: "\e631"; +} diff --git a/alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.ttf b/alpha/admin/uni_modules/uni-icons/components/uni-icons/uniicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..835f33bc9411461b8b9046b3fec742e921d6ce3a GIT binary patch literal 35760 zcmeFacbp?vl{Q?rN>WLsSXIigCAC7gI!S6tox^m`be^1}CwPJ>yxZ{uSzi{WC_=LI+*Wx!<-H!v})21fuKMZQ#fB2Fs zuEGwU_ZyDmuR3&e_s&PS@Be}0T=(JF$l;w=9Als0-iQ4lE^0cm^YDeWhnK#G<4!$@ z>-QZydhsP6Kl0Pv9Cw|EbP-?YO$@C;`+ zuKnR1zxV)MXnddfv56Dn_-W<%#_jZ^d%1f!hyI(6O8C!lXY}93nl=3f9^gzbYS03Jm0vJ;T)Z1IKntfUtypB#zx`e6wG3 zC5AhB&Me^QdH${3yL1otSUp#NN^cKN_yKnkm%XqxczWUgrT^Oo|6lL`SPy&+DZ_DX z1{?B^82rf|!cpSXHhg1*;kZecHy+MI*MqCu>g9T0eYieaf9edzAC9!tJL|pm0UQ~l zBQN;JaG!_sb8)VT%i=%By_I_#_ZIFh?(N(=xVtf?-^|^~y@`7RcMEqbcN=#*_eSmx z?)BVjxU0EqFm9T;Q`~9pTJAdTdhWH{>+qBtxEr~fxSP3Gb60T(xkKDx?g)33JH{R7 zPH-1465x0fg%5CGeb33>TxSiZCZa24wyO7(&Q z>$wfwMs5?gnVaOMxM^;NYvpFSIc_<(f-7(s&u0CxL#u8VbF$klItIryQ@x|5W z48lm`>dOtnnB(dz48rK+>MISxIOOW948n-y>Z=XH*yQSK48kbo>T3axcUVKK~8Y>od!W-aP?gVL3VKU-3CF5aP>U~L7s5+3k`x~;p%%0f{fwn z`wW7#;p+Phg52Ti2MmG);_4R}1X;w@scs-hC9Y0&13^AJNK#+l4o$3aH zH00`3HxT3^SEssxAR)Or)eQt$$+z7tkWDxWPSHIIBXb!IaW`m$ZxcXZRf;QpmZ#4*d zg{!~KAZQq_ewRVeHC+Ae20`m^^>-Kq{lnGoHVB%CtKVY~bP`v;*C1#ou700E&{JIf zeuJQ~xcWN{g6`t#?=lEljH|!fAm}r${tpI0vvKtY41$j1>hCcK+K#I~Xb|)sSAVZT z(12Y1eFi}na`pEc1g*%`|Ir}mN3Q+>gPp}tAE%avLosrF^GJG z`bQ0dZsqD9GYDFitAE@e=v%J-34@?{x%wv!f)3{DpE3yAn5#cz5cD!v|Fl8S&|Lj9 z20>SI_0JjvtVjlpxwFpV+N5QQ~$g{(D+>a3kE^= zbM-G81S^26f5{-&16=*f2Ej7m>R&MkHUd}wszKz<)E_qpb^}-cnn7g6)t@j3wggxI zxp1QBm2=klxXa|a&TVx+;Qp=WwVt{>D}O~9QXW)O>O0h5db_-@^8Ud$^pPT-1=NS-v_4k2r|_kM*0!vaW9xyNll~`AaKH zuPQxR4wv6t{%QC2?wh**v$DGKU?rS_5?F|crGafkiL7dNk-%Y_E4VmkSn6>Hb;SUukEx3l0# zej=BS$yT%Av8Uc*J`xpdRw>aQ5n{34Scli{%@0hjo|#!%t;CXMOO1~vM@By$$wu(0 z7+*JsbCF0c%-{dHFL+pQI~s3&zjaOf89{d%!`6o3fsCO(`6

PqiNa$~E4XJ#a8s%?nsx`&SiQ7Wz{CE9c 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-icons/package.json b/alpha/admin/uni_modules/uni-icons/package.json new file mode 100644 index 0000000..d1c4e77 --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-icons", + "displayName": "uni-icons 图标", + "version": "1.3.5", + "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。", + "keywords": [ + "uni-ui", + "uniui", + "icon", + "图标" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.2.14" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-icons/readme.md b/alpha/admin/uni_modules/uni-icons/readme.md new file mode 100644 index 0000000..86234ba --- /dev/null +++ b/alpha/admin/uni_modules/uni-icons/readme.md @@ -0,0 +1,8 @@ +## Icons 图标 +> **组件名:uni-icons** +> 代码块: `uIcons` + +用于展示 icons 图标 。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 diff --git a/alpha/admin/uni_modules/uni-id-common/changelog.md b/alpha/admin/uni_modules/uni-id-common/changelog.md new file mode 100644 index 0000000..6a3d19b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-common/changelog.md @@ -0,0 +1,26 @@ +## 1.0.13(2022-07-21) +- 修复 创建token时未传角色权限信息生成的token不正确的bug +## 1.0.12(2022-07-15) +- 提升与旧版本uni-id的兼容性(补充读取配置文件时回退平台app-plus、h5),但是仍推荐使用新平台名进行配置(app、web) +## 1.0.11(2022-07-14) +- 修复 部分情况下报`read property 'reduce' of undefined`的错误 +## 1.0.10(2022-07-11) +- 将token存储在用户表的token字段内,与旧版本uni-id保持一致 +## 1.0.9(2022-07-01) +- checkToken兼容token内未缓存角色权限的情况,此时将查库获取角色权限 +## 1.0.8(2022-07-01) +- 修复clientDB默认依赖时部分情况下获取不到uni-id配置的Bug +## 1.0.7(2022-06-30) +- 修复config文件不合法时未抛出具体错误的Bug +## 1.0.6(2022-06-28) +- 移除插件内的数据表schema +## 1.0.5(2022-06-27) +- 修复使用多应用配置时报`Cannot read property 'appId' of undefined`的Bug +## 1.0.4(2022-06-27) +- 修复使用自定义token内容功能报错的Bug [详情](https://ask.dcloud.net.cn/question/147945) +## 1.0.2(2022-06-23) +- 对齐旧版本uni-id默认配置 +## 1.0.1(2022-06-22) +- 补充对uni-config-center的依赖 +## 1.0.0(2022-06-21) +- 提供uni-id token创建、校验、刷新接口,简化旧版uni-id公共模块 diff --git a/alpha/admin/uni_modules/uni-id-common/package.json b/alpha/admin/uni_modules/uni-id-common/package.json new file mode 100644 index 0000000..f92f9fc --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-common/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-id-common", + "displayName": "uni-id-common", + "version": "1.0.13", + "description": "包含uni-id token生成、校验、刷新功能的云函数公共模块", + "keywords": [ + "uni-id-common", + "uniCloud", + "token", + "权限" + ], + "repository": "https://gitcode.net/dcloud/uni-id-common", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "uniCloud", + "云函数模板" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": ["uni-config-center"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "u", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-common/readme.md b/alpha/admin/uni_modules/uni-id-common/readme.md new file mode 100644 index 0000000..5f6a37a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-common/readme.md @@ -0,0 +1,3 @@ +# uni-id-common + +文档请参考:[uni-id-common](https://uniapp.dcloud.net.cn/uniCloud/uni-id-common.html) \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js b/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js new file mode 100644 index 0000000..c51a148 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js @@ -0,0 +1 @@ +"use strict";var e,t=(e=require("crypto"))&&"object"==typeof e&&"default"in e?e.default:e;const n={TOKEN_EXPIRED:"uni-id-token-expired",CHECK_TOKEN_FAILED:"uni-id-check-token-failed",PARAM_REQUIRED:"uni-id-param-required",ACCOUNT_EXISTS:"uni-id-account-exists",ACCOUNT_NOT_EXISTS:"uni-id-account-not-exists",ACCOUNT_CONFLICT:"uni-id-account-conflict",ACCOUNT_BANNED:"uni-id-account-banned",ACCOUNT_AUDITING:"uni-id-account-auditing",ACCOUNT_AUDIT_FAILED:"uni-id-account-audit-failed",ACCOUNT_CLOSED:"uni-id-account-closed"};function i(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}function r(e){if(!e)return;const t=e.match(/^(\d+).(\d+).(\d+)/);return t?t.slice(1,4).map(e=>parseInt(e)):void 0}function o(e,t){const n=r(e),i=r(t);return n?i?function(e,t){const n=Math.max(e.length,t.length);for(let i=0;ir)return 1;if(ne)throw new Error("Config error, tokenExpiresThreshold should be less than tokenExpiresIn")}get customToken(){return this.uniId.interceptorMap.get("customToken")}isTokenInDb(e){return o(e,"1.0.10")>=0}async getUserRecord(){if(this.userRecord)return this.userRecord;const e=await C.doc(this.uid).get();if(this.userRecord=e.data[0],!this.userRecord)throw{errCode:n.ACCOUNT_NOT_EXISTS};switch(this.userRecord.status){case void 0:case 0:break;case 1:throw{errCode:n.ACCOUNT_BANNED};case 2:throw{errCode:n.ACCOUNT_AUDITING};case 3:throw{errCode:n.ACCOUNT_AUDIT_FAILED};case 4:throw{errCode:n.ACCOUNT_CLOSED}}if(this.oldTokenPayload){if(this.isTokenInDb(this.oldTokenPayload.uniIdVersion)){if(-1===(this.userRecord.token||[]).indexOf(this.oldToken))throw{errCode:n.CHECK_TOKEN_FAILED}}if(this.userRecord.valid_token_date&&this.userRecord.valid_token_date>1e3*this.oldTokenPayload.iat)throw{errCode:n.TOKEN_EXPIRED}}return this.userRecord}async updateUserRecord(e){await C.doc(this.uid).update(e)}async getUserPermission(){if(this.userPermission)return this.userPermission;const e=(await this.getUserRecord()).role||[];if(0===e.length)return this.userPermission={role:[],permission:[]},this.userPermission;if(e.includes("admin"))return this.userPermission={role:["admin"],permission:[]},this.userPermission;const t=await m.where({role_id:_.in(e)}).get(),n=(i=t.data.reduce((e,t)=>(t.permission&&e.push(...t.permission),e),[]),Array.from(new Set(i)));var i;return this.userPermission={role:e,permission:n},this.userPermission}async _createToken({uid:e,role:t,permission:i}={}){if(!t||!i){const e=await this.getUserPermission();t=e.role,i=e.permission}let r={uid:e,role:t,permission:i};if(this.uniId.interceptorMap.has("customToken")){const n=this.uniId.interceptorMap.get("customToken");if("function"!=typeof n)throw new Error("Invalid custom token file");r=await n({uid:e,role:t,permission:i})}const o=Date.now(),{tokenSecret:s,tokenExpiresIn:c}=this.config,a=g({...r,uniIdVersion:"1.0.13"},s,{expiresIn:c}),u=await this.getUserRecord(),d=(u.token||[]).filter(e=>{try{const t=this._checkToken(e);if(u.valid_token_date&&u.valid_token_date>1e3*t.iat)return!1}catch(e){if(e.errCode===n.TOKEN_EXPIRED)return!1}return!0});return d.push(a),await this.updateUserRecord({last_login_ip:this.clientInfo.clientIP,last_login_date:o,token:d}),{token:a,tokenExpired:o+1e3*c}}async createToken({uid:e,role:t,permission:i}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"uid"}};this.uid=e;const{token:r,tokenExpired:o}=await this._createToken({uid:e,role:t,permission:i});return{errCode:0,token:r,tokenExpired:o}}async refreshToken({token:e}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const t=this._checkToken(e);this.uid=t.uid,this.oldTokenPayload=t;const{uid:i}=t,{role:r,permission:o}=await this.getUserPermission(),{token:s,tokenExpired:c}=await this._createToken({uid:i,role:r,permission:o});return{errCode:0,token:s,tokenExpired:c}}_checkToken(e){const{tokenSecret:t}=this.config;let i;try{i=k(e,t)}catch(e){if("TokenExpiredError"===e.name)throw{errCode:n.TOKEN_EXPIRED};throw{errCode:n.CHECK_TOKEN_FAILED}}return i}async checkToken(e,{autoRefresh:t=!0}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const i=this._checkToken(e);this.uid=i.uid,this.oldTokenPayload=i;const{tokenExpiresThreshold:r}=this.config,{uid:o,role:s,permission:c}=i,a={role:s,permission:c};if(!s&&!c){const{role:e,permission:t}=await this.getUserPermission();a.role=e,a.permission=t}if(!r||!t){const e={code:0,errCode:0,...i,...a};return delete e.uniIdVersion,e}const u=Date.now();let d={};1e3*i.exp-u<1e3*r&&(d=await this._createToken({uid:o}));const l={code:0,errCode:0,...i,...a,...d};return delete l.uniIdVersion,l}}var E=Object.freeze({__proto__:null,checkToken:async function(e,{autoRefresh:t=!0}={}){return new T({uniId:this}).checkToken(e,{autoRefresh:t})},createToken:async function({uid:e,role:t,permission:n}={}){return new T({uniId:this}).createToken({uid:e,role:t,permission:n})},refreshToken:async function({token:e}={}){return new T({uniId:this}).refreshToken({token:e})}});const w=require("uni-config-center")({pluginId:"uni-id"});class A{constructor({context:e,clientInfo:t,config:n}={}){this._clientInfo=e?function(e){return{appId:e.APPID,platform:e.PLATFORM,locale:e.LOCALE,clientIP:e.CLIENTIP,deviceId:e.DEVICEID}}(e):t,this.config=n||this._getOriginConfig(),this.interceptorMap=new Map,w.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(w.resolve("custom-token.js"))),this._i18n=uniCloud.initI18n({locale:this._clientInfo.locale,fallbackLocale:"zh-Hans",messages:d})}setInterceptor(e,t){this.interceptorMap.set(e,t)}_t(...e){return this._i18n.t(...e)}_parseOriginConfig(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getOriginConfig(){if(w.hasFile("config.json")){let e;try{e=w.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseOriginConfig(e)}try{return this._parseOriginConfig(require("uni-id/config.json"))}catch(e){throw new Error("Invalid uni-id config file")}}_getAppConfig(){const e=this._getOriginConfig();return Array.isArray(e)?e.find(e=>e.dcloudAppid===this._clientInfo.appId)||e.find(e=>e.isDefaultConfig):e}_getPlatformConfig(){const e=this._getAppConfig();if(!e)throw new Error(`Config for current app (${this._clientInfo.appId}) was not found, please check your config file or client appId`);let t;switch("app-plus"===this._clientInfo.platform&&(this._clientInfo.platform="app"),"h5"===this._clientInfo.platform&&(this._clientInfo.platform="web"),this._clientInfo.platform){case"web":t="h5";break;case"app":t="app-plus"}const n=[{tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600},e];t&&e[t]&&n.push(e[t]),n.push(e[this._clientInfo.platform]);const i=Object.assign(...n);return["tokenSecret","tokenExpiresIn"].forEach(e=>{if(!i||!i[e])throw new Error(`Config parameter missing, ${e} is required`)}),i}_getConfig(){return this._getPlatformConfig()}}for(const e in E)A.prototype[e]=E[e];function y(e){const t=new A(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(n=e[t],function(){let e;try{e=n.apply(this,arguments)}catch(e){if(a(e))return c.call(this,e),e;throw e}return i(e)?e.then(e=>(a(e)&&c.call(this,e),e),e=>{if(a(e))return c.call(this,e),e;throw e}):(a(e)&&c.call(this,e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var n}})}A.prototype.createInstance=y;const x={createInstance:y};module.exports=x; diff --git a/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t 返回上一路由 > 跳转首页 +- uni-id-co 优化 注册管理员时管理员存在提示文案 +## 1.0.12(2022-09-07) +- 修复 getSupportedLoginType判断是否支持微信公众号、PC网页微信扫码登录方式报错的Bug +- 优化 适配pc端样式 +- 新增 邮箱验证码注册 +- 新增 邮箱验证码找回密码 +- 新增 退出登录(全局)回调事件:`uni-id-pages-logout`,支持通过[uni.$on](https://uniapp.dcloud.net.cn/api/window/communication.html#on)监听; +- 调整 抽离退出登录方法至`/uni_modules/uni-id-pages/common/common.js`中,方便在项目其他页面中调用 +- 调整 用户中心(路径:`/uni_modules/uni-id-pages/pages/userinfo/userinfo`)默认不再显示退出登录按钮。支持页面传参数`showLoginManage=true`恢复显示 +## 1.0.11(2022-09-01) +- 修复 iOS端,一键登录功能卡在showLoading的问题 +- 更新 合并密码强度与长度配置 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#config) +- uni-id-co 修复 调用 removeAuthorizedApp 接口报错的Bug +- uni-id-co 新增 管理端接口 updateUser [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user) +- uni-id-co 调整 为兼容旧版本,未配置密码强度时提供最简单的密码规则校验(长度大于6即可) +- uni-id-co 调整 注册、登录时如果携带了token则尝试对此token进行登出操作 +- uni-id-co 调整 管理端接口 addUser 增加 mobile、email等参数 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user) +## 1.0.10(2022-08-25) +- 修复 导入uni-id-pages插件时未自动导入uni-open-bridge-common的Bug +## 1.0.9(2022-08-23) +- 修复 uni-id-co 缺失uni-open-bridge-common依赖的Bug +## 1.0.8(2022-08-23) +- 新增 H5端支持微信登录(含微信公众号内的网页授权登录 和 普通浏览器内网页生成二维码,实现手机微信扫码登录)[详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#weixinlogin) +- 新增 登录成功(全局)回调事件:`uni-id-pages-login-success`,支持通过[uni.$on](https://uniapp.dcloud.net.cn/api/window/communication.html#on)监听; +- 新增 密码强度(是否必须包含大小写字母、数字和特殊符号以及长度)配置 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#config) +- 调整 uni-id-co 密码规则调整,废除之前的简单校验,允许配置密码强度 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#password-strength) +- 调整 uni-id-co 存储用户 openid 时同时以客户端 AppId 为 Key 的副本,参考:[微信登录](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-weixin)、[QQ登录](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-qq) +- 调整 uni-id-co 依赖 uni-open-bridge-common 存储用户 session_key、access_token 等信息 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#save-user-token) +- 新增 uni-id-co 增加 beforeRegister 钩子用户在注册前向用户记录内添加一些数据 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#before-register) +## 1.0.7(2022-07-19) +- 修复 uni-id-co接口 logout时没有删除token的Bug +## 1.0.6(2022-07-13) +- 新增 允许覆盖内置校验规则 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#custom-validator) +- 修复 app端clientInfo.appVersionCode为数字导致校验无法通过的Bug +## 1.0.5(2022-07-11) +修复 微信小程序调用uni-id-co接口报错的Bug [详情](https://ask.dcloud.net.cn/question/148877) +## 1.0.4(2022-07-06) +- uni-id-co增加clientInfo字段类型校验 +- 监听token更新时机,同步客户端push_clientid至uni-id-device表,改为:同步客户端push_clientid至uni-id-device表和opendb-device表 +## 1.0.3(2022-07-05) +新增监听token更新时机,同步客户端push_clientid至uni-id-device表 +## 1.0.2(2022-07-04) +修复微信小程序登录时无unionid报错的Bug [详情](https://ask.dcloud.net.cn/question/148016) +## 1.0.1(2022-06-28) +添加相关uni-id表 +## 1.0.0(2022-06-23) +正式版 diff --git a/alpha/admin/uni_modules/uni-id-pages/common/common.js b/alpha/admin/uni_modules/uni-id-pages/common/common.js new file mode 100644 index 0000000..a672660 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/common.js @@ -0,0 +1,13 @@ +import pagesJson from '@/pages.json' +const uniIdCo = uniCloud.importObject("uni-id-co") +export default { + async logout() { + await uniIdCo.logout() + uni.removeStorageSync('uni_id_token'); + uni.setStorageSync('uni_id_token_expired', 0) + uni.redirectTo({ + url: `/${pagesJson.uniIdRouter?.loginPage ?? 'uni_modules/uni-id-pages/pages/login/login-withoutpwd'}`, + }); + uni.$emit('uni-id-pages-logout') + }, +} diff --git a/alpha/admin/uni_modules/uni-id-pages/common/login-page.mixin.js b/alpha/admin/uni_modules/uni-id-pages/common/login-page.mixin.js new file mode 100644 index 0000000..97b48bb --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/login-page.mixin.js @@ -0,0 +1,88 @@ +import { + store, + mutations + } from '@/uni_modules/uni-id-pages/common/store.js' +import config from '@/uni_modules/uni-id-pages/config.js' +let mixin = { + data() { + return { + config, + uniIdRedirectUrl: '', + isMounted: false + } + }, + onUnload() { + // #ifdef H5 + document.onkeydown = false + // #endif + }, + mounted() { + this.isMounted = true; + }, + onLoad(e) { + if (e.is_weixin_redirect) { + uni.showLoading({ + mask: true + }) + + if( window.location.href.includes('#') ){ + // 将url通过 ? 分割获取后面的参数字符串 再通过 & 将每一个参数单独分割出来 + let paramsArr = window.location.href.split('?')[1].split('&') + paramsArr.forEach(item=>{ + let arr = item.split('=') + if(arr[0] == 'code'){ + e.code = arr[1] + } + }) + } + this.$nextTick(n => { + // console.log(this.$refs.uniFabLogin); + this.$refs.uniFabLogin.login({ + code:e.code + }, 'weixin') + }) + } + + if (e.uniIdRedirectUrl) { + this.uniIdRedirectUrl = decodeURIComponent(e.uniIdRedirectUrl) + } + }, + computed: { + needAgreements() { + if (this.isMounted) { + if (this.$refs.agreements) { + return this.$refs.agreements.needAgreements + } else { + return false + } + } + }, + agree: { + get() { + if (this.isMounted) { + if (this.$refs.agreements) { + return this.$refs.agreements.isAgree + } else { + return true + } + } + }, + set(agree) { + if (this.$refs.agreements) { + this.$refs.agreements.isAgree = agree + } else { + console.log('不存在 隐私政策协议组件'); + } + } + } + }, + methods: { + loginSuccess(e) { + mutations.loginSuccess({ + ...e, + uniIdRedirectUrl: this.uniIdRedirectUrl + }) + } + } +} +export default mixin diff --git a/alpha/admin/uni_modules/uni-id-pages/common/login-page.scss b/alpha/admin/uni_modules/uni-id-pages/common/login-page.scss new file mode 100644 index 0000000..5de6899 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/login-page.scss @@ -0,0 +1,126 @@ +// 隐藏 edge 浏览器的密码查看按钮 + +/* #ifdef H5 */ +.input-box ::v-deep{ + .uni-input-input[type="password"] { + &::-ms-reveal { + display: none; + } + } +} +/* #endif */ + +.uni-content { + padding: 0 60rpx; +} + +.login-logo { + display: none; +} + +/* #ifndef APP-NVUE */ +@media screen and (min-width: 690px) { + .uni-content { + /* #ifndef H5 */ + padding: 0; + max-width: 300px; + margin-left: calc(50% - 200px); + /* #endif */ + /* #ifdef H5 */ + margin: 0 auto; + position: relative; + top: 100px; + padding: 30px 40px 80px 40px; + max-width: 450px; + max-height: 450px; + border-radius: 10px; + box-shadow: 0 0 20px #efefef; + background-color: #FFF; + /* #endif */ + } + /* #ifdef H5 */ + .login-logo { + display: flex; + justify-content: center; + } + + .login-logo image { + width: 60px; + height: 60px; + } + + .register-back{ + display: none; + } + + uni-button{ + padding-bottom: 1px; + } + + /* #endif */ +} + +.uni-content view { + box-sizing: border-box; +} +/* #endif */ + + + +.title { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + padding: 18px 0; + font-weight: 800; + flex-direction: column; +} + +.tip { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + color: #BDBDC0; + font-size: 11px; + margin: 6px 0; +} + + +/* #ifndef APP-NVUE */ +// 解决小程序端开启虚拟节点virtualHost引起的 class = input-box丢失的问题 [详情参考](https://uniapp.dcloud.net.cn/matter.html#%E5%90%84%E5%AE%B6%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%AE%9E%E7%8E%B0%E6%9C%BA%E5%88%B6%E4%B8%8D%E5%90%8C-%E5%8F%AF%E8%83%BD%E5%AD%98%E5%9C%A8%E7%9A%84%E5%B9%B3%E5%8F%B0%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98) +.uni-content ::v-deep .uni-easyinput__content, +/* #endif */ + +.input-box { + height: 44px; + background-color: #F8F8F8 !important; + border-radius: 0; + font-size: 14px; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex: 1; +} + +.link { + color: #04498c; + cursor: pointer; +} + +.uni-content ::v-deep .uni-forms-item__inner { + padding-bottom: 8px; +} + +.uni-btn { + text-align: center; + height: 40px; + line-height: 40px; + margin: 15px 0 10px 0; + color: #FFF !important; + border-radius: 5px; + font-size: 16px; +} + +.uni-body.uni_modules-uni-id-pages-pages-login-login-withoutpwd{ + height: auto !important; +} diff --git a/alpha/admin/uni_modules/uni-id-pages/common/loginSuccess.js b/alpha/admin/uni_modules/uni-id-pages/common/loginSuccess.js new file mode 100644 index 0000000..48dac11 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/loginSuccess.js @@ -0,0 +1,45 @@ +import pagesJson from '@/pages.json' + +export default function(e = {}) { + const { + showToast = true, toastText = '登录成功', autoBack = true, uniIdRedirectUrl = '' + } = e + + if (showToast) { + uni.showToast({ + title: toastText, + icon: 'none' + }); + } + if (autoBack) { + let delta = 0; //判断需要返回几层 + let pages = getCurrentPages(); + uni.$emit('uni-id-pages-login-success',pages) + pages.forEach((page, index) => { + if (pages[pages.length - index - 1].route.split('/')[3] == 'login') { + delta++ + } + }) + if (uniIdRedirectUrl) { + return uni.reLaunch({ + url: uniIdRedirectUrl + }) + } + // #ifdef H5 + if(e.loginType == 'weixin'){ + return window.history.go(-3) + } + // #endif + + if (delta) { + const page = pagesJson.pages[0] + return uni.reLaunch({ + url: `/${page.path}` + }) + } + + uni.navigateBack({ + delta + }) + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/common/password.js b/alpha/admin/uni_modules/uni-id-pages/common/password.js new file mode 100644 index 0000000..196c240 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/password.js @@ -0,0 +1,85 @@ +// 导入配置 +import config from '@/uni_modules/uni-id-pages/config.js' + +const {passwordStrength} = config + +// 密码强度表达式 +const passwordRules = { + // 密码必须包含大小写字母、数字和特殊符号 + super: /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须包含字母、数字和特殊符号 + strong: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须为字母、数字和特殊符号任意两种的组合 + medium: /^(?![0-9]+$)(?![a-zA-Z]+$)(?![~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]+$)[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须包含字母和数字 + weak: /^(?=.*[0-9])(?=.*[a-zA-Z])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{6,16}$/ +} + +const ERROR = { + normal: { + noPwd: '请输入密码', + noRePwd: '再次输入密码', + rePwdErr: '两次输入密码不一致' + }, + passwordStrengthError: { + super: '密码必须包含大小写字母、数字和特殊符号,密码长度必须在8-16位之间', + strong: '密码必须包含字母、数字和特殊符号,密码长度必须在8-16位之间', + medium: '密码必须为字母、数字和特殊符号任意两种的组合,密码长度必须在8-16位之间', + weak: '密码必须包含字母,密码长度必须在6-16位之间' + } +} + +function validPwd(password) { + //强度校验 + if (passwordStrength && passwordRules[passwordStrength]) { + if (!new RegExp(passwordRules[passwordStrength]).test(password)) { + return ERROR.passwordStrengthError[passwordStrength] + } + } + return true +} + +function getPwdRules(pwdName = 'password', rePwdName = 'password2') { + const rules = {} + rules[pwdName] = { + rules: [{ + required: true, + errorMessage: ERROR.normal.noPwd, + }, + { + validateFunction: function(rule, value, data, callback) { + const checkRes = validPwd(value) + if (checkRes !== true) { + callback(checkRes) + } + return true + } + } + ] + } + + if (rePwdName) { + rules[rePwdName] = { + rules: [{ + required: true, + errorMessage: ERROR.normal.noRePwd, + }, + { + validateFunction: function(rule, value, data, callback) { + if (value != data[pwdName]) { + callback(ERROR.normal.rePwdErr) + } + return true + } + } + ] + } + } + return rules +} + +export default { + ERROR, + validPwd, + getPwdRules +} diff --git a/alpha/admin/uni_modules/uni-id-pages/common/store.js b/alpha/admin/uni_modules/uni-id-pages/common/store.js new file mode 100644 index 0000000..98966d0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/common/store.js @@ -0,0 +1,160 @@ +import pagesJson from '@/pages.json' +import config from '@/uni_modules/uni-id-pages/config.js' + +const uniIdCo = uniCloud.importObject("uni-id-co") +const db = uniCloud.database(); +const usersTable = db.collection('uni-id-users') + +let hostUserInfo = uni.getStorageSync('uni-id-pages-userInfo')||{} +// console.log( hostUserInfo); +const data = { + userInfo: hostUserInfo, + hasLogin: Object.keys(hostUserInfo).length != 0 +} + +// console.log('data', data); +// 定义 mutations, 修改属性 +export const mutations = { + // data不为空,表示传递要更新的值(注意不是覆盖是合并),什么也不传时,直接查库获取更新 + async updateUserInfo(data = false) { + if (data) { + usersTable.where('_id==$env.uid').update(data).then(e => { + // console.log(e); + if (e.result.updated) { + uni.showToast({ + title: "更新成功", + icon: 'none', + duration: 3000 + }); + this.setUserInfo(data) + } else { + uni.showToast({ + title: "没有改变", + icon: 'none', + duration: 3000 + }); + } + }) + + } else { + try { + let res = await usersTable.where("'_id' == $cloudEnv_uid") + .field('mobile,nickname,username,email,avatar_file') + .get() + // console.log('fromDbData',res.result.data); + this.setUserInfo(res.result.data[0]) + } catch (e) { + this.setUserInfo({},{cover:true}) + console.error(e.message, e.errCode); + } + } + }, + async setUserInfo(data, {cover}={cover:false}) { + // console.log('set-userInfo', data); + let userInfo = cover?data:Object.assign(store.userInfo,data) + store.userInfo = Object.assign({},userInfo) + store.hasLogin = Object.keys(store.userInfo).length != 0 + // console.log('store.userInfo', store.userInfo); + uni.setStorage({ + key: "uni-id-pages-userInfo", + data:store.userInfo + }) + return data + }, + async logout() { + // 1. 已经过期就不需要调用服务端的注销接口 2.即使调用注销接口失败,不能阻塞客户端 + if(uniCloud.getCurrentUserInfo().tokenExpired > Date.now()){ + try{ + await uniIdCo.logout() + }catch(e){ + console.error(e); + } + } + uni.removeStorageSync('uni_id_token'); + uni.setStorageSync('uni_id_token_expired', 0) + uni.redirectTo({ + url: `/${pagesJson.uniIdRouter?.loginPage ?? 'uni_modules/uni-id-pages/pages/login/login-withoutpwd'}`, + }); + uni.$emit('uni-id-pages-logout') + this.setUserInfo({},{cover:true}) + }, + + loginBack (e = {}) { + const {uniIdRedirectUrl = ''} = e + let delta = 0; //判断需要返回几层 + let pages = getCurrentPages(); + // console.log(pages); + pages.forEach((page, index) => { + if (pages[pages.length - index - 1].route.split('/')[3] == 'login') { + delta++ + } + }) + // console.log('判断需要返回几层:', delta); + if (uniIdRedirectUrl) { + return uni.reLaunch({ + url: uniIdRedirectUrl + }) + } + // #ifdef H5 + if (e.loginType == 'weixin') { + // console.log('window.history', window.history); + return window.history.go(-3) + } + // #endif + + if (delta) { + const page = pagesJson.pages[0] + return uni.reLaunch({ + url: `/${page.path}` + }) + } + + uni.navigateBack({ + delta + }) + }, + loginSuccess(e = {}){ + const { + showToast = true, toastText = '登录成功', autoBack = true, uniIdRedirectUrl = '', passwordConfirmed + } = e + // console.log({toastText,autoBack}); + if (showToast) { + uni.showToast({ + title: toastText, + icon: 'none', + duration: 3000 + }); + } + this.updateUserInfo() + + uni.$emit('uni-id-pages-login-success') + + if (config.setPasswordAfterLogin && !passwordConfirmed) { + return uni.redirectTo({ + url: uniIdRedirectUrl ? `/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd?uniIdRedirectUrl=${uniIdRedirectUrl}&loginType=${e.loginType}`: `/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd?loginType=${e.loginType}`, + fail: (err) => { + console.log(err) + } + }) + } + + if (autoBack) { + this.loginBack(uniIdRedirectUrl) + } + } + +} + +// #ifdef VUE2 +import Vue from 'vue' +// 通过Vue.observable创建一个可响应的对象 +export const store = Vue.observable(data) +// #endif + +// #ifdef VUE3 +import { + reactive +} from 'vue' +// 通过Vue.observable创建一个可响应的对象 +export const store = reactive(data) +// #endif diff --git a/alpha/admin/uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue b/alpha/admin/uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue new file mode 100644 index 0000000..d714a3a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue @@ -0,0 +1,73 @@ + + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-agreements/uni-id-pages-agreements.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-agreements/uni-id-pages-agreements.vue new file mode 100644 index 0000000..31ab0b7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-agreements/uni-id-pages-agreements.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-avatar/uni-id-pages-avatar.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-avatar/uni-id-pages-avatar.vue new file mode 100644 index 0000000..cb81b37 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-avatar/uni-id-pages-avatar.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-bind-mobile/uni-id-pages-bind-mobile.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-bind-mobile/uni-id-pages-bind-mobile.vue new file mode 100644 index 0000000..56edaec --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-bind-mobile/uni-id-pages-bind-mobile.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue new file mode 100644 index 0000000..b10d7dc --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue new file mode 100644 index 0000000..6c7ca7d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue @@ -0,0 +1,558 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-sms-form/uni-id-pages-sms-form.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-sms-form/uni-id-pages-sms-form.vue new file mode 100644 index 0000000..1d38b87 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-sms-form/uni-id-pages-sms-form.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-user-profile/uni-id-pages-user-profile.vue b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-user-profile/uni-id-pages-user-profile.vue new file mode 100644 index 0000000..7b78f9b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/components/uni-id-pages-user-profile/uni-id-pages-user-profile.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/config.js b/alpha/admin/uni_modules/uni-id-pages/config.js new file mode 100644 index 0000000..2ecffb9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/config.js @@ -0,0 +1,56 @@ +export default { + //调试模式 + "debug": false, + /* + 登录类型 未列举到的或运行环境不支持的,将被自动隐藏。 + 如果需要在不同平台有不同的配置,直接用条件编译即可 + */ + "isAdmin": true, // 区分管理端与用户端 + "loginTypes": [ + // "qq", + // "xiaomi", + // "sinaweibo", + // "taobao", + // "facebook", + // "google", + // "alipay", + // "douyin", + + // #ifdef APP + "univerify", + // #endif + // "weixin", + "username", + // #ifdef APP + "apple", + // #endif + // "smsCode" + ], + //政策协议 + // "agreements": { + // "serviceUrl": "https://xxx", //用户服务协议链接 + // "privacyUrl": "https://xxx", //隐私政策条款链接 + // // 哪些场景下显示,1.注册(包括登录并注册,如:微信登录、苹果登录、短信验证码登录)、2.登录(如:用户名密码登录) + // "scope": [ + // 'register', 'login' + // ] + // }, + // 提供各类服务接入(如微信登录服务)的应用id + "appid": { + "weixin": { + // 微信公众号的appid,来源:登录微信公众号(https://mp.weixin.qq.com)-> 设置与开发 -> 基本配置 -> 公众号开发信息 -> AppID + "h5": "xxxxxx", + // 微信开放平台的appid,来源:登录微信开放平台(https://open.weixin.qq.com) -> 管理中心 -> 网站应用 -> 选择对应的应用名称,点击查看 -> AppID + "web": "xxxxxx" + } + }, + /** + * 密码强度 + * super(超强:密码必须包含大小写字母、数字和特殊符号,长度范围:8-16位之间) + * strong(强: 密密码必须包含字母、数字和特殊符号,长度范围:8-16位之间) + * medium (中:密码必须为字母、数字和特殊符号任意两种的组合,长度范围:8-16位之间) + * weak(弱:密码必须包含字母和数字,长度范围:6-16位之间) + * 为空或false则不验证密码强度 + */ + "passwordStrength":"medium" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/init.js b/alpha/admin/uni_modules/uni-id-pages/init.js new file mode 100644 index 0000000..679ac7a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/init.js @@ -0,0 +1,96 @@ +// 导入配置 +import config from '@/uni_modules/uni-id-pages/config.js'; +// uni-id的云对象 +const uniIdCo = uniCloud.importObject("uni-id-co", { + customUI: true +}) +// 用户配置的登录方式、是否打开调试模式 +const { + loginTypes, + debug +} = config + +export default async function() { + + // 有打开调试模式的情况下 + if (debug) { + // 1. 检查本地uni-id-pages中配置的登录方式,服务器端是否已经配置正确。否则提醒并引导去配置 + //调用云对象,获取服务端已正确配置的登录方式 + let { + supportedLoginType + } = await uniIdCo.getSupportedLoginType() + //console.log("supportedLoginType: " + JSON.stringify(supportedLoginType)); + //登录方式,服务端和客户端的映射关系 + let data = { + smsCode: 'mobile-code', + univerify: 'univerify', + username: 'username-password', + weixin: 'weixin', + qq: 'qq', + xiaomi: 'xiaomi', + sinaweibo: 'sinaweibo', + taobao: 'taobao', + facebook: 'facebook', + google: 'google', + alipay: 'alipay', + apple: "apple" + } + //遍历客户端配置的登录方式,与服务端比对。并在错误时抛出错误提示 + let list = loginTypes.filter(type => !supportedLoginType.includes(data[type])) + if (list.length) { + console.error( + `错误:前端启用的登录方式:${list.join(',')};没有在服务端完成配置。配置文件路径:"/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json"` + ); + } + } + + // #ifdef APP-PLUS + //如果uni-id-pages配置的登录功能有一键登录,有则执行预登录(异步) + if (loginTypes.includes('univerify')) { + uni.preLogin({ + provider: 'univerify', + complete: e => { + // console.log(e); + } + }) + } + // #endif + + //3. 绑定clientDB错误事件 + // clientDB对象 + const db = uniCloud.database() + db.on('error', onDBError) + //clientDB的错误提示 + function onDBError({ + code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue + message + }) { + // console.error('onDBError', {code,message}); + } + // 解绑clientDB错误事件 + //db.off('error', onDBError) + + + //4. 同步客户端push_clientid至device表 + if (uniCloud.onRefreshToken) { + uniCloud.onRefreshToken(() => { + // console.log('onRefreshToken'); + if (uni.getPushClientId) { + uni.getPushClientId({ + success: async function(e) { + // console.log(e) + let pushClientId = e.cid + // console.log(pushClientId); + let res = await uniIdCo.setPushCid({ + pushClientId + }) + // console.log('getPushClientId', res); + }, + fail(e) { + console.log(e) + } + }) + } + }) + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/package.json b/alpha/admin/uni_modules/uni-id-pages/package.json new file mode 100644 index 0000000..26ad9af --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/package.json @@ -0,0 +1,101 @@ +{ + "id": "uni-id-pages", + "displayName": "uni-id-pages", + "version": "1.1.0", + "description": "云端一体简单、统一、可扩展的用户中心页面模版", + "keywords": [ + "用户管理", + "用户中心", + "短信验证码", + "login", + "登录" + ], + "repository": "https://gitcode.net/dcloud/hello_uni-id-pages", + "engines": { + "HBuilderX": "^3.4.17" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "unicloud-template-page" + }, + "uni_modules": { + "dependencies": [ + "uni-captcha", + "uni-config-center", + "uni-data-checkbox", + "uni-easyinput", + "uni-forms", + "uni-icons", + "uni-id-common", + "uni-list", + "uni-load-more", + "uni-popup", + "uni-scss", + "uni-transition", + "uni-open-bridge-common" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "u", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + }, + "dependencies": { + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/common/webview/webview.vue b/alpha/admin/uni_modules/uni-id-pages/pages/common/webview/webview.vue new file mode 100644 index 0000000..71ff55c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/common/webview/webview.vue @@ -0,0 +1,35 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/login/login-smscode.vue b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-smscode.vue new file mode 100644 index 0000000..f847cc5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-smscode.vue @@ -0,0 +1,120 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue new file mode 100644 index 0000000..5e88727 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue @@ -0,0 +1,241 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withpwd.vue b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withpwd.vue new file mode 100644 index 0000000..e7a83b7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/login/login-withpwd.vue @@ -0,0 +1,176 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/register/register-admin.vue b/alpha/admin/uni_modules/uni-id-pages/pages/register/register-admin.vue new file mode 100644 index 0000000..fcaf88a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/register/register-admin.vue @@ -0,0 +1,178 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/register/register-by-email.vue b/alpha/admin/uni_modules/uni-id-pages/pages/register/register-by-email.vue new file mode 100644 index 0000000..805234b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/register/register-by-email.vue @@ -0,0 +1,216 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/register/register.vue b/alpha/admin/uni_modules/uni-id-pages/pages/register/register.vue new file mode 100644 index 0000000..20de1ad --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/register/register.vue @@ -0,0 +1,181 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/register/validator.js b/alpha/admin/uni_modules/uni-id-pages/pages/register/validator.js new file mode 100644 index 0000000..3c39c76 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/register/validator.js @@ -0,0 +1,56 @@ +import passwordMod from '@/uni_modules/uni-id-pages/common/password.js' +export default { + "username": { + "rules": [{ + required: true, + errorMessage: '请输入用户名', + }, + { + minLength: 3, + maxLength: 32, + errorMessage: '用户名长度在 {minLength} 到 {maxLength} 个字符', + }, + { + validateFunction: function(rule, value, data, callback) { + // console.log(value); + if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) { + callback('用户名不能是:手机号或邮箱') + }; + if (/^\d+$/.test(value)) { + callback('用户名不能为纯数字') + }; + if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){ + callback('用户名不能包含中文') + } + return true + } + } + ], + "label": "用户名" + }, + "nickname": { + "rules": [{ + minLength: 3, + maxLength: 32, + errorMessage: '昵称长度在 {minLength} 到 {maxLength} 个字符', + }, + { + validateFunction: function(rule, value, data, callback) { + // console.log(value); + if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) { + callback('昵称不能是:手机号或邮箱') + }; + if (/^\d+$/.test(value)) { + callback('昵称不能为纯数字') + }; + // if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){ + // callback('昵称不能包含中文') + // } + return true + } + } + ], + "label": "昵称" + }, + ...passwordMod.getPwdRules() +} diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue b/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue new file mode 100644 index 0000000..b6e7704 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue @@ -0,0 +1,218 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve.vue b/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve.vue new file mode 100644 index 0000000..6e1976b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/retrieve/retrieve.vue @@ -0,0 +1,241 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue new file mode 100644 index 0000000..a6b2b1f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue new file mode 100644 index 0000000..2992623 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue @@ -0,0 +1,130 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage.vue new file mode 100644 index 0000000..2317b9b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage.vue @@ -0,0 +1,39 @@ + + + + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/README.md b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/README.md new file mode 100644 index 0000000..9219f81 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/README.md @@ -0,0 +1,227 @@ +> 插件来源:[https://ext.dcloud.net.cn/plugin?id=3594](https://ext.dcloud.net.cn/plugin?id=3594) +##### 以下是作者写的插件介绍: + +# Clipper 图片裁剪 +> uniapp 图片裁剪,可用于图片头像等裁剪处理 +> [查看更多](http://liangei.gitee.io/limeui/#/clipper)
+> Q群:458377637 + + +## 平台兼容 + +| H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 | App | +| --- | ---------- | ------------ | ---------- | ---------- | --------- | --- | +| √ | √ | √ | 未测 | √ | √ | √ | + + +## 代码演示 +### 基本用法 +`@success` 事件点击 👉 **确定** 后会返回生成的图片信息,包含 `url`、`width`、`height` + +```html + + + +``` + +```js +// 非uni_modules引入 +import lClipper from '@/components/lime-clipper/' +// uni_modules引入 +import lClipper from '@/uni_modules/lime-clipper/components/lime-clipper/' +export default { + components: {lClipper}, + data() { + return { + show: false, + url: '', + } + } +} +``` + + +### 传入图片 +`image-url`可传入**相对路径**、**临时路径**、**本地路径**、**网络图片**
+ +* **当为网络地址时** +* H5:👉 需要解决跨域问题。
+* 小程序:👉 需要配置 downloadFile 域名
+ + +```html + + + +``` + +```js +export default { + components: {lClipper}, + data() { + return { + imageUrl: 'https://img12.360buyimg.com/pop/s1180x940_jfs/t1/97205/26/1142/87801/5dbac55aEf795d962/48a4d7a63ff80b8b.jpg', + show: false, + url: '', + } + } +} +``` + + +### 确定按钮颜色 +样式变量名:`--l-clipper-confirm-color` +可放到全局样式的 `page` 里或节点的 `style` +```html + +``` +```css +// css 中为组件设置 CSS 变量 +.clipper { + --l-clipper-confirm-color: linear-gradient(to right, #ff6034, #ee0a24) +} +// 全局 +page { + --l-clipper-confirm-color: linear-gradient(to right, #ff6034, #ee0a24) +} +``` + + +### 使用插槽 +共五个插槽 `cancel` 取消按钮、 `photo` 选择图片按钮、 `rotate` 旋转按钮、 `confirm` 确定按钮和默认插槽。 + +```html + + + + 取消 + 选择图片 + 旋转 + 确定 + + + 显示取消按钮 + + + 显示选择图片按钮 + + + 显示旋转按钮 + + + 显示确定按钮 + + + 锁定裁剪框宽度 + + + 锁定裁剪框高度 + + + 锁定裁剪框比例 + + + 限制移动范围 + + + 禁止缩放 + + + 禁止旋转 + + + + + +``` + +```js +export default { + components: {lClipper}, + data() { + return { + show: false, + url: '', + isLockWidth: false, + isLockHeight: false, + isLockRatio: true, + isLimitMove: false, + isDisableScale: false, + isDisableRotate: false, + isShowCancelBtn: true, + isShowPhotoBtn: true, + isShowRotateBtn: true, + isShowConfirmBtn: true + } + } +} +``` + + +## API + +### Props + +| 参数 | 说明 | 类型 | 默认值 | +| ------------- | ------------ | ---------------- | ------------ | +| image-url | 图片路径 | string | | +| quality | 图片的质量,取值范围为 [0, 1],不在范围内时当作1处理 | number | `1` | +| source | `{album: '从相册中选择'}`key为图片来源类型,value为选项说明 | Object | | +| width | 裁剪框宽度,单位为 `rpx` | number | `400` | +| height | 裁剪框高度 | number | `400` | +| min-width | 裁剪框最小宽度 | number | `200` | +| min-height |裁剪框最小高度 | number | `200` | +| max-width | 裁剪框最大宽度 | number | `600` | +| max-height | 裁剪框最大宽度 | number | `600` | +| min-ratio | 图片最小缩放比 | number | `0.5` | +| max-ratio | 图片最大缩放比 | number | `2` | +| rotate-angle | 旋转按钮每次旋转的角度 | number | `90` | +| scale-ratio | 生成图片相对于裁剪框的比例, **比例越高生成图片越清晰** | number | `1` | +| is-lock-width | 是否锁定裁剪框宽度 | boolean | `false` | +| is-lock-height | 是否锁定裁剪框高度上 | boolean | `false` | +| is-lock-ratio | 是否锁定裁剪框比例 | boolean | `true` | +| is-disable-scale | 是否禁止缩放 | boolean | `false` | +| is-disable-rotate | 是否禁止旋转 | boolean | `false` | +| is-limit-move | 是否限制移动范围 | boolean | `false` | +| is-show-photo-btn | 是否显示选择图片按钮 | boolean | `true` | +| is-show-rotate-btn | 是否显示转按钮 | boolean | `true` | +| is-show-confirm-btn | 是否显示确定按钮 | boolean | `true` | +| is-show-cancel-btn | 是否显示关闭按钮 | boolean | `true` | + + + +### 事件 Events + +| 事件名 | 说明 | 回调 | +| ------- | ------------ | -------------- | +| success | 生成图片成功 | {`width`, `height`, `url`} | +| fail | 生成图片失败 | `error` | +| cancel | 关闭 | `false` | +| ready | 图片加载完成 | {`width`, `height`, `path`, `orientation`, `type`} | +| change | 图片大小改变时触发 | {`width`, `height`} | +| rotate | 图片旋转时触发 | `angle` | + +## 常见问题 +> 1、H5端使用网络图片需要解决跨域问题。
+> 2、小程序使用网络图片需要去公众平台增加下载白名单!二级域名也需要配!
+> 3、H5端生成图片是base64,有时显示只有一半可以使用原生标签``
+> 4、IOS APP 请勿使用HBX2.9.3.20201014的版本!这个版本无法生成图片。
+> 5、APP端无成功反馈、也无失败反馈时,请更新基座和HBX。
+ + +## 打赏 +如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
+![输入图片说明](https://images.gitee.com/uploads/images/2020/1122/222521_bb543f96_518581.jpeg "微信图片编辑_20201122220352.jpg") \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/photo.svg b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/photo.svg new file mode 100644 index 0000000..7b4b590 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/photo.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/rotate.svg b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/rotate.svg new file mode 100644 index 0000000..0143706 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/images/rotate.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/index.css b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/index.css new file mode 100644 index 0000000..ce542bf --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/index.css @@ -0,0 +1,160 @@ +.flex-auto { + flex: auto; +} +.bg-transparent { + background-color: rgba(0,0,0,0.9); + transition-duration: 0.35s; +} +.l-clipper { + width: 100vw; + height: calc(100vh - var(--window-top)); + background-color: rgba(0,0,0,0.9); + position: fixed; + top: var(--window-top); + left: 0; + z-index: 1; +} +.l-clipper-mask { + position: relative; + z-index: 2; + pointer-events: none; +} +.l-clipper__content { + pointer-events: none; + position: absolute; + border: 1rpx solid rgba(255,255,255,0.3); + box-sizing: border-box; + box-shadow: rgba(0,0,0,0.5) 0 0 0 80vh; + background: transparent; +} +.l-clipper__content::before, +.l-clipper__content::after { + content: ''; + position: absolute; + border: 1rpx dashed rgba(255,255,255,0.3); +} +.l-clipper__content::before { + width: 100%; + top: 33.33%; + height: 33.33%; + border-left: none; + border-right: none; +} +.l-clipper__content::after { + width: 33.33%; + left: 33.33%; + height: 100%; + border-top: none; + border-bottom: none; +} +.l-clipper__edge { + position: absolute; + width: 34rpx; + height: 34rpx; + border: 6rpx solid #fff; + pointer-events: auto; +} +.l-clipper__edge::before { + content: ''; + position: absolute; + width: 40rpx; + height: 40rpx; + background-color: transparent; +} +.l-clipper__edge:nth-child(1) { + left: -6rpx; + top: -6rpx; + border-bottom-width: 0 !important; + border-right-width: 0 !important; +} +.l-clipper__edge:nth-child(1):before { + top: -50%; + left: -50%; +} +.l-clipper__edge:nth-child(2) { + right: -6rpx; + top: -6rpx; + border-bottom-width: 0 !important; + border-left-width: 0 !important; +} +.l-clipper__edge:nth-child(2):before { + top: -50%; + left: 50%; +} +.l-clipper__edge:nth-child(3) { + left: -6rpx; + bottom: -6rpx; + border-top-width: 0 !important; + border-right-width: 0 !important; +} +.l-clipper__edge:nth-child(3):before { + bottom: -50%; + left: -50%; +} +.l-clipper__edge:nth-child(4) { + right: -6rpx; + bottom: -6rpx; + border-top-width: 0 !important; + border-left-width: 0 !important; +} +.l-clipper__edge:nth-child(4):before { + bottom: -50%; + left: 50%; +} +.l-clipper-image { + width: 100%; + border-style: none; + position: absolute; + top: 0; + left: 0; + z-index: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transform-origin: center; +} +.l-clipper-canvas { + position: fixed; + z-index: 10; + left: -200vw; + top: -200vw; + pointer-events: none; +} +.l-clipper-tools { + position: fixed; + left: 0; + bottom: 10px; + width: 100%; + z-index: 99; + color: #fff; +} +.l-clipper-tools__btns { + font-weight: bold; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 20rpx 40rpx; + box-sizing: border-box; +} +.l-clipper-tools__btns .cancel { + width: 112rpx; + height: 60rpx; + text-align: center; + line-height: 60rpx; +} +.l-clipper-tools__btns .confirm { + width: 112rpx; + height: 60rpx; + line-height: 60rpx; + background-color: #07c160; + border-radius: 6rpx; + text-align: center; +} +.l-clipper-tools__btns image { + display: block; + width: 60rpx; + height: 60rpx; +} +.l-clipper-tools__btns { + flex-direction: row; +} diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/limeClipper.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/limeClipper.vue new file mode 100644 index 0000000..4fc62b3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/limeClipper.vue @@ -0,0 +1,820 @@ + + + + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/utils.js b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/utils.js new file mode 100644 index 0000000..980c439 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/cropImage/limeClipper/utils.js @@ -0,0 +1,244 @@ +/** + * 判断手指触摸位置 + */ +export function determineDirection(clipX, clipY, clipWidth, clipHeight, currentX, currentY) { + /* + * (右下>>1 右上>>2 左上>>3 左下>>4) + */ + let corner; + /** + * 思路:(利用直角坐标系) + * 1.找出裁剪框中心点 + * 2.如点击坐标在上方点与左方点区域内,则点击为左上角 + * 3.如点击坐标在下方点与右方点区域内,则点击为右下角 + * 4.其他角同理 + */ + const mainPoint = [clipX + clipWidth / 2, clipY + clipHeight / 2]; // 中心点 + const currentPoint = [currentX, currentY]; // 触摸点 + + if (currentPoint[0] <= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 3; // 左上 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 2; // 右上 + } else if (currentPoint[0] <= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 4; // 左下 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 1; // 右下 + } + + return corner; +} + +/** + * 图片边缘检测检测时,计算图片偏移量 + */ +export function calcImageOffset(data, scale) { + let left = data.imageLeft; + let top = data.imageTop; + scale = scale || data.scale; + + let imageWidth = data.imageWidth; + let imageHeight = data.imageHeight; + if ((data.angle / 90) % 2) { + imageWidth = data.imageHeight; + imageHeight = data.imageWidth; + } + const { + clipX, + clipWidth, + clipY, + clipHeight + } = data; + + // 当前图片宽度/高度 + const currentImageSize = (size) => (size * scale) / 2; + const currentImageWidth = currentImageSize(imageWidth); + const currentImageHeight = currentImageSize(imageHeight); + + left = clipX + currentImageWidth >= left ? left : clipX + currentImageWidth; + left = clipX + clipWidth - currentImageWidth <= left ? left : clipX + clipWidth - currentImageWidth; + top = clipY + currentImageHeight >= top ? top : clipY + currentImageHeight; + top = clipY + clipHeight - currentImageHeight <= top ? top : clipY + clipHeight - currentImageHeight; + return { + left, + top, + scale + }; +} + +/** + * 图片边缘检测时,计算图片缩放比例 + */ +export function calcImageScale(data, scale) { + scale = scale || data.scale; + let { + imageWidth, + imageHeight, + clipWidth, + clipHeight, + angle + } = data + if ((angle / 90) % 2) { + imageWidth = imageHeight; + imageHeight = imageWidth; + } + if (imageWidth * scale < clipWidth) { + scale = clipWidth / imageWidth; + } + if (imageHeight * scale < clipHeight) { + scale = Math.max(scale, clipHeight / imageHeight); + } + return scale; +} + +/** + * 计算图片尺寸 + */ +export function calcImageSize(width, height, data) { + let imageWidth = width, + imageHeight = height; + let { + clipWidth, + clipHeight, + sysinfo, + width: originWidth, + height: originHeight + } = data + if (imageWidth && imageHeight) { + if (imageWidth / imageHeight > (clipWidth || originWidth) / (clipWidth || originHeight)) { + imageHeight = clipHeight || originHeight; + imageWidth = (width / height) * imageHeight; + } else { + imageWidth = clipWidth || originWidth; + imageHeight = (height / width) * imageWidth; + } + } else { + let sys = sysinfo || uni.getSystemInfoSync(); + imageWidth = sys.windowWidth; + imageHeight = 0; + } + return { + imageWidth, + imageHeight + }; +} + +/** + * 勾股定理求斜边 + */ +export function calcPythagoreanTheorem(width, height) { + return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); +} + +/** + * 拖动裁剪框时计算 + */ +export function clipTouchMoveOfCalculate(data, event) { + const clientX = event.touches[0].clientX; + const clientY = event.touches[0].clientY; + + let { + clipWidth, + clipHeight, + clipY: oldClipY, + clipX: oldClipX, + clipStart, + isLockRatio, + maxWidth, + minWidth, + maxHeight, + minHeight + } = data; + maxWidth = maxWidth / 2; + minWidth = minWidth / 2; + minHeight = minHeight / 2; + maxHeight = maxHeight / 2; + + let width = clipWidth, + height = clipHeight, + clipY = oldClipY, + clipX = oldClipX, + // 获取裁剪框实际宽度/高度 + // 如果大于最大值则使用最大值 + // 如果小于最小值则使用最小值 + sizecorrect = () => { + width = width <= maxWidth ? (width >= minWidth ? width : minWidth) : maxWidth; + height = height <= maxHeight ? (height >= minHeight ? height : minHeight) : maxHeight; + }, + sizeinspect = () => { + sizecorrect(); + if ((width > maxWidth || width < minWidth || height > maxHeight || height < minHeight) && isLockRatio) { + return false; + } else { + return true; + } + }; + //if (clipStart.corner) { + height = clipStart.height + (clipStart.corner > 1 && clipStart.corner < 4 ? 1 : -1) * (clipStart.y - clientY); + //} + switch (clipStart.corner) { + case 1: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) return; + break; + case 2: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + } + + break; + case 3: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + clipX = clipStart.clipX - (width - clipStart.width); + } + + break; + case 4: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipX = clipStart.clipX - (width - clipStart.width); + } + break; + default: + break; + } + return { + width, + height, + clipX, + clipY + }; +} + +/** + * 单指拖动图片计算偏移 + */ +export function imageTouchMoveOfCalcOffset(data, clientXForLeft, clientYForLeft) { + let left = clientXForLeft - data.touchRelative[0].x, + top = clientYForLeft - data.touchRelative[0].y; + return { + left, + top + }; +} diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue new file mode 100644 index 0000000..1b666de --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue @@ -0,0 +1,117 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd.vue new file mode 100644 index 0000000..0b48260 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/set-pwd/set-pwd.vue @@ -0,0 +1,169 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/userinfo.vue b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/userinfo.vue new file mode 100644 index 0000000..5124c4c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/pages/userinfo/userinfo.vue @@ -0,0 +1,248 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/readme.md b/alpha/admin/uni_modules/uni-id-pages/readme.md new file mode 100644 index 0000000..1650e45 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/readme.md @@ -0,0 +1,15 @@ +# 文档已移至uni-id-pages文档[https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html) + + + +关于插件更新的说明: + +所有uni_modules,在HBuilderX里点右键都可以直接升级。或者在插件市场导入覆盖。 + +覆盖时HBuilderX会弹出代码差异比对,可以决定接受哪些更改、拒绝哪些更改。 + +当拒绝局部修改时,注意可能产生兼容性问题。 + +你需要二次开发uni-id-pages的前端页面, +- 如果改动不大,那么每次更新uni-id-pages时,在HBuilderX的对比界面对比一下就好 +- 如果改动较大,建议复制一套前端页面到自己工程的pages目录下,pages.json里只引用根目录pages下的页面,不引用uni_modules下的页面。然后每次uni-id-pages更新,你对比下比上一版uni-id-pages改了什么,看你是否需要再合并到你自己的pages里。pages.json里不引用uni_modules里的页面的话,打包时不会把这些页面打包进去,不影响发行后的包体积 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/apple.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..556f68666ecdb2a0414fb7f2a5a0d7fa484d6df8 GIT binary patch literal 10282 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 Z5FW-2!fSWBq{tqLd+-?8> literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/alipay.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/alipay.png new file mode 100644 index 0000000000000000000000000000000000000000..5256d7a60afcb882681f6a681ae0e10f977d1a4a GIT binary patch literal 3978 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 EU-sXgSpWb4 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/douyin.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/douyin.png new file mode 100644 index 0000000000000000000000000000000000000000..f218f68d952a8e4753792b0529132b4522f5e8a1 GIT binary patch literal 3163 zcmb_e3s4mI89$#vL?wudNX*VjP|>~H-P^sr-GB~oAUJ@Crx4W9eI0jlce~!LaQJA0 zlu|-{h1gaKwG>eqtByeflv0hRwSd}CS_vXD1d*l;8pa1>4buMschSU0C)1nR+uiT~ zJ$~Qs`@a8w3z8C7O!E%(RwxwH;$rp5;BIqWUK7CoK;HERg~DsL*^nxyCdAX6XjL)1 z$O4cL)wlNl#$b1ZOs&yDWi;7CJi$=2rEI5)^L_%@VQCgJJYGF);j=)Vwp!FiR%~irUy}O%vku&r3x9%}Y zLm&)Gz>FX;Fpl61tV4}Bti_EiW+W*s$>`kP;%p9?v2lXS8=zWc2A(Jm({PA@!5STb z!90nRFpE(bENDs0Xe4zgfot9NtL$blkc{Q^s3;WU5sV{XQosyxjqoIkGKj0r8Xb&t3 zZDd`9;}io^It>Yf^jMY?5RNzUFSjNLLZdO_Mi`@jA&v?ttm6SO6bOs!z$>ezp0OUu zVUz;(tGODPP&(G^;x2nE=QYAsPxjErP|^(N+HAs=oNLMiUO6TaboXw6QZxbf4y}7P_#x28Xyr_dEnNU7 zmsWyS4rQk{M~u(GF98xA{iao;ln=AxA{u#B@D+j%x7YIqU@+ z;K>e-a>YBl?}E>ODN^iv4uxXsOxHC|QCt$BP>h3;;tkQm!^1mw?rdvo>*?v~?(VLr zsHm^62SQ*papJ`BDGG=A{&5-&f7Tiv3fpkpDc*;=Q-NF#L5hyP+z7 zbFh&On$%I>u=T-vPvzgP8n+_jZADVhhm-e)&N!WW!5}ri`OUynA~JsJiU;_noBtTj zKXFB>3~4lG4c)qUA#Jg$`JXKr7n>A=Lw!vh?`nRX0`I+5e5n)tI{n7r-3K%79qE_e zeUtC*{(E7_uDCg^KZb7n>%gUr#@O=dyJ9Z%o=T}YyIRL*toHe!Z+X_)AgO6e+M}A> z;618ooplD`lbhzFX(x-FSkLOXS%azCYPuagTJ_<;-J^4>g-u5`tX)*t0UPF~oW1t( zXK!iXfrgTI5*wusTjEMN1UvR+$J*`FQ*Q5j6miwZl(d%FP}S!*r%jx_uW@Pb-o4dl zwW~@SCSH%KYwx|eL)A;KidN_EpWGE#vZLAfC;O7$+_1GRHYvKUSnq@vm1Kl%-4t?R z{-shW^FQ*BW>2qZ{5-*T0TW=0ZuD+`P+yy!)3Pxx_ff#L-><*8Ja?D>g00ZC;AL+G zeO=1u?C@WB9@ouowoUy@EcAhZt7^vSxju?(w!o%r$73A?(~QS$nlCmnyFK`Sfbq7(I}A~)~;FArsm AbN~PV literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/facebook.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..1331b61ffef8e169b1a11974a5749a89427bdcce GIT binary patch literal 3065 zcmb_e4Nz3q6<%Xf&5!6*o0=bWT`5t++kNltd%N##zyP}-C`%BiA~ZJd=Pvt{-M86Y ze#bPK*hZsi{h@{;VrmH(Ley%bpu{-Vj>KeQ5T_aiM;)|k0%aIPWC%IE57>=K{pqyb znY;Vmz2|)A`_4V*-hDGYZT^Huo_s{7(@jW8c4XjRuQtYy#os-@IelEG8~?bHl^x7> zrrIRcV-#dnM8;x|53lQVG0zwK1Zf2d>P3{Ncw-ISO@|G7MUFKrVV$JYXGd-&xzvv` zOVhHX(iIXf8=jx1k14ic01pZZ`eIMMH()D{H4Nk0@Uu2;GU$g*f-7PT@mfHAwliIC zSN%xO8ZCrGF`VAY8z~Dznk~_KnxuFW$(blKK~gr-Vq>lP(T@Q~^UE$4*f6FAVDqjHU@E%v3D+Oq7w-Bn=zNQrON{;LjfpE=wkqk37g53}9O-Z0mEY zK{eo3?*biO{$2o_TBkD{tpiylK4i*30kyy{p~ON=bC#yY zXS4f}5LEqHs+u3#sPqtJJ&jfCXD?B_vRV|FbDINl2tgEUph=n{D4HPoEQ+;JRvXDY zOL8`n95HpOvf?TUn`&E2P*fI8VhbB-{+=l=8CeJl_cfL!n@jb31T0wb2zkil^X3`! z;WXOpYQE~nfiXMt?ei&id%9nBDfxIIkTE|&pOR>|P`t%L&_-&QuG49As8WHpg(;3u zHOs1`$hPm`8It5UGbIrcDI-Fl8Ij;wi;J*G0-_{=wu%fLLQC-mf`V5<8X8WuQNc)* zBqKy3D`BR1nvi*hB1D-c35t<8QX&P)%!ncX7yJrtNFo3Jtayr+Nm^nFE5cZ;RYSE} zF-cAm1l}dMc!ANH;5!{5%y`T%fcHNz+GGhr-sn@lGEXBdW74E-6)Az#_Swu4j3n@c z$jKH0Su8v&Q!K;ELX1i4DC{)SthafaNr4f~G$I(8wGxb#Jd0fph@u_ z-m+QXSsdFXB7tBSULbhRY$dQfQIrrV$u9Zs-YmTcj}?jfZ}Z|K07R-)8N0MKAKj^ zEqL<~zPU_>|3S=u)S)9R!}|~t^TVU<|0ia+G)F4T^uyvCUc2pb!y7p~g>OvlF??0y zm+)neyf{yOe3jo=$n3>`10MDzFAeB)k51Oc7~PhwQ+2vA5$UN}i2!iD4=PVWObs~d zz*Y@&EAbp8)xm;#NZ0`vdcd+BqN{+}4)bcDcL3VD!LbAS2Vr0klIx)GFwCxmjNQ;T z2swLT@gCr+A!|2~?|`=n=yxEd8m{(1`4?cU0=WS$^}yf|9J&O(gK)kZ8qPynJ*+$m z%l5$#KvV_9?SQx%$ZvwQoe)_8sr9h#I7}}G{~RG)&OA*k+Y$;as$6U<1<99s3&;%1%h0Wrl9pXGk2YfJ76ZRC{Kno=J1d=+)% z#We@tUv54(A%5I@YjUm2kHpQ&Z0PxOF2IbX%40`2uD>F^?M`T(xOrvgR@1jD-<0<) zuHXN`&vTY)`oCB@e?9p0j3}$J?8M-?kK$S$ zD(dqX|G99**iSx~@Z81yX|1=mMSXg#YTASuEeo1GKl`TpOUL!bj-k@ut$W2Xax*HZr2&(&gvA>26H3pLp>){nJHL_L-V9{&BInvJX|HUDy&;-}1)B zvrqIaYiQfBdO_7-8TnY*`NWwub!(68YrY!&(l4gZE!bAOu)Vx>UR>9b_>ad;|F*Qb z_T-ed^y*U=8~f}2(3yFKz&daCk%wXef|?DDS3hKRApvR9C7jcNaO zUvf1|X{*}S?W!)!+*Z-vw(>yx%`=VbC;h0Qw5!Sf)-#8l zM|I~~8kb3tN2)yPZsX&XU%ywG$QR$Z*7|149@~Y`GD>gi_`qt#~rCrZo16{d(`{vbO Tf3E$d*QF$;Id&zy^!mR5pSY!V literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/google.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/google.png new file mode 100644 index 0000000000000000000000000000000000000000..9155046e524adfada43323cdf81d8817b881edce GIT binary patch literal 4333 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 U;eq}@^S=~+Ucubc9x<8!1nf~DE&u=k literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/qq.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/qq.png new file mode 100644 index 0000000000000000000000000000000000000000..f170691dc4d52d65bc604720d56a5a498170f1a4 GIT binary patch literal 3449 zcmb_f3se(V8jf0Bq>7dzQruz;^@U6_Gnq+df>;p{sA6f%B5m2)c?AOGVG^DmA5^JQ zMP-$yky0O&x`?ivgBF##F2*!PL`o5U) z6K1G&;5m=C{P_$W#Uyh^KFuYlG{J(Ns>=etiVYTQz@y=4T_~5Rip$BD=n5<-m zWChQ!;4jaR0RS~;r1%-?6pcZa5iA(Nm4R#LvPi%mF)=0w3qqU$`Ek)P{7|i)5K0ri+DIeS!!fNq~WhP!s|dkRelJq%t6l!G9bfj59ELmCmTrYWPk>iq@tYg9U); zs06jn1*EQEN!l z{tC3~@y`N))J8|UV*DZ(wb~WJU<^+KGR6|}i`E83rj8TIIfFJ;&v4;sfTq7wjZPM- z=P09Auh42!#tRiQPMMDa)%+zJR2o*BZdf|OfeWLIT(AIzQ3OIz2qqN>E<>a;7+VGt zG8i5;jn=X%Wv0v2Sy~7|6bLE9Ntqb=nJH))mNHVmY0NS*rB<(|fMAuHO5j8~O@e^$ zN~0`Po1)c&z<`~2;(AnQXpCN~RHc9i26@CPepGm<1R*672o)kDbfcqXVOl2DS;DBW z@or|djEa^01dp&%mV}iAM9?q|ku=6Z6iSm22GazGqa4FZv2nC0jloE17|w|XQY};g zBpQQRnq_c^V+bXLV;BjMh(rvbm;|F(6vH{h<^Q5y1qPBz`E6Dtg0e6QP^BCSL%0+} zAX+MAAckNlid0fclER!r@RN>l%n-oO0P1fT8?seY!q`=cYK4zqiKeN8CJ>ux;KvFVzClaLMRCwF@!@Pf(3~o zL0F6cx3q+u;60*YGzFr^=W1j^Wsxdp?lQ+Tuje+o)bmG%QbsY(%_dmDIH!zb1!K#q zU+4^6%(7B3%|QgG1Y^Qt63||#5|WUhu{cDD(Nb>QKRuBHppTip(dY)P(wI)^xsU|V z)4w_0qF*C#pwb>s9RWSYk)R=@1cpH@@o4Q^*(>ydhEI3&6+`*c`p<&sPdH~VZ(_c{A z-rhS9Th=)K1Zn`_f9wPjb^GcL82HFafOYID!AtUA`t)QS%FupU%qW}cJ->_hLXlkk6eqq ztf{H1Pf^xX*4%ZZzGIige!0z&XS-M3=HTbsEcYC@yZim}Yi8$KChw@;VX^Bjw3=$$ z8#?=zAE|c?3{Bfn-Pt!dEvMQe*BUW<_hwM6Nk;j)^+P-E$J%(jDQr|&h$3-n_u-*6 zEh~L&Go#PXmj5OB*i1Ea?VG7xYf@=*@fSw|?}t6J&cVT6`PmlI;x@14&bGfRnrqJ? zrk;@4N0xTe3R8!D;H$y9Ki~LxUtZoLI3jCr-XUc`{F_^si3`j}rzD-+zIp+7ZSB>C z<*UupeRB>i6+dPAhcCA%(M$fp^|1KK$%o8H@uF=VqTVyiiR`DpRlc2M^$sSM1kO!f z$b;hqd4=B;Zz3z>Z}Hs-vqcXAhjXV2ZCg8#Aqcsn2J()+aqtp_(BSWd{Y$^1VI3 zVAh4LOBd{WRT?m*@%eUqpC{4@JIpK<@l>=k+F%}sL) zix#-gOOx2G9``(;TPwWd$_wF#70(uzKmAC>nus?xS+Bktv3rA8=<&e4^P1mzC+=uo z#7t|$@LNH4$$M1hkEi0+9|~`3@4K41GBRQAmbJy_tzVZvxAji^-Y4ArXK&c(oe{OW z?c|e71E=5h-g(zeB`n`}g?F`x_$b}+xp|H}&ePI*`vO6KIb+EzOWlLTDJy1_o_lBV zOFVn5-1?L}=b_)uW=r1z z{{9=6@VYY{^CxXWhl}n+eNHV)aQj#3GVaK_Nvlv+Hbz3sliO{5wBHB)5>o6CYJ1!HO99l&bhKd zYwK>YnYNTzKd#rk+fw!Yq(+^1Gqm_bZ|0BIyJvJnaIWS3n>A;nPv)F>K|bX|ulwQ- zQ~4|ArDr3ArPmMju8BK+-Rlc~lR|lIVBx7)rF(b&ngDV851z5h#5s>XSy*7!Z=GHi iq5e8?TgdPqlKkKA`|8urK5_nIiV9yB_P159zwvLfty_Tr literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/sinaweibo.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/sinaweibo.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd03812cf81febc94a44c5591ae5b27229dfe9 GIT binary patch literal 4081 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 Tshq94|0>)zZ*#fi6maw(JX>;f literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/univerify.png b/alpha/admin/uni_modules/uni-id-pages/static/app-plus/uni-fab-login/univerify.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0b9f5b56d36120c07016585195093aedf3ba59 GIT binary patch literal 3365 zcmb_f2~-nj9*k`kiK;fc2CxoqYgEcM5ocbaYE0Ona+)zynIzabC9c*% z41(#E1gS=J7_8O3szhOg)WCWTqJ?0@0P74mq3pO+z?+@r4U>|`b@&2ri7J!RX)|av z1qB7_0FsZEe&y5wy0?D=iZSw_RI>@vj_!&>D?hJ|2q2V(D_>aHhBbjgEjkRN9d}-^OVsaSmago#9ek0Orsz8=E1? z&QVUmo-GLZor%iqgsemXYvmuNnysu*;CQ8*0+&oVxkMETqX>kc5KLwxxB(#yFg6m_ z8(_Fy)F`lKetwr|IJFRhWFw>j2SVhpL_x{0l#_a*Fv}Qt!ET`dVY7wGHu1eVz zMnjU2FW7-&fKJp8Jr~d19GiXRE|H-IG1Z82A!6AY}VF)KM z1fmIoffzkQQ6x|CB!z{W;1?d9Hpc*b4v>FGN0W`EaywS}=22nLEC8*ADU8;l9E7nr zpi1C+h$L7&L^B}&lpdi_m`>1yI|?YZH*0roR!fmMj6yukQ4ofa6h!K^1Ox!mG{eCR z%d?Nx#&KM$>Q7)?!m+B3ZSzBNi)&ey(9#^F=Xg-)ET)4<8s#A!spoJG;W0X# z+jg@BCJq>VO#iftIRxHWK-sx5xu7ba*q@q5fp<`@$3sUzm2f1hg9tsSNEF6kh{g#V zVi=NS^f*T|{C`95-p`=>b)EhEd!ToOg)vdqTn@}0jq3N4`QLi%H+kqzru)a~|3{{+ zG}|jo^V{NUJL@){KqA|=z|0FTyM`@z=^EFZ6~xI7hH>(a>7Ri?9%)OR?ocTDMu+bn zijTI&C=@;NGSjnDLZOf(hu*3MkC3xkJh3-VRo^2G{$feNBNSb<&DDiS_u)ngVvO z=x&v>-Tno&(&5{|P$+1v7Ed$>ci#$>H3e(^a)Tt#1b}66S)G*Q_AjoLifScM4mAhl zYQJ3C7$~Zd=6L+?`=pANV6jiS+!DMc$#s6YQIc!?@-(;KFNb`R>=Whvw*&i|0>_$z zrMCc{K(Q}yFA(y!%FTh$TAx%@Bc5*wUTl#!Hw3Ev!OYA4;s)t(b8usWwB8rUsq$B~ z$`$v5+ZqC=?gf|COT1U~w92%{UsNl;RSNB>R7`lb1Q z!gE|RBITXuYMqTkMj|5#&t9M&w2jlwewX;iBJbNc~ z$Ea3@oN{4!^`)FxxJ#u4mu-|hJW|j?o@!HVy152c_f&1@OUY_N< zapdP6DUn9aklM(tS;kOYi?Moq#lRo<*f>kwA&-swc-xrKrL&q&)SfxBdhE64575M` ztDO&qTbk`Jo*EqAIHaO};sh0Wuk78L(p5*#*zJMyQ|IiC!79X)z1^v&E;3)W#A=Fj z&zp*0;SS>u8bxnto%;Rw)9EGV1tTWJxhs#KIJO}6j&**`>x#kYvK9QPn+f#`Sbb=~jRn!M=H)P~RcG!6X1=-{%5 zqMy&yCM?IJRcE(d^;Han4#zDWIrJ>9_3o>2&O8_TG2+0h9~gt1U-@D4f#VS7A+9~w5O z5^Li5^Oam<3}IMZSwIh;z^NO0zD=AnmgT!*;*mAcyT)z!Zt|+=U4u7duIZ^xKbXBi z`{DMMo{>wP<8Q3pJ?~|2SdmW-ZiPhW~SzX}K=?PJd;_mPj~q&<^*z zhF;6Pe9!bnOHJBOGkV-yDGxYg{&1xnDGR~!E62Z!kXDEP-K3>tB<~$NXVHHEmZfmT literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/photo.svg b/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/photo.svg new file mode 100644 index 0000000..7b4b590 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/photo.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/rotate.svg b/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/rotate.svg new file mode 100644 index 0000000..0143706 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/static/limeClipper/rotate.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/alpha/admin/uni_modules/uni-id-pages/static/login/apple.png b/alpha/admin/uni_modules/uni-id-pages/static/login/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..04a3579cbd143037161da2779fb695f731818d81 GIT binary patch literal 18205 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 F^iP+OC9nVh literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/user.png b/alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/user.png new file mode 100644 index 0000000000000000000000000000000000000000..268420b7343d9b2c7c58233e024927363928dc5f GIT binary patch literal 2997 zcmbVO2~ZSg79Q7Q5j7HTFL4?sjZKC!yFv1+pG=~_>DjuLo zfDl(ij7fx8u6Tt-Nzi4Hu!xAt5{5EB6j>Gtmy{wZ(YHMuqe*$BwyXMj|M!3Id++_P z|4t1FUOvg$)mb1AObQI}3+3-d`{^{AzxM91Rr0s-=70#RKrmsd{TwC8&Y2|;jH}jb z!?|!xkeW6bL?mOPSW$w(%%cSY&m{?Fl8$CMgkmH0MlWGcafuMoGhV`X38Og9tQL#omj$(bx#lPPATP$46d5eXkPvhW?fkuk+v7dgfODMr4IEqV9 zjL_n8HLg@+vOi%eHHHmAH6}){+vI@SON-*T7AMql9j%9L^yN+=l>O3{4%Nfk~?Fv?SG?-NPb+&NKlJuT#}324IQA&k$WvSR9cU7wB?W>}9w9+mf8dWYcc@wn z<$r|IH=rdGs(kFms-=ThPbd>Y`2whvLA4*0AyDcHAYcl+A;V0;r>)ArW8zYJ%W#AKa~hrmb)_0P5C4ZxuXj zgXT0C=z{j+aNPnWQ=qpJ>NmjEx1pyLn%;*>3A7!ChB#U zU1y=I82TEZ{Uo#>h1UI0uYY^g_u*n>Z?k z{|Rv7LW9G4?a2aYoumIIM<5t24fONYMvd*tj$hfb)TO*-N=vqC@3c^4N8-J;X=_jP z|JczFV`hH0ziIm^X>!K=+`c6Pmp%VmaV~#_J2m>WQ`*+7>FuxY`Luq#c3 zy*B@=T-nL{os(}kA8s#d4sttKu)5(&?)$N0%5Hix?-r&jF5kT7N{fqhr*d!2n<@EF z=X$?pa#kskQuH9Vy5`C*&qtN9qvuaLd*FEgwVa$F?Bs2y)Z^)Y2MX>Ge4<`<-ox2=Km@qdoqV;Ioq17IzT@JN* zd~r`>KKL(dajWy+K1gfdS@fCccCE+OIr*PfO}}uy!;<(Dx7WsPiOD--%J4SnH!ff6&$@*jp4v-KynP|LBB|0x|-1ceXu&G~~YZsmGKV~%$NYig$?XqEcA?1`DPvM!3srsetOS7NCzHfQWw^oTZ=%-C~( c-EA0EajwApWc_(h`;T>?f3V*PpY_}R2U3RH`~Uy| literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/weixin.png b/alpha/admin/uni_modules/uni-id-pages/static/login/uni-fab-login/weixin.png new file mode 100644 index 0000000000000000000000000000000000000000..af7175b6fed8670ce6e6d1a7a64a4812a4db8cfe GIT binary patch literal 3934 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 CN=BRj literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/login/weixin.png b/alpha/admin/uni_modules/uni-id-pages/static/login/weixin.png new file mode 100644 index 0000000000000000000000000000000000000000..df70aac5092588d7ccb87d75f024d0c9dc804607 GIT binary patch literal 11483 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-center/defaultAvatarUrl.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-center/defaultAvatarUrl.png new file mode 100644 index 0000000000000000000000000000000000000000..c3d33188b94e4843e0311836ffb0fd843195ae4e GIT binary patch literal 5947 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-center/grey.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-center/grey.png new file mode 100644 index 0000000000000000000000000000000000000000..2aae15a5d0b9eea8451df6395d53775bcc676f78 GIT binary patch literal 6669 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 X90PicW&Nka#%63_p2KrU;E<}T zDe2+h;PK<&+yLFg#kQ12y3J!>q#YC$AqK)i8ln=uI5@yjxV80NH4v~L3bnTGAK~S` z?e3%Z{CTXNb?{)vUs7HVN~0qAOvq6} z#liALqCK|;DE#n^QYQtiLdosdegjV>Z>tchM3Ru??nD+}1>iBp$HEwIqSLrZNG6dX zBxd31Mj*UyTT4R1*AX|thi^$pLY+xS`YvwYjk&u-W_{7C_sZ58AL@a$v$oDYy1xGI zMo8$bO&Hleb$xyP{_^^|eTbGe9SIg>JR!u9dTKet)7vWZs z3{_wsWE}L3J&m=sB;iOGey9x+hT!*gal=C6;7H5*x5gC#CKd0d0 z_BUErkH5r(6_|i8)J*`)FZg>(e*oIR|Auq(a(DiNxD8wY;f!!WxO#eEVZndHy4fQ= zkskKQe}nq(?*BjlD_U*sziIrZytughO~S)d*&92JzXbB1LVM`@xgiAf5FSV`cQ``X z8_Oo!KW5|MsfYNdJpTv7vEY9X_H?lQH)DVI{D(;)d>#G`=HH7df&4>?EQ*T1ZAF3ws11cXxc(L`_wR}PH432w^+Y^m6%rHz^9hRbfd%!!qQ9*P zEXpe=E-5JZC#W{k#=+L_Z%`pVK@mPd@NZDCkR(|AKY(IQ*#_zf{cnM7;F7jTcNZvD z5e_a;JA{Cns~s!L-|CfAL^>ngv4pYQ3IA)mI@asCBW)d=u^oSTzdxAN)|OOv_3(tc z!V&694_UD@bg6Xt^>Y(>FB2oWJ6 zAuOKX79oj6gJlW&dksEh1^?A({M#~}z5Z$x5fQ}x1i-)l{{>+3-vRuy-@w%Ys{rVM_~2&U#z=7!90+*o<2}_ zguETr2>xe_Tj1Z#zys?2U-K^}VIv^~7KZb|#Dv87M8I$apM;Iz13s9L2pk5LkU+pC zu=e#|@GmS07Ws!W_}}LLF9L9TsH+_U8&w5Z|Lu(6NLO!!`@d+#4eAcX22+H)$3s?I zcccpo)XmM=0shD85%6}k`71{KZ5S+`NS1$kpMOio2I21TFS7erDu1)U@_&)uf2%1` zVPU9{pafPwf>_rk@<2k2PeNP_&L;{M7qvx*2@44e{lBHD|8_?IGe7;m*xtVjME{p< z?+@?tr)v=SU%kd(k>gJTQTc6hf20SJ|CxXIpRO-#z95N>Jb%Zc|9?^APx{FJ)9CYi zG5j&{e@O!W(S*$`e?R`6(qdo!PKpt(*fr~pO?jzO_WE#eJZ03C@g1 zvArx{X?1#t48A&2=ep@^G^(9dz%rm~!YcI&)M|VwQ+6%9 z@cMFLzv_G`6*Jg$R`ycUzD2q+NN5jn;a|@?<+QzVeZ4_WjtpqpvAmj?xZbzgIPK1u z%8_+EA2pfN9t}R3lJvWhxZd6veG&SdroL}&S^1Ptp#5N3v43<*#`{uY_@(6>X61Fi zdD_>Q0oAh!=E)d|y^IyitZMiLhlc;$+SD#FMubd?8dK>leg(VN&PaAHk7fpF=1p6C zMzr+{yuh#p#R#e9O;e@qE~LMJ8MP-G0yg}g;9x4}_n08D^3;2wW53)E@335>PFHFn z&T`~f1ZI%oyfPMNuQ$`WT1RxiNqLJvpvrPe7>wgfa(l>4RAAul6fbsOeyiOZWGIP_ z&v7vFYn7#LSsaXBSNbz^vV$Jo@`71|cE2Fav%c;2YZ;bEOjR%q0Dd*`1R#tNB*pYc zv;^+5Ic)L+{HxXr_T>b)%?x1vD&QNR@bTv?FD?{Y6woh^e`;z-Sy7dR0!mP+ZE-yB zM{pjU-D3QxZ8Vr9xDEm?3y*?6!`Ih*==zUM_yUF?@{u{3wdJHdvJ}7}l zdWMA)tZ`@C-ml*s{}|T^@>BKqbJK&A8<5Amp}m&-1lg1y+g1Tvib?fwcoU<(YQnz) z*KX=w_%p%2we$0c`Vf`ABK~ON0g$VxYpvQmtpKh;Qp)u&vD}Bv{{qD`Ybt`b#zp3n zMxYxOzK3SOJmWG6En^pQ_Jh5}!wbm*8I7O^R96y-`2{b`x!1cYywUr*BvTVxhYA+g zZ$tp&#)H>7Cz$fngC|?{s&x?BP9aJRHNjw6P6H%cshRrLfX0h(X#2sf*6eF0UFQ~e zEiQj%iQSKD!3=wrldDux;k_DA>e<_D`#8%!;|vDq(z_~2<`dhizNc6fYIIH0V^$2p zi@89q>)(w8y7j6@PKu9}Gm$>dE*t*eQC|icG=wI(^vphcmWU7B5`3^twJ|PwViyyp z>PuObuHrBboE(ATqQHp0o2a}W-?%TkAD5=HWb6@dyoZn=_1?thPFJ5%HLmZMaTu4x zF6#b_87xBcpc30}GGlyi#+ZB1qoCDcd;Ij{nZQrfwjoc4wQt?|R!ZB%j0TD&doOuR z8{#eKeM!YJtlt{Vr5*jIQ-x@-8k2t5${m*o?CqGz0NN@ruy44Q$er#jxjsD&a}}n; zu&f%k21wD_hM+uT(}{-O4OZ%xVUF4C-H{=%C-hE(%NkU`)#n_KrJg@02B1bR&Iq#8 zjH)MDQkB6=Iol$-XZ;bL($j{r=VYQ9YDWP#F!;UnLnK+c80$J#LS4`VlS!$L(1XKN zQZ=$#Imt4G-rV(nY&FgrTOF-O99(eH-zRGV^d_sWYAlZO zU(Bl*Qw7V+h=#&`++xsNZ5xb=RtHGg0LG}BChcOk@|RaRZe%Tss$NlQ3{=`X`KK6w zg`Lv`TI%?H$D)VY?S&`{z=_OQSFp>f2B$}zW*BxbXLQ5atWzO7NFSg=Dc|DMwhXFk7Z+YWlOsl>Odd+mI;;K{;CkikKHWEZl zMlYIGh9=gI26Ul;-Z9d>@bRIc)( z&z*gth-%W5HM^^bq2&BHeJkumd{R#hnPB)`{$}0bfr@wQ<>sIv*L8&ta)k9^N&0)N zmf%+aZMl5o!3Jc$v5m&@Po|W&d}NfEYLI>9v4VRs!jMYQE@gwS2#pk_kk)|NAh0!8ai3Y9{dkr#LE zHz_bS>9qHTaNy1q$se{`r$bwUjy``~t*h`Nx|GHO9nak9 zGds+8!&XpkIj_B`>s1_(bGp5sI0&LuROZ?$r9>MxE-$e&8|OjGliXg#2$%NS{Rw%S zN4u^(@R`1Xv*(_s^{lbSo-Tt{4N!MVPQ(d9#Y-S@6k&L?zJJkYXwz?c)vzB*jSPp` z^c9M2*G%w=4H$f37_sv&m7~*b*Q@;T?%fU&AZ7QC{T(Mok;&e=j=$d%QL)Lyo=TG1 zV*EQNhL@#->pqVg#-;^PiL+Dxmu<&rcg$+|ngFf{(j ztD6Ge!{Q3XDkXtA#V_y#-uD;7a3#TScFnN5rHc;8c_(SuWrfC(2NHyX z8aOj#zV-DvB2-W%ZyHURAcJK2{3T0)L$4^;5{af&@WS#!{<3Oj7G3blw|HyFy^nQk zeasbOM>)Ei89@=P^PPe-*jY2Rr z-#Wl%bgz`a2kFPh?YUM!+xTA&F3Fn^%*nvQyANH@=PYu2@`zE9-YAp) zu4(MqcY1}un{?@Yic~G5@H75e)R$!=H_@=Y(+BUE67_|G5)~4w-1G7RYcl1E^3th& zJ*)1ixQZ0CakNfFn`OSr3-?XOXib_wh|9BIsVZu>bpXY~KFq00v>Awxh+Hvwqll9JH2hEm3k>m+TlJ0;io)QXK}_}!{ugE;NDq3 zH&ZsDfG?fx%|nZ%l%~_Ii_`BpcpAp$(rj6QEHl_xkj`Q|7Ya+SS4^|@C3Q=;ZSf-` zTYOVTS5kfpBPmir2Eb#gc@ZfXQ;|Tegyv!64>F7qjEN%m^Fth(WRBG_3i43sl~Uml z0f2q_;QQsB$6tM33VkE2dB(%}X8OH+l@mZX8RQFynKQ-u&Y*ow)wL@lTGsd1nIX>S z)H%HxcQZMG@!I(Zn#mWS+#A~g=2YWXx*KL|rJE;v@5#N$W(I1R!Tz(Lu z2nK}@1v7eWuKmY7zqNftZBb9gz~0syxDp8F3Amq2D^wmWByy-!#`bUCJYBq-qa^VH zMxF!rhTL{ISNqJ^S5R|^Fzwlpt5ix@4~WU~exYB*MOkY$4rEj=W%Dm*Tks+*)dI}A zvd;3w+KJM|W;XCm2Qi2(r^=&WGC{fI%m(tdbJMA7f@x3^rLK`h-YGr7 zS;fUPkfwhxhRvv}lC-JDp2{neX7Ack0K#Z^Y;iLlIm_HfIAv1+7$_UV-y8JbnyLfe zdCz^d!=W@(bex;sV6HL8>Hp#NPe)xdtrA#FBXc~gCPLP?VbTB5+Wk!@vIxIW(1>`b zew7k14Hnsba=&y&ka!Pvh2cpkWOZDMF!}5qq4BB0e~x|gN5FKaEfY}e&JV|5iz_ms zA0uTWVebUSSYu(`?oI=1^gc4Zl=* zK@~VRfHEyVx&4u?RzJ`%RIFC5`3j9>Mnnka^y6O$|jDaOsT7b z?v;~I@DfT5@>JbKR6y;QwC)q?q!`KDFPRK9dwC7V2FT>m{Rzlv zC^a6iVWN35Fgu3#G0^)^*gV{%ys(D%vb+>U5M42$n1+#Zvq)|%hFzts{L1rVA{Zp| z+<(wXk7ANyY(v2mlrRsJz(s)tU%}EZu=PfAl*@Dc3``G z*@feEpoxWpW4<(9m&l={yS?fsGv`uQTJ_1f3(2dqjVdsmR;9nI?xu!I+n1$g3z#;L zTD?f_k&RV#PGR%&Z}S(QWg16r#n1q)u1Iojd4*I=+__D(SbFA^d`v7M97K)je-pqQ zo_EjolOs!5cAo5T3>nHnYOMiMd#SZI0O8BawSNpA2R7?!)sAF`!q)IYwTP^5r^xtz z)ywrH)PR+;wtZE;NTVEU7ag^XK`d&GyO$<&_52ueuM+ORsbbo5zjT@!Bbmm(ARqlf zkhp+|S5!2_GJA&&NWEa=w~;PP`v$Kdq0Ce)5W@g*e%%dWW*U!z`9zp_`aC{L9S8$@ z`^RF2$OaEh9^dKEpr}fI7LkA)Rz*AZhTkCtW&HMpy2XH{SbW>g~{`jDIA zqqUF~>=oy6^58+JzM=AC8HpdU!?h5SycyzIT#h1l-nG6E)n6z&vScs#^xCC(WvV2Q zfIdbGf18%*mw!7xX!f2u!IPoSy{1u2r@%DQ+8-)l(l2#;KWuJ)xmB7@ZnGgsEKjwO zP$QYyyKGWrQEEK7=oQLi+eP<_mT2A)kfjO+Yzc772Kh|5Z_NmBZ01D5iY5&%?`U7{ zncPm|)ACJJmAg{CoCB$InhTN}>#;g|t@bTsaWwcD3=3#vLaCXkIx-qGnz(SNR3Ri7 zNyivGsaMZn;?_I55GvyQblK|sFB+%S>LmVM!|vn~-)>@n{bj44m+ofeRgQ%@YfY}J zfN3YjHWd)mZVTdWOL$Quj-l*?l@DZVj53++T_4GFs5^Ck&+4dq)S+vMZd?@njAt>- zYHO9QoXj)%MAgAXzyJU@+}8y*#N}HT{uACzYFG@ z44GoxIONWRE$d)HrLGW=dK4$dGimohjRZ*V9KW__hAS4MkCq{DlB4qf;TW4s%fq3$ z^%fik3uLV=!E4l!Yj&c3_YBsma};3HY(cL1B;Czk2782ZWw&yVj0w50($#L&|UK?OTHN8522+*%un-jyrOFctjuw|y`5ecmp9 zh|HVmqYVDA6l(#eW*lby+|B2_vxCTl!Fa(jOuyN?i9LiR-FEPWKET5OYn7xP)0!1d ziITe;vhAfXnPG{A;N-iJ8X3&qR~qInAM(>%SC$>lWBIgrLy0u{{qirGM^ zer~M2MajC&PmQHhON(9`J$S<+?dC@%jyF_4P1)(bYPr${hIJ2+4#|VZAI2(G(mu@u zK5kr(38~%=g$;8W;g+l)3`9J=f6<*&W{ZnD6*7+6|Fp~5ExbKC#d=EV5^%NxQ)}Xc zVYaNqCwL91Iu>X4v!pSBnm+z*TSp-oIQk|(7T$iN5#mctk^F7IEm^PJS6It#1s(}ikrYnd9fnY35SfpXPSmS8G z0|Ej@A8MbI-L~#@QJF@up3!CS7G*QyuX?cz=O4l(hV#Rv))Wr8(D;-$mPKr-ffSj= zeBF1R>haj%QgZ5gBi|vTU_r8QH_xJLU95+8(p_RQK*yUTUl8m{bsqFMPgM@<;hkkz z&%U?`Kh`t4pv3MQ@&xYQ7dBb{(KW~R1DVsKj<)2kFW-*I_c;1wvAwPcR*Qe>xL7(z zPp6OhC6D%l#;Ut;^v%7Fggx26irp3x2T0c+Yd!6!_B^aP>;d$yur6klrn^<&lLJGu ziSCoIF{Nmi(*Afp1!52lbVhaey79bw2vz~i8RfoG1>f%srpJ`J&?mm_l^i)l5Uoyd zwK|v09hnvZUiRC+S)aZ=^5D|^Y-S!$hjacENKN;^gekzYWqgC5-v88&@`DYBmWN7_ z{jf>%Y^{K<$Q7esj}OjyPpXfjopJ&ovldZ{&|=Hs9+4-LuS5EyHTg`@l$5z-9*&|75n! zp-%PDMAD5Sx+Fyrmun8quZ7`Qo~D}5G$iF`7+%#|(_=nLCnXIG3ix4$H4xqvY?)>^ z*naBFTdcr)s#78w3Pvg;!ppIvPigkZ z&=ksD)Kg#MiQu_Lhu&lJKIXY6it>(Sn@*4Y$pKFJXiQkx@gCa>mGE_(wlK#CjTu{y z#`9Bt`gE4qym`ZtOGQ0<(MT9Ypp!LiVg@c=m7c`TyUKjy0Yrr7z+D%e028XP6&@K> z@2hiMhpKcCWqK0rXF!M4dl+8K8^>89I|0oBTA8TM_}ksuO;lIWZ<}XcCGa)?Ifi5L zqHKP|yG^4@X(gRfcIeB)&jBL@gInoe>wgBZc;Oya&#W80NLYv~oi@{iLHt{XZv?`R z_b7nWR=h@1GwD2&C|JcvlDxXsJEBlVv7%QGgS&<_5+Y%0fKJgD7Wfrwx|@y_gceqT zQ4ZnGcy^_*MU+oLl@)cbNJp1*lCt+B=RMr7F)-QEX@-x}EpLo@CR3-z^u8GLH0Ed8 zgh-Vpv=2Xz=&WoxV5#`|a6;+l$65A#i5u2G(0(HfU3&1&S9*Av?|0&LsMWLGu5QVo zve!sFAS8OKD}2DouaHvT0%6Pd#vj>jj z8hO)kA}T>wvC1TtQK+0pom1v=(?f#9oV9MANe4)7Si=wt&#I?_np~51Q6fsp1 zCM*;uTwM13?u$P1=m9}u_WWczdE&@+b{J?QVFbVNDz07)`b1_klmpo&2j@nYhRwes z!>K4u*G|%^?|Czi+YqE_Q0}Ee(RDLdGzYt9fAZKUb=3EV68|u4*O@L%a7!F~$Myz4 z;Ev-0$J0z+Bcdxa2uKs|9+Fh9yr*IOlbM6zD3CH8@BC_IJAUA4yBODa7cvO9T_YnK z`M$D2>d8e_4P)ffIPA9J>vz=6GzobzZiCoI4Pm;NmSzGCiVL-OgNuF`8$kE&YCjLE zPyv`J^LBkV%1GL)pY-OyC%_5o;r^H->WSzER!Yw#Q8`Om+4rIOuEku>mIEoJE zr!*`?scHk)d@kVQ-brRPCx3U!;lMF!Dnk3#Ch|IiVA{!bsGX1$KJ=_kd%e0fYg1y!7{0tYm)JOdtJ5m*gn+=?x6^F&EFic~<27Tb=1+J(|xa z8AapQTa=w;$e zhH+8ST(X9zq3w}ushnSgYLN@`5g_J-Gu%Emv8Xd&#`UhUKir(8g#dE_?;t@PI@os2 zUg~=4e5f|3mX{pM_sr6tQbBcJw1S5-ccm%;lE28K1pN*rZznT*yjYcsCp%oCyq%)s z#E&h%^@hOR4%n|d5MRD(Yw)U5lys)_dqH}Cj_A{$2*xN^rVF0foB3`fw`l>wME2W6 zbElPfr{@E%imWApC2njblBecCH*qcM2{$Lcq+u$50kW7}<4GT?@(i+q+15Coweki6 z)O#%g`23KQwN;LMHN%|VQ`**84NtKYQPSLtGwQyf1)H`Kv6nlNGX=}33h1%#CqwT3 zGOnopDgNS8SldG4reta6WPO|3*4A^vN6&_0vz5^P66O9rZeLoLbpZ)ag(Lbyv3WtJ zz9FBgq)+A@+mN7Iqa9(yogOpgroFNhEf>C2(6@a3@ZQpZ>NLN)nfE0#C7DG|grY_U z=$1@it#Ct?lBoH~nN)$0QrKZ2AnTDwTrTa?r#od`(;YqPdFy9{Ku*wPY3?ffYod_y zgJHvzLH61O4kPjP#lU(g_xta;CxA+d4}|#AIY-X z0g}5r9z_aj-yO=QwIxo`HWU-`*u@@x^pxl&7H<>AI7?^~U50d|-;F}}WVUpHLV-sY zuyAywaurV;#^_s|P5@Hr$Vq^7~{uY);nU4 z;0awI4Pju$cT1{vIjMswOYok?L6k{KvFCej#u%$m!AYZX&`j6Ig@-K0gB_=NviFTh z9IB>S?{XHSb`8`-((9JljULKY9L`d5YC0liwF9<_dC2NY2t6XTa@vkq^|wPTC938WtSrcK~__zAW)> zyX07<3e#OXZuFCpElFMK@Vjkh2f2Nnutc$G>}_5Y8pGD*cB_@O)ObQfr4;t!DCJtp z!}4K|i2pe(aUVB*K+FCERauwG9n1+6*E#L0(TZnZOQ?TtkkDgvVtq$+LOw2czPkS` zCR3LPWgyQ-+qtlms{|Zi)gfeZI)_p{L@EogS+bGua$-;41k6T9x^CTn{b(r#1a_K5 ziuS`Z47VXPv8~`@c)JuKbA|WrJx39}5s&xH)eiLXM6p|!SO!6^Z*dHv^2o3@- z;5KOoZxw;BjrXq>fDKpD ztf*=pl*LH;6vUafB2-r8ds{j(PK5G^z+Ul%5t46T>dyFxF?XX0dkCl!6-Wsfnx9%Z zPE$aaDg+CoM5Bv$%Q@dVa?cqBJn&bwk6?~r&Y|^qN$5cwmx1=435Jiqz+C7^>TnC) z$~Me(KC5tOf=w7%`!9t>Xab1pUPZ!ox9agQk}6c4KMHjGhUW1wXXO!Bf^@#Z@j(;) z{lVWRUtbvTXd2k9WU+_By1Y+HfJd#USC&IX!QZAIt!-Fz-%n+vql%41U*ScREd3zJR0b)hMIN1d&V(0C+zlJR_&XLT)We z`F6_1r^I1e;d=g=h8JtGBr6&jc+(;*w#RgdBb-?$Mo9WMmctlU&-l}rYbzXhL)gswd^wEQ8|{_wLM#P!k5 znB?vw@lL=9!db!In_aZs;f&vKk+gAj z%rkB<$-*1CQ=A2z-jVlYm(JBQZo~@2D2e-I+AnUI;3eBJrnbV0bV)`k+ST-bF*!8D z{pN_F28U%*%zGEtiJxFQ!_PaPsECi&E?ksHGuPF+ipocClJNgzy2y zdcBfQ$XK~_Qnu9IY^PTl*c`xsiIKLS3f zETU6w)Px!FHl;S(oI0LoWFo~mo{_$pekO8H6>au~=NoWMoRnX;oGq(>95YFn$%ir^ zV#FXT$~mw_u8Y|cuNQt!*t~Nqm^OLDY)`5;Wa!t`%c;88?o*?^Tc#Yz1CzBTBZfG6 z(Uvi!=bS*oSzhnMqg-l138y(E#6JX9apOtFi)dwU%>mM0X{&}c!zDY`SJhdZvW^wd znGPo#dGa2GD_F8E zA`@RBw*}WC;ddJ~r$e`O)ErxoTF-^WqCLF*o~J@_`V0Hn?>wK66n!aRg0Jkh<6&RZoaito3~rG* z31uwGPkA(xFFgS*U+wr_&6mC)QQ<3dl@N-`er8n?4aP;irwLCz!ukC094QYkSxB)h zqc;qA{DA4#uiWx`PoPt*pPWzo^c4|AC?a ze`3!yS^hMaCwF>_)U~ULR5@A3y$NQ;bjj2N`Z5<1-X*4C!m%561kr_mS-szBx!)YIxwS2Zfkaj#`h>XKa%5B!*qO= z`6lcY7{zHA;VSIO%T^e04VC!eaxrfq+M4ti-E)=J%10!Lhm*IV8-}7>X}69<3L4>6 zyw^bsBV#F7soM14a=rzc3Y>Z#3h#mq-i0$&fT9k&?a{JPy_wUi0S3eENvD@>yr|QL z%URLrqBLG8?PM!Y z7HLtLzH^IA<2G)(!!Kz@j0jL3*w{69nAvOMxZpyEaecDBV|3PV>9|KwGLxt+_PL*E%W(a?nWY)cn%q_y^tkQIN{r)#$B;B? zK=oMo{%~RyAp|4?YdxzXR&8xlLi=nQI%$+x=fBoC*FKbp#~$`y$&I6;;ddqjFR53j zxExeEF=hAWWlFS8YlWJXK_;@xs+`>q{((D)Y zd^MQyG_o!X>-JGGQo<(#xAAGJRV+B~ zyXb0Jx7^GR#EHs#tMzk7JEyOV9Al}}dK=g~3bn2TG-%D6HGfQdOq8t_yVoLT@M<8T z_Wsag$hUf3zYji-u_yX9%9b-v%{$d-jr+J%2aA4GZ4T*+s9O|f5$m}UD0m13LCO_1 z&2CPAcuCf4=8WtnR|5O7g@5PqNIPfO%$tcx)5F+;j&?`Nl`gJgcgO&2Rgbu#qwfWV z-Kr0hDZZIl1qytKGT9k@U$%G)`nu6g{F7_t;W0UktlW9`f`nc(Pkr*!=!*@qd|Dm~ zComvpVTV0`HYH<=*(wvWSi=%ycakSE3h7#SHK@*?kd2_ecGI(KrPKHYlPJa5|DbyQeb8Na&J zNUNjBd9q2?s=OXJlc~>N4A7xO@LYPmH(Uh=8{9NII29YYSr51f?H z7h2_R1~K0B$uxQ3;DtZx%$JMTQy&)ebIU|try(ZeUJ9K83TUZtZ%@u@h0iAn-p8nj zRyQDtc4T>>+L^t)TFsfRVO&6}=%1>+F0g zU11e@lO%8S_0(4a6>&D5&H3m>cRsy4clFjowcr$#)3i~TLeQ0Jl?9E-- za8VqiK9JAN(`MTziSeTlYTr`A+ zPD~~8@v@}Y_Rh5fk3cYSLGz8t(rM%I)uZPIa%esYi6$zU9C>=Vj6q4ex$&6EWxl8- zlBz)L$xuCax%wsUl&DGIvpoha2mfy#m{&Y`CQz+Z?J{{Q?WeT)VgVzPX>q<^+pm35xk8yzg0D{BHt{KoiS0WGjZ0-Sojird+5`j? zY(7@0bESP%L&eQ{5@bh&IkN}Fz>KQ0P&8w@G)$gUbOGUsnMOYAJu5kvuFuBePU%9< zbzCDR<(&yPasb5BUS`v>MKpBQZ30qiSR`3e|+Y@O(_6yS@6P-0%a zn<{#mPxvUNed5OmMWf*I!ttpVSu3q?er7IZl``RVtfv~03acfu04%Jal@KRdLHzd1 z(bVx8_IitGH7NhGRKYdkpufUE0ZnHB>XOtRNh*oE{prkW{F%*t7b~-%U82A{rFEm9 z+inEyz@$S+RA|#nDAR$|Z_#=tALYUFHmLB;x6VBqkI%BkjHxjJm*rBZ{KJKs=An69 z4DIO+6*ZE5IR^vGG7FVMFUbcM#p1BNT3xMVuhmMGw^Kq9<`ZPWPz7&M1q_`-jsXE# z9=JyQL)Huw|CzxE_Wpu{MMh2qD$iI2dD~DsmF9b22vYK8FxDHUfRZJ_hBfAIXcv&> zx2SH;9C7Wxe+9y6D(4P3G~CG?=w){qDtvAvY~-v(H57zrwlw$|8%&a4R;;~Jgs<$f z_&-TlX)ufAeio;V-%f*Jt&Ob#rU{`4-rmmx*zWc*2bTvE9j~EWnC}>ET?V~wlZ{Xj z-#8|v-&-24ic7MKpe#QQVjeh?uAb<&=?bJtTp!)MOq71pIj`CDuO)oXU<@&>u z3-2{o%(*`%LC|-=F^w&ipth4yS6d!EY091tU8aE?(-;Hr4)12Nn3 z72V;w2<%Zb3uS7e_wrC5S3$N!1u*hylCo+9SkzU|H9WRIgc_whnD}L|EFSN>!4Kbl z%yO^b>Vo58cme-?Z_(8xZl(j|jjDeC5#57KojV2m=AR#im8N$7!vw z1Q~4Ua?=$uCSRS}i1ntr#@D7DH?&Uct(>zRZM@rUS7Ov(Pr(R`_DptHHL+noO0MX_sx}r%@)oH0Gb)(oDV){2nBQd*52y6 zLwYwRpuB1$|A*4AY7rvhfT+_Dsv6@Q33Z{J_8vxdFY zDA0xxcjM|7xOcWVM;53HPzyKw0X&*Twi6t;L!t2LNV*bT?;lY6N^2E&P}x&sB6b1; z5l*966Km5KYF2w~y;_9{G>@suzF;)EEurD4`uu5yyA0{Fd0rX@Pk5B!aNv=5*o*L< z!v2teI3Ws)tprn>dzj|r5w`PXcGT`y$->}02JAH-M%9n->0oh9>yKJ0WVz*6H&hZ( zKUW_pSAhX|pGA?>WJ_YRy-3Xwlhn zNQ7}!MCTf5i7}mvLDg1YZ0N!-4-ftJkVw}SkFk7}V$HBKDD%+F-Zr-fPJ zHklp7he?PBD2xjfLJU^J-^}0-axqAjv5xDg6G`h2NA}%_wQt`)1=`*wg6F|1uAW{^ z-cvwB5oJ`E75zZadzjW!?Vk(&U!;-knIFmqho8D&s@kgd+=sX;I_hz-wMDf9S?^q0 z_fJ%vpDN=k=V+KRNCV3wzrelU6$CsHt6R=`Gfm%A%AoW(Q}zcTu9Axa2sQGO=5dzQ zz&EfPhqh$^0x-QZVp-7(7{(2`QCG8b9@82PyA&$^pA*B9TV)vyPg-$sinbWbYE=%QVh zZrt?vz)&dt(vhgJ*6if-VHoUUWUQG~{98xuz`4SjxhhHexW;K1412}V@C~E4Wf5oA zNZz#W=~`6o^nS46zWa#2;A0#`#h>pr64V~(%%6BOZ>-+CLWaVC-W|gbn)Ug?qFvQa zT#oB9&nptIQuvC6EU>|t!QJ$=AHDiv_yF7iTie`ioPCI`;J$|yGK4MAXkI!^z&cmV z)xN)@ln1ldM7J}bL`z^ymf-KpRsuqz;=vyaOmYt@&TNYkRp8n{!jgU+{ujz-s|Ho8 zlivhl?3k-i25;|WFMf=&NCtOL(8s>UF%Ph9{d15bn6xl{_QQjBHQ^K)(u%9~thpiUDhhBDtA3sOH@E5c4 zr;m0Xi&8fh>59K)F`?z1U=4$Iz<~usT$cE=roB%c_UW(IW74jfArx5+uNWIdP(eky!Aq?66QsrvM`$Qh> zr%C6Pv*p4<2AMWJ)%sp~=OZecr^0wK{oRi)TpyCQmOeGMd2X}5^}Hxlx%C2Dx-NFH zYU`9NZXLiBW@KOP9?H*65i%DReI^!Z03syA4|ajn*e`@W(a$}o5b)Yo>H^tpJmg9B ziECzkyD_Q={{EBeX18f%MDXMOP-=lPDWXCnK!DwZ)Z?+ z&nr+-=D)4_kX+~|Xi!BfNeLuFM_d-eJb={Oxd&6Klj1pJ&DL3XWPpwU0Pk+vzS}Wx zdK!3ta(HS!Yxltr58?{lx~(K#whdkrRZbX;$xc*Bl>vLPpl%HiUh_=z*r0Dssd8$p z^qmpUtgF$)b0a>}@>?I4freiS>+Vc#Mo)gK(9}L3UYO5EIV53k8yp4r23Y|Z;@hc< z-ZhZLh-~*U1N`BD?i3>sLNDa&tp#v}Uhz->PE_Kf?;euCM{;OPOoeM;!TZ!1v#?k6 z@g+8GH12ymXY`>^#29jI3mZtr3t*=8pYsQ!I0|}cz9hnookYC$}5Iq|05%P$-dMmpd1_D03- zrWLZz!tW)MYFSo4AWI>oFpI@DDQjRTI=!HlAglLIYT9?ONTKmlmB55!di+KZXskoi z5+3Z;g67rjCZJe#zYtPbTcJ&pmigDw9|hn@;Iepjb^Z32bw7$>+{A!lM+|lyJ#iFE zP3A__{#DYeW%H*0#JLf|$h{#RX3;eDD1~AUjg_)qXU0wPH!N?)FHJ*QpS=AejXD3j zL}N|aV7zmm&lO7raI{A1TwP!KTJh?Q86=VFLW`qVFdV=_v3qH(G>e1OrNJfsVX%F& zPpk@VIgp&lABkd%l_pzK*6ky*3YE>R@Go;v3`CfPfMW2HDrFOx(?QvdVlaja@hJAv zRaWAyqdF)*6~(YC$0M5EinNi&)W`*~tqa9)Uzu_^JdoU$O3%TF{)A{eozsf{az_;G zFL<9?=0RJY}vz~<0#fQL=r`Nis0GTnkbo{VPsh30F7;p zz>Ajq(@?DAMczOYw~HZ~;TLI&Oy!C>!Wh{V8?@d(-vX$Zcdy>Q{#Z0eygK!h`BH!u z^tx4@n*^|IZ4o(JnA1=5A*z`06bPzfS8ZSGe<{D9acfZ$>3mCP66KlfMWPsroswjM zvd_^)PKNG)!U%q)^yY{FrU6;@anJ4wMH)k{I%&GZoDRxT=axKXAp3A@O?>SOvp~XC z*5m+dI?=riij}`_qMNL*i)V2L;z>eV0cdMH@%JHNvq4)2^LqI>t=~4<1f) zB@DZm{Af)bSxsS#hdk%K;QHugG0e2>o5nAv;@LeY8MA3kK8jW4cIKCOD2fHoZKzZj zPeZY)rkb5-nVL1Z)dS$!_K!ueYJS*P0~xcKWd*S6i*XQK2+YGiu>WGCz;B_At=U7 zafMWc)DGlVTgF?U7>a`~vfEAYU9fFo2!(pygJQ#*XavR9FA6ADI;swIc%j*z{PJ}z zX6$1mu@s7x#(_7XSe&t#E4BRqUPD&3%Vg`d_q!<>Nx;8rzLw0GCGF4{DpgBg9s?0z z#^1ku+L@z@9qZqBa>X@_J6shLB3>^CAN}^*Z@9^Nes#gpn)k%2vEExSL z0c1=~m!RCV?Q(mH2cJuo%Rm@SL8Cfzus5q{K zHPu|0gZ{hIm~79#x^g>uE24E_8BjTyD~4!iaf;7^*{!lF##BI>7Bdo!hmLJacIbDs z9SAfQsT&S#(CfwKY)|C*D%cjC`u<^8Ew6sOc@&%6Q*TExK^POv$VZ`AN0j9cih*vQ zlpE&P&~uj|4E0`50A|862}+CAJ`q1=IFZx4?i5yw%Ty z>EHu5j$jeHS0QsEUJ*(HN3&OKW~=opHYqJ_SfAr7kD4*=>X-E&DAspxcYG#krI*#O zcz4W##%3l$m}Z*D&IDqd%e!-!+!4kbYi{Q-s8%r9D>iT%nQ4v0h;9GgqXiNX70koA zyS|Cy5X^6aVrVE(UTqDSZGQZ46dRDx9TXEHUZEN@{UyHGTGpTwjLSErvXAtNZ8wiC zqWLK116e%HRi-gMSIlV>F*V>O4&!^AL0T|#SA^2S1XJ>jJLcC9 z5s+>T6Mf^r(cg(#ZM%jYf3x_tzDBXPu#531hQv%U;po%EVZlCpq+MdwFZz)v#&0BM z%Y7e^-7<8tdb7mKlry${4c$-=jr7GZ24bp(OElQdkRBoq$v|e_rx5|nAACeYn6o7b z@D%*0h*3x5u+=#5D^)ChpUe8h4j;Bq$zEzgu{WYI z23ATaMlMTX9cmu`8`JiM2fg-et){m62C`r(GDZyhK}qahh0Ko-o0&m5PhGquhDt|& zO3E4&z|1pV$x-n5BxF$RKpLz1>t{MBWqB-;EY}?%4#_LVgWbtM_FOe6rD~PDVyGvI zX`V2FqL|5&iz~^uAA({e82L&1vTgqd#ZYmfl%%h#8TTAt8u%;z|mUa>wItcqOON(&mC`yCyWCW@u9FbDqNM}h&wm#4c2}z{f6{(s>4EtYg7Lnz2rFA*Zo2%#e zVzHGrJltBKOucS;_7@8kl{)+O#gqvw+ZNLSWLs6NI@AmOUa?ftSQgQQD$28g?B24# zjWa0W^iKa65mJ55j?D|KvTn}SiXi(P$AUqD9dKE2L&<>S8k3Y5$dJ$s+ZcuI2}ZlLaL;Z~?3}5T)mAl!z4$3f&;Kds?2|KF&{mW*0c%DT z>t0du{j4MOaty_0G_!?HSJ-HU33&+d?Q;?B3)sb1TdYKI%Sr?Z2mDe}1-u61HQENiOzVJjimPw*DZs1;{!a z-ak}~L@{42cxx16Y;C2pxL|zrV_H*fmCQe(J8j>gG0g-9y1uDZ44tTbUYWkJiSkC% zShhZBUhIbs%6pdVBNfINT_L^z93--O`+3qJ4%ykf`h!X@I- zHkW%9udE~{m^=S{=e`Sy{i zR@KSO+zJ>*v24e2N+kOv6!R@BGKy*1*ddR^?ainKkHt|8Uak%LtCNe0+06w?SwiPK zt`W+ukUL`D9mP712tO!x6pG2%6vQ}TN|-tPQKPYxmIm9GY2G#buSRH}bn1rwL~zsV z2BQssO=F82?bxRuRz{7>Vi5_0=a3G)lV}oc6N&S zgs>EcfwpX-(lUu=hrU_0%)0v*H}6>}_O+p-3Srvq(I+^kP|Uv|)eoHQp!`%Cn^(pB ziQvpN=CI3ZfhMAdp{Jj*mB3Iji9Y|VUUqZKUa@M)udhIfN@sCIEn8m$X+q^Y{;yih zf#DT%TxF%2BZ^4{*#xLJKr!w79ZW{%?=EmNTke&_B7`@iihYtW))8j0eYm%RR8~LZ zZyzmDEY;QMe+mAL&@NlxO+3SdG<%+}9Qnl{h(W!yz|q*zUsCO-hkI>IdYWqCV|{mQZAKZ-Pp znYMjjtcpzXmX+gmw3x8jFRBnXrnw>%5;itEiTT?Pps|Pm78z26w(c=g!$u`d^L|y# zd1UZfdWp|U^tSz1Y}vv=F{Df5s5g?JCxzu>Xv_(-Fc07UO&9+_cy0Wp$7Ou*widOo zF;+Fh@A+qS)d|sEpftx#qLT7>;~)Hp*SDjw(pJ@tVp{(r?1oBt;%%lt>1g2EQ{bhF zj!MoxDl;n(9d;zEV(9mZp`i)Ip{`O+(pz&F>~Y{{a@c2}*g${fy(s3Nc*jr-ovtz* zFgP4<>lmx%ijheZzUY8Z%OrAz$SxGCZjJE=LG|c{XnMYE%{d3fwtrO>#*pqPDS2Ps z0?r&1E7@F{6s%TsTSEh*9}5n!Cfk1B^`Jfb{v=SK5B*3;EMo&SbJIhYg5i zV@;7Vhm~#nN3E3-iaDxSNn|EFC^g&u%y4^ostgPdSK7M+6t6S=j`Xr z>DQ1%@(${VV-*A{@+s_RSOk+_7z6HB*7YT^pj3vC-^+>h$E|b0??o|f7rPV9e`t%QexRxuHwST3q$1Z_veTH`Kl$W9- z^Gjq<48_9wi~u%Y$~0#sy_Yc7T3fsq#ZohEOQ)>GEu29y|F>?s$Ep(7jjEW8Vn}3C z4BR>Xl&<$hv69tBF6EH7%q`9HFTG;b9t*w`UVgE(hE11=Y}GF%S-b?S>PjHnC*heO zBOrB`SFAJ^>D^JRb-zgYx{z~W9_ znjV(5Ri#RPaesZ&m`q^9D5iPE za4}7J62;=5Pr9`GYK#aC6_X9_9dqDd92(pc#aXvlFvgIDZ!6q|nz zYK0FWWWRd*Jf|Mat7vOc?UwAHNWukdR~dGt{I5UHHHtkijP0N*QX5O1FY{2Qj1JFtyywC_2}hoNTFEA8j5`8o1)kjs@4i;^>m_LtldsODCYNM zwdQwsSAqSirDGH;J=}%2bl@H8o?qc-`;xqaW=G^~RUJXE@|R-}?GO~}9tYkXW}&sP z+-~A5*~Jz&;D4al*JGA5=yza!Z1IQzDbmaT{K;ff0zUyM5{vKmU~1)(h>GxGC}xh^ zD=pVUIP5MI0~e`!Ac{dvvM^E1IZpJU7}CD`4(!un)ecuQ=7llleniw-Fe#8Ts@RKP z9NkQ!9)8+U0~<#G&nW6gzMb8N4uy;4Gua!D;&mRchS)LjU;VkGESKTfiby z!88=(|FP9M$0=0|MUz?l-q;o>w_@J=au`{vsO}9Kik+F7TMByhb5hI(tE^gvh7QVY znywit)-?F&7OQ?oH|Ttr#mO9or~x0`r0wpBXMAC&+G_LnQc0oMy;D{+RV?xeGKy_o zAdGd_L9y=EmG4%aETI^7M&MtE0U5>oA8GcN!hc$y%VeNW%KuieGxCGB?N^`Ayr661 zOX>5G$m`F(epi^q@IE^bW|2C#K(&yjo){#GUEP~5irpJ2*@t3V8LS({OrdKS#mwW# zhe={+&NO0Hp!xG0Q@;cb15p|0S6!=D%-@_Af6!2DtCo??A|`bWgjvYmGC>RE+3}4~ ztRu`q4(IDWkIBmV5Q-f>N2NN9l0>lxhiNosMp3}Cnhh-dPeL)i0WDag>6XNtU&KPH zaZrqZGNzg(YL8(UwI@hBAI-HvaEVp_hdQ-~Qru?Rl}pZ@c? z_BZBtqY`FO`hh3YIyBqvA;PUO23Y*W-$fM*N((QWzp|;7 z11rkhx=LF}7R6>Hu>lSXiiBo&L6h5Td&7Ps6cdCrp-#k1J(6JyQM*_P)cS&3K8(Zohq7Ft zjHB4FvCNmm4hgeBv(tsSS*kNAudZa4Zq^oNN=+RJVcK^^5?Ewz({~uNWG_ zEPhZ-L@po2oRrsFP%KpjI$RP<4WzHqRVhRK+oD*6s7{Ee@KJ1g<2(QsQy1e;r#z;l zS{<_}rhQj(BnRwi8FxML`2DC9X5q_SS(!X8xh=l>`pNl&VytpT%F9f{`Bo&0WaXpS zoYgT{=44f@X}GG^K?yn>@(`og7>Xg95Y~5|)-Kk>u&a{CRkP%SU-s(Cg`4(96hk8S zEAq9p7Eb3bzVV?~MKMGTl)?ZdS-$EJz!oTWd4l>uG1yhhsxT(#VcN7x|8O4^6-uKg z$qLIY9Ofrkzz(y>($dMEeH2rFwl4_^fVmW@|JqL10H&cAWpFSai0_$bz~E1OaKa`IL-_QLOr{K{SeUk-3sQv)XN7<0lb zFle-g+F$9Y8$T#UxxSiE4E0K7X`B%}D`hHAB?4riM?;*ffvwje2)7sX)o!3?07lV?#~&x}>eRN5jamXi9$#({tBb{yDVn@|kRJ&)*Y+-XFy zzyA7*d{`gOVOMl@rHWNsEK|dn1y!v2$ab3Qkw^#=!tu5nOcPG|8W?jtFvBeT=XgmT zy9>yK0%ZinX4>FU&pm?Y6??ghKQAr5I*DC6SEL0}3$wTd#rU>p@)kZPS1i~>865wW zs)S}yj1>RY56S=kIUBEX=3jz_fc988MJ@#rTE2P9P(nkWOo1Ypz&IDhpox)-)DW z1eywe&MubvPMF<|4YPPau{Q!TQx!v72W3eW12<%pIfc&@)ZYljf_2GiaiLmvWZEss z?}YhDo|(ljN4%m^pggdH62$`L;)nK}QgM}A@$y5q56>pVK|_E={JU~gF`N-*aSMu} zt@zlqi$MwpV4eVrd+;@iy#X9C`*Uq_Zn``RAi9ziur)WG=~cjugo3*ZhUHK z;cadBt%XbH`clN*X&scPx3-WEfxDireFBniJ`hG5N^R2XNVTfz%mq zbH{y86su1DHnru_IPjF-iyn(i$5iI+dJC#tJV*(j@UmT3pso(v{_x47psfRG=#_eFX{6FHrJTgBeGQ-xCeGC0@`- z9{zvvoXjTUH`ORx%Z@_EY)Xc|k;yu?9;BNYBg4Y^F=f?G&+Xm%T~N$?-85aE&tZM1 z3J@tu-6+;dV+h&yvt3t_KFYW@=BQ#F^SrYy_fY#Hg

n2IMnjSG$0n4EneSAGzt1 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 TKV^xU00000NkvXXu0mjf)B54Y literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/alipay.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/alipay.png new file mode 100644 index 0000000000000000000000000000000000000000..adc0417f86720d9a0702186412ec1a735865ac86 GIT binary patch literal 6184 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 Hv7G+_b1q+7 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/apple.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..4f0840fe2ccb9873bd986dc046813ae7d50cb22d GIT binary patch literal 9231 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 F{{wBB`Ah%+ literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/douyin.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/douyin.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9f299aa5490d42ca36278b42db6364202b75ce GIT binary patch literal 5911 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/sinaweibo.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/sinaweibo.png new file mode 100644 index 0000000000000000000000000000000000000000..4424c7e124f8c901888540ff56e01fcbd858ee51 GIT binary patch literal 7920 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

-0;Ojr@ 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 Xrl*gZhxLB{-!}?!s*pk%(>MPMyHc1> literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/taobao.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/taobao.png new file mode 100644 index 0000000000000000000000000000000000000000..8f0944092327135b88686f39f6b247814e9a825a GIT binary patch literal 12011 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 CXXO9@ literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/user.png b/alpha/admin/uni_modules/uni-id-pages/static/uni-fab-login/user.png new file mode 100644 index 0000000000000000000000000000000000000000..5f330e7b72484c8e00e24c0f890e849717d73aa1 GIT binary patch literal 8175 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 ITfX}L0IZ|bqW}N^ literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/constants.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/constants.js new file mode 100644 index 0000000..a23dee4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/constants.js @@ -0,0 +1,92 @@ +const db = uniCloud.database() +const dbCmd = db.command +const userCollectionName = 'uni-id-users' +const userCollection = db.collection(userCollectionName) +const verifyCollectionName = 'opendb-verify-codes' +const verifyCollection = db.collection(verifyCollectionName) +const deviceCollectionName = 'uni-id-device' +const deviceCollection = db.collection(deviceCollectionName) +const openDataCollectionName = 'opendb-open-data' +const openDataCollection = db.collection(openDataCollectionName) + +const USER_IDENTIFIER = { + username: 'username', + mobile: 'mobile', + email: 'email', + wx_unionid: 'wechat-account', + 'wx_openid.app': 'wechat-account', + 'wx_openid.mp': 'wechat-account', + 'wx_openid.h5': 'wechat-account', + 'wx_openid.web': 'wechat-account', + qq_unionid: 'qq-account', + 'qq_openid.app': 'qq-account', + 'qq_openid.mp': 'qq-account', + ali_openid: 'alipay-account', + apple_openid: 'alipay-account' +} + +const USER_STATUS = { + NORMAL: 0, + BANNED: 1, + AUDITING: 2, + AUDIT_FAILED: 3, + CLOSED: 4 +} + +const CAPTCHA_SCENE = { + REGISTER: 'register', + LOGIN_BY_PWD: 'login-by-pwd', + LOGIN_BY_SMS: 'login-by-sms', + RESET_PWD_BY_SMS: 'reset-pwd-by-sms', + RESET_PWD_BY_EMAIL: 'reset-pwd-by-email', + SEND_SMS_CODE: 'send-sms-code', + SEND_EMAIL_CODE: 'send-email-code', + BIND_MOBILE_BY_SMS: 'bind-mobile-by-sms', + SET_PWD_BY_SMS: 'set-pwd-by-sms' +} + +const LOG_TYPE = { + LOGOUT: 'logout', + LOGIN: 'login', + REGISTER: 'register', + RESET_PWD_BY_SMS: 'reset-pwd', + RESET_PWD_BY_EMAIL: 'reset-pwd', + BIND_MOBILE: 'bind-mobile', + BIND_WEIXIN: 'bind-weixin', + BIND_QQ: 'bind-qq', + BIND_APPLE: 'bind-apple', + BIND_ALIPAY: 'bind-alipay', + UNBIND_WEIXIN: 'unbind-weixin', + UNBIND_QQ: 'unbind-qq', + UNBIND_ALIPAY: 'unbind-alipay', + UNBIND_APPLE: 'unbind-apple' +} + +const SMS_SCENE = { + LOGIN_BY_SMS: 'login-by-sms', + RESET_PWD_BY_SMS: 'reset-pwd-by-sms', + BIND_MOBILE_BY_SMS: 'bind-mobile-by-sms', + SET_PWD_BY_SMS: 'set-pwd-by-sms' +} + +const EMAIL_SCENE = { + REGISTER: 'register', + LOGIN_BY_EMAIL: 'login-by-email', + RESET_PWD_BY_EMAIL: 'reset-pwd-by-email', + BIND_EMAIL: 'bind-email' +} + +module.exports = { + db, + dbCmd, + userCollection, + verifyCollection, + deviceCollection, + openDataCollection, + USER_IDENTIFIER, + USER_STATUS, + CAPTCHA_SCENE, + LOG_TYPE, + SMS_SCENE, + EMAIL_SCENE +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js new file mode 100644 index 0000000..d026fe7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js @@ -0,0 +1,60 @@ +const ERROR = { + ACCOUNT_EXISTS: 'uni-id-account-exists', + ACCOUNT_NOT_EXISTS: 'uni-id-account-not-exists', + ACCOUNT_NOT_EXISTS_IN_CURRENT_APP: 'uni-id-account-not-exists-in-current-app', + ACCOUNT_CONFLICT: 'uni-id-account-conflict', + ACCOUNT_BANNED: 'uni-id-account-banned', + ACCOUNT_AUDITING: 'uni-id-account-auditing', + ACCOUNT_AUDIT_FAILED: 'uni-id-account-audit-failed', + ACCOUNT_CLOSED: 'uni-id-account-closed', + CAPTCHA_REQUIRED: 'uni-id-captcha-required', + PASSWORD_ERROR: 'uni-id-password-error', + PASSWORD_ERROR_EXCEED_LIMIT: 'uni-id-password-error-exceed-limit', + INVALID_USERNAME: 'uni-id-invalid-username', + INVALID_PASSWORD: 'uni-id-invalid-password', + INVALID_PASSWORD_SUPER: 'uni-id-invalid-password-super', + INVALID_PASSWORD_STRONG: 'uni-id-invalid-password-strong', + INVALID_PASSWORD_MEDIUM: 'uni-id-invalid-password-medium', + INVALID_PASSWORD_WEAK: 'uni-id-invalid-password-weak', + INVALID_MOBILE: 'uni-id-invalid-mobile', + INVALID_EMAIL: 'uni-id-invalid-email', + INVALID_NICKNAME: 'uni-id-invalid-nickname', + INVALID_PARAM: 'uni-id-invalid-param', + PARAM_REQUIRED: 'uni-id-param-required', + GET_THIRD_PARTY_ACCOUNT_FAILED: 'uni-id-get-third-party-account-failed', + GET_THIRD_PARTY_USER_INFO_FAILED: 'uni-id-get-third-party-user-info-failed', + MOBILE_VERIFY_CODE_ERROR: 'uni-id-mobile-verify-code-error', + EMAIL_VERIFY_CODE_ERROR: 'uni-id-email-verify-code-error', + ADMIN_EXISTS: 'uni-id-admin-exists', + PERMISSION_ERROR: 'uni-id-permission-error', + SYSTEM_ERROR: 'uni-id-system-error', + SET_INVITE_CODE_FAILED: 'uni-id-set-invite-code-failed', + INVALID_INVITE_CODE: 'uni-id-invalid-invite-code', + CHANGE_INVITER_FORBIDDEN: 'uni-id-change-inviter-forbidden', + BIND_CONFLICT: 'uni-id-bind-conflict', + UNBIND_FAIL: 'uni-id-unbind-failed', + UNBIND_NOT_SUPPORTED: 'uni-id-unbind-not-supported', + UNBIND_UNIQUE_LOGIN: 'uni-id-unbind-unique-login', + UNBIND_PASSWORD_NOT_EXISTS: 'uni-id-unbind-password-not-exists', + UNBIND_MOBILE_NOT_EXISTS: 'uni-id-unbind-mobile-not-exists', + UNSUPPORTED_REQUEST: 'uni-id-unsupported-request', + ILLEGAL_REQUEST: 'uni-id-illegal-request' +} + +function isUniIdError (errCode) { + return Object.values(ERROR).includes(errCode) +} + +class UniCloudError extends Error { + constructor (options) { + super(options.message) + this.errMsg = options.message || '' + this.errCode = options.code + } +} + +module.exports = { + ERROR, + isUniIdError, + UniCloudError +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/universal.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/universal.js new file mode 100644 index 0000000..4bf46a0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/universal.js @@ -0,0 +1,47 @@ +const { ERROR } = require('./error') + +function getHttpClientInfo () { + const requestId = this.getUniCloudRequestId() + const { clientIP, userAgent, source, secretType = 'none' } = this.getClientInfo() + const { clientInfo = {} } = JSON.parse(this.getHttpInfo().body) + + return { + ...clientInfo, + clientIP, + userAgent, + source, + secretType, + requestId + } +} + +function getHttpUniIdToken () { + const { uniIdToken = '' } = JSON.parse(this.getHttpInfo().body) + + return uniIdToken +} + +function verifyHttpMethod () { + const { headers, httpMethod } = this.getHttpInfo() + + if (!/^application\/json/.test(headers['content-type']) || httpMethod.toUpperCase() !== 'POST') { + throw { + errCode: ERROR.UNSUPPORTED_REQUEST, + errMsg: 'unsupported request' + } + } +} + +function universal () { + if (this.getClientInfo().source === 'http') { + verifyHttpMethod.call(this) + this.getParams()[0] = JSON.parse(this.getHttpInfo().body).params + this.getUniversalClientInfo = getHttpClientInfo.bind(this) + this.getUniversalUniIdToken = getHttpUniIdToken.bind(this) + } else { + this.getUniversalClientInfo = this.getClientInfo + this.getUniversalUniIdToken = this.getUniIdToken + } +} + +module.exports = universal diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js new file mode 100644 index 0000000..8996aa5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js @@ -0,0 +1,214 @@ +function batchFindObjctValue (obj = {}, keys = []) { + const values = {} + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const keyPath = key.split('.') + let currentKey = keyPath.shift() + let result = obj + while (currentKey) { + if (!result) { + break + } + result = result[currentKey] + currentKey = keyPath.shift() + } + values[key] = result + } + return values +} + +function getType (val) { + return Object.prototype.toString.call(val).slice(8, -1).toLowerCase() +} + +function hasOwn (obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key) +} + +function isValidString (val) { + return val && getType(val) === 'string' +} + +function isPlainObject (obj) { + return getType(obj) === 'object' +} + +function isFn (fn) { + // 务必注意AsyncFunction + return typeof fn === 'function' +} + +// 获取文件后缀,只添加几种图片类型供客服消息接口使用 +const mime2ext = { + 'image/png': 'png', + 'image/jpeg': 'jpg', + 'image/gif': 'gif', + 'image/svg+xml': 'svg', + 'image/bmp': 'bmp', + 'image/webp': 'webp' +} + +function getExtension (contentType) { + return mime2ext[contentType] +} + +const isSnakeCase = /_(\w)/g +const isCamelCase = /[A-Z]/g + +function snake2camel (value) { + return value.replace(isSnakeCase, (_, c) => (c ? c.toUpperCase() : '')) +} + +function camel2snake (value) { + return value.replace(isCamelCase, str => '_' + str.toLowerCase()) +} + +function parseObjectKeys (obj, type) { + let parserReg, parser + switch (type) { + case 'snake2camel': + parser = snake2camel + parserReg = isSnakeCase + break + case 'camel2snake': + parser = camel2snake + parserReg = isCamelCase + break + } + for (const key in obj) { + if (hasOwn(obj, key)) { + if (parserReg.test(key)) { + const keyCopy = parser(key) + obj[keyCopy] = obj[key] + delete obj[key] + if (isPlainObject(obj[keyCopy])) { + obj[keyCopy] = parseObjectKeys(obj[keyCopy], type) + } else if (Array.isArray(obj[keyCopy])) { + obj[keyCopy] = obj[keyCopy].map((item) => { + return parseObjectKeys(item, type) + }) + } + } + } + } + return obj +} + +function snake2camelJson (obj) { + return parseObjectKeys(obj, 'snake2camel') +} + +function camel2snakeJson (obj) { + return parseObjectKeys(obj, 'camel2snake') +} + +function getOffsetDate (offset) { + return new Date( + Date.now() + (new Date().getTimezoneOffset() + (offset || 0) * 60) * 60000 + ) +} + +function getDateStr (date, separator = '-') { + date = date || new Date() + const dateArr = [] + dateArr.push(date.getFullYear()) + dateArr.push(('00' + (date.getMonth() + 1)).substr(-2)) + dateArr.push(('00' + date.getDate()).substr(-2)) + return dateArr.join(separator) +} + +function getTimeStr (date, separator = ':') { + date = date || new Date() + const timeArr = [] + timeArr.push(('00' + date.getHours()).substr(-2)) + timeArr.push(('00' + date.getMinutes()).substr(-2)) + timeArr.push(('00' + date.getSeconds()).substr(-2)) + return timeArr.join(separator) +} + +function getFullTimeStr (date) { + date = date || new Date() + return getDateStr(date) + ' ' + getTimeStr(date) +} + +function getDistinctArray (arr) { + return Array.from(new Set(arr)) +} + +/** + * 拼接url + * @param {string} base 基础路径 + * @param {string} path 在基础路径上拼接的路径 + * @returns + */ +function resolveUrl (base, path) { + if (/^https?:/.test(path)) { + return path + } + return base + path +} + +function getVerifyCode (len = 6) { + let code = '' + for (let i = 0; i < len; i++) { + code += Math.floor(Math.random() * 10) + } + return code +} + +function coverMobile (mobile) { + if (typeof mobile !== 'string') { + return mobile + } + return mobile.slice(0, 3) + '****' + mobile.slice(7) +} + +function getNonceStr (length = 16) { + let str = '' + while (str.length < length) { + str += Math.random().toString(32).substring(2) + } + return str.substring(0, length) +} + +try { + require('lodash.merge') +} catch (error) { + console.error('uni-id-co缺少依赖,请在uniCloud/cloudfunctions/uni-id-co目录执行 npm install 安装依赖') + throw error +} + +function isMatchUserApp (userAppList, matchAppList) { + if (userAppList === undefined || userAppList === null) { + return true + } + if (getType(userAppList) !== 'array') { + return false + } + if (userAppList.includes('*')) { + return true + } + if (getType(matchAppList) === 'string') { + matchAppList = [matchAppList] + } + return userAppList.some(item => matchAppList.includes(item)) +} + +module.exports = { + getType, + isValidString, + batchFindObjctValue, + isPlainObject, + isFn, + getDistinctArray, + getFullTimeStr, + resolveUrl, + getOffsetDate, + camel2snakeJson, + snake2camelJson, + getExtension, + getVerifyCode, + coverMobile, + getNonceStr, + isMatchUserApp +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js new file mode 100644 index 0000000..e14600c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js @@ -0,0 +1,439 @@ +const { + isValidString, + getType +} = require('./utils.js') +const { + ERROR +} = require('./error') + +const baseValidator = Object.create(null) + +baseValidator.username = function (username) { + const errCode = ERROR.INVALID_USERNAME + if (!isValidString(username)) { + return { + errCode + } + } + if (/^\d+$/.test(username)) { + // 用户名不能为纯数字 + return { + errCode + } + }; + if (!/^[a-zA-Z0-9_-]+$/.test(username)) { + // 用户名仅能使用数字、字母、“_”及“-” + return { + errCode + } + } +} + +baseValidator.password = function (password) { + const errCode = ERROR.INVALID_PASSWORD + if (!isValidString(password)) { + return { + errCode + } + } + if (password.length < 6) { + // 密码长度不能小于6 + return { + errCode + } + } +} + +baseValidator.mobile = function (mobile) { + const errCode = ERROR.INVALID_MOBILE + if (getType(mobile) !== 'string') { + return { + errCode + } + } + if (mobile && !/^1\d{10}$/.test(mobile)) { + return { + errCode + } + } +} + +baseValidator.email = function (email) { + const errCode = ERROR.INVALID_EMAIL + if (getType(email) !== 'string') { + return { + errCode + } + } + if (email && !/@/.test(email)) { + return { + errCode + } + } +} + +baseValidator.nickname = function (nickname) { + const errCode = ERROR.INVALID_NICKNAME + if (nickname.indexOf('@') !== -1) { + // 昵称不允许含@ + return { + errCode + } + }; + if (/^\d+$/.test(nickname)) { + // 昵称不能为纯数字 + return { + errCode + } + }; + if (nickname.length > 100) { + // 昵称不可超过100字符 + return { + errCode + } + } +} + +const baseType = ['string', 'boolean', 'number', 'null'] // undefined不会由客户端提交上来 + +baseType.forEach((type) => { + baseValidator[type] = function (val) { + if (getType(val) === type) { + return + } + return { + errCode: ERROR.INVALID_PARAM + } + } +}) + +function tokenize(name) { + let i = 0 + const result = [] + let token = '' + while (i < name.length) { + const char = name[i] + switch (char) { + case '|': + case '<': + case '>': + token && result.push(token) + result.push(char) + token = '' + break + default: + token += char + break + } + i++ + if (i === name.length && token) { + result.push(token) + } + } + return result +} + +/** + * 处理validator名 + * @param {string} name + */ +function parseValidatorName(name) { + const tokenList = tokenize(name) + let i = 0 + let currentToken = tokenList[i] + const result = { + type: 'root', + children: [], + parent: null + } + let lastRealm = result + while (currentToken) { + switch (currentToken) { + case 'array': { + const currentRealm = { + type: 'array', + children: [], + parent: lastRealm + } + lastRealm.children.push(currentRealm) + lastRealm = currentRealm + break + } + case '<': + if (lastRealm.type !== 'array') { + throw new Error('Invalid validator token "<"') + } + break + case '>': + if (lastRealm.type !== 'array') { + throw new Error('Invalid validator token ">"') + } + lastRealm = lastRealm.parent + break + case '|': + if (lastRealm.type !== 'array' && lastRealm.type !== 'root') { + throw new Error('Invalid validator token "|"') + } + break + default: + lastRealm.children.push({ + type: currentToken + }) + break + } + i++ + currentToken = tokenList[i] + } + return result +} + +function getRuleCategory(rule) { + switch (rule.type) { + case 'array': + return 'array' + case 'root': + return 'root' + default: + return 'base' + } +} + +function isMatchUnionType(val, rule) { + if (!rule.children || rule.children.length === 0) { + return true + } + const children = rule.children + for (let i = 0; i < children.length; i++) { + const child = children[i] + const category = getRuleCategory(child) + let pass = false + switch (category) { + case 'base': + pass = isMatchBaseType(val, child) + break + case 'array': + pass = isMatchArrayType(val, child) + break + default: + break + } + if (pass) { + return true + } + } + return false +} + +function isMatchBaseType(val, rule) { + if (typeof baseValidator[rule.type] !== 'function') { + throw new Error(`invalid schema type: ${rule.type}`) + } + const validateRes = baseValidator[rule.type](val) + if (validateRes && validateRes.errCode) { + return false + } + return true +} + +function isMatchArrayType(arr, rule) { + if (getType(arr) !== 'array') { + return false + } + if (rule.children && rule.children.length && arr.some(item => !isMatchUnionType(item, rule))) { + return false + } + return true +} + +// 特殊符号 https://www.ibm.com/support/pages/password-strength-rules ~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/ +// const specialChar = '~!@#$%^&*_-+=`|\(){}[]:;"\'<>,.?/' +// const specialCharRegExp = /^[~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]$/ +// for (let i = 0, arr = specialChar.split(''); i < arr.length; i++) { +// const char = arr[i] +// if (!specialCharRegExp.test(char)) { +// throw new Error('check special character error: ' + char) +// } +// } + +// 密码强度表达式 +const passwordRules = { + // 密码必须包含大小写字母、数字和特殊符号 + super: /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须包含字母、数字和特殊符号 + strong: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须为字母、数字和特殊符号任意两种的组合 + medium: /^(?![0-9]+$)(?![a-zA-Z]+$)(?![~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]+$)[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{8,16}$/, + // 密码必须包含字母和数字 + weak: /^(?=.*[0-9])(?=.*[a-zA-Z])[0-9a-zA-Z~!@#$%^&*_\-+=`|\\(){}[\]:;"'<>,.?/]{6,16}$/, + +} + +function createPasswordVerifier({ + passwordStrength = '' +} = {}) { + return function (password) { + const passwordRegExp = passwordRules[passwordStrength] + if (!passwordRegExp) { + throw new Error('Invalid password strength config: ' + passwordStrength) + } + const errCode = ERROR.INVALID_PASSWORD + if (!isValidString(password)) { + return { + errCode + } + } + if (!passwordRegExp.test(password)) { + return { + errCode: errCode + '-' + passwordStrength + } + } + } +} + +function isEmpty(value) { + return value === undefined || + value === null || + (typeof value === 'string' && value.trim() === '') +} + +class Validator { + constructor({ + passwordStrength = '' + } = {}) { + this.baseValidator = baseValidator + this.customValidator = Object.create(null) + if (passwordStrength) { + this.mixin( + 'password', + createPasswordVerifier({ + passwordStrength + }) + ) + } + } + + mixin(type, handler) { + this.customValidator[type] = handler + } + + getRealBaseValidator(type) { + return this.customValidator[type] || this.baseValidator[type] + } + + get validator() { + return new Proxy({}, { + get: (_, prop) => { + if (typeof prop !== 'string') { + return + } + const realBaseValidator = this.getRealBaseValidator(prop) + if (realBaseValidator) { + return realBaseValidator + } + const rule = parseValidatorName(prop) + return function (val) { + if (!isMatchUnionType(val, rule)) { + return { + errCode: ERROR.INVALID_PARAM + } + } + } + } + }) + } + + validate(value = {}, schema = {}) { + for (const schemaKey in schema) { + let schemaValue = schema[schemaKey] + if (getType(schemaValue) === 'string') { + schemaValue = { + required: true, + type: schemaValue + } + } + const { + required, + type + } = schemaValue + // value内未传入了schemaKey或对应值为undefined + if (isEmpty(value[schemaKey])) { + if (required) { + return { + errCode: ERROR.PARAM_REQUIRED, + errMsgValue: { + param: schemaKey + }, + schemaKey + } + } else { + //delete value[schemaKey] + continue + } + } + const validateMethod = this.validator[type] + if (!validateMethod) { + throw new Error(`invalid schema type: ${type}`) + } + const validateRes = validateMethod(value[schemaKey]) + if (validateRes) { + validateRes.schemaKey = schemaKey + return validateRes + } + } + } +} + +function checkClientInfo(clientInfo) { + const stringNotRequired = { + required: false, + type: 'string' + } + const numberNotRequired = { + required: false, + type: 'number' + } + const numberOrStringNotRequired = { + required: false, + type: 'number|string' + } + const schema = { + uniPlatform: 'string', + appId: 'string', + deviceId: stringNotRequired, + osName: stringNotRequired, + locale: stringNotRequired, + clientIP: stringNotRequired, + appName: stringNotRequired, + appVersion: stringNotRequired, + appVersionCode: numberOrStringNotRequired, + channel: numberOrStringNotRequired, + userAgent: stringNotRequired, + uniIdToken: stringNotRequired, + deviceBrand: stringNotRequired, + deviceModel: stringNotRequired, + osVersion: stringNotRequired, + osLanguage: stringNotRequired, + osTheme: stringNotRequired, + romName: stringNotRequired, + romVersion: stringNotRequired, + devicePixelRatio: numberNotRequired, + windowWidth: numberNotRequired, + windowHeight: numberNotRequired, + screenWidth: numberNotRequired, + screenHeight: numberNotRequired + } + const validateRes = new Validator().validate(clientInfo, schema) + if (validateRes) { + if (validateRes.errCode === ERROR.PARAM_REQUIRED) { + console.warn('- 如果使用HBuilderX运行本地云函数/云对象功能时出现此提示,请改为使用客户端调用本地云函数方式调试,或更新HBuilderX到3.4.12及以上版本。\n- 如果是缺少clientInfo.appId,请检查项目manifest.json内是否配置了DCloud AppId') + throw new Error(`"clientInfo.${validateRes.schemaKey}" is required.`) + } else { + throw new Error(`Invalid client info: clienInfo.${validateRes.schemaKey}`) + } + } +} + +module.exports = { + Validator, + checkClientInfo +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js new file mode 100644 index 0000000..8a06222 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js @@ -0,0 +1,81 @@ +// 各接口权限配置,未配置接口表示允许任何用户访问(包括未登录用户) +module.exports = { + // 管理接口 + addUser: { + // auth: true // 已登录用户方可操作,配置角色或权限时此项可不写 + role: ['admin'] // 允许进行此操作的角色,包含任一角色均可操作。 + // permission: [] // 允许进行此操作的权限,包含任一权限均可操作。 + // 权限角色均配置时,用户拥有任一权限或任一角色均可操作 + }, + updateUser: { + role: ['admin'] + }, + authorizeAppLogin: { + role: ['admin'] + }, + removeAuthorizedApp: { + role: ['admin'] + }, + setAuthorizedApp: { + role: ['admin'] + }, + + // 用户接口 + closeAccount: { + auth: true + }, + updatePwd: { + auth: true + }, + logout: { + auth: true + }, + bindMobileBySms: { + auth: true + }, + bindMobileByUniverify: { + auth: true + }, + bindMobileByMpWeixin: { + auth: true + }, + bindAlipay: { + auth: true + }, + bindApple: { + auth: true + }, + bindQQ: { + auth: true + }, + bindWeixin: { + auth: true + }, + acceptInvite: { + auth: true + }, + getInvitedUser: { + auth: true + }, + setPushCid: { + auth: true + }, + getAccountInfo: { + auth: true + }, + unbindWeixin: { + auth: true + }, + unbindAlipay: { + auth: true + }, + unbindQQ: { + auth: true + }, + unbindApple: { + auth: true + }, + setPwd: { + auth: true + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js new file mode 100644 index 0000000..69013a4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js @@ -0,0 +1,616 @@ +const uniIdCommon = require('uni-id-common') +const uniCaptcha = require('uni-captcha') +const { + getType +} = require('./common/utils') +const { + checkClientInfo, + Validator +} = require('./common/validator') +const ConfigUtils = require('./lib/utils/config') +const { + isUniIdError +} = require('./common/error') +const middleware = require('./middleware/index') +const universal = require('./common/universal') + +const { + registerAdmin, + registerUser, + registerUserByEmail +} = require('./module/register/index') +const { + addUser, + updateUser +} = require('./module/admin/index') +const { + login, + loginBySms, + loginByUniverify, + loginByWeixin, + loginByAlipay, + loginByQQ, + loginByApple, + loginByWeixinMobile +} = require('./module/login/index') +const { + logout +} = require('./module/logout/index') +const { + bindMobileBySms, + bindMobileByUniverify, + bindMobileByMpWeixin, + bindAlipay, + bindApple, + bindQQ, + bindWeixin, + unbindWeixin, + unbindAlipay, + unbindQQ, + unbindApple +} = require('./module/relate/index') +const { + setPwd, + updatePwd, + resetPwdBySms, + resetPwdByEmail, + closeAccount, + getAccountInfo +} = require('./module/account/index') +const { + createCaptcha, + refreshCaptcha, + sendSmsCode, + sendEmailCode +} = require('./module/verify/index') +const { + refreshToken, + setPushCid, + secureNetworkHandshakeByWeixin +} = require('./module/utils/index') +const { + getInvitedUser, + acceptInvite +} = require('./module/fission') +const { + authorizeAppLogin, + removeAuthorizedApp, + setAuthorizedApp +} = require('./module/multi-end') +const { + getSupportedLoginType +} = require('./module/dev/index') + +const { + externalRegister, + externalLogin +} = require('./module/external') + +module.exports = { + async _before () { + // 支持 callFunction 与 URL化 + universal.call(this) + + const clientInfo = this.getUniversalClientInfo() + /** + * 检查clientInfo,无appId和uniPlatform时本云对象无法正常运行 + * 此外需要保证用到的clientInfo字段均经过类型检查 + * clientInfo由客户端上传并非完全可信,clientInfo内除clientIP、userAgent、source外均为客户端上传参数 + * 否则可能会出现一些意料外的情况 + */ + checkClientInfo(clientInfo) + let clientPlatform = clientInfo.uniPlatform + // 统一platform名称 + switch (clientPlatform) { + case 'app': + case 'app-plus': + clientPlatform = 'app' + break + case 'web': + case 'h5': + clientPlatform = 'web' + break + default: + break + } + + this.clientPlatform = clientPlatform + + // 挂载uni-id实例到this上,方便后续调用 + this.uniIdCommon = uniIdCommon.createInstance({ + clientInfo + }) + + // 包含uni-id配置合并等功能的工具集 + this.configUtils = new ConfigUtils({ + context: this + }) + this.config = this.configUtils.getPlatformConfig() + this.hooks = this.configUtils.getHooks() + + this.validator = new Validator({ + passwordStrength: this.config.passwordStrength + }) + /** + * 示例:覆盖密码验证规则 + */ + // this.validator.mixin('password', function (password) { + // if (typeof password !== 'string' || password.length < 10) { + // // 调整为密码长度不能小于10 + // return { + // errCode: ERROR.INVALID_PASSWORD + // } + // } + // }) + /** + * 示例:新增验证规则 + */ + // this.validator.mixin('timestamp', function (timestamp) { + // if (typeof timestamp !== 'number' || timestamp > Date.now()) { + // return { + // errCode: ERROR.INVALID_PARAM + // } + // } + // }) + // // 新增规则同样可以在数组验证规则中使用 + // this.validator.valdate({ + // timestamp: 123456789 + // }, { + // timestamp: 'timestamp' + // }) + // this.validator.valdate({ + // timestampList: [123456789, 123123123123] + // }, { + // timestampList: 'array' + // }) + // // 甚至更复杂的写法 + // this.validator.valdate({ + // timestamp: [123456789, 123123123123] + // }, { + // timestamp: 'timestamp|array' + // }) + + // 挂载uni-captcha到this上,方便后续调用 + this.uniCaptcha = uniCaptcha + Object.defineProperty(this, 'uniOpenBridge', { + get () { + return require('uni-open-bridge-common') + } + }) + + // 挂载中间件 + this.middleware = {} + for (const mwName in middleware) { + this.middleware[mwName] = middleware[mwName].bind(this) + } + + // 国际化 + const i18n = uniCloud.initI18n({ + locale: clientInfo.locale, + fallbackLocale: 'zh-Hans', + messages: require('./lang/index') + }) + this.t = i18n.t.bind(i18n) + + this.response = {} + + // 请求鉴权验证 + await this.middleware.verifyRequestSign() + + // 通用权限校验模块 + await this.middleware.accessControl() + }, + _after (error, result) { + if (error) { + // 处理中间件内抛出的标准响应对象 + if (error.errCode && getType(error) === 'object') { + const errCode = error.errCode + if (!isUniIdError(errCode)) { + return error + } + return { + errCode, + errMsg: error.errMsg || this.t(errCode, error.errMsgValue) + } + } + throw error + } + return Object.assign(this.response, result) + }, + /** + * 注册管理员 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-admin + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @returns + */ + registerAdmin, + /** + * 新增用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {Array} params.authorizedApp 允许登录的AppID列表 + * @param {Array} params.role 用户角色列表 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {Array} params.tags 用户标签 + * @param {Number} params.status 用户状态 + * @returns + */ + addUser, + /** + * 修改用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user + * @param {Object} params + * @param {String} params.id 要更新的用户id + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {Array} params.authorizedApp 允许登录的AppID列表 + * @param {Array} params.role 用户角色列表 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {Array} params.tags 用户标签 + * @param {Number} params.status 用户状态 + * @returns + */ + updateUser, + /** + * 授权用户登录应用 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#authorize-app-login + * @param {Object} params + * @param {String} params.uid 用户id + * @param {String} params.appId 授权的应用的AppId + * @returns + */ + authorizeAppLogin, + /** + * 移除用户登录授权 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#remove-authorized-app + * @param {Object} params + * @param {String} params.uid 用户id + * @param {String} params.appId 取消授权的应用的AppId + * @returns + */ + removeAuthorizedApp, + /** + * 设置用户允许登录的应用列表 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-authorized-app + * @param {Object} params + * @param {String} params.uid 用户id + * @param {Array} params.appIdList 允许登录的应用AppId列表 + * @returns + */ + setAuthorizedApp, + /** + * 注册普通用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-user + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.captcha 图形验证码 + * @param {String} params.nickname 昵称 + * @param {String} params.inviteCode 邀请码 + * @returns + */ + registerUser, + /** + * 通过邮箱+验证码注册用户 + * @param {Object} params + * @param {String} params.email 邮箱 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {String} params.code 邮箱验证码 + * @param {String} params.inviteCode 邀请码 + * @returns + */ + registerUserByEmail, + /** + * 用户名密码登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {String} params.password 密码 + * @param {String} params.captcha 图形验证码 + * @returns + */ + login, + /** + * 短信验证码登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-sms + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.code 短信验证码 + * @param {String} params.captcha 图形验证码 + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginBySms, + /** + * App端一键登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-univerify + * @param {Object} params + * @param {String} params.access_token APP端一键登录返回的access_token + * @param {String} params.openid APP端一键登录返回的openid + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginByUniverify, + /** + * 微信登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-weixin + * @param {Object} params + * @param {String} params.code 微信登录返回的code + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginByWeixin, + /** + * 支付宝登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-alipay + * @param {Object} params + * @param {String} params.code 支付宝小程序客户端登录返回的code + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginByAlipay, + /** + * QQ登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-qq + * @param {Object} params + * @param {String} params.code QQ小程序登录返回的code参数 + * @param {String} params.accessToken App端QQ登录返回的accessToken参数 + * @param {String} params.accessTokenExpired accessToken过期时间,由App端QQ登录返回的expires_in参数计算而来,单位:毫秒 + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginByQQ, + /** + * 苹果登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-apple + * @param {Object} params + * @param {String} params.identityToken 苹果登录返回的identityToken + * @param {String} params.nickname 用户昵称 + * @param {String} params.inviteCode 邀请码 + * @returns + */ + loginByApple, + loginByWeixinMobile, + /** + * 用户退出登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#logout + * @returns + */ + logout, + /** + * 通过短信验证码绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-sms + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.code 短信验证码 + * @param {String} params.captcha 图形验证码 + * @returns + */ + bindMobileBySms, + /** + * 通过一键登录绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-univerify + * @param {Object} params + * @param {String} params.openid APP端一键登录返回的openid + * @param {String} params.access_token APP端一键登录返回的access_token + * @returns + */ + bindMobileByUniverify, + /** + * 通过微信绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-mp-weixin + * @param {Object} params + * @param {String} params.encryptedData 微信获取手机号返回的加密信息 + * @param {String} params.iv 微信获取手机号返回的初始向量 + * @returns + */ + bindMobileByMpWeixin, + /** + * 绑定微信 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-weixin + * @param {Object} params + * @param {String} params.code 微信登录返回的code + * @returns + */ + bindWeixin, + /** + * 绑定QQ + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-qq + * @param {Object} params + * @param {String} params.code 小程序端QQ登录返回的code + * @param {String} params.accessToken APP端QQ登录返回的accessToken + * @param {String} params.accessTokenExpired accessToken过期时间,由App端QQ登录返回的expires_in参数计算而来,单位:毫秒 + * @returns + */ + bindQQ, + /** + * 绑定支付宝账号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-alipay + * @param {Object} params + * @param {String} params.code 支付宝小程序登录返回的code参数 + * @returns + */ + bindAlipay, + /** + * 绑定苹果账号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-apple + * @param {Object} params + * @param {String} params.identityToken 苹果登录返回identityToken + * @returns + */ + bindApple, + /** + * 更新密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-pwd + * @param {object} params + * @param {string} params.oldPassword 旧密码 + * @param {string} params.newPassword 新密码 + * @returns {object} + */ + updatePwd, + /** + * 通过短信验证码重置密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-sms + * @param {object} params + * @param {string} params.mobile 手机号 + * @param {string} params.mobile 短信验证码 + * @param {string} params.password 密码 + * @param {string} params.captcha 图形验证码 + * @returns {object} + */ + resetPwdBySms, + /** + * 通过邮箱验证码重置密码 + * @param {object} params + * @param {string} params.email 邮箱 + * @param {string} params.code 邮箱验证码 + * @param {string} params.password 密码 + * @param {string} params.captcha 图形验证码 + * @returns {object} + */ + resetPwdByEmail, + /** + * 注销账户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#close-account + * @returns + */ + closeAccount, + /** + * 获取账户账户简略信息 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-account-info + */ + getAccountInfo, + /** + * 创建图形验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#create-captcha + * @param {Object} params + * @param {String} params.scene 图形验证码使用场景 + * @returns + */ + createCaptcha, + /** + * 刷新图形验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#refresh-captcha + * @param {Object} params + * @param {String} params.scene 图形验证码使用场景 + * @returns + */ + refreshCaptcha, + /** + * 发送短信验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#send-sms-code + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.captcha 图形验证码 + * @param {String} params.scene 短信验证码使用场景 + * @returns + */ + sendSmsCode, + /** + * 发送邮箱验证码 + * @tutorial 需自行实现功能 + * @param {Object} params + * @param {String} params.email 邮箱 + * @param {String} params.captcha 图形验证码 + * @param {String} params.scene 短信验证码使用场景 + * @returns + */ + sendEmailCode, + /** + * 刷新token + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#refresh-token + */ + refreshToken, + /** + * 接受邀请 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#accept-invite + * @param {Object} params + * @param {String} params.inviteCode 邀请码 + * @returns + */ + acceptInvite, + /** + * 获取受邀用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-invited-user + * @param {Object} params + * @param {Number} params.level 获取受邀用户的级数,1表示直接邀请的用户 + * @param {Number} params.limit 返回数据大小 + * @param {Number} params.offset 返回数据偏移 + * @param {Boolean} params.needTotal 是否需要返回总数 + * @returns + */ + getInvitedUser, + /** + * 更新device表的push_clien_id + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-push-cid + * @param {object} params + * @param {string} params.pushClientId 客户端pushClientId + * @returns + */ + setPushCid, + /** + * 获取支持的登录方式 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-supported-login-type + * @returns + */ + getSupportedLoginType, + + /** + * 解绑微信 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-weixin + * @returns + */ + unbindWeixin, + /** + * 解绑支付宝 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-alipay + * @returns + */ + unbindAlipay, + /** + * 解绑QQ + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-qq + * @returns + */ + unbindQQ, + /** + * 解绑Apple + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-apple + * @returns + */ + unbindApple, + /** + * 安全网络握手,目前仅处理微信小程序安全网络握手 + */ + secureNetworkHandshakeByWeixin, + /** + * 设置密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-pwd + * @returns + */ + setPwd, + /** + * 外部用户注册,将自身系统的用户账号导入uniId,为其创建一个对应uniId的账号(unieid),使得该账号可以使用依赖uniId的系统及功能。 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external-register + * @returns + */ + externalRegister, + /** + * 外部用户登录,使用unieid即可登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external-login + * @returns + * */ + externalLogin +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js new file mode 100644 index 0000000..d329d01 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js @@ -0,0 +1,52 @@ +const word = { + login: 'login', + 'verify-mobile': 'verify phone number' +} + +const sentence = { + 'uni-id-account-exists': 'Account exists', + 'uni-id-account-not-exists': 'Account does not exists', + 'uni-id-account-not-exists-in-current-app': 'Account does not exists in current app', + 'uni-id-account-conflict': 'User account conflict', + 'uni-id-account-banned': 'Account has been banned', + 'uni-id-account-auditing': 'Account audit in progress', + 'uni-id-account-audit-failed': 'Account audit failed', + 'uni-id-account-closed': 'Account has been closed', + 'uni-id-captcha-required': 'Captcha required', + 'uni-id-password-error': 'Password error', + 'uni-id-password-error-exceed-limit': 'The number of password errors is excessive', + 'uni-id-invalid-username': 'Invalid username', + 'uni-id-invalid-password': 'invalid password', + 'uni-id-invalid-password-super': 'Passwords must have 8-16 characters and contain uppercase letters, lowercase letters, numbers, and symbols.', + 'uni-id-invalid-password-strong': 'Passwords must have 8-16 characters and contain letters, numbers and symbols.', + 'uni-id-invalid-password-medium': 'Passwords must have 8-16 characters and contain at least two of the following: letters, numbers, and symbols.', + 'uni-id-invalid-password-weak': 'Passwords must have 6-16 characters and contain letters and numbers.', + 'uni-id-invalid-mobile': 'Invalid mobile phone number', + 'uni-id-invalid-email': 'Invalid email address', + 'uni-id-invalid-nickname': 'Invalid nickname', + 'uni-id-invalid-param': 'Invalid parameter', + 'uni-id-param-required': 'Parameter required: {param}', + 'uni-id-get-third-party-account-failed': 'Get third party account failed', + 'uni-id-get-third-party-user-info-failed': 'Get third party user info failed', + 'uni-id-mobile-verify-code-error': 'Verify code error or expired', + 'uni-id-email-verify-code-error': 'Verify code error or expired', + 'uni-id-admin-exists': 'Administrator exists', + 'uni-id-permission-error': 'Permission denied', + 'uni-id-system-error': 'System error', + 'uni-id-set-invite-code-failed': 'Set invite code failed', + 'uni-id-invalid-invite-code': 'Invalid invite code', + 'uni-id-change-inviter-forbidden': 'Change inviter is not allowed', + 'uni-id-bind-conflict': 'This account has been bound', + 'uni-id-admin-exist-in-other-apps': 'Administrator is registered in other consoles', + 'uni-id-unbind-failed': 'Please bind first and then unbind', + 'uni-id-unbind-not-supported': 'Unbinding is not supported', + 'uni-id-unbind-mobile-not-exists': 'This is the only way to login at the moment, please bind your phone number and then try to unbind', + 'uni-id-unbind-password-not-exists': 'Please set a password first', + 'uni-id-unsupported-request': 'Unsupported request', + 'uni-id-illegal-request': 'Illegal request' +} + +module.exports = { + ...word, + ...sentence +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/index.js new file mode 100644 index 0000000..1f22998 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/index.js @@ -0,0 +1,22 @@ +let lang = { + 'zh-Hans': require('./zh-hans'), + en: require('./en') +} + +function mergeLanguage (lang1, lang2) { + const localeList = Object.keys(lang1) + localeList.push(...Object.keys(lang2)) + const result = {} + for (let i = 0; i < localeList.length; i++) { + const locale = localeList[i] + result[locale] = Object.assign({}, lang1[locale], lang2[locale]) + } + return result +} + +try { + const langPath = require.resolve('uni-config-center/uni-id/lang/index.js') + lang = mergeLanguage(lang, require(langPath)) +} catch (error) { } + +module.exports = lang diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js new file mode 100644 index 0000000..a42f06d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js @@ -0,0 +1,52 @@ +const word = { + login: '登录', + 'verify-mobile': '验证手机号' +} + +const sentence = { + 'uni-id-account-exists': '此账号已注册', + 'uni-id-account-not-exists': '此账号未注册', + 'uni-id-account-not-exists-in-current-app': '此账号未在该应用注册', + 'uni-id-account-conflict': '用户账号冲突', + 'uni-id-account-banned': '此账号已封禁', + 'uni-id-account-auditing': '此账号正在审核中', + 'uni-id-account-audit-failed': '此账号审核失败', + 'uni-id-account-closed': '此账号已注销', + 'uni-id-captcha-required': '请输入图形验证码', + 'uni-id-password-error': '密码错误', + 'uni-id-password-error-exceed-limit': '密码错误次数过多,请稍后再试', + 'uni-id-invalid-username': '用户名不合法', + 'uni-id-invalid-password': '密码不合法', + 'uni-id-invalid-password-super': '密码必须包含大小写字母、数字和特殊符号,长度8-16位', + 'uni-id-invalid-password-strong': '密码必须包含字母、数字和特殊符号,长度8-16位不合法', + 'uni-id-invalid-password-medium': '密码必须为字母、数字和特殊符号任意两种的组合,长度8-16位', + 'uni-id-invalid-password-weak': '密码必须包含字母和数字,长度6-16位', + 'uni-id-invalid-mobile': '手机号码不合法', + 'uni-id-invalid-email': '邮箱不合法', + 'uni-id-invalid-nickname': '昵称不合法', + 'uni-id-invalid-param': '参数错误', + 'uni-id-param-required': '缺少参数: {param}', + 'uni-id-get-third-party-account-failed': '获取第三方账号失败', + 'uni-id-get-third-party-user-info-failed': '获取用户信息失败', + 'uni-id-mobile-verify-code-error': '手机验证码错误或已过期', + 'uni-id-email-verify-code-error': '邮箱验证码错误或已过期', + 'uni-id-admin-exists': '超级管理员已存在', + 'uni-id-permission-error': '权限错误', + 'uni-id-system-error': '系统错误', + 'uni-id-set-invite-code-failed': '设置邀请码失败', + 'uni-id-invalid-invite-code': '邀请码不可用', + 'uni-id-change-inviter-forbidden': '禁止修改邀请人', + 'uni-id-bind-conflict': '此账号已被绑定', + 'uni-id-admin-exist-in-other-apps': '超级管理员已在其他控制台注册', + 'uni-id-unbind-failed': '请先绑定后再解绑', + 'uni-id-unbind-not-supported': '不支持解绑', + 'uni-id-unbind-mobile-not-exists': '这是当前唯一登录方式,请绑定手机号后再尝试解绑', + 'uni-id-unbind-password-not-exists': '请先设置密码在尝试解绑', + 'uni-id-unsupported-request': '不支持的请求方式', + 'uni-id-illegal-request': '非法请求' +} + +module.exports = { + ...word, + ...sentence +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/README.md new file mode 100644 index 0000000..47d8c4c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/README.md @@ -0,0 +1,3 @@ +# 说明 + +此目录内为uni-id-co基础能力,不建议直接修改。如果你发现有些逻辑加入会更好,或者此部分代码有Bug可以向我们提交PR,仓库地址:[]()。如果有特殊的需求也可以在[论坛](https://ask.dcloud.net.cn/)提出,我们可以讨论下如何实现。 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/index.js new file mode 100644 index 0000000..dbec081 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/index.js @@ -0,0 +1,16 @@ +const AlipayBase = require('../alipayBase') +const protocols = require('./protocols') +module.exports = class Auth extends AlipayBase { + constructor (options) { + super(options) + this._protocols = protocols + } + + async code2Session (code) { + const result = await this._exec('alipay.system.oauth.token', { + grantType: 'authorization_code', + code + }) + return result + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/protocols.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/protocols.js new file mode 100644 index 0000000..cff351d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/account/protocols.js @@ -0,0 +1,10 @@ +module.exports = { + code2Session: { + // args (fromArgs) { + // return fromArgs + // }, + returnValue: { + openid: 'userId' + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/alipayBase.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/alipayBase.js new file mode 100644 index 0000000..1462b04 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/alipay/alipayBase.js @@ -0,0 +1,231 @@ +const { + camel2snakeJson, + snake2camelJson, + getOffsetDate, + getFullTimeStr +} = require('../../../common/utils') +const crypto = require('crypto') + +const ALIPAY_ALGORITHM_MAPPING = { + RSA: 'RSA-SHA1', + RSA2: 'RSA-SHA256' +} + +module.exports = class AlipayBase { + constructor (options = {}) { + if (!options.appId) throw new Error('appId required') + if (!options.privateKey) throw new Error('privateKey required') + const defaultOptions = { + gateway: 'https://openapi.alipay.com/gateway.do', + timeout: 5000, + charset: 'utf-8', + version: '1.0', + signType: 'RSA2', + timeOffset: -new Date().getTimezoneOffset() / 60, + keyType: 'PKCS8' + } + + if (options.sandbox) { + options.gateway = 'https://openapi.alipaydev.com/gateway.do' + } + + this.options = Object.assign({}, defaultOptions, options) + + const privateKeyType = + this.options.keyType === 'PKCS8' ? 'PRIVATE KEY' : 'RSA PRIVATE KEY' + + this.options.privateKey = this._formatKey( + this.options.privateKey, + privateKeyType + ) + if (this.options.alipayPublicKey) { + this.options.alipayPublicKey = this._formatKey( + this.options.alipayPublicKey, + 'PUBLIC KEY' + ) + } + } + + _formatKey (key, type) { + return `-----BEGIN ${type}-----\n${key}\n-----END ${type}-----` + } + + _formatUrl (url, params) { + let requestUrl = url + // 需要放在 url 中的参数列表 + const urlArgs = [ + 'app_id', + 'method', + 'format', + 'charset', + 'sign_type', + 'sign', + 'timestamp', + 'version', + 'notify_url', + 'return_url', + 'auth_token', + 'app_auth_token' + ] + + for (const key in params) { + if (urlArgs.indexOf(key) > -1) { + const val = encodeURIComponent(params[key]) + requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?' + }${key}=${val}` + // 删除 postData 中对应的数据 + delete params[key] + } + } + + return { execParams: params, url: requestUrl } + } + + _getSign (method, params) { + const bizContent = params.bizContent || null + delete params.bizContent + + const signParams = Object.assign({ + method, + appId: this.options.appId, + charset: this.options.charset, + version: this.options.version, + signType: this.options.signType, + timestamp: getFullTimeStr(getOffsetDate(this.options.timeOffset)) + }, params) + + if (bizContent) { + signParams.bizContent = JSON.stringify(camel2snakeJson(bizContent)) + } + + // params key 驼峰转下划线 + const decamelizeParams = camel2snakeJson(signParams) + + // 排序 + const signStr = Object.keys(decamelizeParams) + .sort() + .map((key) => { + let data = decamelizeParams[key] + if (Array.prototype.toString.call(data) !== '[object String]') { + data = JSON.stringify(data) + } + return `${key}=${data}` + }) + .join('&') + + // 计算签名 + const sign = crypto + .createSign(ALIPAY_ALGORITHM_MAPPING[this.options.signType]) + .update(signStr, 'utf8') + .sign(this.options.privateKey, 'base64') + + return Object.assign(decamelizeParams, { sign }) + } + + async _exec (method, params = {}, option = {}) { + // 计算签名 + const signData = this._getSign(method, params) + const { url, execParams } = this._formatUrl(this.options.gateway, signData) + const { status, data } = await uniCloud.httpclient.request(url, { + method: 'POST', + data: execParams, + // 按 text 返回(为了验签) + dataType: 'text', + timeout: this.options.timeout + }) + if (status !== 200) throw new Error('request fail') + /** + * 示例响应格式 + * {"alipay_trade_precreate_response": + * {"code": "10000","msg": "Success","out_trade_no": "111111","qr_code": "https:\/\/"}, + * "sign": "abcde=" + * } + * 或者 + * {"error_response": + * {"code":"40002","msg":"Invalid Arguments","sub_code":"isv.code-invalid","sub_msg":"授权码code无效"}, + * } + */ + const result = JSON.parse(data) + const responseKey = `${method.replace(/\./g, '_')}_response` + const response = result[responseKey] + const errorResponse = result.error_response + if (response) { + // 按字符串验签 + const validateSuccess = option.validateSign ? this._checkResponseSign(data, responseKey) : true + if (validateSuccess) { + if (!response.code || response.code === '10000') { + const errCode = 0 + const errMsg = response.msg || '' + return { + errCode, + errMsg, + ...snake2camelJson(response) + } + } + const msg = response.sub_code ? `${response.sub_code} ${response.sub_msg}` : `${response.msg || 'unkonwn error'}` + throw new Error(msg) + } else { + throw new Error('check sign error') + } + } else if (errorResponse) { + throw new Error(errorResponse.sub_msg || errorResponse.msg || 'request fail') + } + + throw new Error('request fail') + } + + _checkResponseSign (signStr, responseKey) { + if (!this.options.alipayPublicKey || this.options.alipayPublicKey === '') { + console.warn('options.alipayPublicKey is empty') + // 支付宝公钥不存在时不做验签 + return true + } + + // 带验签的参数不存在时返回失败 + if (!signStr) { return false } + + // 根据服务端返回的结果截取需要验签的目标字符串 + const validateStr = this._getSignStr(signStr, responseKey) + // 服务端返回的签名 + const serverSign = JSON.parse(signStr).sign + + // 参数存在,并且是正常的结果(不包含 sub_code)时才验签 + const verifier = crypto.createVerify(ALIPAY_ALGORITHM_MAPPING[this.options.signType]) + verifier.update(validateStr, 'utf8') + return verifier.verify(this.options.alipayPublicKey, serverSign, 'base64') + } + + _getSignStr (originStr, responseKey) { + // 待签名的字符串 + let validateStr = originStr.trim() + // 找到 xxx_response 开始的位置 + const startIndex = originStr.indexOf(`${responseKey}"`) + // 找到最后一个 “"sign"” 字符串的位置(避免) + const lastIndex = originStr.lastIndexOf('"sign"') + + /** + * 删除 xxx_response 及之前的字符串 + * 假设原始字符串为 + * {"xxx_response":{"code":"10000"},"sign":"jumSvxTKwn24G5sAIN"} + * 删除后变为 + * :{"code":"10000"},"sign":"jumSvxTKwn24G5sAIN"} + */ + validateStr = validateStr.substr(startIndex + responseKey.length + 1) + + /** + * 删除最后一个 "sign" 及之后的字符串 + * 删除后变为 + * :{"code":"10000"}, + * {} 之间就是待验签的字符串 + */ + validateStr = validateStr.substr(0, lastIndex) + + // 删除第一个 { 之前的任何字符 + validateStr = validateStr.replace(/^[^{]*{/g, '{') + + // 删除最后一个 } 之后的任何字符 + validateStr = validateStr.replace(/\}([^}]*)$/g, '}') + + return validateStr + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/account/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/account/index.js new file mode 100644 index 0000000..0e51b4d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/account/index.js @@ -0,0 +1,76 @@ +const rsaPublicKeyPem = require('../rsa-public-key-pem') +let authKeysCache = null + +module.exports = class Auth { + constructor (options) { + this.options = Object.assign({ + baseUrl: 'https://appleid.apple.com', + timeout: 10000 + }, options) + } + + async _fetch (url, options) { + const { baseUrl } = this.options + return uniCloud.httpclient.request(baseUrl + url, options) + } + + async verifyIdentityToken (identityToken) { + // 解密出kid,拿取key + const jwtHeader = identityToken.split('.')[0] + const { kid } = JSON.parse(Buffer.from(jwtHeader, 'base64').toString()) + let authKeys + if (authKeysCache) { + authKeys = authKeysCache + } else { + authKeys = await this.getAuthKeys() + authKeysCache = authKeys + } + const usedKey = authKeys.find(item => item.kid === kid) + + /** + * identityToken 格式 + * + * { + * iss: 'https://appleid.apple.com', + * aud: 'io.dcloud.hellouniapp', + * exp: 1610626724, + * iat: 1610540324, + * sub: '000628.30119d332d9b45a3be4a297f9391fd5c.0403', + * c_hash: 'oFfgewoG36cJX00KUbj45A', + * email: 'x2awmap99s@privaterelay.appleid.com', + * email_verified: 'true', + * is_private_email: 'true', + * auth_time: 1610540324, + * nonce_supported: true + * } + */ + const payload = require('jsonwebtoken').verify( + identityToken, + rsaPublicKeyPem(usedKey.n, usedKey.e), + { + algorithms: usedKey.alg + } + ) + + if (payload.iss !== 'https://appleid.apple.com' || payload.aud !== this.options.bundleId) { + throw new Error('Invalid identity token') + } + + return { + openid: payload.sub, + email: payload.email, + emailVerified: payload.email_verified === 'true', + isPrivateEmail: payload.is_private_email === 'true' + } + } + + async getAuthKeys () { + const { status, data } = await this._fetch('/auth/keys', { + method: 'GET', + dataType: 'json', + timeout: this.options.timeout + }) + if (status !== 200) throw new Error('request https://appleid.apple.com/auth/keys fail') + return data.keys + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/rsa-public-key-pem.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/rsa-public-key-pem.js new file mode 100644 index 0000000..e1dbb31 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/apple/rsa-public-key-pem.js @@ -0,0 +1,64 @@ +// http://stackoverflow.com/questions/18835132/xml-to-pem-in-node-js +/* eslint-disable camelcase */ +function rsaPublicKeyPem (modulus_b64, exponent_b64) { + const modulus = Buffer.from(modulus_b64, 'base64') + const exponent = Buffer.from(exponent_b64, 'base64') + + let modulus_hex = modulus.toString('hex') + let exponent_hex = exponent.toString('hex') + + modulus_hex = prepadSigned(modulus_hex) + exponent_hex = prepadSigned(exponent_hex) + + const modlen = modulus_hex.length / 2 + const explen = exponent_hex.length / 2 + + const encoded_modlen = encodeLengthHex(modlen) + const encoded_explen = encodeLengthHex(explen) + const encoded_pubkey = '30' + + encodeLengthHex( + modlen + + explen + + encoded_modlen.length / 2 + + encoded_explen.length / 2 + 2 + ) + + '02' + encoded_modlen + modulus_hex + + '02' + encoded_explen + exponent_hex + + const der_b64 = Buffer.from(encoded_pubkey, 'hex').toString('base64') + + const pem = '-----BEGIN RSA PUBLIC KEY-----\n' + + der_b64.match(/.{1,64}/g).join('\n') + + '\n-----END RSA PUBLIC KEY-----\n' + + return pem +} + +function prepadSigned (hexStr) { + const msb = hexStr[0] + if (msb < '0' || msb > '7') { + return '00' + hexStr + } else { + return hexStr + } +} + +function toHex (number) { + const nstr = number.toString(16) + if (nstr.length % 2) return '0' + nstr + return nstr +} + +// encode ASN.1 DER length field +// if <=127, short form +// if >=128, long form +function encodeLengthHex (n) { + if (n <= 127) return toHex(n) + else { + const n_hex = toHex(n) + const length_of_length_byte = 128 + n_hex.length / 2 // 0x80+numbytes + return toHex(length_of_length_byte) + n_hex + } +} + +module.exports = rsaPublicKeyPem diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/index.js new file mode 100644 index 0000000..149c7de --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/index.js @@ -0,0 +1,36 @@ +const WxAccount = require('./weixin/account/index') +const QQAccount = require('./qq/account/index') +const AliAccount = require('./alipay/account/index') +const AppleAccount = require('./apple/account/index') + +const createApi = require('./share/create-api') + +module.exports = { + initWeixin: function () { + const oauthConfig = this.configUtils.getOauthConfig({ provider: 'weixin' }) + return createApi(WxAccount, { + appId: oauthConfig.appid, + secret: oauthConfig.appsecret + }) + }, + initQQ: function () { + const oauthConfig = this.configUtils.getOauthConfig({ provider: 'qq' }) + return createApi(QQAccount, { + appId: oauthConfig.appid, + secret: oauthConfig.appsecret + }) + }, + initAlipay: function () { + const oauthConfig = this.configUtils.getOauthConfig({ provider: 'alipay' }) + return createApi(AliAccount, { + appId: oauthConfig.appid, + privateKey: oauthConfig.privateKey + }) + }, + initApple: function () { + const oauthConfig = this.configUtils.getOauthConfig({ provider: 'apple' }) + return createApi(AppleAccount, { + bundleId: oauthConfig.bundleId + }) + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/index.js new file mode 100644 index 0000000..9b4879a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/index.js @@ -0,0 +1,97 @@ +const { + UniCloudError +} = require('../../../../common/error') +const { + resolveUrl +} = require('../../../../common/utils') +const { + callQQOpenApi +} = require('../normalize') + +module.exports = class Auth { + constructor (options) { + this.options = Object.assign({ + baseUrl: 'https://graph.qq.com', + timeout: 5000 + }, options) + } + + async _requestQQOpenapi ({ name, url, data, options }) { + const defaultOptions = { + method: 'GET', + dataType: 'json', + dataAsQueryString: true, + timeout: this.options.timeout + } + const result = await callQQOpenApi({ + name: `auth.${name}`, + url: resolveUrl(this.options.baseUrl, url), + data, + options, + defaultOptions + }) + return result + } + + async getUserInfo ({ + accessToken, + openid + } = {}) { + const url = '/user/get_user_info' + const result = await this._requestQQOpenapi({ + name: 'getUserInfo', + url, + data: { + oauthConsumerKey: this.options.appId, + accessToken, + openid + } + }) + return { + nickname: result.nickname, + avatar: result.figureurl_qq_1 + } + } + + async getOpenidByToken ({ + accessToken + } = {}) { + const url = '/oauth2.0/me' + const result = await this._requestQQOpenapi({ + name: 'getOpenidByToken', + url, + data: { + accessToken, + unionid: 1, + fmt: 'json' + } + }) + if (result.clientId !== this.options.appId) { + throw new UniCloudError({ + code: 'APPID_NOT_MATCH', + message: 'appid not match' + }) + } + return { + openid: result.openid, + unionid: result.unionid + } + } + + async code2Session ({ + code + } = {}) { + const url = 'https://api.q.qq.com/sns/jscode2session' + const result = await this._requestQQOpenapi({ + name: 'getOpenidByToken', + url, + data: { + grant_type: 'authorization_code', + appid: this.options.appId, + secret: this.options.secret, + js_code: code + } + }) + return result + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/protocol.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/account/protocol.js new file mode 100644 index 0000000..e69de29 diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/normalize.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/normalize.js new file mode 100644 index 0000000..fcfdc1e --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/qq/normalize.js @@ -0,0 +1,85 @@ +const { + UniCloudError +} = require('../../../common/error') +const { + camel2snakeJson, + snake2camelJson +} = require('../../../common/utils') + +function generateApiResult (apiName, data) { + if (data.ret || data.error) { + // 这三种都是qq的错误码规范 + const code = data.ret || data.error || data.errcode || -2 + const message = data.msg || data.error_description || data.errmsg || `${apiName} fail` + throw new UniCloudError({ + code, + message + }) + } else { + delete data.ret + delete data.msg + delete data.error + delete data.error_description + delete data.errcode + delete data.errmsg + return { + ...data, + errMsg: `${apiName} ok`, + errCode: 0 + } + } +} + +function nomalizeError (apiName, error) { + throw new UniCloudError({ + code: error.code || -2, + message: error.message || `${apiName} fail` + }) +} + +async function callQQOpenApi ({ + name, + url, + data, + options, + defaultOptions +}) { + options = Object.assign({}, defaultOptions, options, { data: camel2snakeJson(Object.assign({}, data)) }) + let result + try { + result = await uniCloud.httpclient.request(url, options) + } catch (e) { + return nomalizeError(name, e) + } + let resData = result.data + const contentType = result.headers['content-type'] + if ( + Buffer.isBuffer(resData) && + (contentType.indexOf('text/plain') === 0 || + contentType.indexOf('application/json') === 0) + ) { + try { + resData = JSON.parse(resData.toString()) + } catch (e) { + resData = resData.toString() + } + } else if (Buffer.isBuffer(resData)) { + resData = { + buffer: resData, + contentType + } + } + return snake2camelJson( + generateApiResult( + name, + resData || { + errCode: -2, + errMsg: 'Request failed' + } + ) + ) +} + +module.exports = { + callQQOpenApi +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/share/create-api.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/share/create-api.js new file mode 100644 index 0000000..c58f1e8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/share/create-api.js @@ -0,0 +1,73 @@ +const { + isFn, + isPlainObject +} = require('../../../common/utils') + +// 注意:不进行递归处理 +function parseParams (params = {}, rule) { + if (!rule || !params) { + return params + } + const internalKeys = ['_pre', '_purify', '_post'] + // 转换之前的处理 + if (rule._pre) { + params = rule._pre(params) + } + // 净化参数 + let purify = { shouldDelete: new Set([]) } + if (rule._purify) { + const _purify = rule._purify + for (const purifyKey in _purify) { + _purify[purifyKey] = new Set(_purify[purifyKey]) + } + purify = Object.assign(purify, _purify) + } + if (isPlainObject(rule)) { + for (const key in rule) { + const parser = rule[key] + if (isFn(parser) && internalKeys.indexOf(key) === -1) { + params[key] = parser(params) + } else if (typeof parser === 'string' && internalKeys.indexOf(key) === -1) { + // 直接转换属性名称的删除旧属性名 + params[key] = params[parser] + purify.shouldDelete.add(parser) + } + } + } else if (isFn(rule)) { + params = rule(params) + } + + if (purify.shouldDelete) { + for (const item of purify.shouldDelete) { + delete params[item] + } + } + + // 转换之后的处理 + if (rule._post) { + params = rule._post(params) + } + + return params +} + +function createApi (ApiClass, options) { + const apiInstance = new ApiClass(options) + return new Proxy(apiInstance, { + get: function (obj, prop) { + if (typeof obj[prop] === 'function' && prop.indexOf('_') !== 0 && obj._protocols && obj._protocols[prop]) { + const protocol = obj._protocols[prop] + return async function (params) { + params = parseParams(params, protocol.args) + let result = await obj[prop](params) + result = parseParams(result, protocol.returnValue) + return result + } + } else { + return obj[prop] + } + } + }) +} + +module.exports = createApi diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/account/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/account/index.js new file mode 100644 index 0000000..7ecea84 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/account/index.js @@ -0,0 +1,111 @@ +const { + callWxOpenApi, + buildUrl +} = require('../normalize') + +module.exports = class Auth { + constructor (options) { + this.options = Object.assign({ + baseUrl: 'https://api.weixin.qq.com', + timeout: 5000 + }, options) + } + + async _requestWxOpenapi ({ name, url, data, options }) { + const defaultOptions = { + method: 'GET', + dataType: 'json', + dataAsQueryString: true, + timeout: this.options.timeout + } + const result = await callWxOpenApi({ + name: `auth.${name}`, + url: `${this.options.baseUrl}${buildUrl(url, data)}`, + data, + options, + defaultOptions + }) + return result + } + + async code2Session (code) { + const url = '/sns/jscode2session' + const result = await this._requestWxOpenapi({ + name: 'code2Session', + url, + data: { + grant_type: 'authorization_code', + appid: this.options.appId, + secret: this.options.secret, + js_code: code + } + }) + return result + } + + async getOauthAccessToken (code) { + const url = '/sns/oauth2/access_token' + const result = await this._requestWxOpenapi({ + name: 'getOauthAccessToken', + url, + data: { + grant_type: 'authorization_code', + appid: this.options.appId, + secret: this.options.secret, + code + } + }) + if (result.expiresIn) { + result.expired = Date.now() + result.expiresIn * 1000 + // delete result.expiresIn + } + return result + } + + async getUserInfo ({ + accessToken, + openid + } = {}) { + const url = '/sns/userinfo' + const { + nickname, + headimgurl: avatar + } = await this._requestWxOpenapi({ + name: 'getUserInfo', + url, + data: { + accessToken, + openid, + appid: this.options.appId, + secret: this.options.secret, + scope: 'snsapi_userinfo' + } + }) + return { + nickname, + avatar + } + } + + async getPhoneNumber (accessToken, code) { + const url = `/wxa/business/getuserphonenumber?access_token=${accessToken}` + const { phoneInfo } = await this._requestWxOpenapi({ + name: 'getPhoneNumber', + url, + data: { + code + }, + options: { + method: 'POST', + dataAsQueryString: false, + headers: { + 'content-type': 'application/json' + } + } + }) + + return { + purePhoneNumber: phoneInfo.purePhoneNumber + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/normalize.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/normalize.js new file mode 100644 index 0000000..908d916 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/normalize.js @@ -0,0 +1,95 @@ +const { + UniCloudError +} = require('../../../common/error') +const { + camel2snakeJson, snake2camelJson +} = require('../../../common/utils') + +function generateApiResult (apiName, data) { + if (data.errcode) { + throw new UniCloudError({ + code: data.errcode || -2, + message: data.errmsg || `${apiName} fail` + }) + } else { + delete data.errcode + delete data.errmsg + return { + ...data, + errMsg: `${apiName} ok`, + errCode: 0 + } + } +} + +function nomalizeError (apiName, error) { + throw new UniCloudError({ + code: error.code || -2, + message: error.message || `${apiName} fail` + }) +} + +// 微信openapi接口接收蛇形(snake case)参数返回蛇形参数,这里进行转化,如果是formdata里面的参数需要在对应api实现时就转为蛇形 +async function callWxOpenApi ({ + name, + url, + data, + options, + defaultOptions +}) { + let result = {} + // 获取二维码的接口wxacode.get和wxacode.getUnlimited不可以传入access_token(可能有其他接口也不可以),否则会返回data format error + const dataCopy = camel2snakeJson(Object.assign({}, data)) + if (dataCopy && dataCopy.access_token) { + delete dataCopy.access_token + } + try { + options = Object.assign({}, defaultOptions, options, { data: dataCopy }) + result = await uniCloud.httpclient.request(url, options) + } catch (e) { + return nomalizeError(name, e) + } + + // 有几个接口成功返回buffer失败返回json,对这些接口统一成返回buffer,然后分别解析 + let resData = result.data + const contentType = result.headers['content-type'] + if ( + Buffer.isBuffer(resData) && + (contentType.indexOf('text/plain') === 0 || + contentType.indexOf('application/json') === 0) + ) { + try { + resData = JSON.parse(resData.toString()) + } catch (e) { + resData = resData.toString() + } + } else if (Buffer.isBuffer(resData)) { + resData = { + buffer: resData, + contentType + } + } + return snake2camelJson( + generateApiResult( + name, + resData || { + errCode: -2, + errMsg: 'Request failed' + } + ) + ) +} + +function buildUrl (url, data) { + let query = '' + if (data && data.accessToken) { + const divider = url.indexOf('?') > -1 ? '&' : '?' + query = `${divider}access_token=${data.accessToken}` + } + return `${url}${query}` +} + +module.exports = { + callWxOpenApi, + buildUrl +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/utils.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/utils.js new file mode 100644 index 0000000..c141016 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/third-party/weixin/utils.js @@ -0,0 +1,87 @@ +const crypto = require('crypto') +const { + isPlainObject +} = require('../../../common/utils') + +// 退款通知解密key=md5(key) +function decryptData (encryptedData, key, iv = '') { + // 解密 + const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv) + // 设置自动 padding 为 true,删除填充补位 + decipher.setAutoPadding(true) + let decoded = decipher.update(encryptedData, 'base64', 'utf8') + decoded += decipher.final('utf8') + return decoded +} + +function md5 (str, encoding = 'utf8') { + return crypto + .createHash('md5') + .update(str, encoding) + .digest('hex') +} + +function sha256 (str, key, encoding = 'utf8') { + return crypto + .createHmac('sha256', key) + .update(str, encoding) + .digest('hex') +} + +function getSignStr (obj) { + return Object.keys(obj) + .filter(key => key !== 'sign' && obj[key] !== undefined && obj[key] !== '') + .sort() + .map(key => key + '=' + obj[key]) + .join('&') +} + +function getNonceStr (length = 16) { + let str = '' + while (str.length < length) { + str += Math.random().toString(32).substring(2) + } + return str.substring(0, length) +} + +// 简易版Object转XML,只可在微信支付时使用,不支持嵌套 +function buildXML (obj, rootName = 'xml') { + const content = Object.keys(obj).map(item => { + if (isPlainObject(obj[item])) { + return `<${item}>` + } else { + return `<${item}>` + } + }) + return `<${rootName}>${content.join('')}` +} + +function isXML (str) { + const reg = /^(<\?xml.*\?>)?(\r?\n)*(.|\r?\n)*<\/xml>$/i + return reg.test(str.trim()) +}; + +// 简易版XML转Object,只可在微信支付时使用,不支持嵌套 +function parseXML (xml) { + const xmlReg = /<(?:xml|root).*?>([\s|\S]*)<\/(?:xml|root)>/ + const str = xmlReg.exec(xml)[1] + const obj = {} + const nodeReg = /<(.*?)>(?:){0,1}<\/.*?>/g + let matches = null + // eslint-disable-next-line no-cond-assign + while ((matches = nodeReg.exec(str))) { + obj[matches[1]] = matches[2] + } + return obj +} + +module.exports = { + decryptData, + md5, + sha256, + getSignStr, + getNonceStr, + buildXML, + parseXML, + isXML +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js new file mode 100644 index 0000000..36a7cbf --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js @@ -0,0 +1,97 @@ +const { + db, + dbCmd, + userCollection +} = require('../../common/constants') +const { + USER_IDENTIFIER +} = require('../../common/constants') +const { + batchFindObjctValue, + getType, + isMatchUserApp +} = require('../../common/utils') + +/** + * 查询满足条件的用户 + * @param {Object} params + * @param {Object} params.userQuery 用户唯一标识组成的查询条件 + * @param {Object} params.authorizedApp 用户允许登录的应用 + * @returns userMatched 满足条件的用户列表 + */ +async function findUser (params = {}) { + const { + userQuery, + authorizedApp = [] + } = params + const condition = getUserQueryCondition(userQuery) + if (condition.length === 0) { + throw new Error('Invalid user query') + } + const authorizedAppType = getType(authorizedApp) + if (authorizedAppType !== 'string' && authorizedAppType !== 'array') { + throw new Error('Invalid authorized app') + } + + let finalQuery + + if (condition.length === 1) { + finalQuery = condition[0] + } else { + finalQuery = dbCmd.or(condition) + } + const userQueryRes = await userCollection.where(finalQuery).get() + return { + total: userQueryRes.data.length, + userMatched: userQueryRes.data.filter(item => { + return isMatchUserApp(item.dcloud_appid, authorizedApp) + }) + } +} + +function getUserIdentifier (userRecord = {}) { + const keys = Object.keys(USER_IDENTIFIER) + return batchFindObjctValue(userRecord, keys) +} + +function getUserQueryCondition (userRecord = {}) { + const userIdentifier = getUserIdentifier(userRecord) + const condition = [] + for (const key in userIdentifier) { + const value = userIdentifier[key] + if (!value) { + // 过滤所有value为假值的条件,在查询用户时没有意义 + continue + } + const queryItem = { + [key]: value + } + // 为兼容用户老数据用户名及邮箱需要同时查小写及原始大小写数据 + if (key === 'mobile') { + queryItem.mobile_confirmed = 1 + } else if (key === 'email') { + queryItem.email_confirmed = 1 + const email = userIdentifier.email + if (email.toLowerCase() !== email) { + condition.push({ + email: email.toLowerCase(), + email_confirmed: 1 + }) + } + } else if (key === 'username') { + const username = userIdentifier.username + if (username.toLowerCase() !== username) { + condition.push({ + username: username.toLowerCase() + }) + } + } + condition.push(queryItem) + } + return condition +} + +module.exports = { + findUser, + getUserIdentifier +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/captcha.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/captcha.js new file mode 100644 index 0000000..0dd620e --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/captcha.js @@ -0,0 +1,76 @@ +const { + ERROR +} = require('../../common/error') + +async function getNeedCaptcha ({ + uid, + username, + mobile, + email, + type = 'login', + limitDuration = 7200000, // 两小时 + limitTimes = 3 // 记录次数 +} = {}) { + const db = uniCloud.database() + const dbCmd = db.command + // 当用户最近“2小时内(limitDuration)”登录失败达到3次(limitTimes)时。要求用户提交验证码 + const now = Date.now() + const uniIdLogCollection = db.collection('uni-id-log') + const userIdentifier = { + user_id: uid, + username, + mobile, + email + } + + let totalKey = 0; let deleteKey = 0 + for (const key in userIdentifier) { + totalKey++ + if (!userIdentifier[key] || typeof userIdentifier[key] !== 'string') { + deleteKey++ + delete userIdentifier[key] + } + } + + if (deleteKey === totalKey) { + throw new Error('System error') // 正常情况下不会进入此条件,但是考虑到后续会有其他开发者修改此云对象,在此处做一个判断 + } + + const { + data: recentRecord + } = await uniIdLogCollection.where({ + ip: this.getUniversalClientInfo().clientIP, + ...userIdentifier, + type, + create_date: dbCmd.gt(now - limitDuration) + }) + .orderBy('create_date', 'desc') + .limit(limitTimes) + .get() + return recentRecord.length === limitTimes && recentRecord.every(item => item.state === 0) +} + +async function verifyCaptcha (params = {}) { + const { + captcha, + scene + } = params + if (!captcha) { + throw { + errCode: ERROR.CAPTCHA_REQUIRED + } + } + const payload = await this.uniCaptcha.verify({ + deviceId: this.getUniversalClientInfo().deviceId, + captcha, + scene + }) + if (payload.errCode) { + throw payload + } +} + +module.exports = { + getNeedCaptcha, + verifyCaptcha +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js new file mode 100644 index 0000000..48d5688 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js @@ -0,0 +1,135 @@ +const { + getWeixinPlatform +} = require('./weixin') +const createConfig = require('uni-config-center') + +const requiredConfig = { + 'web.weixin-h5': ['appid', 'appsecret'], + 'web.weixin-web': ['appid', 'appsecret'], + 'app.weixin': ['appid', 'appsecret'], + 'mp-weixin.weixin': ['appid', 'appsecret'], + 'app.qq': ['appid', 'appsecret'], + 'mp-alipay.alipay': ['appid', 'privateKey'], + 'app.apple': ['bundleId'] +} + +const uniIdConfig = createConfig({ + pluginId: 'uni-id' +}) + +class ConfigUtils { + constructor ({ + context + } = {}) { + this.context = context + this.clientInfo = context.getUniversalClientInfo() + const { + appId, + uniPlatform + } = this.clientInfo + this.appId = appId + switch (uniPlatform) { + case 'app': + case 'app-plus': + this.platform = 'app' + break + case 'web': + case 'h5': + this.platform = 'web' + break + default: + this.platform = uniPlatform + break + } + } + + getConfigArray () { + let configContent + try { + configContent = require('uni-config-center/uni-id/config.json') + } catch (error) { + throw new Error('Invalid config file\n' + error.message) + } + if (configContent[0]) { + return Object.values(configContent) + } + configContent.isDefaultConfig = true + return [configContent] + } + + getAppConfig () { + const configArray = this.getConfigArray() + return configArray.find(item => item.dcloudAppid === this.appId) || configArray.find(item => item.isDefaultConfig) + } + + getPlatformConfig () { + const appConfig = this.getAppConfig() + if (!appConfig) { + throw new Error( + `Config for current app (${this.appId}) was not found, please check your config file or client appId`) + } + const platform = this.platform + if ( + (this.platform === 'app' && appConfig['app-plus']) || + (this.platform === 'web' && appConfig.h5) + ) { + throw new Error( + `Client platform is ${this.platform}, but ${this.platform === 'web' ? 'h5' : 'app-plus'} was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary?id=m-to-co` + ) + } + + const defaultConfig = { + tokenExpiresIn: 7200, + tokenExpiresThreshold: 1200, + passwordErrorLimit: 6, + passwordErrorRetryTime: 3600 + } + return Object.assign(defaultConfig, appConfig, appConfig[platform]) + } + + getOauthProvider ({ + provider + } = {}) { + const clientPlatform = this.platform + let oatuhProivder = provider + if (provider === 'weixin' && clientPlatform === 'web') { + const weixinPlatform = getWeixinPlatform.call(this.context) + if (weixinPlatform === 'h5' || weixinPlatform === 'web') { + oatuhProivder = 'weixin-' + weixinPlatform // weixin-h5 公众号,weixin-web pc端 + } + } + return oatuhProivder + } + + getOauthConfig ({ + provider + } = {}) { + const config = this.getPlatformConfig() + const clientPlatform = this.platform + const oatuhProivder = this.getOauthProvider({ + provider + }) + const requireConfigKey = requiredConfig[`${clientPlatform}.${oatuhProivder}`] || [] + if (!config.oauth || !config.oauth[oatuhProivder]) { + throw new Error(`Config param required: ${clientPlatform}.oauth.${oatuhProivder}`) + } + const oauthConfig = config.oauth[oatuhProivder] + requireConfigKey.forEach((item) => { + if (!oauthConfig[item]) { + throw new Error(`Config param required: ${clientPlatform}.oauth.${oatuhProivder}.${item}`) + } + }) + return oauthConfig + } + + getHooks () { + if (uniIdConfig.hasFile('hooks/index.js')) { + return require( + uniIdConfig.resolve('hooks/index.js') + ) + } + return {} + } +} + +module.exports = ConfigUtils diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/fission.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/fission.js new file mode 100644 index 0000000..84233c3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/fission.js @@ -0,0 +1,192 @@ +const { + dbCmd, + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +/** + * 获取随机邀请码,邀请码由大写字母加数字组成,由于存在手动输入邀请码的场景,从可选字符中去除 0、1、I、O + * @param {number} len 邀请码长度,默认6位 + * @returns {string} 随机邀请码 + */ +function getRandomInviteCode (len = 6) { + const charArr = ['2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] + let code = '' + for (let i = 0; i < len; i++) { + code += charArr[Math.floor(Math.random() * charArr.length)] + } + return code +} + +/** + * 获取可用的邀请码,至多尝试十次以获取可用邀请码。从10亿可选值中随机,碰撞概率较低 + * 也有其他方案可以尝试,比如在数据库内设置一个从0开始计数的数字,每次调用此方法时使用updateAndReturn使数字加1并返回加1后的值,根据这个值生成对应的邀请码,比如(22222A + 1 == 22222B),此方式性能理论更好,但是不适用于旧项目 + * @param {object} param + * @param {string} param.inviteCode 初始随机邀请码 + */ +async function getValidInviteCode () { + let retry = 10 + let code + let codeValid = false + while (retry > 0 && !codeValid) { + retry-- + code = getRandomInviteCode() + const getUserRes = await userCollection.where({ + my_invite_code: code + }).limit(1).get() + if (getUserRes.data.length === 0) { + codeValid = true + break + } + } + if (!codeValid) { + throw { + errCode: ERROR.SET_INVITE_CODE_FAILED + } + } + return code +} + +/** + * 根据邀请码查询邀请人 + * @param {object} param + * @param {string} param.inviteCode 邀请码 + * @param {string} param.queryUid 受邀人id,非空时校验不可被下家或自己邀请 + * @returns + */ +async function findUserByInviteCode ({ + inviteCode, + queryUid +} = {}) { + if (typeof inviteCode !== 'string') { + throw { + errCode: ERROR.SYSTEM_ERROR + } + } + // 根据邀请码查询邀请人 + let getInviterRes + if (queryUid) { + getInviterRes = await userCollection.where({ + _id: dbCmd.neq(queryUid), + inviter_uid: dbCmd.not(dbCmd.all([queryUid])), + my_invite_code: inviteCode + }).get() + } else { + getInviterRes = await userCollection.where({ + my_invite_code: inviteCode + }).get() + } + if (getInviterRes.data.length > 1) { + // 正常情况下不可能进入此条件,以防用户自行修改数据库出错,在此做出判断 + throw { + errCode: ERROR.SYSTEM_ERROR + } + } + const inviterRecord = getInviterRes.data[0] + if (!inviterRecord) { + throw { + errCode: ERROR.INVALID_INVITE_CODE + } + } + return inviterRecord +} + +/** + * 根据邀请码生成邀请信息 + * @param {object} param + * @param {string} param.inviteCode 邀请码 + * @param {string} param.queryUid 受邀人id,非空时校验不可被下家或自己邀请 + * @returns + */ +async function generateInviteInfo ({ + inviteCode, + queryUid +} = {}) { + const inviterRecord = await findUserByInviteCode({ + inviteCode, + queryUid + }) + // 倒叙拼接当前用户邀请链 + const inviterUid = inviterRecord.inviter_uid || [] + inviterUid.unshift(inviterRecord._id) + return { + inviterUid, + inviteTime: Date.now() + } +} + +/** + * 检查当前用户是否可以接受邀请,如果可以返回用户记录 + * @param {string} uid + */ +async function checkInviteInfo (uid) { + // 检查当前用户是否已有邀请人 + const getUserRes = await userCollection.doc(uid).field({ + my_invite_code: true, + inviter_uid: true + }).get() + const userRecord = getUserRes.data[0] + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + if (userRecord.inviter_uid && userRecord.inviter_uid.length > 0) { + throw { + errCode: ERROR.CHANGE_INVITER_FORBIDDEN + } + } + return userRecord +} + +/** + * 指定用户接受邀请码邀请 + * @param {object} param + * @param {string} param.uid 用户uid + * @param {string} param.inviteCode 邀请人的邀请码 + * @returns + */ +async function acceptInvite ({ + uid, + inviteCode +} = {}) { + await checkInviteInfo(uid) + const { + inviterUid, + inviteTime + } = await generateInviteInfo({ + inviteCode, + queryUid: uid + }) + + if (inviterUid === uid) { + throw { + errCode: ERROR.INVALID_INVITE_CODE + } + } + + // 更新当前用户的邀请人信息 + await userCollection.doc(uid).update({ + inviter_uid: inviterUid, + invite_time: inviteTime + }) + + // 更新当前用户邀请的用户的邀请人信息,这步可能较为耗时 + await userCollection.where({ + inviter_uid: uid + }).update({ + inviter_uid: dbCmd.push(inviterUid) + }) + + return { + errCode: 0, + errMsg: '' + } +} + +module.exports = { + acceptInvite, + generateInviteInfo, + getValidInviteCode +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js new file mode 100644 index 0000000..6f863bc --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js @@ -0,0 +1,240 @@ +const { + findUser +} = require('./account') +const { + userCollection, + LOG_TYPE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + logout +} = require('./logout') +const PasswordUtils = require('./password') + +async function realPreLogin (params = {}) { + const { + user + } = params + const appId = this.getUniversalClientInfo().appId + const { + total, + userMatched + } = await findUser({ + userQuery: user, + authorizedApp: appId + }) + if (userMatched.length === 0) { + if (total > 0) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS_IN_CURRENT_APP + } + } + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } else if (userMatched.length > 1) { + throw { + errCode: ERROR.ACCOUNT_CONFLICT + } + } + const userRecord = userMatched[0] + checkLoginUserRecord(userRecord) + return userRecord +} + +async function preLogin (params = {}) { + const { + user + } = params + try { + const user = await realPreLogin.call(this, params) + return user + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + data: user, + type: LOG_TYPE.LOGIN + }) + throw error + } +} + +async function preLoginWithPassword (params = {}) { + const { + user, + password + } = params + try { + const userRecord = await realPreLogin.call(this, params) + const { + passwordErrorLimit, + passwordErrorRetryTime + } = this.config + const { + clientIP + } = this.getUniversalClientInfo() + // 根据ip地址,密码错误次数过多,锁定登录 + let loginIPLimit = userRecord.login_ip_limit || [] + // 清理无用记录 + loginIPLimit = loginIPLimit.filter(item => item.last_error_time > Date.now() - passwordErrorRetryTime * 1000) + let currentIPLimit = loginIPLimit.find(item => item.ip === clientIP) + if (currentIPLimit && currentIPLimit.error_times >= passwordErrorLimit) { + throw { + errCode: ERROR.PASSWORD_ERROR_EXCEED_LIMIT + } + } + const passwordUtils = new PasswordUtils({ + userRecord, + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }) + + const { + success: checkPasswordSuccess, + refreshPasswordInfo + } = passwordUtils.checkUserPassword({ + password + }) + if (!checkPasswordSuccess) { + // 更新用户ip对应的密码错误记录 + if (!currentIPLimit) { + currentIPLimit = { + ip: clientIP, + error_times: 1, + last_error_time: Date.now() + } + loginIPLimit.push(currentIPLimit) + } else { + currentIPLimit.error_times++ + currentIPLimit.last_error_time = Date.now() + } + await userCollection.doc(userRecord._id).update({ + login_ip_limit: loginIPLimit + }) + throw { + errCode: ERROR.PASSWORD_ERROR + } + } + const extraData = {} + if (refreshPasswordInfo) { + extraData.password = refreshPasswordInfo.passwordHash + extraData.password_secret_version = refreshPasswordInfo.version + } + + const currentIPLimitIndex = loginIPLimit.indexOf(currentIPLimit) + if (currentIPLimitIndex > -1) { + loginIPLimit.splice(currentIPLimitIndex, 1) + } + extraData.login_ip_limit = loginIPLimit + return { + user: userRecord, + extraData + } + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + data: user, + type: LOG_TYPE.LOGIN + }) + throw error + } +} + +function checkLoginUserRecord (user) { + switch (user.status) { + case undefined: + case 0: + break + case 1: + throw { + errCode: ERROR.ACCOUNT_BANNED + } + case 2: + throw { + errCode: ERROR.ACCOUNT_AUDITING + } + case 3: + throw { + errCode: ERROR.ACCOUNT_AUDIT_FAILED + } + case 4: + throw { + errCode: ERROR.ACCOUNT_CLOSED + } + default: + break + } +} + +async function thirdPartyLogin (params = {}) { + const { + user + } = params + return { + mobileComfirmd: user.mobile_comfirmd, + emailComfirmd: user.email_comfirmd + } +} + +async function postLogin (params = {}) { + const { + user, + extraData, + isThirdParty = false + } = params + const { + clientIP + } = this.getUniversalClientInfo() + const uniIdToken = this.getUniversalUniIdToken() + const uid = user._id + const updateData = { + last_login_date: Date.now(), + last_login_ip: clientIP, + ...extraData + } + const { + token, + tokenExpired + } = await this.uniIdCommon.createToken({ + uid + }) + + if (uniIdToken) { + try { + await logout.call(this) + } catch (error) {} + } + + await userCollection.doc(uid).update(updateData) + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: LOG_TYPE.LOGIN + }) + return { + errCode: 0, + newToken: { + token, + tokenExpired + }, + uid, + ...( + isThirdParty + ? thirdPartyLogin({ + user + }) + : {} + ), + passwordConfirmed: !!user.password + } +} + +module.exports = { + preLogin, + postLogin, + checkLoginUserRecord, + preLoginWithPassword +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js new file mode 100644 index 0000000..ddcbb97 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js @@ -0,0 +1,49 @@ +const { + dbCmd, + LOG_TYPE, + deviceCollection, + userCollection +} = require('../../common/constants') + +async function logout () { + const { + deviceId + } = this.getUniversalClientInfo() + const uniIdToken = this.getUniversalUniIdToken() + const payload = await this.uniIdCommon.checkToken( + uniIdToken, + { + autoRefresh: false + } + ) + if (payload.errCode) { + throw payload + } + const uid = payload.uid + + // 删除token + await userCollection.doc(uid).update({ + token: dbCmd.pull(uniIdToken) + }) + + // 仅当device表的device_id和user_id均对应时才进行更新 + await deviceCollection.where({ + device_id: deviceId, + user_id: uid + }).update({ + token_expired: 0 + }) + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: LOG_TYPE.LOGOUT + }) + return { + errCode: 0 + } +} + +module.exports = { + logout +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/password.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/password.js new file mode 100644 index 0000000..0e46757 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/password.js @@ -0,0 +1,261 @@ +const { + getType +} = require('../../common/utils') +const crypto = require('crypto') +const createConfig = require('uni-config-center') +const shareConfig = createConfig({ + pluginId: 'uni-id' +}) +let customPassword = {} +if (shareConfig.hasFile('custom-password.js')) { + customPassword = shareConfig.requireFile('custom-password.js') || {} +} + +const passwordAlgorithmMap = { + UNI_ID_HMAC_SHA1: 'hmac-sha1', + UNI_ID_HMAC_SHA256: 'hmac-sha256', + UNI_ID_CUSTOM: 'custom' +} + +const passwordAlgorithmKeyMap = Object.keys(passwordAlgorithmMap).reduce((res, item) => { + res[passwordAlgorithmMap[item]] = item + return res +}, {}) + +const passwordExtMethod = { + [passwordAlgorithmMap.UNI_ID_HMAC_SHA1]: { + verify ({ password }) { + const { password_secret_version: passwordSecretVersion } = this.userRecord + + const passwordSecret = this._getSecretByVersion({ + version: passwordSecretVersion + }) + + const { passwordHash } = this.encrypt({ + password, + passwordSecret + }) + + return passwordHash === this.userRecord.password + }, + encrypt ({ password, passwordSecret }) { + const { value: secret, version } = passwordSecret + const hmac = crypto.createHmac('sha1', secret.toString('ascii')) + + hmac.update(password) + + return { + passwordHash: hmac.digest('hex'), + version + } + } + }, + [passwordAlgorithmMap.UNI_ID_HMAC_SHA256]: { + verify ({ password }) { + const parse = this._parsePassword() + const passwordHash = crypto.createHmac(parse.algorithm, parse.salt).update(password).digest('hex') + + return passwordHash === parse.hash + }, + encrypt ({ password, passwordSecret }) { + const { version } = passwordSecret + + // 默认使用 sha256 加密算法 + const salt = crypto.randomBytes(10).toString('hex') + const sha256Hash = crypto.createHmac(passwordAlgorithmMap.UNI_ID_HMAC_SHA256.substring(5), salt).update(password).digest('hex') + const algorithm = passwordAlgorithmKeyMap[passwordAlgorithmMap.UNI_ID_HMAC_SHA256] + // B 为固定值,对应 PasswordMethodMaps 中的 sha256算法 + // hash 格式 $[PasswordMethodFlagMapsKey]$[salt size]$[salt][Hash] + const passwordHash = `$${algorithm}$${salt.length}$${salt}${sha256Hash}` + + return { + passwordHash, + version + } + } + }, + [passwordAlgorithmMap.UNI_ID_CUSTOM]: { + verify ({ password, passwordSecret }) { + if (!customPassword.verifyPassword) throw new Error('verifyPassword method not found in custom password file') + + // return true or false + return customPassword.verifyPassword({ + password, + passwordSecret, + userRecord: this.userRecord, + clientInfo: this.clientInfo + }) + }, + encrypt ({ password, passwordSecret }) { + if (!customPassword.encryptPassword) throw new Error('encryptPassword method not found in custom password file') + + // return object<{passwordHash: string, version: number}> + return customPassword.encryptPassword({ + password, + passwordSecret, + clientInfo: this.clientInfo + }) + } + } +} + +class PasswordUtils { + constructor ({ + userRecord = {}, + clientInfo, + passwordSecret + } = {}) { + if (!clientInfo) throw new Error('Invalid clientInfo') + if (!passwordSecret) throw new Error('Invalid password secret') + + this.clientInfo = clientInfo + this.userRecord = userRecord + this.passwordSecret = this.prePasswordSecret(passwordSecret) + } + + /** + * passwordSecret 预处理 + * @param passwordSecret + * @return {*[]} + */ + prePasswordSecret (passwordSecret) { + const newPasswordSecret = [] + if (getType(passwordSecret) === 'string') { + newPasswordSecret.push({ + value: passwordSecret, + type: passwordAlgorithmMap.UNI_ID_HMAC_SHA1 + }) + } else if (getType(passwordSecret) === 'array') { + for (const secret of passwordSecret.sort((a, b) => a.version - b.version)) { + newPasswordSecret.push({ + ...secret, + // 没有 type 设置默认 type hmac-sha1 + type: secret.type || passwordAlgorithmMap.UNI_ID_HMAC_SHA1 + }) + } + } else { + throw new Error('Invalid password secret') + } + + return newPasswordSecret + } + + /** + * 获取最新加密密钥 + * @return {*} + * @private + */ + _getLastestSecret () { + return this.passwordSecret[this.passwordSecret.length - 1] + } + + _getOldestSecret () { + return this.passwordSecret[0] + } + + _getSecretByVersion ({ version } = {}) { + if (!version && version !== 0) { + return this._getOldestSecret() + } + if (this.passwordSecret.length === 1) { + return this.passwordSecret[0] + } + return this.passwordSecret.find(item => item.version === version) + } + + /** + * 获取密码的验证/加密方法 + * @param passwordSecret + * @return {*[]} + * @private + */ + _getPasswordExt (passwordSecret) { + const ext = passwordExtMethod[passwordSecret.type] + if (!ext) { + throw new Error(`暂不支持 ${passwordSecret.type} 类型的加密算法`) + } + + const passwordExt = Object.create(null) + + for (const key in ext) { + passwordExt[key] = ext[key].bind(Object.assign(this, Object.keys(ext).reduce((res, item) => { + if (item !== key) { + res[item] = ext[item].bind(this) + } + return res + }, {}))) + } + + return passwordExt + } + + _parsePassword () { + const [algorithmKey = '', cost = 0, hashStr = ''] = this.userRecord.password.split('$').filter(key => key) + const algorithm = passwordAlgorithmMap[algorithmKey] ? passwordAlgorithmMap[algorithmKey].substring(5) : null + const salt = hashStr.substring(0, Number(cost)) + const hash = hashStr.substring(Number(cost)) + + return { + algorithm, + salt, + hash + } + } + + /** + * 生成加密后的密码 + * @param {String} password 密码 + */ + generatePasswordHash ({ password }) { + if (!password) throw new Error('Invalid password') + + const passwordSecret = this._getLastestSecret() + const ext = this._getPasswordExt(passwordSecret) + + const { passwordHash, version } = ext.encrypt({ + password, + passwordSecret + }) + + return { + passwordHash, + version + } + } + + /** + * 密码校验 + * @param {String} password + * @param {Boolean} autoRefresh + * @return {{refreshPasswordInfo: {version: *, passwordHash: *}, success: boolean}|{success: boolean}} + */ + checkUserPassword ({ password, autoRefresh = true }) { + if (!password) throw new Error('Invalid password') + + const { password_secret_version: passwordSecretVersion } = this.userRecord + const passwordSecret = this._getSecretByVersion({ + version: passwordSecretVersion + }) + const ext = this._getPasswordExt(passwordSecret) + + const success = ext.verify({ password, passwordSecret }) + + if (!success) { + return { + success: false + } + } + + let refreshPasswordInfo + if (autoRefresh && passwordSecretVersion !== this._getLastestSecret().version) { + refreshPasswordInfo = this.generatePasswordHash({ password }) + } + + return { + success: true, + refreshPasswordInfo + } + } +} + +module.exports = PasswordUtils diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js new file mode 100644 index 0000000..7ea612d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js @@ -0,0 +1,152 @@ +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +function getQQPlatform () { + const platform = this.clientPlatform + switch (platform) { + case 'app': + case 'app-plus': + return 'app' + case 'mp-qq': + return 'mp' + default: + throw new Error('Unsupported qq platform') + } +} + +async function saveQQUserKey ({ + openid, + sessionKey, // QQ小程序用户sessionKey + accessToken, // App端QQ用户accessToken + accessTokenExpired // App端QQ用户accessToken过期时间 +} = {}) { + // 微信公众平台、开放平台refreshToken有效期均为30天(微信没有在网络请求里面返回30天这个值,务必注意未来可能出现调整,需及时更新此处逻辑)。 + // 此前QQ开放平台有调整过accessToken的过期时间:[access_token有效期由90天缩短至30天](https://wiki.connect.qq.com/%E3%80%90qq%E4%BA%92%E8%81%94%E3%80%91access_token%E6%9C%89%E6%95%88%E6%9C%9F%E8%B0%83%E6%95%B4) + const appId = this.getUniversalClientInfo().appId + const qqPlatform = getQQPlatform.call(this) + const keyObj = { + dcloudAppid: appId, + openid, + platform: 'qq-' + qqPlatform + } + switch (qqPlatform) { + case 'mp': + await this.uniOpenBridge.setSessionKey(keyObj, { + session_key: sessionKey + }, 30 * 24 * 60 * 60) + break + case 'app': + case 'h5': + case 'web': + await this.uniOpenBridge.setUserAccessToken(keyObj, { + access_token: accessToken, + access_token_expired: accessTokenExpired + }, accessTokenExpired + ? Math.floor((accessTokenExpired - Date.now()) / 1000) + : 30 * 24 * 60 * 60 + ) + break + default: + break + } +} + +function generateQQCache ({ + sessionKey, // QQ小程序用户sessionKey + accessToken, // App端QQ用户accessToken + accessTokenExpired // App端QQ用户accessToken过期时间 +} = {}) { + const platform = getQQPlatform.call(this) + let cache + switch (platform) { + case 'app': + cache = { + access_token: accessToken, + access_token_expired: accessTokenExpired + } + break + case 'mp': + cache = { + session_key: sessionKey + } + break + default: + throw new Error('Unsupported qq platform') + } + return { + third_party: { + [`${platform}_qq`]: cache + } + } +} + +function getQQOpenid ({ + userRecord +} = {}) { + const qqPlatform = getQQPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + const qqOpenidObj = userRecord.qq_openid + if (!qqOpenidObj) { + return + } + return qqOpenidObj[`${qqPlatform}_${appId}`] || qqOpenidObj[qqPlatform] +} + +async function getQQCacheFallback ({ + userRecord, + key +} = {}) { + const platform = getQQPlatform.call(this) + const thirdParty = userRecord && userRecord.third_party + if (!thirdParty) { + return + } + const qqCache = thirdParty[`${platform}_qq`] + return qqCache && qqCache[key] +} + +async function getQQCache ({ + uid, + userRecord, + key +} = {}) { + const qqPlatform = getQQPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + + if (!userRecord) { + const getUserRes = await userCollection.doc(uid).get() + userRecord = getUserRes.data[0] + } + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + const openid = getQQOpenid.call(this, { + userRecord + }) + const getCacheMethod = qqPlatform === 'mp' ? 'getSessionKey' : 'getUserAccessToken' + const userKey = await this.uniOpenBridge[getCacheMethod]({ + dcloudAppid: appId, + platform: 'qq-' + qqPlatform, + openid + }) + if (userKey) { + return userKey[key] + } + return getQQCacheFallback({ + userRecord, + key + }) +} + +module.exports = { + getQQPlatform, + generateQQCache, + getQQCache, + saveQQUserKey +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js new file mode 100644 index 0000000..24eec34 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js @@ -0,0 +1,215 @@ +const { + userCollection, + LOG_TYPE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + findUser +} = require('./account') +const { + getValidInviteCode, + generateInviteInfo +} = require('./fission') +const { + logout +} = require('./logout') +const PasswordUtils = require('./password') +const merge = require('lodash.merge') + +async function realPreRegister (params = {}) { + const { + user + } = params + const { + userMatched + } = await findUser({ + userQuery: user, + authorizedApp: this.getUniversalClientInfo().appId + }) + if (userMatched.length > 0) { + throw { + errCode: ERROR.ACCOUNT_EXISTS + } + } +} + +async function preRegister (params = {}) { + try { + await realPreRegister.call(this, params) + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.REGISTER + }) + throw error + } +} + +async function preRegisterWithPassword (params = {}) { + const { + user, + password + } = params + await preRegister.call(this, { + user + }) + const passwordUtils = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }) + const { + passwordHash, + version + } = passwordUtils.generatePasswordHash({ + password + }) + const extraData = { + password: passwordHash, + password_secret_version: version + } + return { + user, + extraData + } +} + +async function thirdPartyRegister ({ + user = {} +} = {}) { + return { + mobileConfirmed: !!(user.mobile && user.mobile_confirmed) || false, + emailConfirmed: !!(user.email && user.email_confirmed) || false + } +} + +async function postRegister (params = {}) { + const { + user, + extraData = {}, + isThirdParty = false, + inviteCode + } = params + const { + appId, + appName, + appVersion, + appVersionCode, + channel, + scene, + clientIP, + osName + } = this.getUniversalClientInfo() + const uniIdToken = this.getUniversalUniIdToken() + + merge(user, extraData) + + const registerChannel = channel || scene + user.register_env = { + appid: appId || '', + uni_platform: this.clientPlatform || '', + os_name: osName || '', + app_name: appName || '', + app_version: appVersion || '', + app_version_code: appVersionCode || '', + channel: registerChannel ? registerChannel + '' : '', // channel可能为数字,统一存为字符串 + client_ip: clientIP || '' + } + + user.register_date = Date.now() + user.dcloud_appid = [appId] + + if (user.username) { + user.username = user.username.toLowerCase() + } + if (user.email) { + user.email = user.email.toLowerCase() + } + + const { + autoSetInviteCode, // 注册时自动设置邀请码 + forceInviteCode // 必须有邀请码才允许注册,注意此逻辑不可对admin生效 + } = this.config + if (autoSetInviteCode) { + user.my_invite_code = await getValidInviteCode() + } + + const isAdmin = user.role && user.role.includes('admin') + + if (forceInviteCode && !isAdmin && !inviteCode) { + throw { + errCode: ERROR.INVALID_INVITE_CODE + } + } + + if (inviteCode) { + const { + inviterUid, + inviteTime + } = await generateInviteInfo({ + inviteCode + }) + user.inviter_uid = inviterUid + user.invite_time = inviteTime + } + + if (uniIdToken) { + try { + await logout.call(this) + } catch (error) {} + } + + const beforeRegister = this.hooks.beforeRegister + let userRecord = user + if (beforeRegister) { + userRecord = await beforeRegister({ + userRecord, + clientInfo: this.getUniversalClientInfo() + }) + } + + const { + id: uid + } = await userCollection.add(userRecord) + + const { + token, + tokenExpired + } = await this.uniIdCommon.createToken({ + uid + }) + + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: LOG_TYPE.REGISTER + }) + + return { + errCode: 0, + uid, + newToken: { + token, + tokenExpired + }, + ...( + isThirdParty + ? thirdPartyRegister({ + user: { + ...userRecord, + _id: uid + } + }) + : {} + ), + passwordConfirmed: !!userRecord.password + } +} + +module.exports = { + preRegister, + preRegisterWithPassword, + postRegister +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js new file mode 100644 index 0000000..8431551 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js @@ -0,0 +1,164 @@ +const { + findUser +} = require('./account') +const { + ERROR +} = require('../../common/error') +const { + userCollection, dbCmd, USER_IDENTIFIER +} = require('../../common/constants') +const { + getUserIdentifier +} = require('../../lib/utils/account') + +const { + batchFindObjctValue +} = require('../../common/utils') +const merge = require('lodash.merge') + +/** + * + * @param {object} param + * @param {string} param.uid 用户id + * @param {string} param.bindAccount 要绑定的三方账户、手机号或邮箱 + */ +async function preBind ({ + uid, + bindAccount, + logType +} = {}) { + const { + userMatched + } = await findUser({ + userQuery: bindAccount, + authorizedApp: this.getUniversalClientInfo().appId + }) + if (userMatched.length > 0) { + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: logType, + success: false + }) + throw { + errCode: ERROR.BIND_CONFLICT + } + } +} + +async function postBind ({ + uid, + extraData = {}, + bindAccount, + logType +} = {}) { + await userCollection.doc(uid).update(merge(bindAccount, extraData)) + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: logType + }) + return { + errCode: 0 + } +} + +async function preUnBind ({ + uid, + unBindAccount, + logType +}) { + const notUnBind = ['username', 'mobile', 'email'] + const userIdentifier = getUserIdentifier(unBindAccount) + const condition = Object.keys(userIdentifier).reduce((res, key) => { + if (userIdentifier[key]) { + if (notUnBind.includes(key)) { + throw { + errCode: ERROR.UNBIND_NOT_SUPPORTED + } + } + + res.push({ + [key]: userIdentifier[key] + }) + } + + return res + }, []) + const currentUnBindAccount = Object.keys(userIdentifier).reduce((res, key) => { + if (userIdentifier[key]) { + res.push(key) + } + return res + }, []) + const { data: users } = await userCollection.where(dbCmd.and( + { _id: uid }, + dbCmd.or(condition) + )).get() + + if (users.length <= 0) { + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: logType, + success: false + }) + throw { + errCode: ERROR.UNBIND_FAIL + } + } + + const [user] = users + const otherAccounts = batchFindObjctValue(user, Object.keys(USER_IDENTIFIER).filter(key => !notUnBind.includes(key) && !currentUnBindAccount.includes(key))) + let hasOtherAccountBind = false + + for (const key in otherAccounts) { + if (otherAccounts[key]) { + hasOtherAccountBind = true + break + } + } + + // 如果没有其他第三方登录方式 + if (!hasOtherAccountBind) { + // 存在用户名或者邮箱但是没有设置过没密码就提示设置密码 + if ((user.username || user.email) && !user.password) { + throw { + errCode: ERROR.UNBIND_PASSWORD_NOT_EXISTS + } + } + // 账号任何登录方式都没有就优先绑定手机号 + if (!user.mobile) { + throw { + errCode: ERROR.UNBIND_MOBILE_NOT_EXISTS + } + } + } +} + +async function postUnBind ({ + uid, + unBindAccount, + logType +}) { + await userCollection.doc(uid).update(unBindAccount) + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: logType + }) + return { + errCode: 0 + } +} + +module.exports = { + preBind, + postBind, + preUnBind, + postUnBind +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/sms.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/sms.js new file mode 100644 index 0000000..21c70e9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/sms.js @@ -0,0 +1,81 @@ +const { + setMobileVerifyCode +} = require('./verify-code') +const { + getVerifyCode +} = require('../../common/utils') + +/** + * 发送短信 + * @param {object} param + * @param {string} param.mobile 手机号 + * @param {object} param.code 可选,验证码 + * @param {object} param.scene 短信场景 + * @param {object} param.templateId 可选,短信模板id + * @returns + */ +async function sendSmsCode ({ + mobile, + code, + scene, + templateId +} = {}) { + const requiredParams = [ + 'name', + 'smsKey', + 'smsSecret', + 'codeExpiresIn' + ] + const smsConfig = (this.config.service && this.config.service.sms) || {} + for (let i = 0; i < requiredParams.length; i++) { + const key = requiredParams[i] + if (!smsConfig[key]) { + throw new Error(`Missing config param: service.sms.${key}`) + } + } + if (!code) { + code = getVerifyCode() + } + let action + switch (scene) { + case 'login-by-sms': + action = this.t('login') + break + default: + action = this.t('verify-mobile') + break + } + const sceneConfig = (smsConfig.scene || {})[scene] || {} + if (!templateId) { + templateId = sceneConfig.templateId + } + if (!templateId) { + throw new Error('"templateId" is required') + } + const codeExpiresIn = sceneConfig.codeExpiresIn || smsConfig.codeExpiresIn + await setMobileVerifyCode.call(this, { + mobile, + code, + expiresIn: codeExpiresIn, + scene + }) + await uniCloud.sendSms({ + smsKey: smsConfig.smsKey, + smsSecret: smsConfig.smsSecret, + phone: mobile, + templateId, + data: { + name: smsConfig.name, + code, + action, + expMinute: '' + Math.round(codeExpiresIn / 60) + } + }) + return { + errCode: 0 + } +} + +module.exports = { + sendSmsCode +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js new file mode 100644 index 0000000..eac7a51 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js @@ -0,0 +1,106 @@ +const { + checkLoginUserRecord, + postLogin +} = require('./login') +const { + postRegister +} = require('./register') +const { + findUser +} = require('./account') +const { + ERROR +} = require('../../common/error') + +async function realPreUnifiedLogin (params = {}) { + const { + user, + type + } = params + const appId = this.getUniversalClientInfo().appId + const { + total, + userMatched + } = await findUser({ + userQuery: user, + authorizedApp: appId + }) + if (userMatched.length === 0) { + if (type === 'login') { + if (total > 0) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS_IN_CURRENT_APP + } + } + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + return { + type: 'register', + user + } + } if (userMatched.length === 1) { + if (type === 'register') { + throw { + errCode: ERROR.ACCOUNT_EXISTS + } + } + const userRecord = userMatched[0] + checkLoginUserRecord(userRecord) + return { + type: 'login', + user: userRecord + } + } else if (userMatched.length > 1) { + throw { + errCode: ERROR.ACCOUNT_CONFLICT + } + } +} + +async function preUnifiedLogin (params = {}) { + try { + const result = await realPreUnifiedLogin.call(this, params) + return result + } catch (error) { + await this.middleware.uniIdLog({ + success: false + }) + throw error + } +} + +async function postUnifiedLogin (params = {}) { + const { + user, + extraData = {}, + isThirdParty = false, + type, + inviteCode + } = params + let result + if (type === 'login') { + result = await postLogin.call(this, { + user, + extraData, + isThirdParty + }) + } else if (type === 'register') { + result = await postRegister.call(this, { + user, + extraData, + isThirdParty, + inviteCode + }) + } + return { + ...result, + type + } +} + +module.exports = { + preUnifiedLogin, + postUnifiedLogin +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/univerify.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/univerify.js new file mode 100644 index 0000000..33c17c0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/univerify.js @@ -0,0 +1,27 @@ +async function getPhoneNumber ({ + // eslint-disable-next-line camelcase + access_token, + openid +} = {}) { + const requiredParams = ['apiKey', 'apiSecret'] + const univerifyConfig = (this.config.service && this.config.service.univerify) || {} + for (let i = 0; i < requiredParams.length; i++) { + const key = requiredParams[i] + if (!univerifyConfig[key]) { + throw new Error(`Missing config param: service.univerify.${key}`) + } + } + return uniCloud.getPhoneNumber({ + provider: 'univerify', + appid: this.getUniversalClientInfo().appId, + apiKey: univerifyConfig.apiKey, + apiSecret: univerifyConfig.apiSecret, + // eslint-disable-next-line camelcase + access_token, + openid + }) +} + +module.exports = { + getPhoneNumber +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/update-user-info.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/update-user-info.js new file mode 100644 index 0000000..ced33b9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/update-user-info.js @@ -0,0 +1,25 @@ +const { + userCollection +} = require('../../common/constants') +const { + USER_STATUS +} = require('../../common/constants') +async function setUserStatus (uid, status) { + const updateData = { + status + } + if (status !== USER_STATUS.NORMAL) { + updateData.valid_token_date = Date.now() + } + await userCollection.doc(uid).update({ + status + }) + // TODO 此接口尚不完善,例如注销后其他客户端可能存在有效token,支持Redis后此处会补充额外逻辑 + return { + errCode: 0 + } +} + +module.exports = { + setUserStatus +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/utils.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/utils.js new file mode 100644 index 0000000..7d3e0f3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/utils.js @@ -0,0 +1,18 @@ +let redisEnable = null +function getRedisEnable() { + // 未用到的时候不调用redis接口,节省一些连接数 + if (redisEnable !== null) { + return redisEnable + } + try { + uniCloud.redis() + redisEnable = true + } catch (error) { + redisEnable = false + } + return redisEnable +} + +module.exports = { + getRedisEnable +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/verify-code.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/verify-code.js new file mode 100644 index 0000000..b11bc02 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/verify-code.js @@ -0,0 +1,152 @@ +const { + dbCmd, + verifyCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + getVerifyCode +} = require('../../common/utils') + +async function setVerifyCode ({ + mobile, + email, + code, + expiresIn, + scene +} = {}) { + const now = Date.now() + const record = { + mobile, + email, + scene, + code: code || getVerifyCode(), + state: 0, + ip: this.getUniversalClientInfo().clientIP, + created_date: now, + expired_date: now + expiresIn * 1000 + } + await verifyCollection.add(record) + return { + errCode: 0 + } +} + +async function setEmailVerifyCode ({ + email, + code, + expiresIn, + scene +} = {}) { + email = email && email.trim() + if (!email) { + throw { + errCode: ERROR.INVALID_EMAIL + } + } + email = email.toLowerCase() + return setVerifyCode.call(this, { + email, + code, + expiresIn, + scene + }) +} + +async function setMobileVerifyCode ({ + mobile, + code, + expiresIn, + scene +} = {}) { + mobile = mobile && mobile.trim() + if (!mobile) { + throw { + errCode: ERROR.INVALID_MOBILE + } + } + return setVerifyCode.call(this, { + mobile, + code, + expiresIn, + scene + }) +} + +async function verifyEmailCode ({ + email, + code, + scene +} = {}) { + email = email && email.trim() + if (!email) { + throw { + errCode: ERROR.INVALID_EMAIL + } + } + email = email.toLowerCase() + const { + data: codeRecord + } = await verifyCollection.where({ + email, + scene, + code, + state: 0, + expired_date: dbCmd.gt(Date.now()) + }).limit(1).get() + + if (codeRecord.length === 0) { + throw { + errCode: ERROR.EMAIL_VERIFY_CODE_ERROR + } + } + await verifyCollection.doc(codeRecord[0]._id).update({ + state: 1 + }) + return { + errCode: 0 + } +} + +async function verifyMobileCode ({ + mobile, + code, + scene +} = {}) { + mobile = mobile && mobile.trim() + if (!mobile) { + throw { + errCode: ERROR.INVALID_MOBILE + } + } + const { + data: codeRecord + } = await verifyCollection.where({ + mobile, + scene, + code, + state: 0, + expired_date: dbCmd.gt(Date.now()) + }).limit(1).get() + + if (codeRecord.length === 0) { + throw { + errCode: ERROR.MOBILE_VERIFY_CODE_ERROR + } + } + + await verifyCollection.doc(codeRecord[0]._id).update({ + state: 1 + }) + return { + errCode: 0 + } +} + +module.exports = { + verifyEmailCode, + verifyMobileCode, + setEmailVerifyCode, + setMobileVerifyCode +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js new file mode 100644 index 0000000..619c722 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js @@ -0,0 +1,234 @@ +const crypto = require('crypto') +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + getRedisEnable +} = require('./utils') +const { + openDataCollection +} = require('../../common/constants') + +function decryptWeixinData ({ + encryptedData, + sessionKey, + iv +} = {}) { + const oauthConfig = this.configUtils.getOauthConfig({ + provider: 'weixin' + }) + const decipher = crypto.createDecipheriv( + 'aes-128-cbc', + Buffer.from(sessionKey, 'base64'), + Buffer.from(iv, 'base64') + ) + // 设置自动 padding 为 true,删除填充补位 + decipher.setAutoPadding(true) + let decoded + decoded = decipher.update(encryptedData, 'base64', 'utf8') + decoded += decipher.final('utf8') + decoded = JSON.parse(decoded) + if (decoded.watermark.appid !== oauthConfig.appid) { + throw new Error('Invalid wechat appid in decode content') + } + return decoded +} + +function getWeixinPlatform () { + const platform = this.clientPlatform + const userAgent = this.getUniversalClientInfo().userAgent + switch (platform) { + case 'app': + case 'app-plus': + return 'app' + case 'mp-weixin': + return 'mp' + case 'h5': + case 'web': + return userAgent.indexOf('MicroMessenger') > -1 ? 'h5' : 'web' + default: + throw new Error('Unsupported weixin platform') + } +} + +async function saveWeixinUserKey ({ + openid, + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + accessTokenExpired // App端微信用户accessToken过期时间 +} = {}) { + // 微信公众平台、开放平台refreshToken有效期均为30天(微信没有在网络请求里面返回30天这个值,务必注意未来可能出现调整,需及时更新此处逻辑)。 + // 此前QQ开放平台有调整过accessToken的过期时间:[access_token有效期由90天缩短至30天](https://wiki.connect.qq.com/%E3%80%90qq%E4%BA%92%E8%81%94%E3%80%91access_token%E6%9C%89%E6%95%88%E6%9C%9F%E8%B0%83%E6%95%B4) + + const appId = this.getUniversalClientInfo().appId + const weixinPlatform = getWeixinPlatform.call(this) + const keyObj = { + dcloudAppid: appId, + openid, + platform: 'weixin-' + weixinPlatform + } + switch (weixinPlatform) { + case 'mp': + await this.uniOpenBridge.setSessionKey(keyObj, { + session_key: sessionKey + }, 30 * 24 * 60 * 60) + break + case 'app': + case 'h5': + case 'web': + await this.uniOpenBridge.setUserAccessToken(keyObj, { + access_token: accessToken, + refresh_token: refreshToken, + access_token_expired: accessTokenExpired + }, 30 * 24 * 60 * 60) + break + default: + break + } +} + +async function saveSecureNetworkCache ({ + code, + openid, + unionid, + sessionKey +}) { + const { + appId + } = this.getUniversalClientInfo() + const key = `uni-id:${appId}:weixin-mp:code:${code}:secure-network-cache` + const value = JSON.stringify({ + openid, + unionid, + session_key: sessionKey + }) + // 此处存储的是code的缓存,有效期两天即可 + const expiredSeconds = 2 * 24 * 60 * 60 + + await openDataCollection.doc(key).set({ + value, + expired: Date.now() + expiredSeconds * 1000 + }) + const isRedisEnable = getRedisEnable() + if (isRedisEnable) { + const redis = uniCloud.redis() + await redis.set(key, value, 'EX', expiredSeconds) + } +} + +function generateWeixinCache ({ + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + accessTokenExpired // App端微信用户accessToken过期时间 +} = {}) { + const platform = getWeixinPlatform.call(this) + let cache + switch (platform) { + case 'app': + case 'h5': + case 'web': + cache = { + access_token: accessToken, + refresh_token: refreshToken, + access_token_expired: accessTokenExpired + } + break + case 'mp': + cache = { + session_key: sessionKey + } + break + default: + throw new Error('Unsupported weixin platform') + } + return { + third_party: { + [`${platform}_weixin`]: cache + } + } +} + +function getWeixinOpenid ({ + userRecord +} = {}) { + const weixinPlatform = getWeixinPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + const wxOpenidObj = userRecord.wx_openid + if (!wxOpenidObj) { + return + } + return wxOpenidObj[`${weixinPlatform}_${appId}`] || wxOpenidObj[weixinPlatform] +} + +async function getWeixinCacheFallback ({ + userRecord, + key +} = {}) { + const platform = getWeixinPlatform.call(this) + const thirdParty = userRecord && userRecord.third_party + if (!thirdParty) { + return + } + const weixinCache = thirdParty[`${platform}_weixin`] + return weixinCache && weixinCache[key] +} + +async function getWeixinCache ({ + uid, + userRecord, + key +} = {}) { + const weixinPlatform = getWeixinPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + if (!userRecord) { + const getUserRes = await userCollection.doc(uid).get() + userRecord = getUserRes.data[0] + } + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + const openid = getWeixinOpenid.call(this, { + userRecord + }) + const getCacheMethod = weixinPlatform === 'mp' ? 'getSessionKey' : 'getUserAccessToken' + const userKey = await this.uniOpenBridge[getCacheMethod]({ + dcloudAppid: appId, + platform: 'weixin-' + weixinPlatform, + openid + }) + if (userKey) { + return userKey[key] + } + return getWeixinCacheFallback({ + userRecord, + key + }) +} + +async function getWeixinAccessToken () { + const weixinPlatform = getWeixinPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + + const cache = await this.uniOpenBridge.getAccessToken({ + dcloudAppid: appId, + platform: 'weixin-' + weixinPlatform + }) + + return cache.access_token +} +module.exports = { + decryptWeixinData, + getWeixinPlatform, + generateWeixinCache, + getWeixinCache, + saveWeixinUserKey, + getWeixinAccessToken, + saveSecureNetworkCache +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/access-control.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/access-control.js new file mode 100644 index 0000000..e333fe0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/access-control.js @@ -0,0 +1,59 @@ +const methodPermission = require('../config/permission') +const { + ERROR +} = require('../common/error') + +function isAccessAllowed (user, setting) { + const { + role: userRole = [], + permission: userPermission = [] + } = user + const { + role: settingRole = [], + permission: settingPermission = [] + } = setting + if (userRole.includes('admin')) { + return + } + if ( + settingRole.length > 0 && + settingRole.every(item => !userRole.includes(item)) + ) { + throw { + errCode: ERROR.PERMISSION_ERROR + } + } + if ( + settingPermission.length > 0 && + settingPermission.every(item => !userPermission.includes(item)) + ) { + throw { + errCode: ERROR.PERMISSION_ERROR + } + } +} + +module.exports = async function () { + const methodName = this.getMethodName() + if (!(methodName in methodPermission)) { + return + } + const { + auth, + role, + permission + } = methodPermission[methodName] + if (auth || role || permission) { + await this.middleware.auth() + } + if (role && role.length === 0) { + throw new Error('[AccessControl]Empty role array is not supported') + } + if (permission && permission.length === 0) { + throw new Error('[AccessControl]Empty permission array is not supported') + } + return isAccessAllowed(this.authInfo, { + role, + permission + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/auth.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/auth.js new file mode 100644 index 0000000..1915335 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/auth.js @@ -0,0 +1,17 @@ +module.exports = async function () { + if (this.authInfo) { // 多次执行auth时如果第一次成功后续不再执行 + return + } + const token = this.getUniversalUniIdToken() + const payload = await this.uniIdCommon.checkToken(token) + if (payload.errCode) { + throw payload + } + this.authInfo = payload + if (payload.token) { + this.response.newToken = { + token: payload.token, + tokenExpired: payload.tokenExpired + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/index.js new file mode 100644 index 0000000..9f7c958 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/index.js @@ -0,0 +1,8 @@ +module.exports = { + auth: require('./auth'), + uniIdLog: require('./uni-id-log'), + validate: require('./validate'), + accessControl: require('./access-control'), + verifyRequestSign: require('./verify-request-sign'), + ...require('./rbac') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/rbac.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/rbac.js new file mode 100644 index 0000000..f42ef8d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/rbac.js @@ -0,0 +1,39 @@ +const { + ERROR +} = require('../common/error') + +function hasRole (...roleList) { + const userRole = this.authInfo.role || [] + if (userRole.includes('admin')) { + return + } + const isMatch = roleList.every(roleItem => { + return userRole.includes(roleItem) + }) + if (!isMatch) { + throw { + errCode: ERROR.PERMISSION_ERROR + } + } +} + +function hasPermission (...permissionList) { + const userRole = this.authInfo.role || [] + const userPermission = this.authInfo.permission || [] + if (userRole.includes('admin')) { + return + } + const isMatch = permissionList.every(permissionItem => { + return userPermission.includes(permissionItem) + }) + if (!isMatch) { + throw { + errCode: ERROR.PERMISSION_ERROR + } + } +} + +module.exports = { + hasRole, + hasPermission +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/uni-id-log.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/uni-id-log.js new file mode 100644 index 0000000..ca6927d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/uni-id-log.js @@ -0,0 +1,39 @@ +const db = uniCloud.database() +module.exports = async function ({ + data = {}, + success = true, + type = 'login' +} = {}) { + const now = Date.now() + const uniIdLogCollection = db.collection('uni-id-log') + const requiredDataKeyList = ['user_id', 'username', 'email', 'mobile'] + const dataCopy = {} + for (let i = 0; i < requiredDataKeyList.length; i++) { + const key = requiredDataKeyList[i] + if (key in data && typeof data[key] === 'string') { + dataCopy[key] = data[key] + } + } + const { + appId, + clientIP, + deviceId, + userAgent + } = this.getUniversalClientInfo() + const logData = { + appid: appId, + device_id: deviceId, + ip: clientIP, + type, + ua: userAgent, + create_date: now, + ...dataCopy + } + + if (success) { + logData.state = 1 + } else { + logData.state = 0 + } + return uniIdLogCollection.add(logData) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/validate.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/validate.js new file mode 100644 index 0000000..52ff047 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/validate.js @@ -0,0 +1,7 @@ +module.exports = function (value = {}, schema = {}) { + const validateRes = this.validator.validate(value, schema) + if (validateRes) { + delete validateRes.schemaKey + throw validateRes + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/verify-request-sign.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/verify-request-sign.js new file mode 100644 index 0000000..84420e3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/middleware/verify-request-sign.js @@ -0,0 +1,39 @@ +const crypto = require('crypto') +const { ERROR } = require('../common/error') +const needSignFunctions = new Set([ + 'externalRegister', + 'externalLogin' +]) + +module.exports = function () { + const methodName = this.getMethodName() + const { source } = this.getUniversalClientInfo() + // 非 HTTP 方式请求不需要鉴权 + if (source !== 'http') return + // 指定接口需要鉴权 + if (!needSignFunctions.has(methodName)) return + + const timeout = 20 * 1000 // 请求超过20秒不能再请求,防止重放攻击 + const { headers, body: _body } = this.getHttpInfo() + const { 'uni-id-nonce': nonce, 'uni-id-timestamp': timestamp, 'uni-id-signature': signature } = headers + const body = JSON.parse(_body).params || {} + const bodyStr = Object.keys(body) + .sort() + .filter(item => typeof body[item] !== 'object') + .map(item => `${item}=${body[item]}`) + .join('&') + + if (isNaN(Number(timestamp)) || (Number(timestamp) + timeout) < Date.now()) { + throw { + errCode: ERROR.ILLEGAL_REQUEST + } + } + + const reSignature = crypto.createHmac('sha256', `${this.config.requestAuthSecret + nonce}`).update(`${timestamp}${bodyStr}`).digest('hex') + + if (signature !== reSignature.toUpperCase()) { + throw { + errCode: ERROR.ILLEGAL_REQUEST + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/close-account.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/close-account.js new file mode 100644 index 0000000..f1bdf96 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/close-account.js @@ -0,0 +1,16 @@ +const { + setUserStatus +} = require('../../lib/utils/update-user-info') +const { + USER_STATUS +} = require('../../common/constants') + +/** + * 注销账户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#close-account + * @returns + */ +module.exports = async function () { + const { uid } = this.authInfo + return setUserStatus(uid, USER_STATUS.CLOSED) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/get-account-info.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/get-account-info.js new file mode 100644 index 0000000..7b8599a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/get-account-info.js @@ -0,0 +1,69 @@ +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +function isUsernameSet (userRecord) { + return !!userRecord.username +} +function isNicknameSet (userRecord) { + return !!userRecord.nickname +} +function isPasswordSet (userRecord) { + return !!userRecord.password +} +function isMobileBound (userRecord) { + return !!(userRecord.mobile && userRecord.mobile_confirmed) +} +function isEmailBound (userRecord) { + return !!(userRecord.email && userRecord.email_confirmed) +} +function isWeixinBound (userRecord) { + return !!( + userRecord.wx_unionid || + Object.keys(userRecord.wx_openid || {}).length + ) +} +function isQQBound (userRecord) { + return !!( + userRecord.qq_unionid || + Object.keys(userRecord.qq_openid || {}).length + ) +} +function isAlipayBound (userRecord) { + return !!userRecord.ali_openid +} +function isAppleBound (userRecord) { + return !!userRecord.apple_openid +} + +/** + * 获取账户账户简略信息 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-account-info + */ +module.exports = async function () { + const { + uid + } = this.authInfo + const getUserRes = await userCollection.doc(uid).get() + const userRecord = getUserRes && getUserRes.data && getUserRes.data[0] + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + return { + errCode: 0, + isUsernameSet: isUsernameSet(userRecord), + isNicknameSet: isNicknameSet(userRecord), + isPasswordSet: isPasswordSet(userRecord), + isMobileBound: isMobileBound(userRecord), + isEmailBound: isEmailBound(userRecord), + isWeixinBound: isWeixinBound(userRecord), + isQQBound: isQQBound(userRecord), + isAlipayBound: isAlipayBound(userRecord), + isAppleBound: isAppleBound(userRecord) + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/index.js new file mode 100644 index 0000000..b4e06d6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/index.js @@ -0,0 +1,8 @@ +module.exports = { + setPwd: require('./set-pwd'), + updatePwd: require('./update-pwd'), + resetPwdBySms: require('./reset-pwd-by-sms'), + resetPwdByEmail: require('./reset-pwd-by-email'), + closeAccount: require('./close-account'), + getAccountInfo: require('./get-account-info') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js new file mode 100644 index 0000000..20c6219 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js @@ -0,0 +1,128 @@ +const { + ERROR +} = require('../../common/error') +const { + getNeedCaptcha, + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + verifyEmailCode +} = require('../../lib/utils/verify-code') +const { + userCollection, + EMAIL_SCENE, + CAPTCHA_SCENE, + LOG_TYPE +} = require('../../common/constants') +const { + findUser +} = require('../../lib/utils/account') +const PasswordUtils = require('../../lib/utils/password') + +/** + * 通过邮箱验证码重置密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-email + * @param {object} params + * @param {string} params.email 邮箱 + * @param {string} params.code 邮箱验证码 + * @param {string} params.password 密码 + * @param {string} params.captcha 图形验证码 + * @returns {object} + */ +module.exports = async function (params = {}) { + const schema = { + email: 'email', + code: 'string', + password: 'password', + captcha: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + email, + code, + password, + captcha + } = params + + const needCaptcha = await getNeedCaptcha.call(this, { + email, + type: LOG_TYPE.RESET_PWD_BY_EMAIL + }) + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.RESET_PWD_BY_EMAIL + }) + } + try { + // 验证手机号验证码,验证不通过时写入失败日志 + await verifyEmailCode({ + email, + code, + scene: EMAIL_SCENE.RESET_PWD_BY_EMAIL + }) + } catch (error) { + await this.middleware.uniIdLog({ + data: { + email + }, + type: LOG_TYPE.RESET_PWD_BY_EMAIL, + success: false + }) + throw error + } + // 根据手机号查找匹配的用户 + const { + total, + userMatched + } = await findUser.call(this, { + userQuery: { + email + }, + authorizedApp: [this.getUniversalClientInfo().appId] + }) + if (userMatched.length === 0) { + if (total > 0) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS_IN_CURRENT_APP + } + } + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } else if (userMatched.length > 1) { + throw { + errCode: ERROR.ACCOUNT_CONFLICT + } + } + const { _id: uid } = userMatched[0] + const { + passwordHash, + version + } = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }).generatePasswordHash({ + password + }) + // 更新用户密码 + await userCollection.doc(uid).update({ + password: passwordHash, + password_secret_version: version, + valid_token_date: Date.now() + }) + + // 写入成功日志 + await this.middleware.uniIdLog({ + data: { + email + }, + type: LOG_TYPE.RESET_PWD_BY_SMS + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js new file mode 100644 index 0000000..bc10dc8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js @@ -0,0 +1,128 @@ +const { + ERROR +} = require('../../common/error') +const { + getNeedCaptcha, + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + verifyMobileCode +} = require('../../lib/utils/verify-code') +const { + userCollection, + SMS_SCENE, + CAPTCHA_SCENE, + LOG_TYPE +} = require('../../common/constants') +const { + findUser +} = require('../../lib/utils/account') +const PasswordUtils = require('../../lib/utils/password') + +/** + * 通过短信验证码重置密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-sms + * @param {object} params + * @param {string} params.mobile 手机号 + * @param {string} params.mobile 短信验证码 + * @param {string} params.password 密码 + * @param {string} params.captcha 图形验证码 + * @returns {object} + */ +module.exports = async function (params = {}) { + const schema = { + mobile: 'mobile', + code: 'string', + password: 'password', + captcha: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + mobile, + code, + password, + captcha + } = params + + const needCaptcha = await getNeedCaptcha.call(this, { + mobile, + type: LOG_TYPE.RESET_PWD_BY_SMS + }) + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.RESET_PWD_BY_SMS + }) + } + try { + // 验证手机号验证码,验证不通过时写入失败日志 + await verifyMobileCode({ + mobile, + code, + scene: SMS_SCENE.RESET_PWD_BY_SMS + }) + } catch (error) { + await this.middleware.uniIdLog({ + data: { + mobile + }, + type: LOG_TYPE.RESET_PWD_BY_SMS, + success: false + }) + throw error + } + // 根据手机号查找匹配的用户 + const { + total, + userMatched + } = await findUser.call(this, { + userQuery: { + mobile + }, + authorizedApp: [this.getUniversalClientInfo().appId] + }) + if (userMatched.length === 0) { + if (total > 0) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS_IN_CURRENT_APP + } + } + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } else if (userMatched.length > 1) { + throw { + errCode: ERROR.ACCOUNT_CONFLICT + } + } + const { _id: uid } = userMatched[0] + const { + passwordHash, + version + } = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }).generatePasswordHash({ + password + }) + // 更新用户密码 + await userCollection.doc(uid).update({ + password: passwordHash, + password_secret_version: version, + valid_token_date: Date.now() + }) + + // 写入成功日志 + await this.middleware.uniIdLog({ + data: { + mobile + }, + type: LOG_TYPE.RESET_PWD_BY_SMS + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/set-pwd.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/set-pwd.js new file mode 100644 index 0000000..f33c6f4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/set-pwd.js @@ -0,0 +1,83 @@ +const { userCollection, SMS_SCENE, LOG_TYPE, CAPTCHA_SCENE } = require('../../common/constants') +const { ERROR } = require('../../common/error') +const { verifyMobileCode } = require('../../lib/utils/verify-code') +const PasswordUtils = require('../../lib/utils/password') +const { getNeedCaptcha, verifyCaptcha } = require('../../lib/utils/captcha') + +module.exports = async function (params = {}) { + const schema = { + password: 'password', + code: 'string', + captcha: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + + const { password, code, captcha } = params + const uid = this.authInfo.uid + const getUserRes = await userCollection.doc(uid).get() + const userRecord = getUserRes.data[0] + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + + const needCaptcha = await getNeedCaptcha.call(this, { + mobile: userRecord.mobile + }) + + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.SET_PWD_BY_SMS + }) + } + + try { + // 验证手机号验证码,验证不通过时写入失败日志 + await verifyMobileCode({ + mobile: userRecord.mobile, + code, + scene: SMS_SCENE.SET_PWD_BY_SMS + }) + } catch (error) { + await this.middleware.uniIdLog({ + data: { + mobile: userRecord.mobile + }, + type: LOG_TYPE.SET_PWD_BY_SMS, + success: false + }) + throw error + } + + const { + passwordHash, + version + } = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }).generatePasswordHash({ + password + }) + + // 更新用户密码 + await userCollection.doc(uid).update({ + password: passwordHash, + password_secret_version: version + }) + + await this.middleware.uniIdLog({ + data: { + mobile: userRecord.mobile + }, + type: LOG_TYPE.SET_PWD_BY_SMS + }) + + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js new file mode 100644 index 0000000..97fd1be --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js @@ -0,0 +1,69 @@ +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const PasswordUtils = require('../../lib/utils/password') +/** + * 更新密码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-pwd + * @param {object} params + * @param {string} params.oldPassword 旧密码 + * @param {string} params.newPassword 新密码 + * @returns {object} + */ +module.exports = async function (params = {}) { + const schema = { + oldPassword: 'string', // 防止密码规则调整导致旧密码无法更新 + newPassword: 'password' + } + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + const getUserRes = await userCollection.doc(uid).get() + const userRecord = getUserRes.data[0] + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + const { + oldPassword, + newPassword + } = params + const passwordUtils = new PasswordUtils({ + userRecord, + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }) + + const { + success: checkPasswordSuccess + } = passwordUtils.checkUserPassword({ + password: oldPassword, + autoRefresh: false + }) + + if (!checkPasswordSuccess) { + throw { + errCode: ERROR.PASSWORD_ERROR + } + } + + const { + passwordHash, + version + } = passwordUtils.generatePasswordHash({ + password: newPassword + }) + + await userCollection.doc(uid).update({ + password: passwordHash, + password_secret_version: version, + valid_token_date: Date.now() // refreshToken时会校验,如果创建token时间在此时间点之前,则拒绝下发新token,返回token失效错误码 + }) + // 执行更新密码操作后客户端应将用户退出重新登录 + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js new file mode 100644 index 0000000..a928489 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js @@ -0,0 +1,121 @@ +const { + findUser +} = require('../../lib/utils/account') +const { + ERROR +} = require('../../common/error') +const { + userCollection +} = require('../../common/constants') +const PasswordUtils = require('../../lib/utils/password') + +/** + * 新增用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {Array} params.authorizedApp 允许登录的AppID列表 + * @param {Array} params.role 用户角色列表 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {Array} params.tags 用户标签 + * @param {Number} params.status 用户状态 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + username: 'username', + password: 'password', + authorizedApp: { + required: false, + type: 'array' + }, // 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录 + nickname: { + required: false, + type: 'nickname' + }, + role: { + require: false, + type: 'array' + }, + mobile: { + required: false, + type: 'mobile' + }, + email: { + required: false, + type: 'email' + }, + tags: { + required: false, + type: 'array' + }, + status: { + required: false, + type: 'number' + } + } + this.middleware.validate(params, schema) + const { + username, + password, + authorizedApp, + nickname, + role, + mobile, + email, + tags, + status + } = params + const { + userMatched + } = await findUser({ + userQuery: { + username, + mobile, + email + }, + authorizedApp + }) + if (userMatched.length) { + throw { + errCode: ERROR.ACCOUNT_EXISTS + } + } + const passwordUtils = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }) + const { + passwordHash, + version + } = passwordUtils.generatePasswordHash({ + password + }) + const data = { + username, + password: passwordHash, + password_secret_version: version, + dcloud_appid: authorizedApp || [], + nickname, + role: role || [], + mobile, + email, + tags: tags || [], + status + } + if (email) { + data.email_confirmed = 1 + } + if (mobile) { + data.mobile_confirmed = 1 + } + + await userCollection.add(data) + return { + errCode: 0, + errMsg: '' + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js new file mode 100644 index 0000000..c8830f5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js @@ -0,0 +1,4 @@ +module.exports = { + addUser: require('./add-user'), + updateUser: require('./update-user') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js new file mode 100644 index 0000000..085d64a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js @@ -0,0 +1,139 @@ +const { + findUser +} = require('../../lib/utils/account') +const { + ERROR +} = require('../../common/error') +const { + userCollection +} = require('../../common/constants') +const PasswordUtils = require('../../lib/utils/password') + +/** + * 修改用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user + * @param {Object} params + * @param {String} params.uid 要更新的用户id + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {Array} params.authorizedApp 允许登录的AppID列表 + * @param {Array} params.role 用户角色列表 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {Array} params.tags 用户标签 + * @param {Number} params.status 用户状态 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + uid: 'string', + username: 'username', + password: { + required: false, + type: 'password' + }, + authorizedApp: { + required: false, + type: 'array' + }, // 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录 + nickname: { + required: false, + type: 'nickname' + }, + role: { + require: false, + type: 'array' + }, + mobile: { + required: false, + type: 'mobile' + }, + email: { + required: false, + type: 'email' + }, + tags: { + required: false, + type: 'array' + }, + status: { + required: false, + type: 'number' + } + } + + this.middleware.validate(params, schema) + + const { + uid, + username, + password, + authorizedApp, + nickname, + role, + mobile, + email, + tags, + status + } = params + + // 更新的用户数据字段 + const data = { + username, + dcloud_appid: authorizedApp, + nickname, + role: role, + mobile, + email, + tags: tags, + status + } + + const realData = Object.keys(data).reduce((res, key) => { + const item = data[key] + if (item !== undefined) { + res[key] = item + } + return res + }, {}) + + // 更新用户名时验证用户名是否重新 + if (username) { + const { + userMatched + } = await findUser({ + userQuery: { + username + }, + authorizedApp + }) + if (userMatched.filter(user => user._id !== uid).length) { + throw { + errCode: ERROR.ACCOUNT_EXISTS + } + } + } + if (password) { + const passwordUtils = new PasswordUtils({ + clientInfo: this.getUniversalClientInfo(), + passwordSecret: this.config.passwordSecret + }) + const { + passwordHash, + version + } = passwordUtils.generatePasswordHash({ + password + }) + + realData.password = passwordHash + realData.password_secret_version = version + } + + await userCollection.doc(uid).update(realData) + + + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/get-supported-login-type.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/get-supported-login-type.js new file mode 100644 index 0000000..476e234 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/get-supported-login-type.js @@ -0,0 +1,71 @@ +function isMobileCodeSupported () { + const config = this.config + return !!(config.service && config.service.sms && config.service.sms.smsKey) +} + +function isUniverifySupport () { + const config = this.config + return !!(config.service && config.service.univerify && config.service.univerify.apiKey) +} + +function isWeixinSupported () { + this.configUtils.getOauthConfig({ + provider: 'weixin' + }) + return true +} + +function isQQSupported () { + this.configUtils.getOauthConfig({ + provider: 'qq' + }) + return true +} + +function isAppleSupported () { + this.configUtils.getOauthConfig({ + provider: 'apple' + }) + return true +} + +function isAlipaySupported () { + this.configUtils.getOauthConfig({ + provider: 'alipay' + }) + return true +} + +const loginTypeTester = { + 'mobile-code': isMobileCodeSupported, + univerify: isUniverifySupport, + weixin: isWeixinSupported, + qq: isQQSupported, + apple: isAppleSupported, + alipay: isAlipaySupported +} + +/** + * 获取支持的登录方式 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-supported-login-type + * @returns + */ +module.exports = async function () { + const supportedLoginType = [ + 'username-password', + 'mobile-password', + 'email-password' + ] + for (const type in loginTypeTester) { + try { + if (loginTypeTester[type].call(this)) { + supportedLoginType.push(type) + } + } catch (error) { } + } + return { + errCode: 0, + errMsg: '', + supportedLoginType + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/index.js new file mode 100644 index 0000000..e22f9f2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/dev/index.js @@ -0,0 +1,3 @@ +module.exports = { + getSupportedLoginType: require('./get-supported-login-type') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/index.js new file mode 100644 index 0000000..fe2ab8b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/index.js @@ -0,0 +1,4 @@ +module.exports = { + externalRegister: require('./register'), + externalLogin: require('./login') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/login.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/login.js new file mode 100644 index 0000000..2eccf09 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/login.js @@ -0,0 +1,29 @@ +const { preLogin, postLogin } = require('../../lib/utils/login') + +module.exports = async function (params = {}) { + const schema = { + unieid: 'username' + } + + this.middleware.validate(params, schema) + + const { + unieid + } = params + + const user = await preLogin.call(this, { + user: { + username: unieid + } + }) + + const result = await postLogin.call(this, { + user + }) + + return { + errCode: result.errCode, + newToken: result.newToken, + unieid + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/register.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/register.js new file mode 100644 index 0000000..ad65c1e --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/external/register.js @@ -0,0 +1,52 @@ +const { preRegister, postRegister } = require('../../lib/utils/register') + +module.exports = async function (params = {}) { + const schema = { + unieid: 'username', + nickname: { + required: false, + type: 'nickname' + }, + gender: { + required: false, + type: 'number' + }, + avatar: { + required: false, + type: 'string' + } + } + + this.middleware.validate(params, schema) + + const { + unieid, + avatar, + gender, + nickname + } = params + + await preRegister.call(this, { + user: { + username: unieid + } + }) + + const result = await postRegister.call(this, { + user: { + username: unieid, + avatar, + gender, + nickname + } + }) + + return { + errCode: result.errCode, + newToken: result.newToken, + unieid, + avatar, + gender, + nickname + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/accept-invite.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/accept-invite.js new file mode 100644 index 0000000..2461e06 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/accept-invite.js @@ -0,0 +1,25 @@ +const { + acceptInvite +} = require('../../lib/utils/fission') + +/** + * 接受邀请 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#accept-invite + * @param {Object} params + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + inviteCode: 'string' + } + this.middleware.validate(params, schema) + const { + inviteCode + } = params + const uid = this.authInfo.uid + return acceptInvite({ + uid, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/get-invited-user.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/get-invited-user.js new file mode 100644 index 0000000..93d4671 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/get-invited-user.js @@ -0,0 +1,80 @@ +const { + userCollection +} = require('../../common/constants') +const { + coverMobile +} = require('../../common/utils') + +/** + * 获取受邀用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-invited-user + * @param {Object} params + * @param {Number} params.level 获取受邀用户的级数,1表示直接邀请的用户 + * @param {Number} params.limit 返回数据大小 + * @param {Number} params.offset 返回数据偏移 + * @param {Boolean} params.needTotal 是否需要返回总数 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + level: 'number', + limit: { + required: false, + type: 'number' + }, + offset: { + required: false, + type: 'number' + }, + needTotal: { + required: false, + type: 'boolean' + } + } + this.middleware.validate(params, schema) + const { + level, + limit = 20, + offset = 0, + needTotal = false + } = params + const uid = this.authInfo.uid + const query = { + [`inviter_uid.${level - 1}`]: uid + } + const getUserRes = await userCollection.where(query) + .field({ + _id: true, + avatar: true, + avatar_file: true, + username: true, + nickname: true, + mobile: true, + invite_time: true + }) + .orderBy('invite_time', 'desc') + .skip(offset) + .limit(limit) + .get() + + const invitedUser = getUserRes.data.map(item => { + return { + uid: item._id, + username: item.username, + nickname: item.nickname, + mobile: coverMobile(item.mobile), + inviteTime: item.invite_time, + avatar: item.avatar, + avatarFile: item.avatar_file + } + }) + const result = { + errCode: 0, + invitedUser + } + if (needTotal) { + const getTotalRes = await userCollection.where(query).count() + result.total = getTotalRes.total + } + return result +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/index.js new file mode 100644 index 0000000..4a9bee1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/fission/index.js @@ -0,0 +1,4 @@ +module.exports = { + acceptInvite: require('./accept-invite'), + getInvitedUser: require('./get-invited-user') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/index.js new file mode 100644 index 0000000..f65f58b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/index.js @@ -0,0 +1,20 @@ +module.exports = { + login: require('./login'), + loginBySms: require('./login-by-sms'), + loginByUniverify: require('./login-by-univerify'), + loginByWeixin: require('./login-by-weixin'), + loginByAlipay: require('./login-by-alipay'), + loginByQQ: require('./login-by-qq'), + loginByApple: require('./login-by-apple'), + loginByBaidu: require('./login-by-baidu'), + loginByDingtalk: require('./login-by-dingtalk'), + loginByToutiao: require('./login-by-toutiao'), + loginByDouyin: require('./login-by-douyin'), + loginByWeibo: require('./login-by-weibo'), + loginByTaobao: require('./login-by-taobao'), + loginByEmailLink: require('./login-by-email-link'), + loginByEmailCode: require('./login-by-email-code'), + loginByFacebook: require('./login-by-facebook'), + loginByGoogle: require('./login-by-google'), + loginByWeixinMobile: require('./login-by-weixin-mobile') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-alipay.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-alipay.js new file mode 100644 index 0000000..d5d4631 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-alipay.js @@ -0,0 +1,70 @@ +const { + initAlipay +} = require('../../lib/third-party/index') +const { + ERROR +} = require('../../common/error') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + LOG_TYPE +} = require('../../common/constants') + +/** + * 支付宝登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-alipay + * @param {Object} params + * @param {String} params.code 支付宝小程序客户端登录返回的code + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: 'string', + inviteCode: { + type: 'string', + required: false + } + } + this.middleware.validate(params, schema) + const { + code, + inviteCode + } = params + const alipayApi = initAlipay.call(this) + let getAlipayAccountResult + try { + getAlipayAccountResult = await alipayApi.code2Session(code) + } catch (error) { + console.error(error) + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid + } = getAlipayAccountResult + + const { + type, + user + } = await preUnifiedLogin.call(this, { + user: { + ali_openid: openid + } + }) + return postUnifiedLogin.call(this, { + user, + extraData: {}, + isThirdParty: true, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-apple.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-apple.js new file mode 100644 index 0000000..5f39e62 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-apple.js @@ -0,0 +1,77 @@ +const { + initApple +} = require('../../lib/third-party/index') +const { + ERROR +} = require('../../common/error') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + LOG_TYPE +} = require('../../common/constants') + +/** + * 苹果登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-apple + * @param {Object} params + * @param {String} params.identityToken 苹果登录返回的identityToken + * @param {String} params.nickname 用户昵称 + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + identityToken: 'string', + nickname: { + required: false, + type: 'nickname' + }, + inviteCode: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + identityToken, + nickname, + inviteCode + } = params + const appleApi = initApple.call(this) + let verifyResult + try { + verifyResult = await appleApi.verifyIdentityToken(identityToken) + } catch (error) { + console.error(error) + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + const { + openid + } = verifyResult + + const { + type, + user + } = await preUnifiedLogin.call(this, { + user: { + apple_openid: openid + } + }) + return postUnifiedLogin.call(this, { + user, + extraData: { + nickname + }, + isThirdParty: true, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-baidu.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-baidu.js new file mode 100644 index 0000000..856449d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-baidu.js @@ -0,0 +1,9 @@ +/** + * 百度登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByBaidu] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-dingtalk.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-dingtalk.js new file mode 100644 index 0000000..afe1f01 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-dingtalk.js @@ -0,0 +1,9 @@ +/** + * 钉钉登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByDingtalk] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-douyin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-douyin.js new file mode 100644 index 0000000..8cd4ab5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-douyin.js @@ -0,0 +1,9 @@ +/** + * 抖音登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByDouyin] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-code.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-code.js new file mode 100644 index 0000000..c3af08f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-code.js @@ -0,0 +1,9 @@ +/** + * 邮箱验证码登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByEmailCode] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-link.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-link.js new file mode 100644 index 0000000..0ebbf3a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-email-link.js @@ -0,0 +1,9 @@ +/** + * 邮箱点击链接登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByEmailLink] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-facebook.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-facebook.js new file mode 100644 index 0000000..5c93bd4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-facebook.js @@ -0,0 +1,9 @@ +/** + * Facebook登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByFacebook] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-google.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-google.js new file mode 100644 index 0000000..8054ece --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-google.js @@ -0,0 +1,9 @@ +/** + * Google登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByGoogle] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-qq.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-qq.js new file mode 100644 index 0000000..fbc4069 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-qq.js @@ -0,0 +1,164 @@ +const { + initQQ +} = require('../../lib/third-party/index') +const { + ERROR +} = require('../../common/error') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + LOG_TYPE +} = require('../../common/constants') +const { + getQQPlatform, + generateQQCache, + saveQQUserKey +} = require('../../lib/utils/qq') +const url = require('url') + +/** + * QQ登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-qq + * @param {Object} params + * @param {String} params.code QQ小程序登录返回的code参数 + * @param {String} params.accessToken App端QQ登录返回的accessToken参数 + * @param {String} params.accessTokenExpired accessToken过期时间,由App端QQ登录返回的expires_in参数计算而来,单位:毫秒 + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: { + type: 'string', + required: false + }, + accessToken: { + type: 'string', + required: false + }, + accessTokenExpired: { + type: 'number', + required: false + }, + inviteCode: { + type: 'string', + required: false + } + } + this.middleware.validate(params, schema) + const { + code, + accessToken, + accessTokenExpired, + inviteCode + } = params + const { + appId + } = this.getUniversalClientInfo() + const qqApi = initQQ.call(this) + const qqPlatform = getQQPlatform.call(this) + let apiName + switch (qqPlatform) { + case 'mp': + apiName = 'code2Session' + break + case 'app': + apiName = 'getOpenidByToken' + break + default: + throw new Error('Unsupported qq platform') + } + let getQQAccountResult + try { + getQQAccountResult = await qqApi[apiName]({ + code, + accessToken + }) + } catch (error) { + console.error(error) + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid, + unionid, + // 保存下面的字段 + sessionKey // QQ小程序用户sessionKey + } = getQQAccountResult + + const { + type, + user + } = await preUnifiedLogin.call(this, { + user: { + qq_openid: { + [qqPlatform]: openid + }, + qq_unionid: unionid + } + }) + const extraData = { + qq_openid: { + [`${qqPlatform}_${appId}`]: openid + } + } + if (type === 'register' && qqPlatform !== 'mp') { + const { + nickname, + avatar + } = await qqApi.getUserInfo({ + accessToken, + openid + }) + // eslint-disable-next-line n/no-deprecated-api + const extName = url.parse(avatar).pathname.split('.').pop() + const cloudPath = `user/avatar/${openid.slice(-8) + Date.now()}-avatar.${extName}` + const getAvatarRes = await uniCloud.httpclient.request(avatar) + if (getAvatarRes.status >= 400) { + throw { + errCode: ERROR.GET_THIRD_PARTY_USER_INFO_FAILED + } + } + const { + fileID + } = await uniCloud.uploadFile({ + cloudPath, + fileContent: getAvatarRes.data + }) + extraData.nickname = nickname + extraData.avatar_file = { + name: cloudPath, + extname: extName, + url: fileID + } + } + await saveQQUserKey.call(this, { + openid, + sessionKey, + accessToken, + accessTokenExpired + }) + return postUnifiedLogin.call(this, { + user, + extraData: { + ...extraData, + ...generateQQCache.call(this, { + openid, + sessionKey, // QQ小程序用户sessionKey + accessToken, // App端QQ用户accessToken + accessTokenExpired // App端QQ用户accessToken过期时间 + }) + }, + isThirdParty: true, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js new file mode 100644 index 0000000..915e9b6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js @@ -0,0 +1,99 @@ +const { + getNeedCaptcha, + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + verifyMobileCode +} = require('../../lib/utils/verify-code') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + CAPTCHA_SCENE, + SMS_SCENE, + LOG_TYPE +} = require('../../common/constants') + +/** + * 短信验证码登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-sms + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.code 短信验证码 + * @param {String} params.captcha 图形验证码 + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + mobile: 'mobile', + code: 'string', + captcha: { + required: false, + type: 'string' + }, + inviteCode: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + mobile, + code, + captcha, + inviteCode + } = params + + const needCaptcha = await getNeedCaptcha.call(this, { + mobile + }) + + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.LOGIN_BY_SMS + }) + } + + try { + await verifyMobileCode({ + mobile, + code, + scene: SMS_SCENE.LOGIN_BY_SMS + }) + } catch (error) { + console.log(error, { + mobile, + code, + type: SMS_SCENE.LOGIN_BY_SMS + }) + await this.middleware.uniIdLog({ + success: false, + data: { + mobile + }, + type: LOG_TYPE.LOGIN + }) + throw error + } + + const { + type, + user + } = await preUnifiedLogin.call(this, { + user: { + mobile + } + }) + return postUnifiedLogin.call(this, { + user, + extraData: { + mobile_confirmed: 1 + }, + isThirdParty: false, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-taobao.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-taobao.js new file mode 100644 index 0000000..6a6d599 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-taobao.js @@ -0,0 +1,9 @@ +/** + * 淘宝登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByTaobao] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-toutiao.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-toutiao.js new file mode 100644 index 0000000..133aadb --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-toutiao.js @@ -0,0 +1,9 @@ +/** + * 头条登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByToutiao] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-univerify.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-univerify.js new file mode 100644 index 0000000..53e681c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-univerify.js @@ -0,0 +1,69 @@ +const { + getPhoneNumber +} = require('../../lib/utils/univerify') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + LOG_TYPE +} = require('../../common/constants') + +/** + * App端一键登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-univerify + * @param {Object} params + * @param {String} params.access_token APP端一键登录返回的access_token + * @param {String} params.openid APP端一键登录返回的openid + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + access_token: 'string', + openid: 'string', + inviteCode: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + // eslint-disable-next-line camelcase + access_token, + openid, + inviteCode + } = params + + let mobile + try { + const phoneInfo = await getPhoneNumber.call(this, { + // eslint-disable-next-line camelcase + access_token, + openid + }) + mobile = phoneInfo.phoneNumber + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw error + } + const { + user, + type + } = await preUnifiedLogin.call(this, { + user: { + mobile + } + }) + return postUnifiedLogin.call(this, { + user, + extraData: { + mobile_confirmed: 1 + }, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weibo.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weibo.js new file mode 100644 index 0000000..496cdb4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weibo.js @@ -0,0 +1,9 @@ +/** + * 微博登录 + * @param {Object} params + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[loginByWeibo] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin-mobile.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin-mobile.js new file mode 100644 index 0000000..c27c2b2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin-mobile.js @@ -0,0 +1,106 @@ +const { + initWeixin +} = require('../../lib/third-party/index') +const { + getWeixinAccessToken +} = require('../../lib/utils/weixin') +const { + ERROR +} = require('../../common/error') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + LOG_TYPE +} = require('../../common/constants') +const { + preBind, + postBind +} = require('../../lib/utils/relate') + +/** + * 微信授权手机号登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-weixin-mobile + * @param {Object} params + * @param {String} params.phoneCode 微信手机号返回的code + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + phoneCode: 'string', + inviteCode: { + type: 'string', + required: false + } + } + + this.middleware.validate(params, schema) + + const { phoneCode, inviteCode } = params + + const weixinApi = initWeixin.call(this) + let mobile + + try { + const accessToken = await getWeixinAccessToken.call(this) + const mobileRes = await weixinApi.getPhoneNumber(accessToken, phoneCode) + mobile = mobileRes.purePhoneNumber + } catch (error) { + console.error(error) + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { type, user } = await preUnifiedLogin.call(this, { + user: { + mobile + } + }) + + let extraData = { + mobile_confirmed: 1 + } + + if (type === 'login') { + // 绑定手机号 + if (!user.mobile_confirmed) { + const bindAccount = { + mobile + } + await preBind.call(this, { + uid: user._id, + bindAccount, + logType: LOG_TYPE.BIND_MOBILE + }) + await postBind.call(this, { + uid: user._id, + bindAccount, + extraData: { + mobile_confirmed: 1 + }, + logType: LOG_TYPE.BIND_MOBILE + }) + extraData = { + ...extraData, + ...bindAccount + } + } + } + + return postUnifiedLogin.call(this, { + user, + extraData: { + ...extraData + }, + isThirdParty: false, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin.js new file mode 100644 index 0000000..fb20db9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-weixin.js @@ -0,0 +1,175 @@ +const { + initWeixin +} = require('../../lib/third-party/index') +const { + ERROR +} = require('../../common/error') +const { + preUnifiedLogin, + postUnifiedLogin +} = require('../../lib/utils/unified-login') +const { + generateWeixinCache, + getWeixinPlatform, + saveWeixinUserKey, + saveSecureNetworkCache +} = require('../../lib/utils/weixin') +const { + LOG_TYPE +} = require('../../common/constants') +const url = require('url') + +/** + * 微信登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-weixin + * @param {Object} params + * @param {String} params.code 微信登录返回的code + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: 'string', + inviteCode: { + type: 'string', + required: false + } + } + this.middleware.validate(params, schema) + const { + code, + inviteCode, + // 内部参数,暂不暴露 + secureNetworkCache = false + } = params + const { + appId + } = this.getUniversalClientInfo() + const weixinApi = initWeixin.call(this) + const weixinPlatform = getWeixinPlatform.call(this) + let apiName + switch (weixinPlatform) { + case 'mp': + apiName = 'code2Session' + break + case 'app': + case 'h5': + case 'web': + apiName = 'getOauthAccessToken' + break + default: + throw new Error('Unsupported weixin platform') + } + let getWeixinAccountResult + try { + getWeixinAccountResult = await weixinApi[apiName](code) + } catch (error) { + console.error(error) + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.LOGIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid, + unionid, + // 保存下面四个字段 + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + expired: accessTokenExpired // App端微信用户accessToken过期时间 + } = getWeixinAccountResult + + if (secureNetworkCache) { + if (weixinPlatform !== 'mp') { + throw new Error('Unsupported weixin platform, expect mp-weixin') + } + await saveSecureNetworkCache({ + code, + openid, + unionid, + sessionKey + }) + } + + const { + type, + user + } = await preUnifiedLogin.call(this, { + user: { + wx_openid: { + [weixinPlatform]: openid + }, + wx_unionid: unionid + } + }) + const extraData = { + wx_openid: { + [`${weixinPlatform}_${appId}`]: openid + } + } + if (type === 'register' && weixinPlatform !== 'mp') { + const { + nickname, + avatar + } = await weixinApi.getUserInfo({ + accessToken, + openid + }) + + if (avatar) { + // eslint-disable-next-line n/no-deprecated-api + const avatarPath = url.parse(avatar).pathname + const extName = avatarPath.indexOf('.') > -1 ? url.parse(avatar).pathname.split('.').pop() : 'jpg' + const cloudPath = `user/avatar/${openid.slice(-8) + Date.now()}-avatar.${extName}` + const getAvatarRes = await uniCloud.httpclient.request(avatar) + if (getAvatarRes.status >= 400) { + throw { + errCode: ERROR.GET_THIRD_PARTY_USER_INFO_FAILED + } + } + + const { + fileID + } = await uniCloud.uploadFile({ + cloudPath, + fileContent: getAvatarRes.data + }) + + extraData.avatar_file = { + name: cloudPath, + extname: extName, + url: fileID + } + } + + extraData.nickname = nickname + } + await saveWeixinUserKey.call(this, { + openid, + sessionKey, + accessToken, + refreshToken, + accessTokenExpired + }) + return postUnifiedLogin.call(this, { + user, + extraData: { + ...extraData, + ...generateWeixinCache.call(this, { + openid, + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + accessTokenExpired // App端微信用户accessToken过期时间 + }) + }, + isThirdParty: true, + type, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login.js new file mode 100644 index 0000000..97e9cfe --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login.js @@ -0,0 +1,94 @@ +const { + preLoginWithPassword, + postLogin +} = require('../../lib/utils/login') +const { + getNeedCaptcha, + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + CAPTCHA_SCENE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +/** + * 用户名密码登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.mobile 手机号 + * @param {String} params.email 邮箱 + * @param {String} params.password 密码 + * @param {String} params.captcha 图形验证码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + username: { + required: false, + type: 'username' + }, + mobile: { + required: false, + type: 'mobile' + }, + email: { + required: false, + type: 'email' + }, + password: 'password', + captcha: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + username, + mobile, + email, + password, + captcha + } = params + if (!username && !mobile && !email) { + throw { + errCode: ERROR.INVALID_USERNAME + } + } else if ( + (username && email) || + (username && mobile) || + (email && mobile) + ) { + throw { + errCode: ERROR.INVALID_PARAM + } + } + const needCaptcha = await getNeedCaptcha.call(this, { + username, + mobile, + email + }) + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.LOGIN_BY_PWD + }) + } + const { + user, + extraData + } = await preLoginWithPassword.call(this, { + user: { + username, + mobile, + email + }, + password + }) + return postLogin.call(this, { + user, + extraData + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/index.js new file mode 100644 index 0000000..544be2b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/index.js @@ -0,0 +1,3 @@ +module.exports = { + logout: require('./logout') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js new file mode 100644 index 0000000..7d491c6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js @@ -0,0 +1,15 @@ +const { + logout +} = require('../../lib/utils/logout') + +/** + * 用户退出登录 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#logout + * @returns + */ +module.exports = async function () { + await logout.call(this) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/authorize-app-login.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/authorize-app-login.js new file mode 100644 index 0000000..8f8a167 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/authorize-app-login.js @@ -0,0 +1,37 @@ +const { + isAuthorizeApproved +} = require('./utils') +const { + dbCmd, + userCollection +} = require('../../common/constants') + +/** + * 授权用户登录应用 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#authorize-app-login + * @param {Object} params + * @param {String} params.uid 用户id + * @param {String} params.appId 授权的应用的AppId + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + uid: 'string', + appId: 'string' + } + this.middleware.validate(params, schema) + const { + uid, + appId + } = params + await isAuthorizeApproved({ + uid, + appIdList: [appId] + }) + await userCollection.doc(uid).update({ + dcloud_appid: dbCmd.push(appId) + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/index.js new file mode 100644 index 0000000..ce9cc7b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/index.js @@ -0,0 +1,5 @@ +module.exports = { + authorizeAppLogin: require('./authorize-app-login'), + removeAuthorizedApp: require('./remove-authorized-app'), + setAuthorizedApp: require('./set-authorized-app') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js new file mode 100644 index 0000000..df82184 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js @@ -0,0 +1,30 @@ +const { + dbCmd, + userCollection +} = require('../../common/constants') + +/** + * 移除用户登录授权 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#remove-authorized-app + * @param {Object} params + * @param {String} params.uid 用户id + * @param {String} params.appId 取消授权的应用的AppId + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + uid: 'string', + appId: 'string' + } + this.middleware.validate(params, schema) + const { + uid, + appId + } = params + await userCollection.doc(uid).update({ + dcloud_appid: dbCmd.pull(appId) + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/set-authorized-app.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/set-authorized-app.js new file mode 100644 index 0000000..a438ef9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/set-authorized-app.js @@ -0,0 +1,36 @@ +const { + isAuthorizeApproved +} = require('./utils') +const { + userCollection +} = require('../../common/constants') + +/** + * 设置用户允许登录的应用列表 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-authorized-app + * @param {Object} params + * @param {String} params.uid 用户id + * @param {Array} params.appIdList 允许登录的应用AppId列表 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + uid: 'string', + appIdList: 'array' + } + this.middleware.validate(params, schema) + const { + uid, + appIdList + } = params + await isAuthorizeApproved({ + uid, + appIdList + }) + await userCollection.doc(uid).update({ + dcloud_appid: appIdList + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js new file mode 100644 index 0000000..4ee4e26 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js @@ -0,0 +1,38 @@ +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + findUser +} = require('../../lib/utils/account') + +async function isAuthorizeApproved ({ + uid, + appIdList +} = {}) { + const getUserRes = await userCollection.doc(uid).get() + const userRecord = getUserRes.data[0] + if (!userRecord) { + throw { + errCode: ERROR.ACCOUNT_NOT_EXISTS + } + } + const { + userMatched + } = await findUser({ + userQuery: userRecord, + authorizedApp: appIdList + }) + + if (userMatched.some(item => item._id !== uid)) { + throw { + errCode: ERROR.ACCOUNT_CONFLICT + } + } +} + +module.exports = { + isAuthorizeApproved +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/index.js new file mode 100644 index 0000000..64ff603 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/index.js @@ -0,0 +1,5 @@ +module.exports = { + registerUser: require('./register-user'), + registerAdmin: require('./register-admin'), + registerUserByEmail: require('./register-user-by-email') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-admin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-admin.js new file mode 100644 index 0000000..5e122ab --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-admin.js @@ -0,0 +1,72 @@ +const { + userCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + preRegisterWithPassword, + postRegister +} = require('../../lib/utils/register') + +/** + * 注册管理员 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-admin + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + username: 'username', + password: 'password', + nickname: { + type: 'nickname', + required: false + } + } + this.middleware.validate(params, schema) + const { + username, + password, + nickname + } = params + const getAdminRes = await userCollection.where({ + role: 'admin' + }).limit(1).get() + if (getAdminRes.data.length > 0) { + const [admin] = getAdminRes.data + const appId = this.getUniversalClientInfo().appId + + if (!admin.dcloud_appid || (admin.dcloud_appid && admin.dcloud_appid.includes(appId))) { + return { + errCode: ERROR.ADMIN_EXISTS, + errMsg: this.t('uni-id-admin-exists') + } + } else { + return { + errCode: ERROR.ADMIN_EXISTS, + errMsg: this.t('uni-id-admin-exist-in-other-apps') + } + } + } + const { + user, + extraData + } = await preRegisterWithPassword.call(this, { + user: { + username + }, + password + }) + return postRegister.call(this, { + user, + extraData: { + ...extraData, + nickname, + role: ['admin'] + } + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user-by-email.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user-by-email.js new file mode 100644 index 0000000..b52c1d2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user-by-email.js @@ -0,0 +1,87 @@ +const { + postRegister, + preRegisterWithPassword +} = require('../../lib/utils/register') +const { + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + CAPTCHA_SCENE, + EMAIL_SCENE, + LOG_TYPE +} = require('../../common/constants') +const { + verifyEmailCode +} = require('../../lib/utils/verify-code') + +/** + * 通过邮箱+验证码注册普通用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-user-by-email + * @param {Object} params + * @param {String} params.email 邮箱 + * @param {String} params.password 密码 + * @param {String} params.nickname 昵称 + * @param {String} params.code 邮箱验证码 + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + email: 'email', + password: 'password', + nickname: { + required: false, + type: 'nickname' + }, + code: 'string', + inviteCode: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + email, + password, + nickname, + code, + inviteCode + } = params + + try { + // 验证邮箱验证码,验证不通过时写入失败日志 + await verifyEmailCode({ + email, + code, + scene: EMAIL_SCENE.REGISTER + }) + } catch (error) { + await this.middleware.uniIdLog({ + data: { + email + }, + type: LOG_TYPE.REGISTER, + success: false + }) + throw error + } + + const { + user, + extraData + } = await preRegisterWithPassword.call(this, { + user: { + email + }, + password + }) + return postRegister.call(this, { + user, + extraData: { + ...extraData, + nickname, + email_confirmed: 1 + }, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js new file mode 100644 index 0000000..130dece --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js @@ -0,0 +1,68 @@ +const { + postRegister, + preRegisterWithPassword +} = require('../../lib/utils/register') +const { + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + CAPTCHA_SCENE +} = require('../../common/constants') + +/** + * 注册普通用户 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-user + * @param {Object} params + * @param {String} params.username 用户名 + * @param {String} params.password 密码 + * @param {String} params.captcha 图形验证码 + * @param {String} params.nickname 昵称 + * @param {String} params.inviteCode 邀请码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + username: 'username', + password: 'password', + captcha: 'string', + nickname: { + required: false, + type: 'nickname' + }, + inviteCode: { + required: false, + type: 'string' + } + } + this.middleware.validate(params, schema) + const { + username, + password, + nickname, + captcha, + inviteCode + } = params + + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.REGISTER + }) + + const { + user, + extraData + } = await preRegisterWithPassword.call(this, { + user: { + username + }, + password + }) + return postRegister.call(this, { + user, + extraData: { + ...extraData, + nickname + }, + inviteCode + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-alipay.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-alipay.js new file mode 100644 index 0000000..bdb451b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-alipay.js @@ -0,0 +1,63 @@ +const { + preBind, + postBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + initAlipay +} = require('../../lib/third-party/index') + +/** + * 绑定支付宝账号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-alipay + * @param {Object} params + * @param {String} params.code 支付宝小程序登录返回的code参数 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: 'string' + } + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + const { + code + } = params + const alipayApi = initAlipay.call(this) + let getAlipayAccountResult + try { + getAlipayAccountResult = await alipayApi().code2Session(code) + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.BIND_ALIPAY + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid + } = getAlipayAccountResult + + const bindAccount = { + ali_openid: openid + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_APPLE + }) + return postBind.call(this, { + uid, + bindAccount, + extraData: {}, + logType: LOG_TYPE.BIND_APPLE + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-apple.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-apple.js new file mode 100644 index 0000000..eb87f8b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-apple.js @@ -0,0 +1,62 @@ +const { + preBind, + postBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + initApple +} = require('../../lib/third-party/index') + +/** + * 绑定苹果账号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-apple + * @param {Object} params + * @param {String} params.identityToken 苹果登录返回identityToken + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + identityToken: 'string' + } + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + const { + identityToken + } = params + const appleApi = initApple.call(this) + let verifyResult + try { + verifyResult = await appleApi.verifyIdentityToken(identityToken) + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.BIND_APPLE + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + const { + openid + } = verifyResult + + const bindAccount = { + apple_openid: openid + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_APPLE + }) + return postBind.call(this, { + uid, + bindAccount, + extraData: {}, + logType: LOG_TYPE.BIND_APPLE + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js new file mode 100644 index 0000000..f4c2bd0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js @@ -0,0 +1,104 @@ +const { + preBind, + postBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE +} = require('../../common/constants') +const { + decryptWeixinData, + getWeixinCache, getWeixinAccessToken +} = require('../../lib/utils/weixin') +const { initWeixin } = require('../../lib/third-party') +const { ERROR } = require('../../common/error') + +/** + * 通过微信绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-mp-weixin + * @param {Object} params + * @param {String} params.encryptedData 微信获取手机号返回的加密信息 + * @param {String} params.iv 微信获取手机号返回的初始向量 + * @param {String} params.code 微信获取手机号返回的code + * @returns + */ +module.exports = async function (params = {}) { + /** + * 微信小程序的规则是客户端应先使用checkSession接口检测上次获取的sessionKey是否仍有效 + * 如果有效则直接使用上次存储的sessionKey即可 + * 如果无效应重新调用login接口再次刷新sessionKey + * 因此此接口不应直接使用客户端login获取的code,只能使用缓存的sessionKey + */ + const schema = { + encryptedData: { + required: false, + type: 'string' + }, + iv: { + required: false, + type: 'string' + }, + code: { + required: false, + type: 'string' + } + } + const { + encryptedData, + iv, + code + } = params + this.middleware.validate(params, schema) + + if ((!encryptedData && !iv) && !code) { + return { + errCode: ERROR.INVALID_PARAM + } + } + + const uid = this.authInfo.uid + + let mobile + if (code) { + // 区分客户端类型 小程序还是App + const accessToken = await getWeixinAccessToken.call(this) + const weixinApi = initWeixin.call(this) + const res = await weixinApi.getPhoneNumber(accessToken, code) + + mobile = res.purePhoneNumber + } else { + const sessionKey = await getWeixinCache.call(this, { + uid, + key: 'session_key' + }) + if (!sessionKey) { + throw new Error('Session key not found') + } + const res = decryptWeixinData.call(this, { + encryptedData, + sessionKey, + iv + }) + + mobile = res.purePhoneNumber + } + + const bindAccount = { + mobile + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_MOBILE + }) + await postBind.call(this, { + uid, + bindAccount, + extraData: { + mobile_confirmed: 1 + }, + logType: LOG_TYPE.BIND_MOBILE + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js new file mode 100644 index 0000000..1640c2d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js @@ -0,0 +1,92 @@ +const { + getNeedCaptcha, + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + LOG_TYPE, + SMS_SCENE, + CAPTCHA_SCENE +} = require('../../common/constants') +const { + verifyMobileCode +} = require('../../lib/utils/verify-code') +const { + preBind, + postBind +} = require('../../lib/utils/relate') + +/** + * 通过短信验证码绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-sms + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.code 短信验证码 + * @param {String} params.captcha 图形验证码 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + mobile: 'mobile', + code: 'string', + captcha: { + type: 'string', + required: false + } + } + const { + mobile, + code, + captcha + } = params + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + + // 判断是否需要验证码 + const needCaptcha = await getNeedCaptcha.call(this, { + uid, + type: LOG_TYPE.BIND_MOBILE + }) + if (needCaptcha) { + await verifyCaptcha.call(this, { + captcha, + scene: CAPTCHA_SCENE.BIND_MOBILE_BY_SMS + }) + } + + try { + // 验证手机号验证码,验证不通过时写入失败日志 + await verifyMobileCode({ + mobile, + code, + scene: SMS_SCENE.BIND_MOBILE_BY_SMS + }) + } catch (error) { + await this.middleware.uniIdLog({ + data: { + user_id: uid + }, + type: LOG_TYPE.BIND_MOBILE, + success: false + }) + throw error + } + const bindAccount = { + mobile + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_MOBILE + }) + await postBind.call(this, { + uid, + bindAccount, + extraData: { + mobile_confirmed: 1 + }, + logType: LOG_TYPE.BIND_MOBILE + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-univerify.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-univerify.js new file mode 100644 index 0000000..2970c61 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-univerify.js @@ -0,0 +1,70 @@ +const { + getPhoneNumber +} = require('../../lib/utils/univerify') +const { + LOG_TYPE +} = require('../../common/constants') +const { + preBind, + postBind +} = require('../../lib/utils/relate') + +/** + * 通过一键登录绑定手机号 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-univerify + * @param {Object} params + * @param {String} params.openid APP端一键登录返回的openid + * @param {String} params.access_token APP端一键登录返回的access_token + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + openid: 'string', + access_token: 'string' + } + const { + openid, + // eslint-disable-next-line camelcase + access_token + } = params + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + let mobile + try { + const phoneInfo = await getPhoneNumber.call(this, { + // eslint-disable-next-line camelcase + access_token, + openid + }) + mobile = phoneInfo.phoneNumber + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + data: { + user_id: uid + }, + type: LOG_TYPE.BIND_MOBILE + }) + throw error + } + + const bindAccount = { + mobile + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_MOBILE + }) + await postBind.call(this, { + uid, + bindAccount, + extraData: { + mobile_confirmed: 1 + }, + logType: LOG_TYPE.BIND_MOBILE + }) + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-qq.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-qq.js new file mode 100644 index 0000000..574f917 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-qq.js @@ -0,0 +1,110 @@ +const { + preBind, + postBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +const { + initQQ +} = require('../../lib/third-party/index') +const { + generateQQCache, + getQQPlatform, + saveQQUserKey +} = require('../../lib/utils/qq') + +/** + * 绑定QQ + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-qq + * @param {Object} params + * @param {String} params.code 小程序端QQ登录返回的code + * @param {String} params.accessToken APP端QQ登录返回的accessToken + * @param {String} params.accessTokenExpired accessToken过期时间,由App端QQ登录返回的expires_in参数计算而来,单位:毫秒 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: { + type: 'string', + required: false + }, + accessToken: { + type: 'string', + required: false + }, + accessTokenExpired: { + type: 'number', + required: false + } + } + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + const { + code, + accessToken, + accessTokenExpired + } = params + const qqPlatform = getQQPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + const qqApi = initQQ.call(this) + const clientPlatform = this.clientPlatform + const apiName = clientPlatform === 'mp-qq' ? 'code2Session' : 'getOpenidByToken' + let getQQAccountResult + try { + getQQAccountResult = await qqApi[apiName]({ + code, + accessToken + }) + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.BIND_QQ + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid, + unionid, + // 保存下面四个字段 + sessionKey // 微信小程序用户sessionKey + } = getQQAccountResult + + const bindAccount = { + qq_openid: { + [qqPlatform]: openid + }, + qq_unionid: unionid + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_QQ + }) + await saveQQUserKey.call(this, { + openid, + sessionKey, + accessToken, + accessTokenExpired + }) + return postBind.call(this, { + uid, + bindAccount, + extraData: { + qq_openid: { + [`${qqPlatform}_${appId}`]: openid + }, + ...generateQQCache.call(this, { + openid, + sessionKey + }) + }, + logType: LOG_TYPE.BIND_QQ + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-weixin.js new file mode 100644 index 0000000..d649478 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-weixin.js @@ -0,0 +1,100 @@ +const { + preBind, + postBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE +} = require('../../common/constants') +const { + generateWeixinCache, + saveWeixinUserKey, + getWeixinPlatform +} = require('../../lib/utils/weixin') +const { + initWeixin +} = require('../../lib/third-party/index') +const { + ERROR +} = require('../../common/error') + +/** + * 绑定微信 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-weixin + * @param {Object} params + * @param {String} params.code 微信登录返回的code + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: 'string' + } + this.middleware.validate(params, schema) + const uid = this.authInfo.uid + const { + code + } = params + const weixinPlatform = getWeixinPlatform.call(this) + const appId = this.getUniversalClientInfo().appId + + const weixinApi = initWeixin.call(this) + const clientPlatform = this.clientPlatform + const apiName = clientPlatform === 'mp-weixin' ? 'code2Session' : 'getOauthAccessToken' + let getWeixinAccountResult + try { + getWeixinAccountResult = await weixinApi[apiName](code) + } catch (error) { + await this.middleware.uniIdLog({ + success: false, + type: LOG_TYPE.BIND_WEIXIN + }) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + + const { + openid, + unionid, + // 保存下面四个字段 + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + expired: accessTokenExpired // App端微信用户accessToken过期时间 + } = getWeixinAccountResult + + const bindAccount = { + wx_openid: { + [weixinPlatform]: openid + }, + wx_unionid: unionid + } + await preBind.call(this, { + uid, + bindAccount, + logType: LOG_TYPE.BIND_WEIXIN + }) + await saveWeixinUserKey.call(this, { + openid, + sessionKey, + accessToken, + refreshToken, + accessTokenExpired + }) + return postBind.call(this, { + uid, + bindAccount, + extraData: { + wx_openid: { + [`${weixinPlatform}_${appId}`]: openid + }, + ...generateWeixinCache.call(this, { + openid, + sessionKey, // 微信小程序用户sessionKey + accessToken, // App端微信用户accessToken + refreshToken, // App端微信用户refreshToken + accessTokenExpired // App端微信用户accessToken过期时间 + }) + }, + logType: LOG_TYPE.BIND_WEIXIN + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/index.js new file mode 100644 index 0000000..4d99c02 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/index.js @@ -0,0 +1,13 @@ +module.exports = { + bindMobileBySms: require('./bind-mobile-by-sms'), + bindMobileByUniverify: require('./bind-mobile-by-univerify'), + bindMobileByMpWeixin: require('./bind-mobile-by-mp-weixin'), + bindAlipay: require('./bind-alipay'), + bindApple: require('./bind-apple'), + bindQQ: require('./bind-qq'), + bindWeixin: require('./bind-weixin'), + unbindWeixin: require('./unbind-weixin'), + unbindAlipay: require('./unbind-alipay'), + unbindQQ: require('./unbind-qq'), + unbindApple: require('./unbind-apple') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-alipay.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-alipay.js new file mode 100644 index 0000000..67bb43b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-alipay.js @@ -0,0 +1,32 @@ +const { + preUnBind, + postUnBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE, dbCmd +} = require('../../common/constants') + +/** + * 解绑支付宝 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-alipay + * @returns + */ +module.exports = async function () { + const { uid } = this.authInfo + + await preUnBind.call(this, { + uid, + unBindAccount: { + ali_openid: dbCmd.exists(true) + }, + logType: LOG_TYPE.UNBIND_ALIPAY + }) + + return await postUnBind.call(this, { + uid, + unBindAccount: { + ali_openid: dbCmd.remove() + }, + logType: LOG_TYPE.UNBIND_ALIPAY + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-apple.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-apple.js new file mode 100644 index 0000000..111c1bf --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-apple.js @@ -0,0 +1,32 @@ +const { + preUnBind, + postUnBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE, dbCmd +} = require('../../common/constants') + +/** + * 解绑apple + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-apple + * @returns + */ +module.exports = async function () { + const { uid } = this.authInfo + + await preUnBind.call(this, { + uid, + unBindAccount: { + apple_openid: dbCmd.exists(true) + }, + logType: LOG_TYPE.UNBIND_APPLE + }) + + return await postUnBind.call(this, { + uid, + unBindAccount: { + apple_openid: dbCmd.remove() + }, + logType: LOG_TYPE.UNBIND_APPLE + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-qq.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-qq.js new file mode 100644 index 0000000..0f9e02e --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-qq.js @@ -0,0 +1,46 @@ +const { + preUnBind, + postUnBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE, dbCmd +} = require('../../common/constants') +const { + getQQPlatform +} = require('../../lib/utils/qq') + +/** + * 解绑QQ + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-qq + * @returns + */ +module.exports = async function () { + const { uid } = this.authInfo + const { appId } = this.getUniversalClientInfo() + const qqPlatform = getQQPlatform.call(this) + + await preUnBind.call(this, { + uid, + unBindAccount: { + qq_openid: dbCmd.or([ + { + [qqPlatform]: dbCmd.exists(true) + }, + { + [`${qqPlatform}_${appId}`]: dbCmd.exists(true) + } + ]), + qq_unionid: dbCmd.exists(true) + }, + logType: LOG_TYPE.UNBIND_QQ + }) + + return await postUnBind.call(this, { + uid, + unBindAccount: { + qq_openid: dbCmd.remove(), + qq_unionid: dbCmd.remove() + }, + logType: LOG_TYPE.UNBIND_QQ + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-weixin.js new file mode 100644 index 0000000..8770bbd --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/unbind-weixin.js @@ -0,0 +1,40 @@ +const { + preUnBind, + postUnBind +} = require('../../lib/utils/relate') +const { + LOG_TYPE, dbCmd +} = require('../../common/constants') +const { + getWeixinPlatform +} = require('../../lib/utils/weixin') + +/** + * 解绑微信 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-weixin + * @returns + */ +module.exports = async function () { + const { uid } = this.authInfo + const weixinPlatform = getWeixinPlatform.call(this) + + await preUnBind.call(this, { + uid, + unBindAccount: { + wx_openid: { + [weixinPlatform]: dbCmd.exists(true) + }, + wx_unionid: dbCmd.exists(true) + }, + logType: LOG_TYPE.UNBIND_WEIXIN + }) + + return await postUnBind.call(this, { + uid, + unBindAccount: { + wx_openid: dbCmd.remove(), + wx_unionid: dbCmd.remove() + }, + logType: LOG_TYPE.UNBIND_WEIXIN + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/index.js new file mode 100644 index 0000000..0ec67a5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/index.js @@ -0,0 +1,5 @@ +module.exports = { + refreshToken: require('./refresh-token'), + setPushCid: require('./set-push-cid'), + secureNetworkHandshakeByWeixin: require('./secure-network-handshake-by-weixin') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/refresh-token.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/refresh-token.js new file mode 100644 index 0000000..4b0d0a8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/refresh-token.js @@ -0,0 +1,19 @@ +/** + * 刷新token + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#refresh-token + */ +module.exports = async function () { + const { + token, + tokenExpired + } = await this.uniIdCommon.refreshToken({ + token: this.getUniversalUniIdToken() + }) + return { + errCode: 0, + newToken: { + token, + tokenExpired + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/secure-network-handshake-by-weixin.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/secure-network-handshake-by-weixin.js new file mode 100644 index 0000000..82ea0b3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/secure-network-handshake-by-weixin.js @@ -0,0 +1,73 @@ +const { + ERROR +} = require('../../common/error') +const { + initWeixin +} = require('../../lib/third-party/index') +const { + saveWeixinUserKey, + saveSecureNetworkCache +} = require('../../lib/utils/weixin') +const loginByWeixin = require('../login/login-by-weixin') +/** + * 微信安全网络握手 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-push-cid + * @param {object} params + * @param {string} params.code 微信登录返回的code + * @param {boolean} params.callLoginByWeixin 是否同时调用一次微信登录 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + code: 'string', + callLoginByWeixin: { + type: 'boolean', + required: false + } + } + this.middleware.validate(params, schema) + let platform = this.clientPlatform + if (platform !== 'mp-weixin') { + throw new Error(`[secureNetworkHandshake] platform ${platform} is not supported`) + } + const { + code, + callLoginByWeixin = false + } = params + if (callLoginByWeixin) { + return loginByWeixin.call(this, { + code, + secureNetworkCache: true + }) + } + + const weixinApi = initWeixin.call(this) + let getWeixinAccountResult + try { + getWeixinAccountResult = await weixinApi.code2Session(code) + } catch (error) { + console.error(error) + throw { + errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED + } + } + const { + openid, + unionid, + sessionKey // 微信小程序用户sessionKey + } = getWeixinAccountResult + await saveSecureNetworkCache.call(this, { + code, + openid, + unionid, + sessionKey + }) + await saveWeixinUserKey.call(this, { + openid, + sessionKey + }) + + return { + errCode: 0 + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js new file mode 100644 index 0000000..326b4ff --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js @@ -0,0 +1,141 @@ +const { + deviceCollection +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +async function setOpendbDevice ({ + pushClientId +} = {}) { + // 仅新增,如果存在进行更新操作 + const { + appId, + deviceId, + deviceBrand, + deviceModel, + osName, + osVersion, + osLanguage, + osTheme, + devicePixelRatio, + windowWidth, + windowHeight, + screenWidth, + screenHeight, + romName, + romVersion + } = this.getUniversalClientInfo() + const platform = this.clientPlatform + const now = Date.now() + + const db = uniCloud.database() + const opendbDeviceCollection = db.collection('opendb-device') + const getDeviceRes = await opendbDeviceCollection.where({ + device_id: deviceId + }).get() + const data = { + appid: appId, + device_id: deviceId, + vendor: deviceBrand, + model: deviceModel, + uni_platform: platform, + os_name: osName, + os_version: osVersion, + os_language: osLanguage, + os_theme: osTheme, + pixel_ratio: devicePixelRatio, + window_width: windowWidth, + window_height: windowHeight, + screen_width: screenWidth, + screen_height: screenHeight, + rom_name: romName, + rom_version: romVersion, + last_update_date: now, + push_clientid: pushClientId + } + if (getDeviceRes.data.length > 0) { + await opendbDeviceCollection.where({ + device_id: deviceId + }).update(data) + return + } + data.create_date = now + await opendbDeviceCollection.add(data) +} + +/** + * 更新device表的push_clien_id + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-push-cid + * @param {object} params + * @param {string} params.pushClientId 客户端pushClientId + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + pushClientId: 'string' + } + this.middleware.validate(params, schema) + const { + deviceId, + appId, + osName + } = this.getUniversalClientInfo() + let platform = this.clientPlatform + if (platform === 'app') { + platform += osName + } + + const { + uid, + exp + } = this.authInfo + const { pushClientId } = params + const tokenExpired = exp * 1000 + const getDeviceRes = await deviceCollection.where({ + device_id: deviceId + }).get() + // console.log(getDeviceRes) + if (getDeviceRes.data.length > 1) { + return { + errCode: ERROR.SYSTEM_ERROR + } + } + const deviceRecord = getDeviceRes.data[0] + await setOpendbDevice.call(this, { + pushClientId + }) + if (!deviceRecord) { + await deviceCollection.add({ + user_id: uid, + device_id: deviceId, + token_expired: tokenExpired, + push_clientid: pushClientId, + appid: appId + }) + return { + errCode: 0 + } + } + // 同一用户允许更新token_expired,不同用户在token_expired小于Date.now()时允许更新。搭配逻辑:用户退出登录时将token_expired置0 + if ( + deviceRecord.user_id === uid || + (deviceRecord.token_expired < Date.now()) + ) { + await deviceCollection.where({ + device_id: deviceId + }).update({ + user_id: uid, + token_expired: tokenExpired, + push_clientid: pushClientId, + appid: appId + }) + return { + errCode: 0 + } + } + + return { + errCode: ERROR.SYSTEM_ERROR + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/create-captcha.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/create-captcha.js new file mode 100644 index 0000000..9103d5b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/create-captcha.js @@ -0,0 +1,34 @@ +const { + CAPTCHA_SCENE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +/** + * 创建图形验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#create-captcha + * @param {Object} params + * @param {String} params.scene 图形验证码使用场景 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + scene: 'string' + } + this.middleware.validate(params, schema) + + const deviceId = this.getUniversalClientInfo().deviceId + const { + scene + } = params + if (!(Object.values(CAPTCHA_SCENE).includes(scene))) { + throw { + errCode: ERROR.INVALID_PARAM + } + } + return this.uniCaptcha.create({ + deviceId, + scene + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/index.js new file mode 100644 index 0000000..fba3524 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/index.js @@ -0,0 +1,7 @@ +module.exports = { + createCaptcha: require('./create-captcha'), + refreshCaptcha: require('./refresh-captcha'), + sendSmsCode: require('./send-sms-code'), + sendEmailLink: require('./send-email-link'), + sendEmailCode: require('./send-email-code') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/refresh-captcha.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/refresh-captcha.js new file mode 100644 index 0000000..7a1cab9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/refresh-captcha.js @@ -0,0 +1,34 @@ +const { + CAPTCHA_SCENE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +/** + * 刷新图形验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#refresh-captcha + * @param {Object} params + * @param {String} params.scene 图形验证码使用场景 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + scene: 'string' + } + this.middleware.validate(params, schema) + + const deviceId = this.getUniversalClientInfo().deviceId + const { + scene + } = params + if (!(Object.values(CAPTCHA_SCENE).includes(scene))) { + throw { + errCode: ERROR.INVALID_PARAM + } + } + return this.uniCaptcha.refresh({ + deviceId, + scene + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-code.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-code.js new file mode 100644 index 0000000..1a6304d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-code.js @@ -0,0 +1,60 @@ +const { + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + EMAIL_SCENE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') +/** + * 发送邮箱验证码,可用于登录、注册、绑定邮箱、修改密码等操作 + * @tutorial + * @param {Object} params + * @param {String} params.email 邮箱 + * @param {String} params.captcha 图形验证码 + * @param {String} params.scene 使用场景 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + email: 'email', + captcha: 'string', + scene: 'string' + } + this.middleware.validate(params, schema) + + const { + email, + captcha, + scene + } = params + + if (!(Object.values(EMAIL_SCENE).includes(scene))) { + throw { + errCode: ERROR.INVALID_PARAM + } + } + + await verifyCaptcha.call(this, { + scene: 'send-email-code', + captcha + }) + + // -- 测试代码 + await require('../../lib/utils/verify-code') + .setEmailVerifyCode.call(this, { + email, + code: '123456', + expiresIn: 180, + scene + }) + return { + errCode: 'uni-id-invalid-mail-template', + errMsg: `已启动测试模式,直接使用:123456作为邮箱验证码即可。\n如果是正式项目,需自行实现发送邮件的相关功能` + } + // -- 测试代码 + + + //发送邮件--需自行实现 +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-link.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-link.js new file mode 100644 index 0000000..f643434 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-email-link.js @@ -0,0 +1,12 @@ +/** + * 发送邮箱链接,可用于登录、注册、绑定邮箱、修改密码等操作 + * @tutorial + * @param {Object} params + * @param {String} params.email 邮箱 + * @param {String} params.scene 使用场景 + * @returns + */ +module.exports = async function (params = {}) { + // 此接口暂未实现,欢迎向我们提交pr + throw new Error('api[sendEmailLink] is not yet implemented') +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-sms-code.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-sms-code.js new file mode 100644 index 0000000..b392e7e --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/verify/send-sms-code.js @@ -0,0 +1,71 @@ +const { + sendSmsCode +} = require('../../lib/utils/sms') +const { + verifyCaptcha +} = require('../../lib/utils/captcha') +const { + SMS_SCENE +} = require('../../common/constants') +const { + ERROR +} = require('../../common/error') + +/** + * 发送短信验证码 + * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#send-sms-code + * @param {Object} params + * @param {String} params.mobile 手机号 + * @param {String} params.captcha 图形验证码 + * @param {String} params.scene 短信验证码使用场景 + * @returns + */ +module.exports = async function (params = {}) { + const schema = { + mobile: 'mobile', + captcha: 'string', + scene: 'string' + } + this.middleware.validate(params, schema) + const { + mobile, + captcha, + scene + } = params + if (!(Object.values(SMS_SCENE).includes(scene))) { + throw { + errCode: ERROR.INVALID_PARAM + } + } + await verifyCaptcha.call(this, { + scene: 'send-sms-code', + captcha + }) + + // -- 测试代码 + const { + templateId + } = (this.config.service && + this.config.service.sms && + this.config.service.sms.scene && + this.config.service.sms.scene[scene]) || {} + if (!templateId) { + await require('../../lib/utils/verify-code') + .setMobileVerifyCode.call(this, { + mobile: params.mobile, + code: '123456', + expiresIn: 180, + scene + }) + return { + errCode: 'uni-id-invalid-sms-template-id', + errMsg: `未找到scene=${scene},的短信模版templateId。\n已启动测试模式,直接使用:123456作为短信验证码即可。\n如果是正式项目,请在路径:/common/uni-config-center/uni-id/config.json中service->sms中配置密钥等信息\n更多详情:https://uniapp.dcloud.io/uniCloud/uni-id.html#config` + } + } + // -- 测试代码 + + return sendSmsCode.call(this, { + mobile, + scene + }) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver new file mode 100644 index 0000000..10497aa --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../semver/bin/semver" "$@" + ret=$? +else + node "$basedir/../semver/bin/semver" "$@" + ret=$? +fi +exit $ret diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.cmd b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.cmd new file mode 100644 index 0000000..eb3aaa1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.cmd @@ -0,0 +1,17 @@ +@ECHO off +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +"%_prog%" "%dp0%\..\semver\bin\semver" %* +ENDLOCAL +EXIT /b %errorlevel% +:find_dp0 +SET dp0=%~dp0 +EXIT /b diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.ps1 b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.ps1 new file mode 100644 index 0000000..a3315ff --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/.bin/semver.ps1 @@ -0,0 +1,18 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + & "$basedir/node$exe" "$basedir/../semver/bin/semver" $args + $ret=$LASTEXITCODE +} else { + & "node$exe" "$basedir/../semver/bin/semver" $args + $ret=$LASTEXITCODE +} +exit $ret diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.npmignore b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.npmignore new file mode 100644 index 0000000..34e4f5c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.npmignore @@ -0,0 +1,2 @@ +.*.sw[mnop] +node_modules/ diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.travis.yml b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.travis.yml new file mode 100644 index 0000000..78e1c01 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: +- "0.11" +- "0.10" diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/LICENSE.txt b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/LICENSE.txt new file mode 100644 index 0000000..9a064f3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/LICENSE.txt @@ -0,0 +1,12 @@ +Copyright (c) 2013, GoInstant Inc., a salesforce.com company +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of salesforce.com, nor GoInstant, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/README.md new file mode 100644 index 0000000..4f227f5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/README.md @@ -0,0 +1,50 @@ +# buffer-equal-constant-time + +Constant-time `Buffer` comparison for node.js. Should work with browserify too. + +[![Build Status](https://travis-ci.org/goinstant/buffer-equal-constant-time.png?branch=master)](https://travis-ci.org/goinstant/buffer-equal-constant-time) + +```sh + npm install buffer-equal-constant-time +``` + +# Usage + +```js + var bufferEq = require('buffer-equal-constant-time'); + + var a = new Buffer('asdf'); + var b = new Buffer('asdf'); + if (bufferEq(a,b)) { + // the same! + } else { + // different in at least one byte! + } +``` + +If you'd like to install an `.equal()` method onto the node.js `Buffer` and +`SlowBuffer` prototypes: + +```js + require('buffer-equal-constant-time').install(); + + var a = new Buffer('asdf'); + var b = new Buffer('asdf'); + if (a.equal(b)) { + // the same! + } else { + // different in at least one byte! + } +``` + +To get rid of the installed `.equal()` method, call `.restore()`: + +```js + require('buffer-equal-constant-time').restore(); +``` + +# Legal + +© 2013 GoInstant Inc., a salesforce.com company + +Licensed under the BSD 3-clause license. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/index.js new file mode 100644 index 0000000..5462c1f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/index.js @@ -0,0 +1,41 @@ +/*jshint node:true */ +'use strict'; +var Buffer = require('buffer').Buffer; // browserify +var SlowBuffer = require('buffer').SlowBuffer; + +module.exports = bufferEq; + +function bufferEq(a, b) { + + // shortcutting on type is necessary for correctness + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + return false; + } + + // buffer sizes should be well-known information, so despite this + // shortcutting, it doesn't leak any information about the *contents* of the + // buffers. + if (a.length !== b.length) { + return false; + } + + var c = 0; + for (var i = 0; i < a.length; i++) { + /*jshint bitwise:false */ + c |= a[i] ^ b[i]; // XOR + } + return c === 0; +} + +bufferEq.install = function() { + Buffer.prototype.equal = SlowBuffer.prototype.equal = function equal(that) { + return bufferEq(this, that); + }; +}; + +var origBufEqual = Buffer.prototype.equal; +var origSlowBufEqual = SlowBuffer.prototype.equal; +bufferEq.restore = function() { + Buffer.prototype.equal = origBufEqual; + SlowBuffer.prototype.equal = origSlowBufEqual; +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/package.json new file mode 100644 index 0000000..85a5890 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/package.json @@ -0,0 +1,55 @@ +{ + "_from": "buffer-equal-constant-time@1.0.1", + "_id": "buffer-equal-constant-time@1.0.1", + "_inBundle": false, + "_integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "_location": "/buffer-equal-constant-time", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "buffer-equal-constant-time@1.0.1", + "name": "buffer-equal-constant-time", + "escapedName": "buffer-equal-constant-time", + "rawSpec": "1.0.1", + "saveSpec": null, + "fetchSpec": "1.0.1" + }, + "_requiredBy": [ + "/jwa" + ], + "_resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "_shasum": "f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819", + "_spec": "buffer-equal-constant-time@1.0.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jwa", + "author": { + "name": "GoInstant Inc., a salesforce.com company" + }, + "bugs": { + "url": "https://github.com/goinstant/buffer-equal-constant-time/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Constant-time comparison of Buffers", + "devDependencies": { + "mocha": "~1.15.1" + }, + "homepage": "https://github.com/goinstant/buffer-equal-constant-time#readme", + "keywords": [ + "buffer", + "equal", + "constant-time", + "crypto" + ], + "license": "BSD-3-Clause", + "main": "index.js", + "name": "buffer-equal-constant-time", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/goinstant/buffer-equal-constant-time.git" + }, + "scripts": { + "test": "mocha test.js" + }, + "version": "1.0.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/test.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/test.js new file mode 100644 index 0000000..0bc972d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/buffer-equal-constant-time/test.js @@ -0,0 +1,42 @@ +/*jshint node:true */ +'use strict'; + +var bufferEq = require('./index'); +var assert = require('assert'); + +describe('buffer-equal-constant-time', function() { + var a = new Buffer('asdfasdf123456'); + var b = new Buffer('asdfasdf123456'); + var c = new Buffer('asdfasdf'); + + describe('bufferEq', function() { + it('says a == b', function() { + assert.strictEqual(bufferEq(a, b), true); + }); + + it('says a != c', function() { + assert.strictEqual(bufferEq(a, c), false); + }); + }); + + describe('install/restore', function() { + before(function() { + bufferEq.install(); + }); + after(function() { + bufferEq.restore(); + }); + + it('installed an .equal method', function() { + var SlowBuffer = require('buffer').SlowBuffer; + assert.ok(Buffer.prototype.equal); + assert.ok(SlowBuffer.prototype.equal); + }); + + it('infected existing Buffers', function() { + assert.strictEqual(a.equal(b), true); + assert.strictEqual(a.equal(c), false); + }); + }); + +}); diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/CODEOWNERS b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/CODEOWNERS new file mode 100644 index 0000000..4451d3d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/CODEOWNERS @@ -0,0 +1 @@ +* @omsmith diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/LICENSE new file mode 100644 index 0000000..8754ed6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015 D2L Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/README.md new file mode 100644 index 0000000..daa95d6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/README.md @@ -0,0 +1,65 @@ +# ecdsa-sig-formatter + +[![Build Status](https://travis-ci.org/Brightspace/node-ecdsa-sig-formatter.svg?branch=master)](https://travis-ci.org/Brightspace/node-ecdsa-sig-formatter) [![Coverage Status](https://coveralls.io/repos/Brightspace/node-ecdsa-sig-formatter/badge.svg)](https://coveralls.io/r/Brightspace/node-ecdsa-sig-formatter) + +Translate between JOSE and ASN.1/DER encodings for ECDSA signatures + +## Install +```sh +npm install ecdsa-sig-formatter --save +``` + +## Usage +```js +var format = require('ecdsa-sig-formatter'); + +var derSignature = '..'; // asn.1/DER encoded ecdsa signature + +var joseSignature = format.derToJose(derSignature); + +``` + +### API + +--- + +#### `.derToJose(Buffer|String signature, String alg)` -> `String` + +Convert the ASN.1/DER encoded signature to a JOSE-style concatenated signature. +Returns a _base64 url_ encoded `String`. + +* If _signature_ is a `String`, it should be _base64_ encoded +* _alg_ must be one of _ES256_, _ES384_ or _ES512_ + +--- + +#### `.joseToDer(Buffer|String signature, String alg)` -> `Buffer` + +Convert the JOSE-style concatenated signature to an ASN.1/DER encoded +signature. Returns a `Buffer` + +* If _signature_ is a `String`, it should be _base64 url_ encoded +* _alg_ must be one of _ES256_, _ES384_ or _ES512_ + +## Contributing + +1. **Fork** the repository. Committing directly against this repository is + highly discouraged. + +2. Make your modifications in a branch, updating and writing new unit tests + as necessary in the `spec` directory. + +3. Ensure that all tests pass with `npm test` + +4. `rebase` your changes against master. *Do not merge*. + +5. Submit a pull request to this repository. Wait for tests to run and someone + to chime in. + +### Code Style + +This repository is configured with [EditorConfig][EditorConfig] and +[ESLint][ESLint] rules. + +[EditorConfig]: http://editorconfig.org/ +[ESLint]: http://eslint.org diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/package.json new file mode 100644 index 0000000..d549849 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/package.json @@ -0,0 +1,73 @@ +{ + "_from": "ecdsa-sig-formatter@1.0.11", + "_id": "ecdsa-sig-formatter@1.0.11", + "_inBundle": false, + "_integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "_location": "/ecdsa-sig-formatter", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "ecdsa-sig-formatter@1.0.11", + "name": "ecdsa-sig-formatter", + "escapedName": "ecdsa-sig-formatter", + "rawSpec": "1.0.11", + "saveSpec": null, + "fetchSpec": "1.0.11" + }, + "_requiredBy": [ + "/jwa" + ], + "_resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "_shasum": "ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf", + "_spec": "ecdsa-sig-formatter@1.0.11", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jwa", + "author": { + "name": "D2L Corporation" + }, + "bugs": { + "url": "https://github.com/Brightspace/node-ecdsa-sig-formatter/issues" + }, + "bundleDependencies": false, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "deprecated": false, + "description": "Translate ECDSA signatures between ASN.1/DER and JOSE-style concatenation", + "devDependencies": { + "bench": "^0.3.6", + "chai": "^3.5.0", + "coveralls": "^2.11.9", + "eslint": "^2.12.0", + "eslint-config-brightspace": "^0.2.1", + "istanbul": "^0.4.3", + "jwk-to-pem": "^1.2.5", + "mocha": "^2.5.3", + "native-crypto": "^1.7.0" + }, + "homepage": "https://github.com/Brightspace/node-ecdsa-sig-formatter#readme", + "keywords": [ + "ecdsa", + "der", + "asn.1", + "jwt", + "jwa", + "jsonwebtoken", + "jose" + ], + "license": "Apache-2.0", + "main": "src/ecdsa-sig-formatter.js", + "name": "ecdsa-sig-formatter", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Brightspace/node-ecdsa-sig-formatter.git" + }, + "scripts": { + "check-style": "eslint .", + "pretest": "npm run check-style", + "report-cov": "cat ./coverage/lcov.info | coveralls", + "test": "istanbul cover --root src _mocha -- spec" + }, + "typings": "./src/ecdsa-sig-formatter.d.ts", + "version": "1.0.11" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.d.ts b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.d.ts new file mode 100644 index 0000000..9693aa0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.d.ts @@ -0,0 +1,17 @@ +/// + +declare module "ecdsa-sig-formatter" { + /** + * Convert the ASN.1/DER encoded signature to a JOSE-style concatenated signature. Returns a base64 url encoded String. + * If signature is a String, it should be base64 encoded + * alg must be one of ES256, ES384 or ES512 + */ + export function derToJose(signature: Buffer | string, alg: string): string; + + /** + * Convert the JOSE-style concatenated signature to an ASN.1/DER encoded signature. Returns a Buffer + * If signature is a String, it should be base64 url encoded + * alg must be one of ES256, ES384 or ES512 + */ + export function joseToDer(signature: Buffer | string, alg: string): Buffer +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js new file mode 100644 index 0000000..38eeb9b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js @@ -0,0 +1,187 @@ +'use strict'; + +var Buffer = require('safe-buffer').Buffer; + +var getParamBytesForAlg = require('./param-bytes-for-alg'); + +var MAX_OCTET = 0x80, + CLASS_UNIVERSAL = 0, + PRIMITIVE_BIT = 0x20, + TAG_SEQ = 0x10, + TAG_INT = 0x02, + ENCODED_TAG_SEQ = (TAG_SEQ | PRIMITIVE_BIT) | (CLASS_UNIVERSAL << 6), + ENCODED_TAG_INT = TAG_INT | (CLASS_UNIVERSAL << 6); + +function base64Url(base64) { + return base64 + .replace(/=/g, '') + .replace(/\+/g, '-') + .replace(/\//g, '_'); +} + +function signatureAsBuffer(signature) { + if (Buffer.isBuffer(signature)) { + return signature; + } else if ('string' === typeof signature) { + return Buffer.from(signature, 'base64'); + } + + throw new TypeError('ECDSA signature must be a Base64 string or a Buffer'); +} + +function derToJose(signature, alg) { + signature = signatureAsBuffer(signature); + var paramBytes = getParamBytesForAlg(alg); + + // the DER encoded param should at most be the param size, plus a padding + // zero, since due to being a signed integer + var maxEncodedParamLength = paramBytes + 1; + + var inputLength = signature.length; + + var offset = 0; + if (signature[offset++] !== ENCODED_TAG_SEQ) { + throw new Error('Could not find expected "seq"'); + } + + var seqLength = signature[offset++]; + if (seqLength === (MAX_OCTET | 1)) { + seqLength = signature[offset++]; + } + + if (inputLength - offset < seqLength) { + throw new Error('"seq" specified length of "' + seqLength + '", only "' + (inputLength - offset) + '" remaining'); + } + + if (signature[offset++] !== ENCODED_TAG_INT) { + throw new Error('Could not find expected "int" for "r"'); + } + + var rLength = signature[offset++]; + + if (inputLength - offset - 2 < rLength) { + throw new Error('"r" specified length of "' + rLength + '", only "' + (inputLength - offset - 2) + '" available'); + } + + if (maxEncodedParamLength < rLength) { + throw new Error('"r" specified length of "' + rLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); + } + + var rOffset = offset; + offset += rLength; + + if (signature[offset++] !== ENCODED_TAG_INT) { + throw new Error('Could not find expected "int" for "s"'); + } + + var sLength = signature[offset++]; + + if (inputLength - offset !== sLength) { + throw new Error('"s" specified length of "' + sLength + '", expected "' + (inputLength - offset) + '"'); + } + + if (maxEncodedParamLength < sLength) { + throw new Error('"s" specified length of "' + sLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); + } + + var sOffset = offset; + offset += sLength; + + if (offset !== inputLength) { + throw new Error('Expected to consume entire buffer, but "' + (inputLength - offset) + '" bytes remain'); + } + + var rPadding = paramBytes - rLength, + sPadding = paramBytes - sLength; + + var dst = Buffer.allocUnsafe(rPadding + rLength + sPadding + sLength); + + for (offset = 0; offset < rPadding; ++offset) { + dst[offset] = 0; + } + signature.copy(dst, offset, rOffset + Math.max(-rPadding, 0), rOffset + rLength); + + offset = paramBytes; + + for (var o = offset; offset < o + sPadding; ++offset) { + dst[offset] = 0; + } + signature.copy(dst, offset, sOffset + Math.max(-sPadding, 0), sOffset + sLength); + + dst = dst.toString('base64'); + dst = base64Url(dst); + + return dst; +} + +function countPadding(buf, start, stop) { + var padding = 0; + while (start + padding < stop && buf[start + padding] === 0) { + ++padding; + } + + var needsSign = buf[start + padding] >= MAX_OCTET; + if (needsSign) { + --padding; + } + + return padding; +} + +function joseToDer(signature, alg) { + signature = signatureAsBuffer(signature); + var paramBytes = getParamBytesForAlg(alg); + + var signatureBytes = signature.length; + if (signatureBytes !== paramBytes * 2) { + throw new TypeError('"' + alg + '" signatures must be "' + paramBytes * 2 + '" bytes, saw "' + signatureBytes + '"'); + } + + var rPadding = countPadding(signature, 0, paramBytes); + var sPadding = countPadding(signature, paramBytes, signature.length); + var rLength = paramBytes - rPadding; + var sLength = paramBytes - sPadding; + + var rsBytes = 1 + 1 + rLength + 1 + 1 + sLength; + + var shortLength = rsBytes < MAX_OCTET; + + var dst = Buffer.allocUnsafe((shortLength ? 2 : 3) + rsBytes); + + var offset = 0; + dst[offset++] = ENCODED_TAG_SEQ; + if (shortLength) { + // Bit 8 has value "0" + // bits 7-1 give the length. + dst[offset++] = rsBytes; + } else { + // Bit 8 of first octet has value "1" + // bits 7-1 give the number of additional length octets. + dst[offset++] = MAX_OCTET | 1; + // length, base 256 + dst[offset++] = rsBytes & 0xff; + } + dst[offset++] = ENCODED_TAG_INT; + dst[offset++] = rLength; + if (rPadding < 0) { + dst[offset++] = 0; + offset += signature.copy(dst, offset, 0, paramBytes); + } else { + offset += signature.copy(dst, offset, rPadding, paramBytes); + } + dst[offset++] = ENCODED_TAG_INT; + dst[offset++] = sLength; + if (sPadding < 0) { + dst[offset++] = 0; + signature.copy(dst, offset, paramBytes); + } else { + signature.copy(dst, offset, paramBytes + sPadding); + } + + return dst; +} + +module.exports = { + derToJose: derToJose, + joseToDer: joseToDer +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js new file mode 100644 index 0000000..9fe67ac --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js @@ -0,0 +1,23 @@ +'use strict'; + +function getParamSize(keySize) { + var result = ((keySize / 8) | 0) + (keySize % 8 === 0 ? 0 : 1); + return result; +} + +var paramBytesForAlg = { + ES256: getParamSize(256), + ES384: getParamSize(384), + ES512: getParamSize(521) +}; + +function getParamBytesForAlg(alg) { + var paramBytes = paramBytesForAlg[alg]; + if (paramBytes) { + return paramBytes; + } + + throw new Error('Unknown algorithm "' + alg + '"'); +} + +module.exports = getParamBytesForAlg; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/CHANGELOG.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/CHANGELOG.md new file mode 100644 index 0000000..54364a2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/CHANGELOG.md @@ -0,0 +1,476 @@ +# Change Log + + +All notable changes to this project will be documented in this file starting from version **v4.0.0**. +This project adheres to [Semantic Versioning](http://semver.org/). + +## 8.5.1 - 2019-03-18 + +### Bug fix + + - fix: ensure correct PS signing and verification (#585) ([e5874ae428ffc0465e6bd4e660f89f78b56a74a6](https://github.com/auth0/node-jsonwebtoken/commit/e5874ae428ffc0465e6bd4e660f89f78b56a74a6)), closes [#585](https://github.com/auth0/node-jsonwebtoken/issues/585) + +### Docs + + - README: fix markdown for algorithms table ([84e03ef70f9c44a3aef95a1dc122c8238854f683](https://github.com/auth0/node-jsonwebtoken/commit/84e03ef70f9c44a3aef95a1dc122c8238854f683)) + +## 8.5.0 - 2019-02-20 + +### New Functionality + + - feat: add PS JWA support for applicable node versions (#573) ([eefb9d9c6eec54718fa6e41306bda84788df7bec](https://github.com/auth0/node-jsonwebtoken/commit/eefb9d9c6eec54718fa6e41306bda84788df7bec)), closes [#573](https://github.com/auth0/node-jsonwebtoken/issues/573) + - Add complete option in jwt.verify (#522) ([8737789dd330cf9e7870f4df97fd52479adbac22](https://github.com/auth0/node-jsonwebtoken/commit/8737789dd330cf9e7870f4df97fd52479adbac22)), closes [#522](https://github.com/auth0/node-jsonwebtoken/issues/522) + + ### Test Improvements + + - Add tests for private claims in the payload (#555) ([5147852896755dc1291825e2e40556f964411fb2](https://github.com/auth0/node-jsonwebtoken/commit/5147852896755dc1291825e2e40556f964411fb2)), closes [#555](https://github.com/auth0/node-jsonwebtoken/issues/555) + - Force use_strict during testing (#577) ([7b60c127ceade36c33ff33be066e435802001c94](https://github.com/auth0/node-jsonwebtoken/commit/7b60c127ceade36c33ff33be066e435802001c94)), closes [#577](https://github.com/auth0/node-jsonwebtoken/issues/577) + - Refactor tests related to jti and jwtid (#544) ([7eebbc75ab89e01af5dacf2aae90fe05a13a1454](https://github.com/auth0/node-jsonwebtoken/commit/7eebbc75ab89e01af5dacf2aae90fe05a13a1454)), closes [#544](https://github.com/auth0/node-jsonwebtoken/issues/544) + - ci: remove nsp from tests (#569) ([da8f55c3c7b4dd0bfc07a2df228500fdd050242a](https://github.com/auth0/node-jsonwebtoken/commit/da8f55c3c7b4dd0bfc07a2df228500fdd050242a)), closes [#569](https://github.com/auth0/node-jsonwebtoken/issues/569) + +### Docs + +- Fix 'cert' token which isn't a cert (#554) ([0c24fe68cd2866cea6322016bf993cd897fefc98](https://github.com/auth0/node-jsonwebtoken/commit/0c24fe68cd2866cea6322016bf993cd897fefc98)), closes [#554](https://github.com/auth0/node-jsonwebtoken/issues/554) + + +## 8.4.0 - 2018-11-14 + +### New Functionality + + - Add verify option for nonce validation (#540) ([e7938f06fdf2ed3aa88745b72b8ae4ee66c2d0d0](https://github.com/auth0/node-jsonwebtoken/commit/e7938f06fdf2ed3aa88745b72b8ae4ee66c2d0d0)), closes [#540](https://github.com/auth0/node-jsonwebtoken/issues/540) + +### Bug Fixes + + - Updating Node version in Engines spec in package.json (#528) ([cfd1079305170a897dee6a5f55039783e6ee2711](https://github.com/auth0/node-jsonwebtoken/commit/cfd1079305170a897dee6a5f55039783e6ee2711)), closes [#528](https://github.com/auth0/node-jsonwebtoken/issues/528) [#509](https://github.com/auth0/node-jsonwebtoken/issues/509) + - Fixed error message when empty string passed as expiresIn or notBefore option (#531) ([7f9604ac98d4d0ff8d873c3d2b2ea64bd285cb76](https://github.com/auth0/node-jsonwebtoken/commit/7f9604ac98d4d0ff8d873c3d2b2ea64bd285cb76)), closes [#531](https://github.com/auth0/node-jsonwebtoken/issues/531) + +### Docs + + - Update README.md (#527) ([b76f2a80f5229ee5cde321dd2ff14aa5df16d283](https://github.com/auth0/node-jsonwebtoken/commit/b76f2a80f5229ee5cde321dd2ff14aa5df16d283)), closes [#527](https://github.com/auth0/node-jsonwebtoken/issues/527) + - Update README.md (#538) ([1956c4006472fd285b8a85074257cbdbe9131cbf](https://github.com/auth0/node-jsonwebtoken/commit/1956c4006472fd285b8a85074257cbdbe9131cbf)), closes [#538](https://github.com/auth0/node-jsonwebtoken/issues/538) + - Edited the README.md to make certain parts of the document for the api easier to read, emphasizing the examples. (#548) ([dc89a641293d42f72ecfc623ce2eabc33954cb9d](https://github.com/auth0/node-jsonwebtoken/commit/dc89a641293d42f72ecfc623ce2eabc33954cb9d)), closes [#548](https://github.com/auth0/node-jsonwebtoken/issues/548) + - Document NotBeforeError (#529) ([29cd654b956529e939ae8f8c30b9da7063aad501](https://github.com/auth0/node-jsonwebtoken/commit/29cd654b956529e939ae8f8c30b9da7063aad501)), closes [#529](https://github.com/auth0/node-jsonwebtoken/issues/529) + +### Test Improvements + + - Use lolex for faking date in tests (#491) ([677ead6d64482f2067b11437dda07309abe73cfa](https://github.com/auth0/node-jsonwebtoken/commit/677ead6d64482f2067b11437dda07309abe73cfa)), closes [#491](https://github.com/auth0/node-jsonwebtoken/issues/491) + - Update dependencies used for running tests (#518) ([5498bdc4865ffb2ba2fd44d889fad7e83873bb33](https://github.com/auth0/node-jsonwebtoken/commit/5498bdc4865ffb2ba2fd44d889fad7e83873bb33)), closes [#518](https://github.com/auth0/node-jsonwebtoken/issues/518) + - Minor test refactoring for recently added tests (#504) ([e2860a9d2a412627d79741a95bc7159971b923b9](https://github.com/auth0/node-jsonwebtoken/commit/e2860a9d2a412627d79741a95bc7159971b923b9)), closes [#504](https://github.com/auth0/node-jsonwebtoken/issues/504) + - Create and implement async/sync test helpers (#523) ([683d8a9b31ad6327948f84268bd2c8e4350779d1](https://github.com/auth0/node-jsonwebtoken/commit/683d8a9b31ad6327948f84268bd2c8e4350779d1)), closes [#523](https://github.com/auth0/node-jsonwebtoken/issues/523) + - Refactor tests related to audience and aud (#503) ([53d405e0223cce7c83cb51ecf290ca6bec1e9679](https://github.com/auth0/node-jsonwebtoken/commit/53d405e0223cce7c83cb51ecf290ca6bec1e9679)), closes [#503](https://github.com/auth0/node-jsonwebtoken/issues/503) + - Refactor tests related to expiresIn and exp (#501) ([72f0d9e5b11a99082250665d1200c58182903fa6](https://github.com/auth0/node-jsonwebtoken/commit/72f0d9e5b11a99082250665d1200c58182903fa6)), closes [#501](https://github.com/auth0/node-jsonwebtoken/issues/501) + - Refactor tests related to iat and maxAge (#507) ([877bd57ab2aca9b7d230805b21f921baed3da169](https://github.com/auth0/node-jsonwebtoken/commit/877bd57ab2aca9b7d230805b21f921baed3da169)), closes [#507](https://github.com/auth0/node-jsonwebtoken/issues/507) + - Refactor tests related to iss and issuer (#543) ([0906a3fa80f52f959ac1b6343d3024ce5c7e9dea](https://github.com/auth0/node-jsonwebtoken/commit/0906a3fa80f52f959ac1b6343d3024ce5c7e9dea)), closes [#543](https://github.com/auth0/node-jsonwebtoken/issues/543) + - Refactor tests related to kid and keyid (#545) ([88645427a0adb420bd3e149199a2a6bf1e17277e](https://github.com/auth0/node-jsonwebtoken/commit/88645427a0adb420bd3e149199a2a6bf1e17277e)), closes [#545](https://github.com/auth0/node-jsonwebtoken/issues/545) + - Refactor tests related to notBefore and nbf (#497) ([39adf87a6faef3df984140f88e6724ddd709fd89](https://github.com/auth0/node-jsonwebtoken/commit/39adf87a6faef3df984140f88e6724ddd709fd89)), closes [#497](https://github.com/auth0/node-jsonwebtoken/issues/497) + - Refactor tests related to subject and sub (#505) ([5a7fa23c0b4ac6c25304dab8767ef840b43a0eca](https://github.com/auth0/node-jsonwebtoken/commit/5a7fa23c0b4ac6c25304dab8767ef840b43a0eca)), closes [#505](https://github.com/auth0/node-jsonwebtoken/issues/505) + - Implement async/sync tests for exp claim (#536) ([9ae3f207ac64b7450ea0a3434418f5ca58d8125e](https://github.com/auth0/node-jsonwebtoken/commit/9ae3f207ac64b7450ea0a3434418f5ca58d8125e)), closes [#536](https://github.com/auth0/node-jsonwebtoken/issues/536) + - Implement async/sync tests for nbf claim (#537) ([88bc965061ed65299a395f42a100fb8f8c3c683e](https://github.com/auth0/node-jsonwebtoken/commit/88bc965061ed65299a395f42a100fb8f8c3c683e)), closes [#537](https://github.com/auth0/node-jsonwebtoken/issues/537) + - Implement async/sync tests for sub claim (#534) ([342b07bb105a35739eb91265ba5b9dd33c300fc6](https://github.com/auth0/node-jsonwebtoken/commit/342b07bb105a35739eb91265ba5b9dd33c300fc6)), closes [#534](https://github.com/auth0/node-jsonwebtoken/issues/534) + - Implement async/sync tests for the aud claim (#535) ([1c8ff5a68e6da73af2809c9d87faaf78602c99bb](https://github.com/auth0/node-jsonwebtoken/commit/1c8ff5a68e6da73af2809c9d87faaf78602c99bb)), closes [#535](https://github.com/auth0/node-jsonwebtoken/issues/535) + +### CI + + - Added Istanbul to check test-coverage (#468) ([9676a8306428a045e34c3987bd0680fb952b44e3](https://github.com/auth0/node-jsonwebtoken/commit/9676a8306428a045e34c3987bd0680fb952b44e3)), closes [#468](https://github.com/auth0/node-jsonwebtoken/issues/468) + - Complete ESLint conversion and cleanup (#490) ([cb1d2e1e40547f7ecf29fa6635041df6cbba7f40](https://github.com/auth0/node-jsonwebtoken/commit/cb1d2e1e40547f7ecf29fa6635041df6cbba7f40)), closes [#490](https://github.com/auth0/node-jsonwebtoken/issues/490) + - Make code-coverage mandatory when running tests (#495) ([fb0084a78535bfea8d0087c0870e7e3614a2cbe5](https://github.com/auth0/node-jsonwebtoken/commit/fb0084a78535bfea8d0087c0870e7e3614a2cbe5)), closes [#495](https://github.com/auth0/node-jsonwebtoken/issues/495) + + +## 8.3.0 - 2018-06-11 + + - docs: add some clarifications (#473) ([cd33cc81f06068b9df6c224d300dc6f70d8904ab](https://github.com/auth0/node-jsonwebtoken/commit/cd33cc81f06068b9df6c224d300dc6f70d8904ab)), closes [#473](https://github.com/auth0/node-jsonwebtoken/issues/473) + - ci: fix ci execution, remove not needed script (#472) ([c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5](https://github.com/auth0/node-jsonwebtoken/commit/c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5)), closes [#472](https://github.com/auth0/node-jsonwebtoken/issues/472) + - new feature: Secret callback revisited (#480) ([d01cc7bcbdeb606d997a580f967b3169fcc622ba](https://github.com/auth0/node-jsonwebtoken/commit/d01cc7bcbdeb606d997a580f967b3169fcc622ba)), closes [#480](https://github.com/auth0/node-jsonwebtoken/issues/480) + - docs:Update README.md (#461) ([f0e0954505f274da95a8d9603598e455b4d2c894](https://github.com/auth0/node-jsonwebtoken/commit/f0e0954505f274da95a8d9603598e455b4d2c894)), closes [#461](https://github.com/auth0/node-jsonwebtoken/issues/461) + + +## 8.2.2 - 2018-05-30 + + - security: deps: jws@3.1.5 (#477) ([ebde9b7cc75cb7ab5176de7ebc4a1d6a8f05bd51](https://github.com/auth0/node-jsonwebtoken/commit/ebde9b7cc75cb7ab5176de7ebc4a1d6a8f05bd51)), closes [#465](https://github.com/auth0/node-jsonwebtoken/issues/465) + - docs: add some clarifications (#473) ([cd33cc81f06068b9df6c224d300dc6f70d8904ab](https://github.com/auth0/node-jsonwebtoken/commit/cd33cc81f06068b9df6c224d300dc6f70d8904ab)), closes [#473](https://github.com/auth0/node-jsonwebtoken/issues/473) + - ci: fix ci execution, remove not needed script (#472) ([c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5](https://github.com/auth0/node-jsonwebtoken/commit/c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5)), closes [#472](https://github.com/auth0/node-jsonwebtoken/issues/472) + - docs: Update README.md (#461) ([f0e0954505f274da95a8d9603598e455b4d2c894](https://github.com/auth0/node-jsonwebtoken/commit/f0e0954505f274da95a8d9603598e455b4d2c894)), closes [#461](https://github.com/auth0/node-jsonwebtoken/issues/461) + + +## 8.2.1 - 2018-04-05 + + - bug fix: Check payload is not null when decoded. (#444) ([1232ae9352ce5fd1ca6c593291ce6ad0834a1ff5](https://github.com/auth0/node-jsonwebtoken/commit/1232ae9352ce5fd1ca6c593291ce6ad0834a1ff5)) + - docs: Clarify that buffer/string payloads must be JSON (#442) ([e8ac1be7565a3fd986d40cb5e31a9f6c4d9aed1b](https://github.com/auth0/node-jsonwebtoken/commit/e8ac1be7565a3fd986d40cb5e31a9f6c4d9aed1b)) + + +## 8.2.0 - 2018-03-02 + + - Add a new mutatePayload option (#446) ([d6d7c5e5103f05a92d3633ac190d3025a0455be0](https://github.com/auth0/node-jsonwebtoken/commit/d6d7c5e5103f05a92d3633ac190d3025a0455be0)) + + +## 8.1.1 - 2018-01-22 + + - ci: add newer node versions to build matrix (#428) ([83f3eee44e122da06f812d7da4ace1fa26c24d9d](https://github.com/auth0/node-jsonwebtoken/commit/83f3eee44e122da06f812d7da4ace1fa26c24d9d)) + - deps: Bump ms version to add support for negative numbers (#438) ([25e0e624545eaef76f3c324a134bf103bc394724](https://github.com/auth0/node-jsonwebtoken/commit/25e0e624545eaef76f3c324a134bf103bc394724)) + - docs: Minor typo (#424) ([dddcb73ac05de11b81feeb629f6cf78dd03d2047](https://github.com/auth0/node-jsonwebtoken/commit/dddcb73ac05de11b81feeb629f6cf78dd03d2047)) + - bug fix: Not Before (nbf) calculated based on iat/timestamp (#437) ([2764a64908d97c043d62eba0bf6c600674f9a6d6](https://github.com/auth0/node-jsonwebtoken/commit/2764a64908d97c043d62eba0bf6c600674f9a6d6)), closes [#435](https://github.com/auth0/node-jsonwebtoken/issues/435) + + +## 8.1.0 - 2017-10-09 + + - #402: Don't fail if captureStackTrace is not a function (#410) ([77ee965d9081faaf21650f266399f203f69533c5](https://github.com/auth0/node-jsonwebtoken/commit/77ee965d9081faaf21650f266399f203f69533c5)) + - #403: Clarify error wording for "Expected object" error. (#409) ([bb27eb346f0ff675a320b2de16b391a7cfeadc58](https://github.com/auth0/node-jsonwebtoken/commit/bb27eb346f0ff675a320b2de16b391a7cfeadc58)) + - Enhance audience check to verify against regular expressions (#398) ([81501a17da230af7b74a3f7535ab5cd3a19c8315](https://github.com/auth0/node-jsonwebtoken/commit/81501a17da230af7b74a3f7535ab5cd3a19c8315)) + + +## 8.0.1 - 2017-09-12 + + - Remove `lodash.isarray` dependency (#394) ([7508e8957cb1c778f72fa9a363a7b135b3c9c36d](https://github.com/auth0/node-jsonwebtoken/commit/7508e8957cb1c778f72fa9a363a7b135b3c9c36d)) + +## 8.0.0 - 2017-09-06 + + **Breaking changes: See [Migration notes from v7](https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v7-to-v8)** + + - docs: readme, migration notes ([12cd8f7f47224f904f6b8f39d1dee73775de4f6f](https://github.com/auth0/node-jsonwebtoken/commit/12cd8f7f47224f904f6b8f39d1dee73775de4f6f)) + - verify: remove process.nextTick (#302) ([3305cf04e3f674b9fb7e27c9b14ddd159650ff82](https://github.com/auth0/node-jsonwebtoken/commit/3305cf04e3f674b9fb7e27c9b14ddd159650ff82)) + - Reduce size of NPM package (#347) ([0be5409ac6592eeaae373dce91ec992fa101bd8a](https://github.com/auth0/node-jsonwebtoken/commit/0be5409ac6592eeaae373dce91ec992fa101bd8a)) + - Remove joi to shrink module size (#348) ([2e7e68dbd59e845cdd940afae0a296f48438445f](https://github.com/auth0/node-jsonwebtoken/commit/2e7e68dbd59e845cdd940afae0a296f48438445f)) + - maxAge: Add validation to timespan result ([66a4f8b996c8357727ce62a84605a005b2f5eb18](https://github.com/auth0/node-jsonwebtoken/commit/66a4f8b996c8357727ce62a84605a005b2f5eb18)) + +## 7.4.3 - 2017-08-17 + + - Fix breaking change on 7.4.2 for empty secret + "none" algorithm (sync code style) ([PR 386](https://github.com/auth0/node-jsonwebtoken/pull/386)) + +## 7.4.2 - 2017-08-04 + + - bugfix: sign: add check to be sure secret has a value ([c584d1cbc34b788977b36f17cd57ab2212f1230e](https://github.com/auth0/node-jsonwebtoken/commit/c584d1cbc34b788977b36f17cd57ab2212f1230e)) + - docs: about refreshing tokens ([016fc10b847bfbb76b82171cb530f32d7da2001b](https://github.com/auth0/node-jsonwebtoken/commit/016fc10b847bfbb76b82171cb530f32d7da2001b)) + - docs: verifying with base64 encoded secrets ([c25e9906801f89605080cc71b3ee23a5e45a5811](https://github.com/auth0/node-jsonwebtoken/commit/c25e9906801f89605080cc71b3ee23a5e45a5811)) + - tests: Add tests for ES256 ([89900ea00735f76b04f437c9f542285b420fa9cb](https://github.com/auth0/node-jsonwebtoken/commit/89900ea00735f76b04f437c9f542285b420fa9cb)) + - docs: document keyid as option (#361) ([00086c2c006d7fc1a47bae02fa87d194d79aa558](https://github.com/auth0/node-jsonwebtoken/commit/00086c2c006d7fc1a47bae02fa87d194d79aa558)) + - docs: readme: Using private key with passpharase (#353) ([27a7f1d4f35b662426ff0270526d48658da4c8b7](https://github.com/auth0/node-jsonwebtoken/commit/27a7f1d4f35b662426ff0270526d48658da4c8b7)) + +## 7.4.1 - 2017-05-17 + + - bump ms to v2 due a ReDoS vulnerability (#352) ([adcfd6ae4088c838769d169f8cd9154265aa13e0](https://github.com/auth0/node-jsonwebtoken/commit/adcfd6ae4088c838769d169f8cd9154265aa13e0)) + +## 7.4.0 - 2017-04-24 + + - Add docs about numeric date fields ([659f73119900a4d837650d9b3f5af4e64a2f843b](https://github.com/auth0/node-jsonwebtoken/commit/659f73119900a4d837650d9b3f5af4e64a2f843b)) + - Make Options object optional for callback-ish sign ([e202c4fd00c35a24e9ab606eab89186ade13d0cc](https://github.com/auth0/node-jsonwebtoken/commit/e202c4fd00c35a24e9ab606eab89186ade13d0cc)) + +## 7.3.0 - 2017-02-13 + + - Add more information to `maxAge` option in README ([1b0592e99cc8def293eed177e2575fa7f1cf7aa5](https://github.com/auth0/node-jsonwebtoken/commit/1b0592e99cc8def293eed177e2575fa7f1cf7aa5)) + - Add `clockTimestamp` option to `verify()` you can set the current time in seconds with it (#274) ([8fdc1504f4325e7003894ffea078da9cba5208d9](https://github.com/auth0/node-jsonwebtoken/commit/8fdc1504f4325e7003894ffea078da9cba5208d9)) + - Fix handling non string tokens on `verify()` input (#305) ([1b6ec8d466504f58c5a6e2dae3360c828bad92fb](https://github.com/auth0/node-jsonwebtoken/commit/1b6ec8d466504f58c5a6e2dae3360c828bad92fb)), closes [#305](https://github.com/auth0/node-jsonwebtoken/issues/305) + - Fixed a simple typo in docs (#287) ([a54240384e24e18c00e75884295306db311d0cb7](https://github.com/auth0/node-jsonwebtoken/commit/a54240384e24e18c00e75884295306db311d0cb7)), closes [#287](https://github.com/auth0/node-jsonwebtoken/issues/287) + - Raise jws.decode error to avoid confusion with "invalid token" error (#294) ([7f68fe06c88d5c5653785bd66bc68c5b20e1bd8e](https://github.com/auth0/node-jsonwebtoken/commit/7f68fe06c88d5c5653785bd66bc68c5b20e1bd8e)) + - rauchg/ms.js changed to zeit/ms (#303) ([35d84152a6b716d757cb5b1dd3c79fe3a1bc0628](https://github.com/auth0/node-jsonwebtoken/commit/35d84152a6b716d757cb5b1dd3c79fe3a1bc0628)) + +## 7.2.1 - 2016-12-07 + + - add nsp check to find vulnerabilities on npm test ([4219c34b5346811c07f520f10516cc495bcc70dd](https://github.com/auth0/node-jsonwebtoken/commit/4219c34b5346811c07f520f10516cc495bcc70dd)) + - revert to joi@^6 to keep ES5 compatibility ([51d4796c07344bf817687f7ccfeef78f00bf5b4f](https://github.com/auth0/node-jsonwebtoken/commit/51d4796c07344bf817687f7ccfeef78f00bf5b4f)) + +## 7.2.0 - 2016-12-06 + + - improve the documentation for expiration ([771e0b5f9bed90771fb79140eb38e51a3ecac8f0](https://github.com/auth0/node-jsonwebtoken/commit/771e0b5f9bed90771fb79140eb38e51a3ecac8f0)) + - Restructured a sentence ([ccc7610187a862f7a50177eadc9152eef26cd065](https://github.com/auth0/node-jsonwebtoken/commit/ccc7610187a862f7a50177eadc9152eef26cd065)) + - Allow `keyid` on `sign`. ([b412be91b89acb3a742bb609d3b54e47e1dfc441](https://github.com/auth0/node-jsonwebtoken/commit/b412be91b89acb3a742bb609d3b54e47e1dfc441)) + - upgrade joi ([715e3d928023d414d45c6dc3f096a7c8448139ae](https://github.com/auth0/node-jsonwebtoken/commit/715e3d928023d414d45c6dc3f096a7c8448139ae)) + - upgrade to latest nodes and Travis infrastructure ([3febcc1dd23ecdec1abbf89313959941d15eb47a](https://github.com/auth0/node-jsonwebtoken/commit/3febcc1dd23ecdec1abbf89313959941d15eb47a)) + + +## 7.1.10 - 2016-12-06 + + - Bump node-jws version number ([07813dd7194630c9f452684279178af76464a759](https://github.com/auth0/node-jsonwebtoken/commit/07813dd7194630c9f452684279178af76464a759)) + - improve the documentation for expiration ([771e0b5f9bed90771fb79140eb38e51a3ecac8f0](https://github.com/auth0/node-jsonwebtoken/commit/771e0b5f9bed90771fb79140eb38e51a3ecac8f0)) + +## 7.1.9 - 2016-08-11 + + - Revert "Merge branch 'venatir-master'" ([d06359ef3b4e619680e043ee7c16adda16598f52](https://github.com/auth0/node-jsonwebtoken/commit/d06359ef3b4e619680e043ee7c16adda16598f52)) + + + +## 7.1.8 - 2016-08-10 + + - Fixed tests, however typ: 'JWT' should not be in the options at all, so please review other tests ([01903bcdc61b4ed429acbbd1fe0ffe0db364473b](https://github.com/auth0/node-jsonwebtoken/commit/01903bcdc61b4ed429acbbd1fe0ffe0db364473b)) + - Removing unnecessary extra decoding. jwtString is already verified as valid and signature checked ([55d5834f7b637011e1d8b927ff78a92a5fd521cf](https://github.com/auth0/node-jsonwebtoken/commit/55d5834f7b637011e1d8b927ff78a92a5fd521cf)) + - update changelog ([5117aacd0118a10331889a64e61d8186112d8a23](https://github.com/auth0/node-jsonwebtoken/commit/5117aacd0118a10331889a64e61d8186112d8a23)) + + +## 7.1.7 - 2016-07-29 + + - Use lodash.once instead of unlicensed/unmaintained cb ([3ac95ad93ef3068a64e03d8d14deff231b1ed529](https://github.com/auth0/node-jsonwebtoken/commit/3ac95ad93ef3068a64e03d8d14deff231b1ed529)) + +## 7.1.6 - 2016-07-15 + + - fix issue with buffer payload. closes #216 ([6b50ff324b4dfd2cb0e49b666f14a6672d015b22](https://github.com/auth0/node-jsonwebtoken/commit/6b50ff324b4dfd2cb0e49b666f14a6672d015b22)), closes [#216](https://github.com/auth0/node-jsonwebtoken/issues/216) + + +## 7.1.5 - 2016-07-15 + + - update jws in package.json ([b6260951eefc68aae5f4ede359210761f901ff7a](https://github.com/auth0/node-jsonwebtoken/commit/b6260951eefc68aae5f4ede359210761f901ff7a)) + + +## 7.1.4 - 2016-07-14 + + - add redundant test ([bece8816096f324511c3efcb8db0e64b75d757a1](https://github.com/auth0/node-jsonwebtoken/commit/bece8816096f324511c3efcb8db0e64b75d757a1)) + - fix an issue of double callback on error ([758ca5eeca2f1b06c32c9fce70642bf488b2e52b](https://github.com/auth0/node-jsonwebtoken/commit/758ca5eeca2f1b06c32c9fce70642bf488b2e52b)) + +## 7.1.2 - 2016-07-12 + + - do not stringify the payload when signing async - closes #224 ([084f537d3dfbcef2bea411cc0a1515899cc8aa21](https://github.com/auth0/node-jsonwebtoken/commit/084f537d3dfbcef2bea411cc0a1515899cc8aa21)), closes [#224](https://github.com/auth0/node-jsonwebtoken/issues/224) + +## 7.1.1 - 2016-07-12 + + - do not mutate options in jwt.verify, closes #227 ([63263a28a268624dab0927b9ad86fffa44a10f84](https://github.com/auth0/node-jsonwebtoken/commit/63263a28a268624dab0927b9ad86fffa44a10f84)), closes [#227](https://github.com/auth0/node-jsonwebtoken/issues/227) + - refactor into multiple files ([e11d505207fa33501298300c9accbfb809d8748d](https://github.com/auth0/node-jsonwebtoken/commit/e11d505207fa33501298300c9accbfb809d8748d)) + +## 7.1.0 - 2016-07-12 + + - Exp calculated based on iat. fix #217 ([757a16e0e35ad19f9e456820f55d5d9f3fc76aee](https://github.com/auth0/node-jsonwebtoken/commit/757a16e0e35ad19f9e456820f55d5d9f3fc76aee)), closes [#217](https://github.com/auth0/node-jsonwebtoken/issues/217) + +## 7.0.0 - 2016-05-19 + + - change jwt.sign to return errors on callback instead of throwing errors ([1e46c5a42aa3dab8478efa4081d8f8f5c5485d56](https://github.com/auth0/node-jsonwebtoken/commit/1e46c5a42aa3dab8478efa4081d8f8f5c5485d56)) + +## 6.2.0 - 2016-04-29 + + - add support for `options.clockTolerance` to `jwt.verify` ([65ddea934f226bf06bc9d6a55be9587515cfc38d](https://github.com/auth0/node-jsonwebtoken/commit/65ddea934f226bf06bc9d6a55be9587515cfc38d)) + +## 6.1.2 - 2016-04-29 + + - fix sign method for node.js 0.12. closes #193 ([9c38374142d3929be3c9314b5e9bc5d963c5955f](https://github.com/auth0/node-jsonwebtoken/commit/9c38374142d3929be3c9314b5e9bc5d963c5955f)), closes [#193](https://github.com/auth0/node-jsonwebtoken/issues/193) + - improve async test ([7b0981380ddc40a5f1208df520631785b5ffb85a](https://github.com/auth0/node-jsonwebtoken/commit/7b0981380ddc40a5f1208df520631785b5ffb85a)) + +## 6.1.0 - 2016-04-27 + + - verify unsigned tokens ([ec880791c10ed5ef7c8df7bf28ebb95c810479ed](https://github.com/auth0/node-jsonwebtoken/commit/ec880791c10ed5ef7c8df7bf28ebb95c810479ed)) + +## 6.0.1 - 2016-04-27 + +This was an immediate change after publishing 6.0.0. + + - throw error on invalid options when the payload is not an object ([304f1b33075f79ed66f784e27dc4f5307aa39e27](https://github.com/auth0/node-jsonwebtoken/commit/304f1b33075f79ed66f784e27dc4f5307aa39e27)) + +## 6.0.0 - 2016-04-27 + + - Change .sign to standard async callback ([50873c7d45d2733244d5da8afef3d1872e657a60](https://github.com/auth0/node-jsonwebtoken/commit/50873c7d45d2733244d5da8afef3d1872e657a60)) + - Improved the options for the `sign` method ([53c3987b3cc34e95eb396b26fc9b051276e2f6f9](https://github.com/auth0/node-jsonwebtoken/commit/53c3987b3cc34e95eb396b26fc9b051276e2f6f9)) + + - throw error on invalid options like `expiresIn` when the payload is not an object ([304f1b33075f79ed66f784e27dc4f5307aa39e27](https://github.com/auth0/node-jsonwebtoken/commit/304f1b33075f79ed66f784e27dc4f5307aa39e27)) + - `expiresInMinutes` and `expiresInSeconds` are deprecated and no longer supported. + - `notBeforeInMinutes` and `notBeforeInSeconds` are deprecated and no longer supported. + - `options` are strongly validated. + - `options.expiresIn`, `options.notBefore`, `options.audience`, `options.issuer`, `options.subject` and `options.jwtid` are mutually exclusive with `payload.exp`, `payload.nbf`, `payload.aud`, `payload.iss` + - `options.algorithm` is properly validated. + - `options.headers` is renamed to `options.header`. + + - update CHANGELOG to reflect most of the changes. closes #136 ([b87a1a8d2e2533fbfab518765a54f00077918eb7](https://github.com/auth0/node-jsonwebtoken/commit/b87a1a8d2e2533fbfab518765a54f00077918eb7)), closes [#136](https://github.com/auth0/node-jsonwebtoken/issues/136) + - update readme ([53a88ecf4494e30e1d62a1cf3cc354650349f486](https://github.com/auth0/node-jsonwebtoken/commit/53a88ecf4494e30e1d62a1cf3cc354650349f486)) + +## 5.7.0 - 2016-02-16 + + + - add support for validating multiples issuers. closes #163 ([39d9309ae05648dbd72e5fd1993df064ad0e8fa5](https://github.com/auth0/node-jsonwebtoken/commit/39d9309ae05648dbd72e5fd1993df064ad0e8fa5)), closes [#163](https://github.com/auth0/node-jsonwebtoken/issues/163) + + +## 5.6.1 - 2016-02-16 + + + - 5.6.1 ([06d8209d499dbc9a8dd978ab6cbb9c6818fde203](https://github.com/auth0/node-jsonwebtoken/commit/06d8209d499dbc9a8dd978ab6cbb9c6818fde203)) + - fix wrong error when setting expiration on non-object payload. closes #153 ([7f7d76edfd918d6afc7c7cead888caa42ccaceb4](https://github.com/auth0/node-jsonwebtoken/commit/7f7d76edfd918d6afc7c7cead888caa42ccaceb4)), closes [#153](https://github.com/auth0/node-jsonwebtoken/issues/153) + + + +## 5.6.0 - 2016-02-16 + + + - added missing validations of sub and jti ([a1affe960d0fc52e9042bcbdedb65734f8855580](https://github.com/auth0/node-jsonwebtoken/commit/a1affe960d0fc52e9042bcbdedb65734f8855580)) + - Fix tests in jwt.rs.tests.js which causes 4 to fail ([8aedf2b1f575b0d9575c1fc9f2ac7bc868f75ff1](https://github.com/auth0/node-jsonwebtoken/commit/8aedf2b1f575b0d9575c1fc9f2ac7bc868f75ff1)) + - Update README.md ([349b7cd00229789b138928ca060d3ef015aedaf9](https://github.com/auth0/node-jsonwebtoken/commit/349b7cd00229789b138928ca060d3ef015aedaf9)) + + + +## 5.5.4 - 2016-01-04 + + + - minor ([46552e7c45025c76e3f647680d7539a66bfac612](https://github.com/auth0/node-jsonwebtoken/commit/46552e7c45025c76e3f647680d7539a66bfac612)) + + + +## 5.5.3 - 2016-01-04 + + + - add a console.warn on invalid options for string payloads ([71200f14deba0533d3261266348338fac2d14661](https://github.com/auth0/node-jsonwebtoken/commit/71200f14deba0533d3261266348338fac2d14661)) + - minor ([65b1f580382dc58dd3da6f47a52713776fd7cdf2](https://github.com/auth0/node-jsonwebtoken/commit/65b1f580382dc58dd3da6f47a52713776fd7cdf2)) + + + +## 5.5.2 - 2016-01-04 + + + - fix signing method with sealed objects, do not modify the params object. closes #147 ([be9c09af83b09c9e72da8b2c6166fa51d92aeab6](https://github.com/auth0/node-jsonwebtoken/commit/be9c09af83b09c9e72da8b2c6166fa51d92aeab6)), closes [#147](https://github.com/auth0/node-jsonwebtoken/issues/147) + + + +## 5.5.1 - 2016-01-04 + + + - fix nbf verification. fix #152 ([786d37b299c67771b5e71a2ca476666ab0f97d98](https://github.com/auth0/node-jsonwebtoken/commit/786d37b299c67771b5e71a2ca476666ab0f97d98)), closes [#152](https://github.com/auth0/node-jsonwebtoken/issues/152) + + + +## 5.5.0 - 2015-12-28 + + + - improvements to nbf and jti claims ([46372e928f6d2e7398f9b88022ca617d2a3b0699](https://github.com/auth0/node-jsonwebtoken/commit/46372e928f6d2e7398f9b88022ca617d2a3b0699)) + - Remove duplicate payload line (fix bug in IE strict mode) ([8163d698e0c5ad8c44817a5dcd42a15d7e9c6bc8](https://github.com/auth0/node-jsonwebtoken/commit/8163d698e0c5ad8c44817a5dcd42a15d7e9c6bc8)) + - Remove duplicate require('ms') line ([7c00bcbcbf8f7503a1070b394a165eccd41de66f](https://github.com/auth0/node-jsonwebtoken/commit/7c00bcbcbf8f7503a1070b394a165eccd41de66f)) + - Update README to reflect addition of async sign ([d661d4b6f68eb417834c99b36769444723041ccf](https://github.com/auth0/node-jsonwebtoken/commit/d661d4b6f68eb417834c99b36769444723041ccf)) + + + +## 5.4.0 - 2015-10-02 + + + - deprecate expireInMinutes and expireInSeconds - in favor of expiresIn ([39ecc6f8f310f8462e082f1d53de0b4222b29b6f](https://github.com/auth0/node-jsonwebtoken/commit/39ecc6f8f310f8462e082f1d53de0b4222b29b6f)) + + +## 5.3.0 - 2015-10-02 + + + - 5.3.0 ([5d559ced3fbf10c1adae2e5792deda06ea89bcd3](https://github.com/auth0/node-jsonwebtoken/commit/5d559ced3fbf10c1adae2e5792deda06ea89bcd3)) + - minor ([6e81ff87a3799b0e56db09cbae42a97e784716c4](https://github.com/auth0/node-jsonwebtoken/commit/6e81ff87a3799b0e56db09cbae42a97e784716c4)) + + + +## 5.1.0 - 2015-10-02 + + + - added async signing ([9414fbcb15a1f9cf4fe147d070e9424c547dabba](https://github.com/auth0/node-jsonwebtoken/commit/9414fbcb15a1f9cf4fe147d070e9424c547dabba)) + - Update README.md ([40b2aaaa843442dfb8ee7b574f0a788177e7c904](https://github.com/auth0/node-jsonwebtoken/commit/40b2aaaa843442dfb8ee7b574f0a788177e7c904)) + + + +## 5.0.5 - 2015-08-19 + + + - add ms dep to package.json ([f13b3fb7f29dff787e7c91ebe2eb5adeeb05f251](https://github.com/auth0/node-jsonwebtoken/commit/f13b3fb7f29dff787e7c91ebe2eb5adeeb05f251)) + - add note to explain, related to #96 #101 #6 ([dd8969e0e6ed0bcb9cae905d2b1a96476bd85da3](https://github.com/auth0/node-jsonwebtoken/commit/dd8969e0e6ed0bcb9cae905d2b1a96476bd85da3)) + - add tests for options.headers ([7787dd74e705787c39a871ca29c75a2e0a3948ac](https://github.com/auth0/node-jsonwebtoken/commit/7787dd74e705787c39a871ca29c75a2e0a3948ac)) + - add tests for verify expires ([d7c5793d98c300603440ab460c11665f661ad3a0](https://github.com/auth0/node-jsonwebtoken/commit/d7c5793d98c300603440ab460c11665f661ad3a0)) + - add verify option maxAge (with tests) ([49d54e54f7e70b1c53a2e4ee67e116c907d75319](https://github.com/auth0/node-jsonwebtoken/commit/49d54e54f7e70b1c53a2e4ee67e116c907d75319)) + - fix spelling error in error message ([8078b11b224fa05ac9003ca5aa2c85e9f0128cfb](https://github.com/auth0/node-jsonwebtoken/commit/8078b11b224fa05ac9003ca5aa2c85e9f0128cfb)) + - Fix typo options.header is not a documented option + ([5feaa5b962ccbddeff054817a410f7b0c1e6ce7f](https://github.com/auth0/node-jsonwebtoken/commit/5feaa5b962ccbddeff054817a410f7b0c1e6ce7f)) + - update JWT spec link. closes #112 ([f5fa50f797456a12240589161835c7ea30807195](https://github.com/auth0/node-jsonwebtoken/commit/f5fa50f797456a12240589161835c7ea30807195)), closes [#112](https://github.com/auth0/node-jsonwebtoken/issues/112) + + +## 5.0.3 - 2015-07-15 + + - Added nbf support ([f26ba4e2fa197a20497632b63ffcd13ae93aacc4](https://github.com/auth0/node-jsonwebtoken/commit/f26ba4e2fa197a20497632b63ffcd13ae93aacc4)) + - Added support for subject and jwt id ([ab76ec5bc554e2d1e25376ddb7cea711d86af651](https://github.com/auth0/node-jsonwebtoken/commit/ab76ec5bc554e2d1e25376ddb7cea711d86af651)) + - Fix `this` referring to the global object instead of `module.exports` in `verify()` ([93f554312e37129027fcf4916f48cb8d1b53588c](https://github.com/auth0/node-jsonwebtoken/commit/93f554312e37129027fcf4916f48cb8d1b53588c)) + - Fix typo, line 139 README, complete option for .decode. ([59c110aeb8c7c1847ef2ffd77702d13627c89e10](https://github.com/auth0/node-jsonwebtoken/commit/59c110aeb8c7c1847ef2ffd77702d13627c89e10)) + - minor ([61ff1172272b582902313e958058ff22413494af](https://github.com/auth0/node-jsonwebtoken/commit/61ff1172272b582902313e958058ff22413494af)) + + + +## 5.0.2 - 2015-06-15 + + + - fix typo in docs . closes #86 ([3d3413221f36acef4dfd1cbed87f1f3565cd6f84](https://github.com/auth0/node-jsonwebtoken/commit/3d3413221f36acef4dfd1cbed87f1f3565cd6f84)), closes [#86](https://github.com/auth0/node-jsonwebtoken/issues/86) + + + +## 5.0.1 - 2015-05-15 + + + - Add option to return header and payload when decoding. ([7254e011b59f892d1947e6c11819281adac7069d](https://github.com/auth0/node-jsonwebtoken/commit/7254e011b59f892d1947e6c11819281adac7069d)) + - Avoid uncaught "SyntaxError: Unexpected token ͧ" error. ([0dc59cd6ee15d83a606acffa7909ee76176ae186](https://github.com/auth0/node-jsonwebtoken/commit/0dc59cd6ee15d83a606acffa7909ee76176ae186)) + - Document complete option in README. ([ec32b20241a74d9681ea26e1a7024b4642468c00](https://github.com/auth0/node-jsonwebtoken/commit/ec32b20241a74d9681ea26e1a7024b4642468c00)) + - Fix example in README, silence verbose logging. ([ba3174d10033c41e9c211a38f1cc67f74fbd7f69](https://github.com/auth0/node-jsonwebtoken/commit/ba3174d10033c41e9c211a38f1cc67f74fbd7f69)) + - Fix link to auth0.com in README ([1b3c5ff72c9bc25e9271646e679f3080f2a042a0](https://github.com/auth0/node-jsonwebtoken/commit/1b3c5ff72c9bc25e9271646e679f3080f2a042a0)) + - Immediate return if not decoded. ([851bda2b10168f3269c3da6e74d310742f31a193](https://github.com/auth0/node-jsonwebtoken/commit/851bda2b10168f3269c3da6e74d310742f31a193)) + - Prevent throw on undefined/null secret ([0fdf78d4dbf609455f3277d6169a987aef0384d4](https://github.com/auth0/node-jsonwebtoken/commit/0fdf78d4dbf609455f3277d6169a987aef0384d4)) + - Removed path from test ([d6240e24186732d368bffe21143becf44c38f0d6](https://github.com/auth0/node-jsonwebtoken/commit/d6240e24186732d368bffe21143becf44c38f0d6)) + - Simplified checking for missing key ([f1cffd033bffc44f20558eda4a797c3fa2f4ee05](https://github.com/auth0/node-jsonwebtoken/commit/f1cffd033bffc44f20558eda4a797c3fa2f4ee05)) + - Typo ([ffe68dbe0219bab535c1018448eb4c0b22f1f902](https://github.com/auth0/node-jsonwebtoken/commit/ffe68dbe0219bab535c1018448eb4c0b22f1f902)) + - Update CHANGELOG.md ([927cce0dad1bc9aad75aeef53e276cf4cfc0d776](https://github.com/auth0/node-jsonwebtoken/commit/927cce0dad1bc9aad75aeef53e276cf4cfc0d776)) + - Update CHANGELOG.md ([6879e0fdde222995c70a3a69a4af94993d9c667e](https://github.com/auth0/node-jsonwebtoken/commit/6879e0fdde222995c70a3a69a4af94993d9c667e)) + - Update CHANGELOG.md ([c5596c10e8705727fa13e0394184a606083078bc](https://github.com/auth0/node-jsonwebtoken/commit/c5596c10e8705727fa13e0394184a606083078bc)) + - Update CHANGELOG.md ([07541f0315f26d179e1cde92732b6124d6869b6f](https://github.com/auth0/node-jsonwebtoken/commit/07541f0315f26d179e1cde92732b6124d6869b6f)) + - Update CHANGELOG.md ([e6465d48ddd1dc2c3297229b28c78fd5490a2ba9](https://github.com/auth0/node-jsonwebtoken/commit/e6465d48ddd1dc2c3297229b28c78fd5490a2ba9)) + +## [5.0.0] - 2015-04-11 + +### Changed + + - [sign] Only set defautl `iat` if the user does not specify that argument. + + https://github.com/auth0/node-jsonwebtoken/commit/e900282a8d2dff1d4dec815f7e6aa7782e867d91 + https://github.com/auth0/node-jsonwebtoken/commit/35036b188b4ee6b42df553bbb93bc8a6b19eae9d + https://github.com/auth0/node-jsonwebtoken/commit/954bd7a312934f03036b6bb6f00edd41f29e54d9 + https://github.com/auth0/node-jsonwebtoken/commit/24a370080e0b75f11d4717cd2b11b2949d95fc2e + https://github.com/auth0/node-jsonwebtoken/commit/a77df6d49d4ec688dfd0a1cc723586bffe753516 + +### Security + + - [verify] Update to jws@^3.0.0 and renaming `header.alg` mismatch exception to `invalid algorithm` and adding more mismatch tests. + + As `jws@3.0.0` changed the verify method signature to be `jws.verify(signature, algorithm, secretOrKey)`, the token header must be decoded first in order to make sure that the `alg` field matches one of the allowed `options.algorithms`. After that, the now validated `header.alg` is passed to `jws.verify` + + As the order of steps has changed, the error that was thrown when the JWT was invalid is no longer the `jws` one: + ``` + { [Error: Invalid token: no header in signature 'a.b.c'] code: 'MISSING_HEADER', signature: 'a.b.c' } + ``` + + That old error (removed from jws) has been replaced by a `JsonWebTokenError` with message `invalid token`. + + > Important: versions >= 4.2.2 this library are safe to use but we decided to deprecate everything `< 5.0.0` to prevent security warnings from library `node-jws` when doing `npm install`. + + https://github.com/auth0/node-jsonwebtoken/commit/634b8ed0ff5267dc25da5c808634208af109824e + https://github.com/auth0/node-jsonwebtoken/commit/9f24ffd5791febb449d4d03ff58d7807da9b9b7e + https://github.com/auth0/node-jsonwebtoken/commit/19e6cc6a1f2fd90356f89b074223b9665f2aa8a2 + https://github.com/auth0/node-jsonwebtoken/commit/1e4623420159c6410616f02a44ed240f176287a9 + https://github.com/auth0/node-jsonwebtoken/commit/954bd7a312934f03036b6bb6f00edd41f29e54d9 + https://github.com/auth0/node-jsonwebtoken/commit/24a370080e0b75f11d4717cd2b11b2949d95fc2e + https://github.com/auth0/node-jsonwebtoken/commit/a77df6d49d4ec688dfd0a1cc723586bffe753516 + +## [4.2.2] - 2015-03-26 +### Fixed + + - [asymmetric-keys] Fix verify for RSAPublicKey formated keys (`jfromaniello - awlayton`) + https://github.com/auth0/node-jsonwebtoken/commit/402794663b9521bf602fcc6f2e811e7d3912f9dc + https://github.com/auth0/node-jsonwebtoken/commit/8df6aabbc7e1114c8fb3917931078254eb52c222 + +## [4.2.1] - 2015-03-17 +### Fixed + + - [asymmetric-keys] Fixed issue when public key starts with BEING PUBLIC KEY (https://github.com/auth0/node-jsonwebtoken/issues/70) (`jfromaniello`) + https://github.com/auth0/node-jsonwebtoken/commit/7017e74db9b194448ff488b3e16468ada60c4ee5 + +## [4.2.0] - 2015-03-16 +### Security + + - [asymmetric-keys] Making sure a token signed with an asymmetric key will be verified using a asymmetric key. + When the verification part was expecting a token digitally signed with an asymmetric key (RS/ES family) of algorithms an attacker could send a token signed with a symmetric algorithm (HS* family). + + The issue was caused because the same signature was used to verify both type of tokens (`verify` method parameter: `secretOrPublicKey`). + + This change adds a new parameter to the verify called `algorithms`. This can be used to specify a list of supported algorithms, but the default value depends on the secret used: if the secretOrPublicKey contains the string `BEGIN CERTIFICATE` the default is `[ 'RS256','RS384','RS512','ES256','ES384','ES512' ]` otherwise is `[ 'HS256','HS384','HS512' ]`. (`jfromaniello`) + https://github.com/auth0/node-jsonwebtoken/commit/c2bf7b2cd7e8daf66298c2d168a008690bc4bdd3 + https://github.com/auth0/node-jsonwebtoken/commit/1bb584bc382295eeb7ee8c4452a673a77a68b687 + +## [4.1.0] - 2015-03-10 +### Changed +- Assume the payload is JSON even when there is no `typ` property. [5290db1](https://github.com/auth0/node-jsonwebtoken/commit/5290db1bd74f74cd38c90b19e2355ef223a4d931) + +## [4.0.0] - 2015-03-06 +### Changed +- The default encoding is now utf8 instead of binary. [92d33bd](https://github.com/auth0/node-jsonwebtoken/commit/92d33bd99a3416e9e5a8897d9ad8ff7d70a00bfd) +- Add `encoding` as a new option to `sign`. [1fc385e](https://github.com/auth0/node-jsonwebtoken/commit/1fc385ee10bd0018cd1441552dce6c2e5a16375f) +- Add `ignoreExpiration` to `verify`. [8d4da27](https://github.com/auth0/node-jsonwebtoken/commit/8d4da279e1b351ac71ace276285c9255186d549f) +- Add `expiresInSeconds` to `sign`. [dd156cc](https://github.com/auth0/node-jsonwebtoken/commit/dd156cc30f17028744e60aec0502897e34609329) + +### Fixed +- Fix wrong error message when the audience doesn't match. [44e3c8d](https://github.com/auth0/node-jsonwebtoken/commit/44e3c8d757e6b4e2a57a69a035f26b4abec3e327) +- Fix wrong error message when the issuer doesn't match. [44e3c8d](https://github.com/auth0/node-jsonwebtoken/commit/44e3c8d757e6b4e2a57a69a035f26b4abec3e327) +- Fix wrong `iat` and `exp` values when signing with `noTimestamp`. [331b7bc](https://github.com/auth0/node-jsonwebtoken/commit/331b7bc9cc335561f8806f2c4558e105cb53e0a6) diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/LICENSE new file mode 100644 index 0000000..bcd1854 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Auth0, Inc. (http://auth0.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/README.md new file mode 100644 index 0000000..f966435 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/README.md @@ -0,0 +1,375 @@ +# jsonwebtoken + +| **Build** | **Dependency** | +|-----------|---------------| +| [![Build Status](https://secure.travis-ci.org/auth0/node-jsonwebtoken.svg?branch=master)](http://travis-ci.org/auth0/node-jsonwebtoken) | [![Dependency Status](https://david-dm.org/auth0/node-jsonwebtoken.svg)](https://david-dm.org/auth0/node-jsonwebtoken) | + + +An implementation of [JSON Web Tokens](https://tools.ietf.org/html/rfc7519). + +This was developed against `draft-ietf-oauth-json-web-token-08`. It makes use of [node-jws](https://github.com/brianloveswords/node-jws) + +# Install + +```bash +$ npm install jsonwebtoken +``` + +# Migration notes + +* [From v7 to v8](https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v7-to-v8) + +# Usage + +### jwt.sign(payload, secretOrPrivateKey, [options, callback]) + +(Asynchronous) If a callback is supplied, the callback is called with the `err` or the JWT. + +(Synchronous) Returns the JsonWebToken as string + +`payload` could be an object literal, buffer or string representing valid JSON. +> **Please _note_ that** `exp` or any other claim is only set if the payload is an object literal. Buffer or string payloads are not checked for JSON validity. + +> If `payload` is not a buffer or a string, it will be coerced into a string using `JSON.stringify`. + +`secretOrPrivateKey` is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM +encoded private key for RSA and ECDSA. In case of a private key with passphrase an object `{ key, passphrase }` can be used (based on [crypto documentation](https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format)), in this case be sure you pass the `algorithm` option. + +`options`: + +* `algorithm` (default: `HS256`) +* `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). + > Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`). +* `notBefore`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). + > Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`). +* `audience` +* `issuer` +* `jwtid` +* `subject` +* `noTimestamp` +* `header` +* `keyid` +* `mutatePayload`: if true, the sign function will modify the payload object directly. This is useful if you need a raw reference to the payload after claims have been applied to it but before it has been encoded into a token. + + + +> There are no default values for `expiresIn`, `notBefore`, `audience`, `subject`, `issuer`. These claims can also be provided in the payload directly with `exp`, `nbf`, `aud`, `sub` and `iss` respectively, but you **_can't_** include in both places. + +Remember that `exp`, `nbf` and `iat` are **NumericDate**, see related [Token Expiration (exp claim)](#token-expiration-exp-claim) + + +The header can be customized via the `options.header` object. + +Generated jwts will include an `iat` (issued at) claim by default unless `noTimestamp` is specified. If `iat` is inserted in the payload, it will be used instead of the real timestamp for calculating other things like `exp` given a timespan in `options.expiresIn`. + +Synchronous Sign with default (HMAC SHA256) + +```js +var jwt = require('jsonwebtoken'); +var token = jwt.sign({ foo: 'bar' }, 'shhhhh'); +``` + +Synchronous Sign with RSA SHA256 +```js +// sign with RSA SHA256 +var privateKey = fs.readFileSync('private.key'); +var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'}); +``` + +Sign asynchronously +```js +jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' }, function(err, token) { + console.log(token); +}); +``` + +Backdate a jwt 30 seconds +```js +var older_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh'); +``` + +#### Token Expiration (exp claim) + +The standard for JWT defines an `exp` claim for expiration. The expiration is represented as a **NumericDate**: + +> A JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds. This is equivalent to the IEEE Std 1003.1, 2013 Edition [POSIX.1] definition "Seconds Since the Epoch", in which each day is accounted for by exactly 86400 seconds, other than that non-integer values can be represented. See RFC 3339 [RFC3339] for details regarding date/times in general and UTC in particular. + +This means that the `exp` field should contain the number of seconds since the epoch. + +Signing a token with 1 hour of expiration: + +```javascript +jwt.sign({ + exp: Math.floor(Date.now() / 1000) + (60 * 60), + data: 'foobar' +}, 'secret'); +``` + +Another way to generate a token like this with this library is: + +```javascript +jwt.sign({ + data: 'foobar' +}, 'secret', { expiresIn: 60 * 60 }); + +//or even better: + +jwt.sign({ + data: 'foobar' +}, 'secret', { expiresIn: '1h' }); +``` + +### jwt.verify(token, secretOrPublicKey, [options, callback]) + +(Asynchronous) If a callback is supplied, function acts asynchronously. The callback is called with the decoded payload if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will be called with the error. + +(Synchronous) If a callback is not supplied, function acts synchronously. Returns the payload decoded if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will throw the error. + +`token` is the JsonWebToken string + +`secretOrPublicKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM +encoded public key for RSA and ECDSA. +If `jwt.verify` is called asynchronous, `secretOrPublicKey` can be a function that should fetch the secret or public key. See below for a detailed example + +As mentioned in [this comment](https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138), there are other libraries that expect base64 encoded secrets (random bytes encoded using base64), if that is your case you can pass `Buffer.from(secret, 'base64')`, by doing this the secret will be decoded using base64 and the token verification will use the original random bytes. + +`options` + +* `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`. +* `audience`: if you want to check audience (`aud`), provide a value here. The audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. + > Eg: `"urn:foo"`, `/urn:f[o]{2}/`, `[/urn:f[o]{2}/, "urn:bar"]` +* `complete`: return an object with the decoded `{ payload, header, signature }` instead of only the usual content of the payload. +* `issuer` (optional): string or array of strings of valid values for the `iss` field. +* `ignoreExpiration`: if `true` do not validate the expiration of the token. +* `ignoreNotBefore`... +* `subject`: if you want to check subject (`sub`), provide a value here +* `clockTolerance`: number of seconds to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers +* `maxAge`: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). + > Eg: `1000`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`). +* `clockTimestamp`: the time in seconds that should be used as the current time for all necessary comparisons. +* `nonce`: if you want to check `nonce` claim, provide a string value here. It is used on Open ID for the ID Tokens. ([Open ID implementation notes](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes)) + + +```js +// verify a token symmetric - synchronous +var decoded = jwt.verify(token, 'shhhhh'); +console.log(decoded.foo) // bar + +// verify a token symmetric +jwt.verify(token, 'shhhhh', function(err, decoded) { + console.log(decoded.foo) // bar +}); + +// invalid token - synchronous +try { + var decoded = jwt.verify(token, 'wrong-secret'); +} catch(err) { + // err +} + +// invalid token +jwt.verify(token, 'wrong-secret', function(err, decoded) { + // err + // decoded undefined +}); + +// verify a token asymmetric +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, function(err, decoded) { + console.log(decoded.foo) // bar +}); + +// verify audience +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, { audience: 'urn:foo' }, function(err, decoded) { + // if audience mismatch, err == invalid audience +}); + +// verify issuer +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) { + // if issuer mismatch, err == invalid issuer +}); + +// verify jwt id +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) { + // if jwt id mismatch, err == invalid jwt id +}); + +// verify subject +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) { + // if subject mismatch, err == invalid subject +}); + +// alg mismatch +var cert = fs.readFileSync('public.pem'); // get public key +jwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) { + // if token alg != RS256, err == invalid signature +}); + +// Verify using getKey callback +// Example uses https://github.com/auth0/node-jwks-rsa as a way to fetch the keys. +var jwksClient = require('jwks-rsa'); +var client = jwksClient({ + jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json' +}); +function getKey(header, callback){ + client.getSigningKey(header.kid, function(err, key) { + var signingKey = key.publicKey || key.rsaPublicKey; + callback(null, signingKey); + }); +} + +jwt.verify(token, getKey, options, function(err, decoded) { + console.log(decoded.foo) // bar +}); + +``` + +### jwt.decode(token [, options]) + +(Synchronous) Returns the decoded payload without verifying if the signature is valid. + +> __Warning:__ This will __not__ verify whether the signature is valid. You should __not__ use this for untrusted messages. You most likely want to use `jwt.verify` instead. + +`token` is the JsonWebToken string + +`options`: + +* `json`: force JSON.parse on the payload even if the header doesn't contain `"typ":"JWT"`. +* `complete`: return an object with the decoded payload and header. + +Example + +```js +// get the decoded payload ignoring signature, no secretOrPrivateKey needed +var decoded = jwt.decode(token); + +// get the decoded payload and header +var decoded = jwt.decode(token, {complete: true}); +console.log(decoded.header); +console.log(decoded.payload) +``` + +## Errors & Codes +Possible thrown errors during verification. +Error is the first argument of the verification callback. + +### TokenExpiredError + +Thrown error if the token is expired. + +Error object: + +* name: 'TokenExpiredError' +* message: 'jwt expired' +* expiredAt: [ExpDate] + +```js +jwt.verify(token, 'shhhhh', function(err, decoded) { + if (err) { + /* + err = { + name: 'TokenExpiredError', + message: 'jwt expired', + expiredAt: 1408621000 + } + */ + } +}); +``` + +### JsonWebTokenError +Error object: + +* name: 'JsonWebTokenError' +* message: + * 'jwt malformed' + * 'jwt signature is required' + * 'invalid signature' + * 'jwt audience invalid. expected: [OPTIONS AUDIENCE]' + * 'jwt issuer invalid. expected: [OPTIONS ISSUER]' + * 'jwt id invalid. expected: [OPTIONS JWT ID]' + * 'jwt subject invalid. expected: [OPTIONS SUBJECT]' + +```js +jwt.verify(token, 'shhhhh', function(err, decoded) { + if (err) { + /* + err = { + name: 'JsonWebTokenError', + message: 'jwt malformed' + } + */ + } +}); +``` + +### NotBeforeError +Thrown if current time is before the nbf claim. + +Error object: + +* name: 'NotBeforeError' +* message: 'jwt not active' +* date: 2018-10-04T16:10:44.000Z + +```js +jwt.verify(token, 'shhhhh', function(err, decoded) { + if (err) { + /* + err = { + name: 'NotBeforeError', + message: 'jwt not active', + date: 2018-10-04T16:10:44.000Z + } + */ + } +}); +``` + + +## Algorithms supported + +Array of supported algorithms. The following algorithms are currently supported. + +alg Parameter Value | Digital Signature or MAC Algorithm +----------------|---------------------------- +HS256 | HMAC using SHA-256 hash algorithm +HS384 | HMAC using SHA-384 hash algorithm +HS512 | HMAC using SHA-512 hash algorithm +RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm +RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm +RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm +PS256 | RSASSA-PSS using SHA-256 hash algorithm (only node ^6.12.0 OR >=8.0.0) +PS384 | RSASSA-PSS using SHA-384 hash algorithm (only node ^6.12.0 OR >=8.0.0) +PS512 | RSASSA-PSS using SHA-512 hash algorithm (only node ^6.12.0 OR >=8.0.0) +ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm +ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm +ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm +none | No digital signature or MAC value included + +## Refreshing JWTs + +First of all, we recommend you to think carefully if auto-refreshing a JWT will not introduce any vulnerability in your system. + +We are not comfortable including this as part of the library, however, you can take a look at [this example](https://gist.github.com/ziluvatar/a3feb505c4c0ec37059054537b38fc48) to show how this could be accomplished. +Apart from that example there are [an issue](https://github.com/auth0/node-jsonwebtoken/issues/122) and [a pull request](https://github.com/auth0/node-jsonwebtoken/pull/172) to get more knowledge about this topic. + +# TODO + +* X.509 certificate chain is not checked + +## Issue Reporting + +If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. + +## Author + +[Auth0](https://auth0.com) + +## License + +This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/decode.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/decode.js new file mode 100644 index 0000000..8fe1adc --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/decode.js @@ -0,0 +1,30 @@ +var jws = require('jws'); + +module.exports = function (jwt, options) { + options = options || {}; + var decoded = jws.decode(jwt, options); + if (!decoded) { return null; } + var payload = decoded.payload; + + //try parse the payload + if(typeof payload === 'string') { + try { + var obj = JSON.parse(payload); + if(obj !== null && typeof obj === 'object') { + payload = obj; + } + } catch (e) { } + } + + //return header if `complete` option is enabled. header includes claims + //such as `kid` and `alg` used to select the key within a JWKS needed to + //verify the signature + if (options.complete === true) { + return { + header: decoded.header, + payload: payload, + signature: decoded.signature + }; + } + return payload; +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/index.js new file mode 100644 index 0000000..161eb2d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/index.js @@ -0,0 +1,8 @@ +module.exports = { + decode: require('./decode'), + verify: require('./verify'), + sign: require('./sign'), + JsonWebTokenError: require('./lib/JsonWebTokenError'), + NotBeforeError: require('./lib/NotBeforeError'), + TokenExpiredError: require('./lib/TokenExpiredError'), +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/JsonWebTokenError.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/JsonWebTokenError.js new file mode 100644 index 0000000..e068222 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/JsonWebTokenError.js @@ -0,0 +1,14 @@ +var JsonWebTokenError = function (message, error) { + Error.call(this, message); + if(Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = 'JsonWebTokenError'; + this.message = message; + if (error) this.inner = error; +}; + +JsonWebTokenError.prototype = Object.create(Error.prototype); +JsonWebTokenError.prototype.constructor = JsonWebTokenError; + +module.exports = JsonWebTokenError; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/NotBeforeError.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/NotBeforeError.js new file mode 100644 index 0000000..7b30084 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/NotBeforeError.js @@ -0,0 +1,13 @@ +var JsonWebTokenError = require('./JsonWebTokenError'); + +var NotBeforeError = function (message, date) { + JsonWebTokenError.call(this, message); + this.name = 'NotBeforeError'; + this.date = date; +}; + +NotBeforeError.prototype = Object.create(JsonWebTokenError.prototype); + +NotBeforeError.prototype.constructor = NotBeforeError; + +module.exports = NotBeforeError; \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/TokenExpiredError.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/TokenExpiredError.js new file mode 100644 index 0000000..abb704f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/TokenExpiredError.js @@ -0,0 +1,13 @@ +var JsonWebTokenError = require('./JsonWebTokenError'); + +var TokenExpiredError = function (message, expiredAt) { + JsonWebTokenError.call(this, message); + this.name = 'TokenExpiredError'; + this.expiredAt = expiredAt; +}; + +TokenExpiredError.prototype = Object.create(JsonWebTokenError.prototype); + +TokenExpiredError.prototype.constructor = TokenExpiredError; + +module.exports = TokenExpiredError; \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/psSupported.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/psSupported.js new file mode 100644 index 0000000..8c04144 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/psSupported.js @@ -0,0 +1,3 @@ +var semver = require('semver'); + +module.exports = semver.satisfies(process.version, '^6.12.0 || >=8.0.0'); diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/timespan.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/timespan.js new file mode 100644 index 0000000..e509869 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/lib/timespan.js @@ -0,0 +1,18 @@ +var ms = require('ms'); + +module.exports = function (time, iat) { + var timestamp = iat || Math.floor(Date.now() / 1000); + + if (typeof time === 'string') { + var milliseconds = ms(time); + if (typeof milliseconds === 'undefined') { + return; + } + return Math.floor(timestamp + milliseconds / 1000); + } else if (typeof time === 'number') { + return timestamp + time; + } else { + return; + } + +}; \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/package.json new file mode 100644 index 0000000..66732ab --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/package.json @@ -0,0 +1,99 @@ +{ + "_from": "jsonwebtoken@8.5.1", + "_id": "jsonwebtoken@8.5.1", + "_inBundle": false, + "_integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "_location": "/jsonwebtoken", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "jsonwebtoken@8.5.1", + "name": "jsonwebtoken", + "escapedName": "jsonwebtoken", + "rawSpec": "8.5.1", + "saveSpec": null, + "fetchSpec": "8.5.1" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "_shasum": "00e71e0b8df54c2121a1f26137df2280673bcc0d", + "_spec": "jsonwebtoken@8.5.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co", + "author": { + "name": "auth0" + }, + "bugs": { + "url": "https://github.com/auth0/node-jsonwebtoken/issues" + }, + "bundleDependencies": false, + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "deprecated": false, + "description": "JSON Web Token implementation (symmetric and asymmetric)", + "devDependencies": { + "atob": "^2.1.2", + "chai": "^4.1.2", + "conventional-changelog": "~1.1.0", + "cost-of-modules": "^1.0.1", + "eslint": "^4.19.1", + "mocha": "^5.2.0", + "nsp": "^2.6.2", + "nyc": "^11.9.0", + "sinon": "^6.0.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + }, + "files": [ + "lib", + "decode.js", + "sign.js", + "verify.js" + ], + "homepage": "https://github.com/auth0/node-jsonwebtoken#readme", + "keywords": [ + "jwt" + ], + "license": "MIT", + "main": "index.js", + "name": "jsonwebtoken", + "nyc": { + "check-coverage": true, + "lines": 95, + "statements": 95, + "functions": 100, + "branches": 95, + "exclude": [ + "./test/**" + ], + "reporter": [ + "json", + "lcov", + "text-summary" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/auth0/node-jsonwebtoken.git" + }, + "scripts": { + "coverage": "nyc mocha --use_strict", + "lint": "eslint .", + "test": "npm run lint && npm run coverage && cost-of-modules" + }, + "version": "8.5.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/sign.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/sign.js new file mode 100644 index 0000000..f649ce4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/sign.js @@ -0,0 +1,206 @@ +var timespan = require('./lib/timespan'); +var PS_SUPPORTED = require('./lib/psSupported'); +var jws = require('jws'); +var includes = require('lodash.includes'); +var isBoolean = require('lodash.isboolean'); +var isInteger = require('lodash.isinteger'); +var isNumber = require('lodash.isnumber'); +var isPlainObject = require('lodash.isplainobject'); +var isString = require('lodash.isstring'); +var once = require('lodash.once'); + +var SUPPORTED_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'none'] +if (PS_SUPPORTED) { + SUPPORTED_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512'); +} + +var sign_options_schema = { + expiresIn: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"expiresIn" should be a number of seconds or string representing a timespan' }, + notBefore: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"notBefore" should be a number of seconds or string representing a timespan' }, + audience: { isValid: function(value) { return isString(value) || Array.isArray(value); }, message: '"audience" must be a string or array' }, + algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' }, + header: { isValid: isPlainObject, message: '"header" must be an object' }, + encoding: { isValid: isString, message: '"encoding" must be a string' }, + issuer: { isValid: isString, message: '"issuer" must be a string' }, + subject: { isValid: isString, message: '"subject" must be a string' }, + jwtid: { isValid: isString, message: '"jwtid" must be a string' }, + noTimestamp: { isValid: isBoolean, message: '"noTimestamp" must be a boolean' }, + keyid: { isValid: isString, message: '"keyid" must be a string' }, + mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' } +}; + +var registered_claims_schema = { + iat: { isValid: isNumber, message: '"iat" should be a number of seconds' }, + exp: { isValid: isNumber, message: '"exp" should be a number of seconds' }, + nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' } +}; + +function validate(schema, allowUnknown, object, parameterName) { + if (!isPlainObject(object)) { + throw new Error('Expected "' + parameterName + '" to be a plain object.'); + } + Object.keys(object) + .forEach(function(key) { + var validator = schema[key]; + if (!validator) { + if (!allowUnknown) { + throw new Error('"' + key + '" is not allowed in "' + parameterName + '"'); + } + return; + } + if (!validator.isValid(object[key])) { + throw new Error(validator.message); + } + }); +} + +function validateOptions(options) { + return validate(sign_options_schema, false, options, 'options'); +} + +function validatePayload(payload) { + return validate(registered_claims_schema, true, payload, 'payload'); +} + +var options_to_payload = { + 'audience': 'aud', + 'issuer': 'iss', + 'subject': 'sub', + 'jwtid': 'jti' +}; + +var options_for_objects = [ + 'expiresIn', + 'notBefore', + 'noTimestamp', + 'audience', + 'issuer', + 'subject', + 'jwtid', +]; + +module.exports = function (payload, secretOrPrivateKey, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } else { + options = options || {}; + } + + var isObjectPayload = typeof payload === 'object' && + !Buffer.isBuffer(payload); + + var header = Object.assign({ + alg: options.algorithm || 'HS256', + typ: isObjectPayload ? 'JWT' : undefined, + kid: options.keyid + }, options.header); + + function failure(err) { + if (callback) { + return callback(err); + } + throw err; + } + + if (!secretOrPrivateKey && options.algorithm !== 'none') { + return failure(new Error('secretOrPrivateKey must have a value')); + } + + if (typeof payload === 'undefined') { + return failure(new Error('payload is required')); + } else if (isObjectPayload) { + try { + validatePayload(payload); + } + catch (error) { + return failure(error); + } + if (!options.mutatePayload) { + payload = Object.assign({},payload); + } + } else { + var invalid_options = options_for_objects.filter(function (opt) { + return typeof options[opt] !== 'undefined'; + }); + + if (invalid_options.length > 0) { + return failure(new Error('invalid ' + invalid_options.join(',') + ' option for ' + (typeof payload ) + ' payload')); + } + } + + if (typeof payload.exp !== 'undefined' && typeof options.expiresIn !== 'undefined') { + return failure(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.')); + } + + if (typeof payload.nbf !== 'undefined' && typeof options.notBefore !== 'undefined') { + return failure(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.')); + } + + try { + validateOptions(options); + } + catch (error) { + return failure(error); + } + + var timestamp = payload.iat || Math.floor(Date.now() / 1000); + + if (options.noTimestamp) { + delete payload.iat; + } else if (isObjectPayload) { + payload.iat = timestamp; + } + + if (typeof options.notBefore !== 'undefined') { + try { + payload.nbf = timespan(options.notBefore, timestamp); + } + catch (err) { + return failure(err); + } + if (typeof payload.nbf === 'undefined') { + return failure(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + } + + if (typeof options.expiresIn !== 'undefined' && typeof payload === 'object') { + try { + payload.exp = timespan(options.expiresIn, timestamp); + } + catch (err) { + return failure(err); + } + if (typeof payload.exp === 'undefined') { + return failure(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + } + + Object.keys(options_to_payload).forEach(function (key) { + var claim = options_to_payload[key]; + if (typeof options[key] !== 'undefined') { + if (typeof payload[claim] !== 'undefined') { + return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.')); + } + payload[claim] = options[key]; + } + }); + + var encoding = options.encoding || 'utf8'; + + if (typeof callback === 'function') { + callback = callback && once(callback); + + jws.createSign({ + header: header, + privateKey: secretOrPrivateKey, + payload: payload, + encoding: encoding + }).once('error', callback) + .once('done', function (signature) { + callback(null, signature); + }); + } else { + return jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding}); + } +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/verify.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/verify.js new file mode 100644 index 0000000..1df99f8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jsonwebtoken/verify.js @@ -0,0 +1,225 @@ +var JsonWebTokenError = require('./lib/JsonWebTokenError'); +var NotBeforeError = require('./lib/NotBeforeError'); +var TokenExpiredError = require('./lib/TokenExpiredError'); +var decode = require('./decode'); +var timespan = require('./lib/timespan'); +var PS_SUPPORTED = require('./lib/psSupported'); +var jws = require('jws'); + +var PUB_KEY_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512']; +var RSA_KEY_ALGS = ['RS256', 'RS384', 'RS512']; +var HS_ALGS = ['HS256', 'HS384', 'HS512']; + +if (PS_SUPPORTED) { + PUB_KEY_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512'); + RSA_KEY_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512'); +} + +module.exports = function (jwtString, secretOrPublicKey, options, callback) { + if ((typeof options === 'function') && !callback) { + callback = options; + options = {}; + } + + if (!options) { + options = {}; + } + + //clone this object since we are going to mutate it. + options = Object.assign({}, options); + + var done; + + if (callback) { + done = callback; + } else { + done = function(err, data) { + if (err) throw err; + return data; + }; + } + + if (options.clockTimestamp && typeof options.clockTimestamp !== 'number') { + return done(new JsonWebTokenError('clockTimestamp must be a number')); + } + + if (options.nonce !== undefined && (typeof options.nonce !== 'string' || options.nonce.trim() === '')) { + return done(new JsonWebTokenError('nonce must be a non-empty string')); + } + + var clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000); + + if (!jwtString){ + return done(new JsonWebTokenError('jwt must be provided')); + } + + if (typeof jwtString !== 'string') { + return done(new JsonWebTokenError('jwt must be a string')); + } + + var parts = jwtString.split('.'); + + if (parts.length !== 3){ + return done(new JsonWebTokenError('jwt malformed')); + } + + var decodedToken; + + try { + decodedToken = decode(jwtString, { complete: true }); + } catch(err) { + return done(err); + } + + if (!decodedToken) { + return done(new JsonWebTokenError('invalid token')); + } + + var header = decodedToken.header; + var getSecret; + + if(typeof secretOrPublicKey === 'function') { + if(!callback) { + return done(new JsonWebTokenError('verify must be called asynchronous if secret or public key is provided as a callback')); + } + + getSecret = secretOrPublicKey; + } + else { + getSecret = function(header, secretCallback) { + return secretCallback(null, secretOrPublicKey); + }; + } + + return getSecret(header, function(err, secretOrPublicKey) { + if(err) { + return done(new JsonWebTokenError('error in secret or public key callback: ' + err.message)); + } + + var hasSignature = parts[2].trim() !== ''; + + if (!hasSignature && secretOrPublicKey){ + return done(new JsonWebTokenError('jwt signature is required')); + } + + if (hasSignature && !secretOrPublicKey) { + return done(new JsonWebTokenError('secret or public key must be provided')); + } + + if (!hasSignature && !options.algorithms) { + options.algorithms = ['none']; + } + + if (!options.algorithms) { + options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') || + ~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ? PUB_KEY_ALGS : + ~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ? RSA_KEY_ALGS : HS_ALGS; + + } + + if (!~options.algorithms.indexOf(decodedToken.header.alg)) { + return done(new JsonWebTokenError('invalid algorithm')); + } + + var valid; + + try { + valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey); + } catch (e) { + return done(e); + } + + if (!valid) { + return done(new JsonWebTokenError('invalid signature')); + } + + var payload = decodedToken.payload; + + if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) { + if (typeof payload.nbf !== 'number') { + return done(new JsonWebTokenError('invalid nbf value')); + } + if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) { + return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000))); + } + } + + if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) { + if (typeof payload.exp !== 'number') { + return done(new JsonWebTokenError('invalid exp value')); + } + if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) { + return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000))); + } + } + + if (options.audience) { + var audiences = Array.isArray(options.audience) ? options.audience : [options.audience]; + var target = Array.isArray(payload.aud) ? payload.aud : [payload.aud]; + + var match = target.some(function (targetAudience) { + return audiences.some(function (audience) { + return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience; + }); + }); + + if (!match) { + return done(new JsonWebTokenError('jwt audience invalid. expected: ' + audiences.join(' or '))); + } + } + + if (options.issuer) { + var invalid_issuer = + (typeof options.issuer === 'string' && payload.iss !== options.issuer) || + (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1); + + if (invalid_issuer) { + return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer)); + } + } + + if (options.subject) { + if (payload.sub !== options.subject) { + return done(new JsonWebTokenError('jwt subject invalid. expected: ' + options.subject)); + } + } + + if (options.jwtid) { + if (payload.jti !== options.jwtid) { + return done(new JsonWebTokenError('jwt jwtid invalid. expected: ' + options.jwtid)); + } + } + + if (options.nonce) { + if (payload.nonce !== options.nonce) { + return done(new JsonWebTokenError('jwt nonce invalid. expected: ' + options.nonce)); + } + } + + if (options.maxAge) { + if (typeof payload.iat !== 'number') { + return done(new JsonWebTokenError('iat required when maxAge is specified')); + } + + var maxAgeTimestamp = timespan(options.maxAge, payload.iat); + if (typeof maxAgeTimestamp === 'undefined') { + return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) { + return done(new TokenExpiredError('maxAge exceeded', new Date(maxAgeTimestamp * 1000))); + } + } + + if (options.complete === true) { + var signature = decodedToken.signature; + + return done(null, { + header: header, + payload: payload, + signature: signature + }); + } + + return done(null, payload); + }); +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/LICENSE new file mode 100644 index 0000000..caeb849 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2013 Brian J. Brennan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/README.md new file mode 100644 index 0000000..fb433e2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/README.md @@ -0,0 +1,150 @@ +# node-jwa [![Build Status](https://travis-ci.org/brianloveswords/node-jwa.svg?branch=master)](https://travis-ci.org/brianloveswords/node-jwa) + +A +[JSON Web Algorithms](http://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-08.html) +implementation focusing (exclusively, at this point) on the algorithms necessary for +[JSON Web Signatures](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html). + +This library supports all of the required, recommended and optional cryptographic algorithms for JWS: + +alg Parameter Value | Digital Signature or MAC Algorithm +----------------|---------------------------- +HS256 | HMAC using SHA-256 hash algorithm +HS384 | HMAC using SHA-384 hash algorithm +HS512 | HMAC using SHA-512 hash algorithm +RS256 | RSASSA using SHA-256 hash algorithm +RS384 | RSASSA using SHA-384 hash algorithm +RS512 | RSASSA using SHA-512 hash algorithm +PS256 | RSASSA-PSS using SHA-256 hash algorithm +PS384 | RSASSA-PSS using SHA-384 hash algorithm +PS512 | RSASSA-PSS using SHA-512 hash algorithm +ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm +ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm +ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm +none | No digital signature or MAC value included + +Please note that PS* only works on Node 6.12+ (excluding 7.x). + +# Requirements + +In order to run the tests, a recent version of OpenSSL is +required. **The version that comes with OS X (OpenSSL 0.9.8r 8 Feb +2011) is not recent enough**, as it does not fully support ECDSA +keys. You'll need to use a version > 1.0.0; I tested with OpenSSL 1.0.1c 10 May 2012. + +# Testing + +To run the tests, do + +```bash +$ npm test +``` + +This will generate a bunch of keypairs to use in testing. If you want to +generate new keypairs, do `make clean` before running `npm test` again. + +## Methodology + +I spawn `openssl dgst -sign` to test OpenSSL sign → JS verify and +`openssl dgst -verify` to test JS sign → OpenSSL verify for each of the +RSA and ECDSA algorithms. + +# Usage + +## jwa(algorithm) + +Creates a new `jwa` object with `sign` and `verify` methods for the +algorithm. Valid values for algorithm can be found in the table above +(`'HS256'`, `'HS384'`, etc) and are case-insensitive. Passing an invalid +algorithm value will throw a `TypeError`. + + +## jwa#sign(input, secretOrPrivateKey) + +Sign some input with either a secret for HMAC algorithms, or a private +key for RSA and ECDSA algorithms. + +If input is not already a string or buffer, `JSON.stringify` will be +called on it to attempt to coerce it. + +For the HMAC algorithm, `secretOrPrivateKey` should be a string or a +buffer. For ECDSA and RSA, the value should be a string representing a +PEM encoded **private** key. + +Output [base64url](http://en.wikipedia.org/wiki/Base64#URL_applications) +formatted. This is for convenience as JWS expects the signature in this +format. If your application needs the output in a different format, +[please open an issue](https://github.com/brianloveswords/node-jwa/issues). In +the meantime, you can use +[brianloveswords/base64url](https://github.com/brianloveswords/base64url) +to decode the signature. + +As of nodejs *v0.11.8*, SPKAC support was introduce. If your nodeJs +version satisfies, then you can pass an object `{ key: '..', passphrase: '...' }` + + +## jwa#verify(input, signature, secretOrPublicKey) + +Verify a signature. Returns `true` or `false`. + +`signature` should be a base64url encoded string. + +For the HMAC algorithm, `secretOrPublicKey` should be a string or a +buffer. For ECDSA and RSA, the value should be a string represented a +PEM encoded **public** key. + + +# Example + +HMAC +```js +const jwa = require('jwa'); + +const hmac = jwa('HS256'); +const input = 'super important stuff'; +const secret = 'shhhhhh'; + +const signature = hmac.sign(input, secret); +hmac.verify(input, signature, secret) // === true +hmac.verify(input, signature, 'trickery!') // === false +``` + +With keys +```js +const fs = require('fs'); +const jwa = require('jwa'); +const privateKey = fs.readFileSync(__dirname + '/ecdsa-p521-private.pem'); +const publicKey = fs.readFileSync(__dirname + '/ecdsa-p521-public.pem'); + +const ecdsa = jwa('ES512'); +const input = 'very important stuff'; + +const signature = ecdsa.sign(input, privateKey); +ecdsa.verify(input, signature, publicKey) // === true +``` +## License + +MIT + +``` +Copyright (c) 2013 Brian J. Brennan + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/index.js new file mode 100644 index 0000000..e71e6d1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/index.js @@ -0,0 +1,252 @@ +var bufferEqual = require('buffer-equal-constant-time'); +var Buffer = require('safe-buffer').Buffer; +var crypto = require('crypto'); +var formatEcdsa = require('ecdsa-sig-formatter'); +var util = require('util'); + +var MSG_INVALID_ALGORITHM = '"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".' +var MSG_INVALID_SECRET = 'secret must be a string or buffer'; +var MSG_INVALID_VERIFIER_KEY = 'key must be a string or a buffer'; +var MSG_INVALID_SIGNER_KEY = 'key must be a string, a buffer or an object'; + +var supportsKeyObjects = typeof crypto.createPublicKey === 'function'; +if (supportsKeyObjects) { + MSG_INVALID_VERIFIER_KEY += ' or a KeyObject'; + MSG_INVALID_SECRET += 'or a KeyObject'; +} + +function checkIsPublicKey(key) { + if (Buffer.isBuffer(key)) { + return; + } + + if (typeof key === 'string') { + return; + } + + if (!supportsKeyObjects) { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + + if (typeof key !== 'object') { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + + if (typeof key.type !== 'string') { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + + if (typeof key.asymmetricKeyType !== 'string') { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + + if (typeof key.export !== 'function') { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } +}; + +function checkIsPrivateKey(key) { + if (Buffer.isBuffer(key)) { + return; + } + + if (typeof key === 'string') { + return; + } + + if (typeof key === 'object') { + return; + } + + throw typeError(MSG_INVALID_SIGNER_KEY); +}; + +function checkIsSecretKey(key) { + if (Buffer.isBuffer(key)) { + return; + } + + if (typeof key === 'string') { + return key; + } + + if (!supportsKeyObjects) { + throw typeError(MSG_INVALID_SECRET); + } + + if (typeof key !== 'object') { + throw typeError(MSG_INVALID_SECRET); + } + + if (key.type !== 'secret') { + throw typeError(MSG_INVALID_SECRET); + } + + if (typeof key.export !== 'function') { + throw typeError(MSG_INVALID_SECRET); + } +} + +function fromBase64(base64) { + return base64 + .replace(/=/g, '') + .replace(/\+/g, '-') + .replace(/\//g, '_'); +} + +function toBase64(base64url) { + base64url = base64url.toString(); + + var padding = 4 - base64url.length % 4; + if (padding !== 4) { + for (var i = 0; i < padding; ++i) { + base64url += '='; + } + } + + return base64url + .replace(/\-/g, '+') + .replace(/_/g, '/'); +} + +function typeError(template) { + var args = [].slice.call(arguments, 1); + var errMsg = util.format.bind(util, template).apply(null, args); + return new TypeError(errMsg); +} + +function bufferOrString(obj) { + return Buffer.isBuffer(obj) || typeof obj === 'string'; +} + +function normalizeInput(thing) { + if (!bufferOrString(thing)) + thing = JSON.stringify(thing); + return thing; +} + +function createHmacSigner(bits) { + return function sign(thing, secret) { + checkIsSecretKey(secret); + thing = normalizeInput(thing); + var hmac = crypto.createHmac('sha' + bits, secret); + var sig = (hmac.update(thing), hmac.digest('base64')) + return fromBase64(sig); + } +} + +function createHmacVerifier(bits) { + return function verify(thing, signature, secret) { + var computedSig = createHmacSigner(bits)(thing, secret); + return bufferEqual(Buffer.from(signature), Buffer.from(computedSig)); + } +} + +function createKeySigner(bits) { + return function sign(thing, privateKey) { + checkIsPrivateKey(privateKey); + thing = normalizeInput(thing); + // Even though we are specifying "RSA" here, this works with ECDSA + // keys as well. + var signer = crypto.createSign('RSA-SHA' + bits); + var sig = (signer.update(thing), signer.sign(privateKey, 'base64')); + return fromBase64(sig); + } +} + +function createKeyVerifier(bits) { + return function verify(thing, signature, publicKey) { + checkIsPublicKey(publicKey); + thing = normalizeInput(thing); + signature = toBase64(signature); + var verifier = crypto.createVerify('RSA-SHA' + bits); + verifier.update(thing); + return verifier.verify(publicKey, signature, 'base64'); + } +} + +function createPSSKeySigner(bits) { + return function sign(thing, privateKey) { + checkIsPrivateKey(privateKey); + thing = normalizeInput(thing); + var signer = crypto.createSign('RSA-SHA' + bits); + var sig = (signer.update(thing), signer.sign({ + key: privateKey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST + }, 'base64')); + return fromBase64(sig); + } +} + +function createPSSKeyVerifier(bits) { + return function verify(thing, signature, publicKey) { + checkIsPublicKey(publicKey); + thing = normalizeInput(thing); + signature = toBase64(signature); + var verifier = crypto.createVerify('RSA-SHA' + bits); + verifier.update(thing); + return verifier.verify({ + key: publicKey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST + }, signature, 'base64'); + } +} + +function createECDSASigner(bits) { + var inner = createKeySigner(bits); + return function sign() { + var signature = inner.apply(null, arguments); + signature = formatEcdsa.derToJose(signature, 'ES' + bits); + return signature; + }; +} + +function createECDSAVerifer(bits) { + var inner = createKeyVerifier(bits); + return function verify(thing, signature, publicKey) { + signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64'); + var result = inner(thing, signature, publicKey); + return result; + }; +} + +function createNoneSigner() { + return function sign() { + return ''; + } +} + +function createNoneVerifier() { + return function verify(thing, signature) { + return signature === ''; + } +} + +module.exports = function jwa(algorithm) { + var signerFactories = { + hs: createHmacSigner, + rs: createKeySigner, + ps: createPSSKeySigner, + es: createECDSASigner, + none: createNoneSigner, + } + var verifierFactories = { + hs: createHmacVerifier, + rs: createKeyVerifier, + ps: createPSSKeyVerifier, + es: createECDSAVerifer, + none: createNoneVerifier, + } + var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i); + if (!match) + throw typeError(MSG_INVALID_ALGORITHM, algorithm); + var algo = (match[1] || match[3]).toLowerCase(); + var bits = match[2]; + + return { + sign: signerFactories[algo](bits), + verify: verifierFactories[algo](bits), + } +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/package.json new file mode 100644 index 0000000..939dc10 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jwa/package.json @@ -0,0 +1,69 @@ +{ + "_from": "jwa@^1.4.1", + "_id": "jwa@1.4.1", + "_inBundle": false, + "_integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "_location": "/jwa", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "jwa@^1.4.1", + "name": "jwa", + "escapedName": "jwa", + "rawSpec": "^1.4.1", + "saveSpec": null, + "fetchSpec": "^1.4.1" + }, + "_requiredBy": [ + "/jws" + ], + "_resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "_shasum": "743c32985cb9e98655530d53641b66c8645b039a", + "_spec": "jwa@^1.4.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jws", + "author": { + "name": "Brian J. Brennan", + "email": "brianloveswords@gmail.com" + }, + "bugs": { + "url": "https://github.com/brianloveswords/node-jwa/issues" + }, + "bundleDependencies": false, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + }, + "deprecated": false, + "description": "JWA implementation (supports all JWS algorithms)", + "devDependencies": { + "base64url": "^2.0.0", + "jwk-to-pem": "^2.0.1", + "semver": "4.3.6", + "tap": "6.2.0" + }, + "directories": { + "test": "test" + }, + "homepage": "https://github.com/brianloveswords/node-jwa#readme", + "keywords": [ + "jwa", + "jws", + "jwt", + "rsa", + "ecdsa", + "hmac" + ], + "license": "MIT", + "main": "index.js", + "name": "jwa", + "repository": { + "type": "git", + "url": "git://github.com/brianloveswords/node-jwa.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.4.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/CHANGELOG.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/CHANGELOG.md new file mode 100644 index 0000000..af8fc28 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/CHANGELOG.md @@ -0,0 +1,34 @@ +# Change Log +All notable changes to this project will be documented in this file. + +## [3.0.0] +### Changed +- **BREAKING**: `jwt.verify` now requires an `algorithm` parameter, and + `jws.createVerify` requires an `algorithm` option. The `"alg"` field + signature headers is ignored. This mitigates a critical security flaw + in the library which would allow an attacker to generate signatures with + arbitrary contents that would be accepted by `jwt.verify`. See + https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ + for details. + +## [2.0.0] - 2015-01-30 +### Changed +- **BREAKING**: Default payload encoding changed from `binary` to + `utf8`. `utf8` is a is a more sensible default than `binary` because + many payloads, as far as I can tell, will contain user-facing + strings that could be in any language. ([6b6de48]) + +- Code reorganization, thanks [@fearphage]! ([7880050]) + +### Added +- Option in all relevant methods for `encoding`. For those few users + that might be depending on a `binary` encoding of the messages, this + is for them. ([6b6de48]) + +[unreleased]: https://github.com/brianloveswords/node-jws/compare/v2.0.0...HEAD +[2.0.0]: https://github.com/brianloveswords/node-jws/compare/v1.0.1...v2.0.0 + +[7880050]: https://github.com/brianloveswords/node-jws/commit/7880050 +[6b6de48]: https://github.com/brianloveswords/node-jws/commit/6b6de48 + +[@fearphage]: https://github.com/fearphage diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/LICENSE new file mode 100644 index 0000000..caeb849 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2013 Brian J. Brennan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/index.js new file mode 100644 index 0000000..8c8da93 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/index.js @@ -0,0 +1,22 @@ +/*global exports*/ +var SignStream = require('./lib/sign-stream'); +var VerifyStream = require('./lib/verify-stream'); + +var ALGORITHMS = [ + 'HS256', 'HS384', 'HS512', + 'RS256', 'RS384', 'RS512', + 'PS256', 'PS384', 'PS512', + 'ES256', 'ES384', 'ES512' +]; + +exports.ALGORITHMS = ALGORITHMS; +exports.sign = SignStream.sign; +exports.verify = VerifyStream.verify; +exports.decode = VerifyStream.decode; +exports.isValid = VerifyStream.isValid; +exports.createSign = function createSign(opts) { + return new SignStream(opts); +}; +exports.createVerify = function createVerify(opts) { + return new VerifyStream(opts); +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/data-stream.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/data-stream.js new file mode 100644 index 0000000..3535d31 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/data-stream.js @@ -0,0 +1,55 @@ +/*global module, process*/ +var Buffer = require('safe-buffer').Buffer; +var Stream = require('stream'); +var util = require('util'); + +function DataStream(data) { + this.buffer = null; + this.writable = true; + this.readable = true; + + // No input + if (!data) { + this.buffer = Buffer.alloc(0); + return this; + } + + // Stream + if (typeof data.pipe === 'function') { + this.buffer = Buffer.alloc(0); + data.pipe(this); + return this; + } + + // Buffer or String + // or Object (assumedly a passworded key) + if (data.length || typeof data === 'object') { + this.buffer = data; + this.writable = false; + process.nextTick(function () { + this.emit('end', data); + this.readable = false; + this.emit('close'); + }.bind(this)); + return this; + } + + throw new TypeError('Unexpected data type ('+ typeof data + ')'); +} +util.inherits(DataStream, Stream); + +DataStream.prototype.write = function write(data) { + this.buffer = Buffer.concat([this.buffer, Buffer.from(data)]); + this.emit('data', data); +}; + +DataStream.prototype.end = function end(data) { + if (data) + this.write(data); + this.emit('end', data); + this.emit('close'); + this.writable = false; + this.readable = false; +}; + +module.exports = DataStream; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/sign-stream.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/sign-stream.js new file mode 100644 index 0000000..6a7ee42 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/sign-stream.js @@ -0,0 +1,78 @@ +/*global module*/ +var Buffer = require('safe-buffer').Buffer; +var DataStream = require('./data-stream'); +var jwa = require('jwa'); +var Stream = require('stream'); +var toString = require('./tostring'); +var util = require('util'); + +function base64url(string, encoding) { + return Buffer + .from(string, encoding) + .toString('base64') + .replace(/=/g, '') + .replace(/\+/g, '-') + .replace(/\//g, '_'); +} + +function jwsSecuredInput(header, payload, encoding) { + encoding = encoding || 'utf8'; + var encodedHeader = base64url(toString(header), 'binary'); + var encodedPayload = base64url(toString(payload), encoding); + return util.format('%s.%s', encodedHeader, encodedPayload); +} + +function jwsSign(opts) { + var header = opts.header; + var payload = opts.payload; + var secretOrKey = opts.secret || opts.privateKey; + var encoding = opts.encoding; + var algo = jwa(header.alg); + var securedInput = jwsSecuredInput(header, payload, encoding); + var signature = algo.sign(securedInput, secretOrKey); + return util.format('%s.%s', securedInput, signature); +} + +function SignStream(opts) { + var secret = opts.secret||opts.privateKey||opts.key; + var secretStream = new DataStream(secret); + this.readable = true; + this.header = opts.header; + this.encoding = opts.encoding; + this.secret = this.privateKey = this.key = secretStream; + this.payload = new DataStream(opts.payload); + this.secret.once('close', function () { + if (!this.payload.writable && this.readable) + this.sign(); + }.bind(this)); + + this.payload.once('close', function () { + if (!this.secret.writable && this.readable) + this.sign(); + }.bind(this)); +} +util.inherits(SignStream, Stream); + +SignStream.prototype.sign = function sign() { + try { + var signature = jwsSign({ + header: this.header, + payload: this.payload.buffer, + secret: this.secret.buffer, + encoding: this.encoding + }); + this.emit('done', signature); + this.emit('data', signature); + this.emit('end'); + this.readable = false; + return signature; + } catch (e) { + this.readable = false; + this.emit('error', e); + this.emit('close'); + } +}; + +SignStream.sign = jwsSign; + +module.exports = SignStream; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/tostring.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/tostring.js new file mode 100644 index 0000000..f5a49a3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/tostring.js @@ -0,0 +1,10 @@ +/*global module*/ +var Buffer = require('buffer').Buffer; + +module.exports = function toString(obj) { + if (typeof obj === 'string') + return obj; + if (typeof obj === 'number' || Buffer.isBuffer(obj)) + return obj.toString(); + return JSON.stringify(obj); +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/verify-stream.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/verify-stream.js new file mode 100644 index 0000000..39f7c73 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/lib/verify-stream.js @@ -0,0 +1,120 @@ +/*global module*/ +var Buffer = require('safe-buffer').Buffer; +var DataStream = require('./data-stream'); +var jwa = require('jwa'); +var Stream = require('stream'); +var toString = require('./tostring'); +var util = require('util'); +var JWS_REGEX = /^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/; + +function isObject(thing) { + return Object.prototype.toString.call(thing) === '[object Object]'; +} + +function safeJsonParse(thing) { + if (isObject(thing)) + return thing; + try { return JSON.parse(thing); } + catch (e) { return undefined; } +} + +function headerFromJWS(jwsSig) { + var encodedHeader = jwsSig.split('.', 1)[0]; + return safeJsonParse(Buffer.from(encodedHeader, 'base64').toString('binary')); +} + +function securedInputFromJWS(jwsSig) { + return jwsSig.split('.', 2).join('.'); +} + +function signatureFromJWS(jwsSig) { + return jwsSig.split('.')[2]; +} + +function payloadFromJWS(jwsSig, encoding) { + encoding = encoding || 'utf8'; + var payload = jwsSig.split('.')[1]; + return Buffer.from(payload, 'base64').toString(encoding); +} + +function isValidJws(string) { + return JWS_REGEX.test(string) && !!headerFromJWS(string); +} + +function jwsVerify(jwsSig, algorithm, secretOrKey) { + if (!algorithm) { + var err = new Error("Missing algorithm parameter for jws.verify"); + err.code = "MISSING_ALGORITHM"; + throw err; + } + jwsSig = toString(jwsSig); + var signature = signatureFromJWS(jwsSig); + var securedInput = securedInputFromJWS(jwsSig); + var algo = jwa(algorithm); + return algo.verify(securedInput, signature, secretOrKey); +} + +function jwsDecode(jwsSig, opts) { + opts = opts || {}; + jwsSig = toString(jwsSig); + + if (!isValidJws(jwsSig)) + return null; + + var header = headerFromJWS(jwsSig); + + if (!header) + return null; + + var payload = payloadFromJWS(jwsSig); + if (header.typ === 'JWT' || opts.json) + payload = JSON.parse(payload, opts.encoding); + + return { + header: header, + payload: payload, + signature: signatureFromJWS(jwsSig) + }; +} + +function VerifyStream(opts) { + opts = opts || {}; + var secretOrKey = opts.secret||opts.publicKey||opts.key; + var secretStream = new DataStream(secretOrKey); + this.readable = true; + this.algorithm = opts.algorithm; + this.encoding = opts.encoding; + this.secret = this.publicKey = this.key = secretStream; + this.signature = new DataStream(opts.signature); + this.secret.once('close', function () { + if (!this.signature.writable && this.readable) + this.verify(); + }.bind(this)); + + this.signature.once('close', function () { + if (!this.secret.writable && this.readable) + this.verify(); + }.bind(this)); +} +util.inherits(VerifyStream, Stream); +VerifyStream.prototype.verify = function verify() { + try { + var valid = jwsVerify(this.signature.buffer, this.algorithm, this.key.buffer); + var obj = jwsDecode(this.signature.buffer, this.encoding); + this.emit('done', valid, obj); + this.emit('data', valid); + this.emit('end'); + this.readable = false; + return valid; + } catch (e) { + this.readable = false; + this.emit('error', e); + this.emit('close'); + } +}; + +VerifyStream.decode = jwsDecode; +VerifyStream.isValid = isValidJws; +VerifyStream.verify = jwsVerify; + +module.exports = VerifyStream; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/package.json new file mode 100644 index 0000000..9aef701 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/package.json @@ -0,0 +1,64 @@ +{ + "_from": "jws@^3.2.2", + "_id": "jws@3.2.2", + "_inBundle": false, + "_integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "_location": "/jws", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "jws@^3.2.2", + "name": "jws", + "escapedName": "jws", + "rawSpec": "^3.2.2", + "saveSpec": null, + "fetchSpec": "^3.2.2" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "_shasum": "001099f3639468c9414000e99995fa52fb478304", + "_spec": "jws@^3.2.2", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "Brian J Brennan" + }, + "bugs": { + "url": "https://github.com/brianloveswords/node-jws/issues" + }, + "bundleDependencies": false, + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + }, + "deprecated": false, + "description": "Implementation of JSON Web Signatures", + "devDependencies": { + "semver": "^5.1.0", + "tape": "~2.14.0" + }, + "directories": { + "test": "test" + }, + "gitHead": "c0f6b27bcea5a2ad2e304d91c2e842e4076a6b03", + "homepage": "https://github.com/brianloveswords/node-jws#readme", + "keywords": [ + "jws", + "json", + "web", + "signatures" + ], + "license": "MIT", + "main": "index.js", + "name": "jws", + "repository": { + "type": "git", + "url": "git://github.com/brianloveswords/node-jws.git" + }, + "scripts": { + "test": "make test" + }, + "version": "3.2.2" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/readme.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/readme.md new file mode 100644 index 0000000..1910c9a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/jws/readme.md @@ -0,0 +1,255 @@ +# node-jws [![Build Status](https://secure.travis-ci.org/brianloveswords/node-jws.png)](http://travis-ci.org/brianloveswords/node-jws) + +An implementation of [JSON Web Signatures](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html). + +This was developed against `draft-ietf-jose-json-web-signature-08` and +implements the entire spec **except** X.509 Certificate Chain +signing/verifying (patches welcome). + +There are both synchronous (`jws.sign`, `jws.verify`) and streaming +(`jws.createSign`, `jws.createVerify`) APIs. + +# Install + +```bash +$ npm install jws +``` + +# Usage + +## jws.ALGORITHMS + +Array of supported algorithms. The following algorithms are currently supported. + +alg Parameter Value | Digital Signature or MAC Algorithm +----------------|---------------------------- +HS256 | HMAC using SHA-256 hash algorithm +HS384 | HMAC using SHA-384 hash algorithm +HS512 | HMAC using SHA-512 hash algorithm +RS256 | RSASSA using SHA-256 hash algorithm +RS384 | RSASSA using SHA-384 hash algorithm +RS512 | RSASSA using SHA-512 hash algorithm +PS256 | RSASSA-PSS using SHA-256 hash algorithm +PS384 | RSASSA-PSS using SHA-384 hash algorithm +PS512 | RSASSA-PSS using SHA-512 hash algorithm +ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm +ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm +ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm +none | No digital signature or MAC value included + +## jws.sign(options) + +(Synchronous) Return a JSON Web Signature for a header and a payload. + +Options: + +* `header` +* `payload` +* `secret` or `privateKey` +* `encoding` (Optional, defaults to 'utf8') + +`header` must be an object with an `alg` property. `header.alg` must be +one a value found in `jws.ALGORITHMS`. See above for a table of +supported algorithms. + +If `payload` is not a buffer or a string, it will be coerced into a string +using `JSON.stringify`. + +Example + +```js +const signature = jws.sign({ + header: { alg: 'HS256' }, + payload: 'h. jon benjamin', + secret: 'has a van', +}); +``` + +## jws.verify(signature, algorithm, secretOrKey) + +(Synchronous) Returns `true` or `false` for whether a signature matches a +secret or key. + +`signature` is a JWS Signature. `header.alg` must be a value found in `jws.ALGORITHMS`. +See above for a table of supported algorithms. `secretOrKey` is a string or +buffer containing either the secret for HMAC algorithms, or the PEM +encoded public key for RSA and ECDSA. + +Note that the `"alg"` value from the signature header is ignored. + + +## jws.decode(signature) + +(Synchronous) Returns the decoded header, decoded payload, and signature +parts of the JWS Signature. + +Returns an object with three properties, e.g. +```js +{ header: { alg: 'HS256' }, + payload: 'h. jon benjamin', + signature: 'YOWPewyGHKu4Y_0M_vtlEnNlqmFOclqp4Hy6hVHfFT4' +} +``` + +## jws.createSign(options) + +Returns a new SignStream object. + +Options: + +* `header` (required) +* `payload` +* `key` || `privateKey` || `secret` +* `encoding` (Optional, defaults to 'utf8') + +Other than `header`, all options expect a string or a buffer when the +value is known ahead of time, or a stream for convenience. +`key`/`privateKey`/`secret` may also be an object when using an encrypted +private key, see the [crypto documentation][encrypted-key-docs]. + +Example: + +```js + +// This... +jws.createSign({ + header: { alg: 'RS256' }, + privateKey: privateKeyStream, + payload: payloadStream, +}).on('done', function(signature) { + // ... +}); + +// is equivalent to this: +const signer = jws.createSign({ + header: { alg: 'RS256' }, +}); +privateKeyStream.pipe(signer.privateKey); +payloadStream.pipe(signer.payload); +signer.on('done', function(signature) { + // ... +}); +``` + +## jws.createVerify(options) + +Returns a new VerifyStream object. + +Options: + +* `signature` +* `algorithm` +* `key` || `publicKey` || `secret` +* `encoding` (Optional, defaults to 'utf8') + +All options expect a string or a buffer when the value is known ahead of +time, or a stream for convenience. + +Example: + +```js + +// This... +jws.createVerify({ + publicKey: pubKeyStream, + signature: sigStream, +}).on('done', function(verified, obj) { + // ... +}); + +// is equivilant to this: +const verifier = jws.createVerify(); +pubKeyStream.pipe(verifier.publicKey); +sigStream.pipe(verifier.signature); +verifier.on('done', function(verified, obj) { + // ... +}); +``` + +## Class: SignStream + +A `Readable Stream` that emits a single data event (the calculated +signature) when done. + +### Event: 'done' +`function (signature) { }` + +### signer.payload + +A `Writable Stream` that expects the JWS payload. Do *not* use if you +passed a `payload` option to the constructor. + +Example: + +```js +payloadStream.pipe(signer.payload); +``` + +### signer.secret
signer.key
signer.privateKey + +A `Writable Stream`. Expects the JWS secret for HMAC, or the privateKey +for ECDSA and RSA. Do *not* use if you passed a `secret` or `key` option +to the constructor. + +Example: + +```js +privateKeyStream.pipe(signer.privateKey); +``` + +## Class: VerifyStream + +This is a `Readable Stream` that emits a single data event, the result +of whether or not that signature was valid. + +### Event: 'done' +`function (valid, obj) { }` + +`valid` is a boolean for whether or not the signature is valid. + +### verifier.signature + +A `Writable Stream` that expects a JWS Signature. Do *not* use if you +passed a `signature` option to the constructor. + +### verifier.secret
verifier.key
verifier.publicKey + +A `Writable Stream` that expects a public key or secret. Do *not* use if you +passed a `key` or `secret` option to the constructor. + +# TODO + +* It feels like there should be some convenience options/APIs for + defining the algorithm rather than having to define a header object + with `{ alg: 'ES512' }` or whatever every time. + +* X.509 support, ugh + +# License + +MIT + +``` +Copyright (c) 2013-2015 Brian J. Brennan + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +[encrypted-key-docs]: https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/README.md new file mode 100644 index 0000000..26e9377 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/README.md @@ -0,0 +1,18 @@ +# lodash.includes v4.3.0 + +The [lodash](https://lodash.com/) method `_.includes` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.includes +``` + +In Node.js: +```js +var includes = require('lodash.includes'); +``` + +See the [documentation](https://lodash.com/docs#includes) or [package source](https://github.com/lodash/lodash/blob/4.3.0-npm-packages/lodash.includes) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/index.js new file mode 100644 index 0000000..e88d533 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/index.js @@ -0,0 +1,745 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array ? array.length : 0, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return baseFindIndex(array, baseIsNaN, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ +function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object ? baseValues(object, keys(object)) : []; +} + +module.exports = includes; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/package.json new file mode 100644 index 0000000..1466a06 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.includes/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.includes@^4.3.0", + "_id": "lodash.includes@4.3.0", + "_inBundle": false, + "_integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "_location": "/lodash.includes", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.includes@^4.3.0", + "name": "lodash.includes", + "escapedName": "lodash.includes", + "rawSpec": "^4.3.0", + "saveSpec": null, + "fetchSpec": "^4.3.0" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "_shasum": "60bb98a87cb923c68ca1e51325483314849f553f", + "_spec": "lodash.includes@^4.3.0", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.includes` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "includes" + ], + "license": "MIT", + "name": "lodash.includes", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.3.0" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/LICENSE new file mode 100644 index 0000000..b054ca5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/README.md new file mode 100644 index 0000000..b3c476b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/README.md @@ -0,0 +1,18 @@ +# lodash.isboolean v3.0.3 + +The [lodash](https://lodash.com/) method `_.isBoolean` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isboolean +``` + +In Node.js: +```js +var isBoolean = require('lodash.isboolean'); +``` + +See the [documentation](https://lodash.com/docs#isBoolean) or [package source](https://github.com/lodash/lodash/blob/3.0.3-npm-packages/lodash.isboolean) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/index.js new file mode 100644 index 0000000..23bbabd --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/index.js @@ -0,0 +1,70 @@ +/** + * lodash 3.0.3 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ +function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isBoolean; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/package.json new file mode 100644 index 0000000..40e770c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isboolean/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.isboolean@^3.0.3", + "_id": "lodash.isboolean@3.0.3", + "_inBundle": false, + "_integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "_location": "/lodash.isboolean", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.isboolean@^3.0.3", + "name": "lodash.isboolean", + "escapedName": "lodash.isboolean", + "rawSpec": "^3.0.3", + "saveSpec": null, + "fetchSpec": "^3.0.3" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "_shasum": "6c2e171db2a257cd96802fd43b01b20d5f5870f6", + "_spec": "lodash.isboolean@^3.0.3", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.isBoolean` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isboolean" + ], + "license": "MIT", + "name": "lodash.isboolean", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.3" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/README.md new file mode 100644 index 0000000..3a78567 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/README.md @@ -0,0 +1,18 @@ +# lodash.isinteger v4.0.4 + +The [lodash](https://lodash.com/) method `_.isInteger` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isinteger +``` + +In Node.js: +```js +var isInteger = require('lodash.isinteger'); +``` + +See the [documentation](https://lodash.com/docs#isInteger) or [package source](https://github.com/lodash/lodash/blob/4.0.4-npm-packages/lodash.isinteger) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/index.js new file mode 100644 index 0000000..3bf06f0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/index.js @@ -0,0 +1,265 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ +function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +module.exports = isInteger; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/package.json new file mode 100644 index 0000000..5a41b3a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isinteger/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.isinteger@^4.0.4", + "_id": "lodash.isinteger@4.0.4", + "_inBundle": false, + "_integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "_location": "/lodash.isinteger", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.isinteger@^4.0.4", + "name": "lodash.isinteger", + "escapedName": "lodash.isinteger", + "rawSpec": "^4.0.4", + "saveSpec": null, + "fetchSpec": "^4.0.4" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "_shasum": "619c0af3d03f8b04c31f5882840b77b11cd68343", + "_spec": "lodash.isinteger@^4.0.4", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.isInteger` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isinteger" + ], + "license": "MIT", + "name": "lodash.isinteger", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.0.4" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/LICENSE new file mode 100644 index 0000000..b054ca5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/README.md new file mode 100644 index 0000000..a1d434d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/README.md @@ -0,0 +1,18 @@ +# lodash.isnumber v3.0.3 + +The [lodash](https://lodash.com/) method `_.isNumber` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isnumber +``` + +In Node.js: +```js +var isNumber = require('lodash.isnumber'); +``` + +See the [documentation](https://lodash.com/docs#isNumber) or [package source](https://github.com/lodash/lodash/blob/3.0.3-npm-packages/lodash.isnumber) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/index.js new file mode 100644 index 0000000..35a8573 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/index.js @@ -0,0 +1,79 @@ +/** + * lodash 3.0.3 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var numberTag = '[object Number]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ +function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); +} + +module.exports = isNumber; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/package.json new file mode 100644 index 0000000..6b91a93 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isnumber/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.isnumber@^3.0.3", + "_id": "lodash.isnumber@3.0.3", + "_inBundle": false, + "_integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "_location": "/lodash.isnumber", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.isnumber@^3.0.3", + "name": "lodash.isnumber", + "escapedName": "lodash.isnumber", + "rawSpec": "^3.0.3", + "saveSpec": null, + "fetchSpec": "^3.0.3" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "_shasum": "3ce76810c5928d03352301ac287317f11c0b1ffc", + "_spec": "lodash.isnumber@^3.0.3", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.isNumber` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isnumber" + ], + "license": "MIT", + "name": "lodash.isnumber", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.3" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/README.md new file mode 100644 index 0000000..aeefd74 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/README.md @@ -0,0 +1,18 @@ +# lodash.isplainobject v4.0.6 + +The [lodash](https://lodash.com/) method `_.isPlainObject` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isplainobject +``` + +In Node.js: +```js +var isPlainObject = require('lodash.isplainobject'); +``` + +See the [documentation](https://lodash.com/docs#isPlainObject) or [package source](https://github.com/lodash/lodash/blob/4.0.6-npm-packages/lodash.isplainobject) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/index.js new file mode 100644 index 0000000..0f820ee --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/index.js @@ -0,0 +1,139 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} + +module.exports = isPlainObject; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/package.json new file mode 100644 index 0000000..bb79e32 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isplainobject/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.isplainobject@^4.0.6", + "_id": "lodash.isplainobject@4.0.6", + "_inBundle": false, + "_integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "_location": "/lodash.isplainobject", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.isplainobject@^4.0.6", + "name": "lodash.isplainobject", + "escapedName": "lodash.isplainobject", + "rawSpec": "^4.0.6", + "saveSpec": null, + "fetchSpec": "^4.0.6" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "_shasum": "7c526a52d89b45c45cc690b88163be0497f550cb", + "_spec": "lodash.isplainobject@^4.0.6", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.isPlainObject` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isplainobject" + ], + "license": "MIT", + "name": "lodash.isplainobject", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.0.6" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/LICENSE new file mode 100644 index 0000000..b054ca5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/README.md new file mode 100644 index 0000000..f184029 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/README.md @@ -0,0 +1,18 @@ +# lodash.isstring v4.0.1 + +The [lodash](https://lodash.com/) method `_.isString` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isstring +``` + +In Node.js: +```js +var isString = require('lodash.isstring'); +``` + +See the [documentation](https://lodash.com/docs#isString) or [package source](https://github.com/lodash/lodash/blob/4.0.1-npm-packages/lodash.isstring) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/index.js new file mode 100644 index 0000000..408225c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/index.js @@ -0,0 +1,95 @@ +/** + * lodash 4.0.1 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type Function + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); +} + +module.exports = isString; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/package.json new file mode 100644 index 0000000..7bb3597 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.isstring/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.isstring@^4.0.1", + "_id": "lodash.isstring@4.0.1", + "_inBundle": false, + "_integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "_location": "/lodash.isstring", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.isstring@^4.0.1", + "name": "lodash.isstring", + "escapedName": "lodash.isstring", + "rawSpec": "^4.0.1", + "saveSpec": null, + "fetchSpec": "^4.0.1" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "_shasum": "d527dfb5456eca7cc9bb95d5daeaf88ba54a5451", + "_spec": "lodash.isstring@^4.0.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.isString` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isstring" + ], + "license": "MIT", + "name": "lodash.isstring", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.0.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/LICENSE new file mode 100644 index 0000000..77c42f1 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/LICENSE @@ -0,0 +1,47 @@ +Copyright OpenJS Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/README.md new file mode 100644 index 0000000..91b7538 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/README.md @@ -0,0 +1,18 @@ +# lodash.merge v4.6.2 + +The [Lodash](https://lodash.com/) method `_.merge` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.merge +``` + +In Node.js: +```js +var merge = require('lodash.merge'); +``` + +See the [documentation](https://lodash.com/docs#merge) or [package source](https://github.com/lodash/lodash/blob/4.6.2-npm-packages/lodash.merge) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/index.js new file mode 100644 index 0000000..8e75d95 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/index.js @@ -0,0 +1,1977 @@ +/** + * Lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 800, + HOT_SPAN = 16; + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); + +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeMax = Math.max, + nativeNow = Date.now; + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'), + nativeCreate = getNative(Object, 'create'); + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; +}()); + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; +} + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; + this.size = 0; +} + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; +} + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; +} + +/** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } +} + +/** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ +function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; +} + +/** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); +} + +/** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); +} + +/** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); +}; + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; +} + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; +} + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +/** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; +} + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} + +/** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ +function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; +} + +/** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; +} + +/** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var setToString = shortOut(baseSetToString); + +/** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ +function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); +}; + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; +} + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + +/** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ +function toPlainObject(value) { + return copyObject(value, keysIn(value)); +} + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +} + +/** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ +var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); +}); + +/** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ +function constant(value) { + return function() { + return value; + }; +} + +/** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ +function identity(value) { + return value; +} + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = merge; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/package.json new file mode 100644 index 0000000..94a4656 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.merge/package.json @@ -0,0 +1,61 @@ +{ + "_from": "lodash.merge@4.6.2", + "_id": "lodash.merge@4.6.2", + "_inBundle": false, + "_integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "_location": "/lodash.merge", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "lodash.merge@4.6.2", + "name": "lodash.merge", + "escapedName": "lodash.merge", + "rawSpec": "4.6.2", + "saveSpec": null, + "fetchSpec": "4.6.2" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "_shasum": "558aa53b43b661e1925a0afdfa36a9a1085fe57a", + "_spec": "lodash.merge@4.6.2", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be" + } + ], + "deprecated": false, + "description": "The Lodash method `_.merge` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "merge" + ], + "license": "MIT", + "name": "lodash.merge", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.6.2" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/README.md new file mode 100644 index 0000000..c4a2f16 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/README.md @@ -0,0 +1,18 @@ +# lodash.once v4.1.1 + +The [lodash](https://lodash.com/) method `_.once` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.once +``` + +In Node.js: +```js +var once = require('lodash.once'); +``` + +See the [documentation](https://lodash.com/docs#once) or [package source](https://github.com/lodash/lodash/blob/4.1.1-npm-packages/lodash.once) for more details. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/index.js new file mode 100644 index 0000000..414ceb3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/index.js @@ -0,0 +1,294 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +/** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ +function once(func) { + return before(2, func); +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +module.exports = once; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/package.json new file mode 100644 index 0000000..06d309a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/lodash.once/package.json @@ -0,0 +1,69 @@ +{ + "_from": "lodash.once@^4.0.0", + "_id": "lodash.once@4.1.1", + "_inBundle": false, + "_integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "_location": "/lodash.once", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "lodash.once@^4.0.0", + "name": "lodash.once", + "escapedName": "lodash.once", + "rawSpec": "^4.0.0", + "saveSpec": null, + "fetchSpec": "^4.0.0" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "_shasum": "0dd3971213c7c56df880977d504c88fb471a97ac", + "_spec": "lodash.once@^4.0.0", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "deprecated": false, + "description": "The lodash method `_.once` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "once" + ], + "license": "MIT", + "name": "lodash.once", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.1.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/index.js new file mode 100644 index 0000000..ea734fb --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/index.js @@ -0,0 +1,162 @@ +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; +} + +/** + * Pluralization helper. + */ + +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/license.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/license.md new file mode 100644 index 0000000..fa5d39b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/license.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/package.json new file mode 100644 index 0000000..5819fcf --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/package.json @@ -0,0 +1,70 @@ +{ + "_from": "ms@^2.1.1", + "_id": "ms@2.1.3", + "_inBundle": false, + "_integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "_location": "/ms", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "ms@^2.1.1", + "name": "ms", + "escapedName": "ms", + "rawSpec": "^2.1.1", + "saveSpec": null, + "fetchSpec": "^2.1.1" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "_shasum": "574c8138ce1d2b5861f0b44579dbadd60c6615b2", + "_spec": "ms@^2.1.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "bugs": { + "url": "https://github.com/vercel/ms/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Tiny millisecond conversion utility", + "devDependencies": { + "eslint": "4.18.2", + "expect.js": "0.3.1", + "husky": "0.14.3", + "lint-staged": "5.0.0", + "mocha": "4.0.1", + "prettier": "2.0.5" + }, + "eslintConfig": { + "extends": "eslint:recommended", + "env": { + "node": true, + "es6": true + } + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/vercel/ms#readme", + "license": "MIT", + "lint-staged": { + "*.js": [ + "npm run lint", + "prettier --single-quote --write", + "git add" + ] + }, + "main": "./index", + "name": "ms", + "repository": { + "type": "git", + "url": "git+https://github.com/vercel/ms.git" + }, + "scripts": { + "lint": "eslint lib/* bin/*", + "precommit": "lint-staged", + "test": "mocha tests.js" + }, + "version": "2.1.3" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/readme.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/readme.md new file mode 100644 index 0000000..0fc1abb --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/ms/readme.md @@ -0,0 +1,59 @@ +# ms + +![CI](https://github.com/vercel/ms/workflows/CI/badge.svg) + +Use this package to easily convert various time formats to milliseconds. + +## Examples + +```js +ms('2 days') // 172800000 +ms('1d') // 86400000 +ms('10h') // 36000000 +ms('2.5 hrs') // 9000000 +ms('2h') // 7200000 +ms('1m') // 60000 +ms('5s') // 5000 +ms('1y') // 31557600000 +ms('100') // 100 +ms('-3 days') // -259200000 +ms('-1h') // -3600000 +ms('-200') // -200 +``` + +### Convert from Milliseconds + +```js +ms(60000) // "1m" +ms(2 * 60000) // "2m" +ms(-3 * 60000) // "-3m" +ms(ms('10 hours')) // "10h" +``` + +### Time Format Written-Out + +```js +ms(60000, { long: true }) // "1 minute" +ms(2 * 60000, { long: true }) // "2 minutes" +ms(-3 * 60000, { long: true }) // "-3 minutes" +ms(ms('10 hours'), { long: true }) // "10 hours" +``` + +## Features + +- Works both in [Node.js](https://nodejs.org) and in the browser +- If a number is supplied to `ms`, a string with a unit is returned +- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) +- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned + +## Related Packages + +- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. + +## Caught a Bug? + +1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device +2. Link the package to the global module directory: `npm link` +3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! + +As always, you can run the tests using: `npm test` diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/LICENSE new file mode 100644 index 0000000..0c068ce --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/README.md new file mode 100644 index 0000000..e9a81af --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/README.md @@ -0,0 +1,584 @@ +# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] + +[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg +[travis-url]: https://travis-ci.org/feross/safe-buffer +[npm-image]: https://img.shields.io/npm/v/safe-buffer.svg +[npm-url]: https://npmjs.org/package/safe-buffer +[downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg +[downloads-url]: https://npmjs.org/package/safe-buffer +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg +[standard-url]: https://standardjs.com + +#### Safer Node.js Buffer API + +**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`, +`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.** + +**Uses the built-in implementation when available.** + +## install + +``` +npm install safe-buffer +``` + +## usage + +The goal of this package is to provide a safe replacement for the node.js `Buffer`. + +It's a drop-in replacement for `Buffer`. You can use it by adding one `require` line to +the top of your node.js modules: + +```js +var Buffer = require('safe-buffer').Buffer + +// Existing buffer code will continue to work without issues: + +new Buffer('hey', 'utf8') +new Buffer([1, 2, 3], 'utf8') +new Buffer(obj) +new Buffer(16) // create an uninitialized buffer (potentially unsafe) + +// But you can use these new explicit APIs to make clear what you want: + +Buffer.from('hey', 'utf8') // convert from many types to a Buffer +Buffer.alloc(16) // create a zero-filled buffer (safe) +Buffer.allocUnsafe(16) // create an uninitialized buffer (potentially unsafe) +``` + +## api + +### Class Method: Buffer.from(array) + + +* `array` {Array} + +Allocates a new `Buffer` using an `array` of octets. + +```js +const buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]); + // creates a new Buffer containing ASCII bytes + // ['b','u','f','f','e','r'] +``` + +A `TypeError` will be thrown if `array` is not an `Array`. + +### Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]]) + + +* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or + a `new ArrayBuffer()` +* `byteOffset` {Number} Default: `0` +* `length` {Number} Default: `arrayBuffer.length - byteOffset` + +When passed a reference to the `.buffer` property of a `TypedArray` instance, +the newly created `Buffer` will share the same allocated memory as the +TypedArray. + +```js +const arr = new Uint16Array(2); +arr[0] = 5000; +arr[1] = 4000; + +const buf = Buffer.from(arr.buffer); // shares the memory with arr; + +console.log(buf); + // Prints: + +// changing the TypedArray changes the Buffer also +arr[1] = 6000; + +console.log(buf); + // Prints: +``` + +The optional `byteOffset` and `length` arguments specify a memory range within +the `arrayBuffer` that will be shared by the `Buffer`. + +```js +const ab = new ArrayBuffer(10); +const buf = Buffer.from(ab, 0, 2); +console.log(buf.length); + // Prints: 2 +``` + +A `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`. + +### Class Method: Buffer.from(buffer) + + +* `buffer` {Buffer} + +Copies the passed `buffer` data onto a new `Buffer` instance. + +```js +const buf1 = Buffer.from('buffer'); +const buf2 = Buffer.from(buf1); + +buf1[0] = 0x61; +console.log(buf1.toString()); + // 'auffer' +console.log(buf2.toString()); + // 'buffer' (copy is not changed) +``` + +A `TypeError` will be thrown if `buffer` is not a `Buffer`. + +### Class Method: Buffer.from(str[, encoding]) + + +* `str` {String} String to encode. +* `encoding` {String} Encoding to use, Default: `'utf8'` + +Creates a new `Buffer` containing the given JavaScript string `str`. If +provided, the `encoding` parameter identifies the character encoding. +If not provided, `encoding` defaults to `'utf8'`. + +```js +const buf1 = Buffer.from('this is a tést'); +console.log(buf1.toString()); + // prints: this is a tést +console.log(buf1.toString('ascii')); + // prints: this is a tC)st + +const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex'); +console.log(buf2.toString()); + // prints: this is a tést +``` + +A `TypeError` will be thrown if `str` is not a string. + +### Class Method: Buffer.alloc(size[, fill[, encoding]]) + + +* `size` {Number} +* `fill` {Value} Default: `undefined` +* `encoding` {String} Default: `utf8` + +Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the +`Buffer` will be *zero-filled*. + +```js +const buf = Buffer.alloc(5); +console.log(buf); + // +``` + +The `size` must be less than or equal to the value of +`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is +`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will +be created if a `size` less than or equal to 0 is specified. + +If `fill` is specified, the allocated `Buffer` will be initialized by calling +`buf.fill(fill)`. See [`buf.fill()`][] for more information. + +```js +const buf = Buffer.alloc(5, 'a'); +console.log(buf); + // +``` + +If both `fill` and `encoding` are specified, the allocated `Buffer` will be +initialized by calling `buf.fill(fill, encoding)`. For example: + +```js +const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); +console.log(buf); + // +``` + +Calling `Buffer.alloc(size)` can be significantly slower than the alternative +`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance +contents will *never contain sensitive data*. + +A `TypeError` will be thrown if `size` is not a number. + +### Class Method: Buffer.allocUnsafe(size) + + +* `size` {Number} + +Allocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must +be less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit +architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is +thrown. A zero-length Buffer will be created if a `size` less than or equal to +0 is specified. + +The underlying memory for `Buffer` instances created in this way is *not +initialized*. The contents of the newly created `Buffer` are unknown and +*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such +`Buffer` instances to zeroes. + +```js +const buf = Buffer.allocUnsafe(5); +console.log(buf); + // + // (octets will be different, every time) +buf.fill(0); +console.log(buf); + // +``` + +A `TypeError` will be thrown if `size` is not a number. + +Note that the `Buffer` module pre-allocates an internal `Buffer` instance of +size `Buffer.poolSize` that is used as a pool for the fast allocation of new +`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated +`new Buffer(size)` constructor) only when `size` is less than or equal to +`Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default +value of `Buffer.poolSize` is `8192` but can be modified. + +Use of this pre-allocated internal memory pool is a key difference between +calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`. +Specifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer +pool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal +Buffer pool if `size` is less than or equal to half `Buffer.poolSize`. The +difference is subtle but can be important when an application requires the +additional performance that `Buffer.allocUnsafe(size)` provides. + +### Class Method: Buffer.allocUnsafeSlow(size) + + +* `size` {Number} + +Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The +`size` must be less than or equal to the value of +`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is +`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will +be created if a `size` less than or equal to 0 is specified. + +The underlying memory for `Buffer` instances created in this way is *not +initialized*. The contents of the newly created `Buffer` are unknown and +*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such +`Buffer` instances to zeroes. + +When using `Buffer.allocUnsafe()` to allocate new `Buffer` instances, +allocations under 4KB are, by default, sliced from a single pre-allocated +`Buffer`. This allows applications to avoid the garbage collection overhead of +creating many individually allocated Buffers. This approach improves both +performance and memory usage by eliminating the need to track and cleanup as +many `Persistent` objects. + +However, in the case where a developer may need to retain a small chunk of +memory from a pool for an indeterminate amount of time, it may be appropriate +to create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then +copy out the relevant bits. + +```js +// need to keep around a few small chunks of memory +const store = []; + +socket.on('readable', () => { + const data = socket.read(); + // allocate for retained data + const sb = Buffer.allocUnsafeSlow(10); + // copy the data into the new allocation + data.copy(sb, 0, 0, 10); + store.push(sb); +}); +``` + +Use of `Buffer.allocUnsafeSlow()` should be used only as a last resort *after* +a developer has observed undue memory retention in their applications. + +A `TypeError` will be thrown if `size` is not a number. + +### All the Rest + +The rest of the `Buffer` API is exactly the same as in node.js. +[See the docs](https://nodejs.org/api/buffer.html). + + +## Related links + +- [Node.js issue: Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660) +- [Node.js Enhancement Proposal: Buffer.from/Buffer.alloc/Buffer.zalloc/Buffer() soft-deprecate](https://github.com/nodejs/node-eps/pull/4) + +## Why is `Buffer` unsafe? + +Today, the node.js `Buffer` constructor is overloaded to handle many different argument +types like `String`, `Array`, `Object`, `TypedArrayView` (`Uint8Array`, etc.), +`ArrayBuffer`, and also `Number`. + +The API is optimized for convenience: you can throw any type at it, and it will try to do +what you want. + +Because the Buffer constructor is so powerful, you often see code like this: + +```js +// Convert UTF-8 strings to hex +function toHex (str) { + return new Buffer(str).toString('hex') +} +``` + +***But what happens if `toHex` is called with a `Number` argument?*** + +### Remote Memory Disclosure + +If an attacker can make your program call the `Buffer` constructor with a `Number` +argument, then they can make it allocate uninitialized memory from the node.js process. +This could potentially disclose TLS private keys, user data, or database passwords. + +When the `Buffer` constructor is passed a `Number` argument, it returns an +**UNINITIALIZED** block of memory of the specified `size`. When you create a `Buffer` like +this, you **MUST** overwrite the contents before returning it to the user. + +From the [node.js docs](https://nodejs.org/api/buffer.html#buffer_new_buffer_size): + +> `new Buffer(size)` +> +> - `size` Number +> +> The underlying memory for `Buffer` instances created in this way is not initialized. +> **The contents of a newly created `Buffer` are unknown and could contain sensitive +> data.** Use `buf.fill(0)` to initialize a Buffer to zeroes. + +(Emphasis our own.) + +Whenever the programmer intended to create an uninitialized `Buffer` you often see code +like this: + +```js +var buf = new Buffer(16) + +// Immediately overwrite the uninitialized buffer with data from another buffer +for (var i = 0; i < buf.length; i++) { + buf[i] = otherBuf[i] +} +``` + + +### Would this ever be a problem in real code? + +Yes. It's surprisingly common to forget to check the type of your variables in a +dynamically-typed language like JavaScript. + +Usually the consequences of assuming the wrong type is that your program crashes with an +uncaught exception. But the failure mode for forgetting to check the type of arguments to +the `Buffer` constructor is more catastrophic. + +Here's an example of a vulnerable service that takes a JSON payload and converts it to +hex: + +```js +// Take a JSON payload {str: "some string"} and convert it to hex +var server = http.createServer(function (req, res) { + var data = '' + req.setEncoding('utf8') + req.on('data', function (chunk) { + data += chunk + }) + req.on('end', function () { + var body = JSON.parse(data) + res.end(new Buffer(body.str).toString('hex')) + }) +}) + +server.listen(8080) +``` + +In this example, an http client just has to send: + +```json +{ + "str": 1000 +} +``` + +and it will get back 1,000 bytes of uninitialized memory from the server. + +This is a very serious bug. It's similar in severity to the +[the Heartbleed bug](http://heartbleed.com/) that allowed disclosure of OpenSSL process +memory by remote attackers. + + +### Which real-world packages were vulnerable? + +#### [`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht) + +[Mathias Buus](https://github.com/mafintosh) and I +([Feross Aboukhadijeh](http://feross.org/)) found this issue in one of our own packages, +[`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht). The bug would allow +anyone on the internet to send a series of messages to a user of `bittorrent-dht` and get +them to reveal 20 bytes at a time of uninitialized memory from the node.js process. + +Here's +[the commit](https://github.com/feross/bittorrent-dht/commit/6c7da04025d5633699800a99ec3fbadf70ad35b8) +that fixed it. We released a new fixed version, created a +[Node Security Project disclosure](https://nodesecurity.io/advisories/68), and deprecated all +vulnerable versions on npm so users will get a warning to upgrade to a newer version. + +#### [`ws`](https://www.npmjs.com/package/ws) + +That got us wondering if there were other vulnerable packages. Sure enough, within a short +period of time, we found the same issue in [`ws`](https://www.npmjs.com/package/ws), the +most popular WebSocket implementation in node.js. + +If certain APIs were called with `Number` parameters instead of `String` or `Buffer` as +expected, then uninitialized server memory would be disclosed to the remote peer. + +These were the vulnerable methods: + +```js +socket.send(number) +socket.ping(number) +socket.pong(number) +``` + +Here's a vulnerable socket server with some echo functionality: + +```js +server.on('connection', function (socket) { + socket.on('message', function (message) { + message = JSON.parse(message) + if (message.type === 'echo') { + socket.send(message.data) // send back the user's message + } + }) +}) +``` + +`socket.send(number)` called on the server, will disclose server memory. + +Here's [the release](https://github.com/websockets/ws/releases/tag/1.0.1) where the issue +was fixed, with a more detailed explanation. Props to +[Arnout Kazemier](https://github.com/3rd-Eden) for the quick fix. Here's the +[Node Security Project disclosure](https://nodesecurity.io/advisories/67). + + +### What's the solution? + +It's important that node.js offers a fast way to get memory otherwise performance-critical +applications would needlessly get a lot slower. + +But we need a better way to *signal our intent* as programmers. **When we want +uninitialized memory, we should request it explicitly.** + +Sensitive functionality should not be packed into a developer-friendly API that loosely +accepts many different types. This type of API encourages the lazy practice of passing +variables in without checking the type very carefully. + +#### A new API: `Buffer.allocUnsafe(number)` + +The functionality of creating buffers with uninitialized memory should be part of another +API. We propose `Buffer.allocUnsafe(number)`. This way, it's not part of an API that +frequently gets user input of all sorts of different types passed into it. + +```js +var buf = Buffer.allocUnsafe(16) // careful, uninitialized memory! + +// Immediately overwrite the uninitialized buffer with data from another buffer +for (var i = 0; i < buf.length; i++) { + buf[i] = otherBuf[i] +} +``` + + +### How do we fix node.js core? + +We sent [a PR to node.js core](https://github.com/nodejs/node/pull/4514) (merged as +`semver-major`) which defends against one case: + +```js +var str = 16 +new Buffer(str, 'utf8') +``` + +In this situation, it's implied that the programmer intended the first argument to be a +string, since they passed an encoding as a second argument. Today, node.js will allocate +uninitialized memory in the case of `new Buffer(number, encoding)`, which is probably not +what the programmer intended. + +But this is only a partial solution, since if the programmer does `new Buffer(variable)` +(without an `encoding` parameter) there's no way to know what they intended. If `variable` +is sometimes a number, then uninitialized memory will sometimes be returned. + +### What's the real long-term fix? + +We could deprecate and remove `new Buffer(number)` and use `Buffer.allocUnsafe(number)` when +we need uninitialized memory. But that would break 1000s of packages. + +~~We believe the best solution is to:~~ + +~~1. Change `new Buffer(number)` to return safe, zeroed-out memory~~ + +~~2. Create a new API for creating uninitialized Buffers. We propose: `Buffer.allocUnsafe(number)`~~ + +#### Update + +We now support adding three new APIs: + +- `Buffer.from(value)` - convert from any type to a buffer +- `Buffer.alloc(size)` - create a zero-filled buffer +- `Buffer.allocUnsafe(size)` - create an uninitialized buffer with given size + +This solves the core problem that affected `ws` and `bittorrent-dht` which is +`Buffer(variable)` getting tricked into taking a number argument. + +This way, existing code continues working and the impact on the npm ecosystem will be +minimal. Over time, npm maintainers can migrate performance-critical code to use +`Buffer.allocUnsafe(number)` instead of `new Buffer(number)`. + + +### Conclusion + +We think there's a serious design issue with the `Buffer` API as it exists today. It +promotes insecure software by putting high-risk functionality into a convenient API +with friendly "developer ergonomics". + +This wasn't merely a theoretical exercise because we found the issue in some of the +most popular npm packages. + +Fortunately, there's an easy fix that can be applied today. Use `safe-buffer` in place of +`buffer`. + +```js +var Buffer = require('safe-buffer').Buffer +``` + +Eventually, we hope that node.js core can switch to this new, safer behavior. We believe +the impact on the ecosystem would be minimal since it's not a breaking change. +Well-maintained, popular packages would be updated to use `Buffer.alloc` quickly, while +older, insecure packages would magically become safe from this attack vector. + + +## links + +- [Node.js PR: buffer: throw if both length and enc are passed](https://github.com/nodejs/node/pull/4514) +- [Node Security Project disclosure for `ws`](https://nodesecurity.io/advisories/67) +- [Node Security Project disclosure for`bittorrent-dht`](https://nodesecurity.io/advisories/68) + + +## credit + +The original issues in `bittorrent-dht` +([disclosure](https://nodesecurity.io/advisories/68)) and +`ws` ([disclosure](https://nodesecurity.io/advisories/67)) were discovered by +[Mathias Buus](https://github.com/mafintosh) and +[Feross Aboukhadijeh](http://feross.org/). + +Thanks to [Adam Baldwin](https://github.com/evilpacket) for helping disclose these issues +and for his work running the [Node Security Project](https://nodesecurity.io/). + +Thanks to [John Hiesey](https://github.com/jhiesey) for proofreading this README and +auditing the code. + + +## license + +MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org) diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.d.ts b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.d.ts new file mode 100644 index 0000000..e9fed80 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.d.ts @@ -0,0 +1,187 @@ +declare module "safe-buffer" { + export class Buffer { + length: number + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): { type: 'Buffer', data: any[] }; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + constructor (str: string, encoding?: string); + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + constructor (size: number); + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + constructor (array: Uint8Array); + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + constructor (arrayBuffer: ArrayBuffer); + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + constructor (array: any[]); + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + constructor (buffer: Buffer); + prototype: Buffer; + /** + * Allocates a new Buffer using an {array} of octets. + * + * @param array + */ + static from(array: any[]): Buffer; + /** + * When passed a reference to the .buffer property of a TypedArray instance, + * the newly created Buffer will share the same allocated memory as the TypedArray. + * The optional {byteOffset} and {length} arguments specify a memory range + * within the {arrayBuffer} that will be shared by the Buffer. + * + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length + */ + static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer + */ + static from(buffer: Buffer): Buffer; + /** + * Creates a new Buffer containing the given JavaScript string {str}. + * If provided, the {encoding} parameter identifies the character encoding. + * If not provided, {encoding} defaults to 'utf8'. + * + * @param str + */ + static from(str: string, encoding?: string): Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + static isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + static isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + static byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + static concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + static compare(buf1: Buffer, buf2: Buffer): number; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + * @param fill if specified, buffer will be initialized by calling buf.fill(fill). + * If parameter is omitted, buffer will be filled with zeros. + * @param encoding encoding used for call to buf.fill while initalizing + */ + static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + static allocUnsafe(size: number): Buffer; + /** + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + static allocUnsafeSlow(size: number): Buffer; + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.js new file mode 100644 index 0000000..f8d3ec9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/index.js @@ -0,0 +1,65 @@ +/*! safe-buffer. MIT License. Feross Aboukhadijeh */ +/* eslint-disable node/no-deprecated-api */ +var buffer = require('buffer') +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.prototype = Object.create(Buffer.prototype) + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/package.json new file mode 100644 index 0000000..7d59ffd --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/safe-buffer/package.json @@ -0,0 +1,78 @@ +{ + "_from": "safe-buffer@^5.0.1", + "_id": "safe-buffer@5.2.1", + "_inBundle": false, + "_integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "_location": "/safe-buffer", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "safe-buffer@^5.0.1", + "name": "safe-buffer", + "escapedName": "safe-buffer", + "rawSpec": "^5.0.1", + "saveSpec": null, + "fetchSpec": "^5.0.1" + }, + "_requiredBy": [ + "/ecdsa-sig-formatter", + "/jwa", + "/jws" + ], + "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "_shasum": "1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "_spec": "safe-buffer@^5.0.1", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jws", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "https://feross.org" + }, + "bugs": { + "url": "https://github.com/feross/safe-buffer/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Safer Node.js Buffer API", + "devDependencies": { + "standard": "*", + "tape": "^5.0.0" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "homepage": "https://github.com/feross/safe-buffer", + "keywords": [ + "buffer", + "buffer allocate", + "node security", + "safe", + "safe-buffer", + "security", + "uninitialized" + ], + "license": "MIT", + "main": "index.js", + "name": "safe-buffer", + "repository": { + "type": "git", + "url": "git://github.com/feross/safe-buffer.git" + }, + "scripts": { + "test": "standard && tape test/*.js" + }, + "types": "index.d.ts", + "version": "5.2.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/CHANGELOG.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/CHANGELOG.md new file mode 100644 index 0000000..66304fd --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/CHANGELOG.md @@ -0,0 +1,39 @@ +# changes log + +## 5.7 + +* Add `minVersion` method + +## 5.6 + +* Move boolean `loose` param to an options object, with + backwards-compatibility protection. +* Add ability to opt out of special prerelease version handling with + the `includePrerelease` option flag. + +## 5.5 + +* Add version coercion capabilities + +## 5.4 + +* Add intersection checking + +## 5.3 + +* Add `minSatisfying` method + +## 5.2 + +* Add `prerelease(v)` that returns prerelease components + +## 5.1 + +* Add Backus-Naur for ranges +* Remove excessively cute inspection methods + +## 5.0 + +* Remove AMD/Browserified build artifacts +* Fix ltr and gtr when using the `*` range +* Fix for range `*` with a prerelease identifier diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/LICENSE b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/README.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/README.md new file mode 100644 index 0000000..f8dfa5a --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/README.md @@ -0,0 +1,412 @@ +semver(1) -- The semantic versioner for npm +=========================================== + +## Install + +```bash +npm install --save semver +```` + +## Usage + +As a node module: + +```js +const semver = require('semver') + +semver.valid('1.2.3') // '1.2.3' +semver.valid('a.b.c') // null +semver.clean(' =v1.2.3 ') // '1.2.3' +semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true +semver.gt('1.2.3', '9.8.7') // false +semver.lt('1.2.3', '9.8.7') // true +semver.minVersion('>=1.0.0') // '1.0.0' +semver.valid(semver.coerce('v2')) // '2.0.0' +semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' +``` + +As a command-line utility: + +``` +$ semver -h + +A JavaScript implementation of the https://semver.org/ specification +Copyright Isaac Z. Schlueter + +Usage: semver [options] [ [...]] +Prints valid versions sorted by SemVer precedence + +Options: +-r --range + Print versions that match the specified range. + +-i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, or prerelease. Default level is 'patch'. + Only one version may be specified. + +--preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + +-l --loose + Interpret versions and ranges loosely + +-p --include-prerelease + Always include prerelease versions in range matching + +-c --coerce + Coerce a string into SemVer if possible + (does not imply --loose) + +Program exits successfully if any valid version satisfies +all supplied ranges, and prints all satisfying versions. + +If no satisfying versions are found, then exits failure. + +Versions are printed in ascending order, so supplying +multiple versions to the utility will just sort them. +``` + +## Versions + +A "version" is described by the `v2.0.0` specification found at +. + +A leading `"="` or `"v"` character is stripped off and ignored. + +## Ranges + +A `version range` is a set of `comparators` which specify versions +that satisfy the range. + +A `comparator` is composed of an `operator` and a `version`. The set +of primitive `operators` is: + +* `<` Less than +* `<=` Less than or equal to +* `>` Greater than +* `>=` Greater than or equal to +* `=` Equal. If no operator is specified, then equality is assumed, + so this operator is optional, but MAY be included. + +For example, the comparator `>=1.2.7` would match the versions +`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` +or `1.1.0`. + +Comparators can be joined by whitespace to form a `comparator set`, +which is satisfied by the **intersection** of all of the comparators +it includes. + +A range is composed of one or more comparator sets, joined by `||`. A +version matches a range if and only if every comparator in at least +one of the `||`-separated comparator sets is satisfied by the version. + +For example, the range `>=1.2.7 <1.3.0` would match the versions +`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, +or `1.1.0`. + +The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, +`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. + +### Prerelease Tags + +If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then +it will only be allowed to satisfy comparator sets if at least one +comparator with the same `[major, minor, patch]` tuple also has a +prerelease tag. + +For example, the range `>1.2.3-alpha.3` would be allowed to match the +version `1.2.3-alpha.7`, but it would *not* be satisfied by +`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater +than" `1.2.3-alpha.3` according to the SemVer sort rules. The version +range only accepts prerelease tags on the `1.2.3` version. The +version `3.4.5` *would* satisfy the range, because it does not have a +prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. + +The purpose for this behavior is twofold. First, prerelease versions +frequently are updated very quickly, and contain many breaking changes +that are (by the author's design) not yet fit for public consumption. +Therefore, by default, they are excluded from range matching +semantics. + +Second, a user who has opted into using a prerelease version has +clearly indicated the intent to use *that specific* set of +alpha/beta/rc versions. By including a prerelease tag in the range, +the user is indicating that they are aware of the risk. However, it +is still not appropriate to assume that they have opted into taking a +similar risk on the *next* set of prerelease versions. + +Note that this behavior can be suppressed (treating all prerelease +versions as if they were normal versions, for the purpose of range +matching) by setting the `includePrerelease` flag on the options +object to any +[functions](https://github.com/npm/node-semver#functions) that do +range matching. + +#### Prerelease Identifiers + +The method `.inc` takes an additional `identifier` string argument that +will append the value of the string as a prerelease identifier: + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta') +// '1.2.4-beta.0' +``` + +command-line example: + +```bash +$ semver 1.2.3 -i prerelease --preid beta +1.2.4-beta.0 +``` + +Which then can be used to increment further: + +```bash +$ semver 1.2.4-beta.0 -i prerelease +1.2.4-beta.1 +``` + +### Advanced Range Syntax + +Advanced range syntax desugars to primitive comparators in +deterministic ways. + +Advanced ranges may be combined in the same way as primitive +comparators using white space or `||`. + +#### Hyphen Ranges `X.Y.Z - A.B.C` + +Specifies an inclusive set. + +* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` + +If a partial version is provided as the first version in the inclusive +range, then the missing pieces are replaced with zeroes. + +* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` + +If a partial version is provided as the second version in the +inclusive range, then all versions that start with the supplied parts +of the tuple are accepted, but nothing that would be greater than the +provided tuple parts. + +* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0` +* `1.2.3 - 2` := `>=1.2.3 <3.0.0` + +#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` + +Any of `X`, `x`, or `*` may be used to "stand in" for one of the +numeric values in the `[major, minor, patch]` tuple. + +* `*` := `>=0.0.0` (Any version satisfies) +* `1.x` := `>=1.0.0 <2.0.0` (Matching major version) +* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions) + +A partial version range is treated as an X-Range, so the special +character is in fact optional. + +* `""` (empty string) := `*` := `>=0.0.0` +* `1` := `1.x.x` := `>=1.0.0 <2.0.0` +* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0` + +#### Tilde Ranges `~1.2.3` `~1.2` `~1` + +Allows patch-level changes if a minor version is specified on the +comparator. Allows minor-level changes if not. + +* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0` +* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`) +* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`) +* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0` +* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`) +* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`) +* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. + +#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` + +Allows changes that do not modify the left-most non-zero digit in the +`[major, minor, patch]` tuple. In other words, this allows patch and +minor updates for versions `1.0.0` and above, patch updates for +versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. + +Many authors treat a `0.x` version as if the `x` were the major +"breaking-change" indicator. + +Caret ranges are ideal when an author may make breaking changes +between `0.2.4` and `0.3.0` releases, which is a common practice. +However, it presumes that there will *not* be breaking changes between +`0.2.4` and `0.2.5`. It allows for changes that are presumed to be +additive (but non-breaking), according to commonly observed practices. + +* `^1.2.3` := `>=1.2.3 <2.0.0` +* `^0.2.3` := `>=0.2.3 <0.3.0` +* `^0.0.3` := `>=0.0.3 <0.0.4` +* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. +* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the + `0.0.3` version *only* will be allowed, if they are greater than or + equal to `beta`. So, `0.0.3-pr.2` would be allowed. + +When parsing caret ranges, a missing `patch` value desugars to the +number `0`, but will allow flexibility within that value, even if the +major and minor versions are both `0`. + +* `^1.2.x` := `>=1.2.0 <2.0.0` +* `^0.0.x` := `>=0.0.0 <0.1.0` +* `^0.0` := `>=0.0.0 <0.1.0` + +A missing `minor` and `patch` values will desugar to zero, but also +allow flexibility within those values, even if the major version is +zero. + +* `^1.x` := `>=1.0.0 <2.0.0` +* `^0.x` := `>=0.0.0 <1.0.0` + +### Range Grammar + +Putting all this together, here is a Backus-Naur grammar for ranges, +for the benefit of parser authors: + +```bnf +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ +``` + +## Functions + +All methods and classes take a final `options` object argument. All +options in this object are `false` by default. The options supported +are: + +- `loose` Be more forgiving about not-quite-valid semver strings. + (Any resulting output will always be 100% strict compliant, of + course.) For backwards compatibility reasons, if the `options` + argument is a boolean value instead of an object, it is interpreted + to be the `loose` param. +- `includePrerelease` Set to suppress the [default + behavior](https://github.com/npm/node-semver#prerelease-tags) of + excluding prerelease tagged versions from ranges unless they are + explicitly opted into. + +Strict-mode Comparators and Ranges will be strict about the SemVer +strings that they parse. + +* `valid(v)`: Return the parsed version, or null if it's not valid. +* `inc(v, release)`: Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, + `prepatch`, or `prerelease`), or null if it's not valid + * `premajor` in one call will bump the version up to the next major + version and down to a prerelease of that major version. + `preminor`, and `prepatch` work the same way. + * If called from a non-prerelease version, the `prerelease` will work the + same as `prepatch`. It increments the patch version, then makes a + prerelease. If the input version is already a prerelease it simply + increments it. +* `prerelease(v)`: Returns an array of prerelease components, or null + if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` +* `major(v)`: Return the major version number. +* `minor(v)`: Return the minor version number. +* `patch(v)`: Return the patch version number. +* `intersects(r1, r2, loose)`: Return true if the two supplied ranges + or comparators intersect. +* `parse(v)`: Attempt to parse a string as a semantic version, returning either + a `SemVer` object or `null`. + +### Comparison + +* `gt(v1, v2)`: `v1 > v2` +* `gte(v1, v2)`: `v1 >= v2` +* `lt(v1, v2)`: `v1 < v2` +* `lte(v1, v2)`: `v1 <= v2` +* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, + even if they're not the exact same string. You already know how to + compare strings. +* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. +* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call + the corresponding function above. `"==="` and `"!=="` do simple + string comparison, but are included for completeness. Throws if an + invalid comparison string is provided. +* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions + in descending order when passed to `Array.sort()`. +* `diff(v1, v2)`: Returns difference between two versions by the release type + (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), + or null if the versions are the same. + +### Comparators + +* `intersects(comparator)`: Return true if the comparators intersect + +### Ranges + +* `validRange(range)`: Return the valid range or null if it's not valid +* `satisfies(version, range)`: Return true if the version satisfies the + range. +* `maxSatisfying(versions, range)`: Return the highest version in the list + that satisfies the range, or `null` if none of them do. +* `minSatisfying(versions, range)`: Return the lowest version in the list + that satisfies the range, or `null` if none of them do. +* `minVersion(range)`: Return the lowest version that can possibly match + the given range. +* `gtr(version, range)`: Return `true` if version is greater than all the + versions possible in the range. +* `ltr(version, range)`: Return `true` if version is less than all the + versions possible in the range. +* `outside(version, range, hilo)`: Return true if the version is outside + the bounds of the range in either the high or low direction. The + `hilo` argument must be either the string `'>'` or `'<'`. (This is + the function called by `gtr` and `ltr`.) +* `intersects(range)`: Return true if any of the ranges comparators intersect + +Note that, since ranges may be non-contiguous, a version might not be +greater than a range, less than a range, *or* satisfy a range! For +example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` +until `2.0.0`, so the version `1.2.10` would not be greater than the +range (because `2.0.1` satisfies, which is higher), nor less than the +range (since `1.2.8` satisfies, which is lower), and it also does not +satisfy the range. + +If you want to know if a version satisfies or does not satisfy a +range, use the `satisfies(version, range)` function. + +### Coercion + +* `coerce(version)`: Coerces a string to semver if possible + +This aims to provide a very forgiving translation of a non-semver string to +semver. It looks for the first digit in a string, and consumes all +remaining characters which satisfy at least a partial semver (e.g., `1`, +`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer +versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All +surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes +`3.4.0`). Only text which lacks digits will fail coercion (`version one` +is not valid). The maximum length for any semver component considered for +coercion is 16 characters; longer components will be ignored +(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any +semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value +components are invalid (`9999999999999999.4.7.4` is likely invalid). diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/bin/semver b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/bin/semver new file mode 100644 index 0000000..801e77f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/bin/semver @@ -0,0 +1,160 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +var argv = process.argv.slice(2) + +var versions = [] + +var range = [] + +var inc = null + +var version = require('../package.json').version + +var loose = false + +var includePrerelease = false + +var coerce = false + +var identifier + +var semver = require('../semver') + +var reverse = false + +var options = {} + +main() + +function main () { + if (!argv.length) return help() + while (argv.length) { + var a = argv.shift() + var indexOfEqualSign = a.indexOf('=') + if (indexOfEqualSign !== -1) { + a = a.slice(0, indexOfEqualSign) + argv.unshift(a.slice(indexOfEqualSign + 1)) + } + switch (a) { + case '-rv': case '-rev': case '--rev': case '--reverse': + reverse = true + break + case '-l': case '--loose': + loose = true + break + case '-p': case '--include-prerelease': + includePrerelease = true + break + case '-v': case '--version': + versions.push(argv.shift()) + break + case '-i': case '--inc': case '--increment': + switch (argv[0]) { + case 'major': case 'minor': case 'patch': case 'prerelease': + case 'premajor': case 'preminor': case 'prepatch': + inc = argv.shift() + break + default: + inc = 'patch' + break + } + break + case '--preid': + identifier = argv.shift() + break + case '-r': case '--range': + range.push(argv.shift()) + break + case '-c': case '--coerce': + coerce = true + break + case '-h': case '--help': case '-?': + return help() + default: + versions.push(a) + break + } + } + + var options = { loose: loose, includePrerelease: includePrerelease } + + versions = versions.map(function (v) { + return coerce ? (semver.coerce(v) || { version: v }).version : v + }).filter(function (v) { + return semver.valid(v) + }) + if (!versions.length) return fail() + if (inc && (versions.length !== 1 || range.length)) { return failInc() } + + for (var i = 0, l = range.length; i < l; i++) { + versions = versions.filter(function (v) { + return semver.satisfies(v, range[i], options) + }) + if (!versions.length) return fail() + } + return success(versions) +} + +function failInc () { + console.error('--inc can only be used on a single version with no range') + fail() +} + +function fail () { process.exit(1) } + +function success () { + var compare = reverse ? 'rcompare' : 'compare' + versions.sort(function (a, b) { + return semver[compare](a, b, options) + }).map(function (v) { + return semver.clean(v, options) + }).map(function (v) { + return inc ? semver.inc(v, inc, options, identifier) : v + }).forEach(function (v, i, _) { console.log(v) }) +} + +function help () { + console.log(['SemVer ' + version, + '', + 'A JavaScript implementation of the https://semver.org/ specification', + 'Copyright Isaac Z. Schlueter', + '', + 'Usage: semver [options] [ [...]]', + 'Prints valid versions sorted by SemVer precedence', + '', + 'Options:', + '-r --range ', + ' Print versions that match the specified range.', + '', + '-i --increment []', + ' Increment a version by the specified level. Level can', + ' be one of: major, minor, patch, premajor, preminor,', + " prepatch, or prerelease. Default level is 'patch'.", + ' Only one version may be specified.', + '', + '--preid ', + ' Identifier to be used to prefix premajor, preminor,', + ' prepatch or prerelease version increments.', + '', + '-l --loose', + ' Interpret versions and ranges loosely', + '', + '-p --include-prerelease', + ' Always include prerelease versions in range matching', + '', + '-c --coerce', + ' Coerce a string into SemVer if possible', + ' (does not imply --loose)', + '', + 'Program exits successfully if any valid version satisfies', + 'all supplied ranges, and prints all satisfying versions.', + '', + 'If no satisfying versions are found, then exits failure.', + '', + 'Versions are printed in ascending order, so supplying', + 'multiple versions to the utility will just sort them.' + ].join('\n')) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/package.json new file mode 100644 index 0000000..2a192e8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/package.json @@ -0,0 +1,60 @@ +{ + "_from": "semver@^5.6.0", + "_id": "semver@5.7.1", + "_inBundle": false, + "_integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "_location": "/semver", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "semver@^5.6.0", + "name": "semver", + "escapedName": "semver", + "rawSpec": "^5.6.0", + "saveSpec": null, + "fetchSpec": "^5.6.0" + }, + "_requiredBy": [ + "/jsonwebtoken" + ], + "_resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "_shasum": "a954f931aeba508d307bbf069eff0c01c96116f7", + "_spec": "semver@^5.6.0", + "_where": "G:\\Github\\SE\\teamwork\\great-teamwork\\alpha\\admin\\uni_modules\\uni-id-pages\\uniCloud\\cloudfunctions\\uni-id-co\\node_modules\\jsonwebtoken", + "bin": { + "semver": "bin/semver" + }, + "bugs": { + "url": "https://github.com/npm/node-semver/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "The semantic version parser used by npm.", + "devDependencies": { + "tap": "^13.0.0-rc.18" + }, + "files": [ + "bin", + "range.bnf", + "semver.js" + ], + "homepage": "https://github.com/npm/node-semver#readme", + "license": "ISC", + "main": "semver.js", + "name": "semver", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/node-semver.git" + }, + "scripts": { + "postpublish": "git push origin --all; git push origin --tags", + "postversion": "npm publish", + "preversion": "npm test", + "test": "tap" + }, + "tap": { + "check-coverage": true + }, + "version": "5.7.1" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/range.bnf b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/range.bnf new file mode 100644 index 0000000..d4c6ae0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | [1-9] ( [0-9] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/semver.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/semver.js new file mode 100644 index 0000000..d315d5d --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/semver/semver.js @@ -0,0 +1,1483 @@ +exports = module.exports = SemVer + +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} +} + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' + +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 + +// The actual regexps go on exports.re +var re = exports.re = [] +var src = exports.src = [] +var R = 0 + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++ +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' +var NUMERICIDENTIFIERLOOSE = R++ +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++ +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++ +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')' + +var MAINVERSIONLOOSE = R++ +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')' + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++ +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')' + +var PRERELEASEIDENTIFIERLOOSE = R++ +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')' + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++ +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' + +var PRERELEASELOOSE = R++ +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++ +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++ +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++ +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?' + +src[FULL] = '^' + FULLPLAIN + '$' + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?' + +var LOOSE = R++ +src[LOOSE] = '^' + LOOSEPLAIN + '$' + +var GTLT = R++ +src[GTLT] = '((?:<|>)?=?)' + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++ +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +var XRANGEIDENTIFIER = R++ +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' + +var XRANGEPLAIN = R++ +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?' + +var XRANGEPLAINLOOSE = R++ +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?' + +var XRANGE = R++ +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' +var XRANGELOOSE = R++ +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +var COERCE = R++ +src[COERCE] = '(?:^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++ +src[LONETILDE] = '(?:~>?)' + +var TILDETRIM = R++ +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') +var tildeTrimReplace = '$1~' + +var TILDE = R++ +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' +var TILDELOOSE = R++ +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++ +src[LONECARET] = '(?:\\^)' + +var CARETTRIM = R++ +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') +var caretTrimReplace = '$1^' + +var CARET = R++ +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' +var CARETLOOSE = R++ +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++ +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' +var COMPARATOR = R++ +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++ +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++ +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$' + +var HYPHENRANGELOOSE = R++ +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +var STAR = R++ +src[STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? re[LOOSE] : re[FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() +} + +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version +} + +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compare(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.rcompare(a, b, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY) { + return true + } + + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First, split based on boolean or || + this.raw = range + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range) + } + + this.format() +} + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range +} + +Range.prototype.toString = function () { + return this.range +} + +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + range = range.trim() + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, re[COMPARATORTRIM]) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace) + + // normalize spaces + range = range.split(/\s+/).join(' ') + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) + } + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) + + return set +} + +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some(function (thisComparators) { + return thisComparators.every(function (thisComparator) { + return range.set.some(function (rangeComparators) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + }) + }) +} + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[TILDELOOSE] : re[TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[CARETLOOSE] : re[CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], '') +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version) { + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + var match = version.match(re[COERCE]) + + if (match == null) { + return null + } + + return parse(match[1] + + '.' + (match[2] || '0') + + '.' + (match[3] || '0')) +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/LICENSE.md b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/LICENSE.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/fonts/font.ttf b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/fonts/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a60ce88613704bc7fe02dbff52043c3757a0c9d7 GIT binary patch literal 7080 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/index.js new file mode 100644 index 0000000..6e5c3c8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/index.js @@ -0,0 +1 @@ +"use strict";var e=require("assert"),t=require("path");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),r=n(t);const s={10001:"uni-captcha-create-fail",10002:"uni-captcha-verify-fail",10003:"uni-captcha-refresh-fail",10101:"uni-captcha-deviceId-required",10102:"uni-captcha-text-required",10103:"uni-captcha-verify-overdue",10104:"uni-captcha-verify-fail",50403:"uni-captcha-interior-fail"};function a(e){const t=.2*Math.random()-.1;switch(e.type){case"M":case"L":e.x+=t,e.y+=t;break;case"Q":case"C":e.x+=t,e.y+=t,e.x1+=t,e.y1+=t}return e}function i(e,t,n,o,r,s,a){let i,l,c,u,p,h;if(e<=0||e>=1)throw RangeError("spliteCurveAt requires position > 0 && position < 1");return u=[],p=0,i={},l={},c={},i.x=t,i.y=n,l.x=o,l.y=r,c.x=s,c.y=a,h=e,u[p++]=i.x,u[p++]=i.y,u[p++]=i.x+=(l.x-i.x)*h,u[p++]=i.y+=(l.y-i.y)*h,l.x+=(c.x-l.x)*h,l.y+=(c.y-l.y)*h,u[p++]=i.x+(l.x-i.x)*h,u[p++]=i.y+(l.y-i.y)*h,u[p++]=l.x,u[p++]=l.y,u[p++]=c.x,u[p++]=c.y,u}function l(e,t){return Math.random()*(t-e)+e}var c=function(e,t){const n=e[0];o.default(n,"expect a string");const r=t.fontSize,s=r/t.font.unitsPerEm,c=t.font.charToGlyph(n),u=c.advanceWidth?c.advanceWidth*s:0,p=t.x-u/2,h=(t.ascender+t.descender)*s,f=t.y+h/2,d=c.getPath(p,f,r);d.commands.forEach(a),d.commands=function(e,t){const n=[];for(let o=0;ot.truncateLineProbability){const e=l(-.1,.1);n.push(r),n.push({type:"L",x:(r.x+s.x)/2+e,y:(r.y+s.y)/2+e})}else n.push(r)}else if("Q"===r.type&&o>=1){const s=e[o-1];if(("L"===s.type||"M"===s.type)&&Math.random()>t.truncateCurveProbability){const e=s.x,o=s.y,a=l(-.1,.1),c=r.x1+a,u=r.y1+a,p=r.x+a,h=r.y+a,f=i(l(t.truncateCurvePositionMin,t.truncateCurvePositionMax),e,o,c,u,p,h),d={type:"Q",x1:f[2],y1:f[3],x:f[4],y:f[5]},g={type:"L",x:f[4],y:f[5]},m={type:"Q",x1:f[6],y1:f[7],x:f[8],y:f[9]},y={type:"L",x:f[8],y:f[9]};n.push(d),n.push(g),n.push(m),n.push(y)}}else n.push(r)}return n}(d.commands,t);return d.toPathData()};function u(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function p(e,t){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=t,this.destLen=0,this.ltree=new u,this.dtree=new u}var h=new u,f=new u,d=new Uint8Array(30),g=new Uint16Array(30),m=new Uint8Array(30),y=new Uint16Array(30),v=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),b=new u,S=new Uint8Array(320);function x(e,t,n,o){var r,s;for(r=0;r>>=1,t}function O(e,t,n){if(!t)return n;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-t;return e.tag>>>=t,e.bitcount-=t,o+n}function w(e,t){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++r,n+=t.table[r],o-=t.table[r]}while(o>=0);return e.tag=s,e.bitcount-=r,t.trans[n+o]}function k(e,t,n){var o,r,s,a,i,l;for(o=O(e,5,257),r=O(e,5,1),s=O(e,4,4),a=0;a<19;++a)S[a]=0;for(a=0;a8;)e.sourceIndex--,e.bitcount-=8;if((t=256*(t=e.source[e.sourceIndex+1])+e.source[e.sourceIndex])!==(65535&~(256*e.source[e.sourceIndex+3]+e.source[e.sourceIndex+2])))return-3;for(e.sourceIndex+=4,n=t;n;--n)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,0}!function(e,t){var n;for(n=0;n<7;++n)e.table[n]=0;for(e.table[7]=24,e.table[8]=152,e.table[9]=112,n=0;n<24;++n)e.trans[n]=256+n;for(n=0;n<144;++n)e.trans[24+n]=n;for(n=0;n<8;++n)e.trans[168+n]=280+n;for(n=0;n<112;++n)e.trans[176+n]=144+n;for(n=0;n<5;++n)t.table[n]=0;for(t.table[5]=32,n=0;n<32;++n)t.trans[n]=n}(h,f),x(d,g,4,3),x(m,y,2,1),d[28]=0,g[28]=258;var C=function(e,t){var n,o,r=new p(e,t);do{switch(n=E(r),O(r,2,0)){case 0:o=D(r);break;case 1:o=R(r,h,f);break;case 2:k(r,r.ltree,r.dtree),o=R(r,r.ltree,r.dtree);break;default:o=-3}if(0!==o)throw new Error("Data error")}while(!n);return r.destLenthis.x2&&(this.x2=e)),"number"==typeof t&&((isNaN(this.y1)||isNaN(this.y2))&&(this.y1=t,this.y2=t),tthis.y2&&(this.y2=t))},I.prototype.addX=function(e){this.addPoint(e,null)},I.prototype.addY=function(e){this.addPoint(null,e)},I.prototype.addBezier=function(e,t,n,o,r,s,a,i){const l=[e,t],c=[n,o],u=[r,s],p=[a,i];this.addPoint(e,t),this.addPoint(a,i);for(let e=0;e<=1;e++){const t=6*l[e]-12*c[e]+6*u[e],n=-3*l[e]+9*c[e]-9*u[e]+3*p[e],o=3*c[e]-3*l[e];if(0===n){if(0===t)continue;const n=-o/t;0=0&&n>0&&(e+=" "),e+=t(o)}return e}e=void 0!==e?e:2;let o="";for(let e=0;e=0&&e<=255,"Byte value should be between 0 and 255."),[e]},F.BYTE=H(1),A.CHAR=function(e){return[e.charCodeAt(0)]},F.CHAR=H(1),A.CHARARRAY=function(e){const t=[];for(let n=0;n>8&255,255&e]},F.USHORT=H(2),A.SHORT=function(e){return e>=32768&&(e=-(65536-e)),[e>>8&255,255&e]},F.SHORT=H(2),A.UINT24=function(e){return[e>>16&255,e>>8&255,255&e]},F.UINT24=H(3),A.ULONG=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]},F.ULONG=H(4),A.LONG=function(e){return e>=2147483648&&(e=-(4294967296-e)),[e>>24&255,e>>16&255,e>>8&255,255&e]},F.LONG=H(4),A.FIXED=A.ULONG,F.FIXED=F.ULONG,A.FWORD=A.SHORT,F.FWORD=F.SHORT,A.UFWORD=A.USHORT,F.UFWORD=F.USHORT,A.LONGDATETIME=function(e){return[0,0,0,0,e>>24&255,e>>16&255,e>>8&255,255&e]},F.LONGDATETIME=H(8),A.TAG=function(e){return N.argument(4===e.length,"Tag should be exactly 4 ASCII characters."),[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]},F.TAG=H(4),A.Card8=A.BYTE,F.Card8=F.BYTE,A.Card16=A.USHORT,F.Card16=F.USHORT,A.OffSize=A.BYTE,F.OffSize=F.BYTE,A.SID=A.USHORT,F.SID=F.USHORT,A.NUMBER=function(e){return e>=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?A.NUMBER16(e):A.NUMBER32(e)},F.NUMBER=function(e){return A.NUMBER(e).length},A.NUMBER16=function(e){return[28,e>>8&255,255&e]},F.NUMBER16=H(3),A.NUMBER32=function(e){return[29,e>>24&255,e>>16&255,e>>8&255,255&e]},F.NUMBER32=H(5),A.REAL=function(e){let t=e.toString();const n=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(n){const o=parseFloat("1e"+((n[2]?+n[2]:0)+n[1].length));t=(Math.round(e*o)/o).toString()}let o="";for(let e=0,n=t.length;e>8&255,t[t.length]=255&o}return t},F.UTF16=function(e){return 2*e.length};const z={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"};P.MACSTRING=function(e,t,n,o){const r=z[o];if(void 0===r)return;let s="";for(let o=0;o=-128&&e<=127}function X(e,t,n){let o=0;const r=e.length;for(;t>8&255,t+256&255)}return s}A.MACSTRING=function(e,t){const n=function(e){if(!W){W={};for(let e in z)W[e]=new String(e)}const t=W[e];if(void 0===t)return;if(_){const e=_.get(t);if(void 0!==e)return e}const n=z[e];if(void 0===n)return;const o={};for(let e=0;e=128&&(r=n[r],void 0===r))return;o[t]=r}return o},F.MACSTRING=function(e,t){const n=A.MACSTRING(e,t);return void 0!==n?n.length:0},A.VARDELTAS=function(e){let t=0;const n=[];for(;t=-128&&o<=127?V(e,t,n):j(e,t,n)}return n},A.INDEX=function(e){let t=1;const n=[t],o=[];for(let r=0;r>8,t[s+1]=255&a,t=t.concat(o[n])}return t},F.TABLE=function(e){let t=0;const n=e.fields.length;for(let o=0;o0)return new ce(this.data,this.offset+t).parseStruct(e)},ce.prototype.parseListOfLists=function(e){const t=this.parseOffset16List(),n=t.length,o=this.relativeOffset,r=new Array(n);for(let o=0;o=0;r-=1){const n=pe.getUShort(e,t+4+8*r),s=pe.getUShort(e,t+4+8*r+2);if(3===n&&(0===s||1===s||10===s)){o=pe.getULong(e,t+4+8*r+4);break}}if(-1===o)throw new Error("No valid cmap sub-tables found.");const r=new pe.Parser(e,t+o);if(n.format=r.parseUShort(),12===n.format)!function(e,t){let n;t.parseUShort(),e.length=t.parseULong(),e.language=t.parseULong(),e.groupCount=n=t.parseULong(),e.glyphIndexMap={};for(let o=0;o>1,t.skip("uShort",3),e.glyphIndexMap={};const a=new pe.Parser(n,o+r+14),i=new pe.Parser(n,o+r+16+2*s),l=new pe.Parser(n,o+r+16+4*s),c=new pe.Parser(n,o+r+16+6*s);let u=o+r+16+8*s;for(let t=0;t0?(s=e.parseByte(),0==(t&r)&&(s=-s),s=n+s):s=(t&r)>0?n:n+e.parseShort(),s}function Ee(e,t,n){const o=new pe.Parser(t,n);let r,s;if(e.numberOfContours=o.parseShort(),e._xMin=o.parseShort(),e._yMin=o.parseShort(),e._xMax=o.parseShort(),e._yMax=o.parseShort(),e.numberOfContours>0){const t=e.endPointIndices=[];for(let n=0;n0){const t=o.parseByte();for(let n=0;n0){const a=[];let i;if(n>0){for(let e=0;e=0,a.push(i);let e=0;for(let t=0;t0?(2&r)>0?(n.dx=o.parseShort(),n.dy=o.parseShort()):n.matchedPoints=[o.parseUShort(),o.parseUShort()]:(2&r)>0?(n.dx=o.parseChar(),n.dy=o.parseChar()):n.matchedPoints=[o.parseByte(),o.parseByte()],(8&r)>0?n.xScale=n.yScale=o.parseF2Dot14():(64&r)>0?(n.xScale=o.parseF2Dot14(),n.yScale=o.parseF2Dot14()):(128&r)>0&&(n.xScale=o.parseF2Dot14(),n.scale01=o.parseF2Dot14(),n.scale10=o.parseF2Dot14(),n.yScale=o.parseF2Dot14()),e.components.push(n),t=!!(32&r)}if(256&r){e.instructionLength=o.parseUShort(),e.instructions=[];for(let t=0;tt.points.length-1||o.matchedPoints[1]>r.points.length-1)throw Error("Matched points out of range in "+t.name);const n=t.points[o.matchedPoints[0]];let s=r.points[o.matchedPoints[1]];const a={xScale:o.xScale,scale01:o.scale01,scale10:o.scale10,yScale:o.yScale,dx:0,dy:0};s=Oe([s],a)[0],a.dx=n.x-s.x,a.dy=n.y-s.y,e=Oe(r.points,a)}t.points=t.points.concat(e)}}return we(t.points)}var Re={getPath:we,parse:function(e,t,n,o){const r=new Ie.GlyphSet(o);for(let s=0;s>4,s=15&o;if(15===r)break;if(t+=n[r],15===s)break;t+=n[s]}return parseFloat(t)}(e);if(t>=32&&t<=246)return t-139;if(t>=247&&t<=250)return n=e.parseByte(),256*(t-247)+n+108;if(t>=251&&t<=254)return n=e.parseByte(),256*-(t-251)-n-108;throw new Error("Invalid b0 "+t)}function Pe(e,t,n){t=void 0!==t?t:0;const o=new pe.Parser(e,t),r=[];let s=[];for(n=void 0!==n?n:e.length;o.relativeOffset>1,l.length=0,d=!0}return function n(p){let x,U,T,E,O,w,k,R,D,C,L,I,M=0;for(;M1&&!d&&(v=l.shift()+h,d=!0),y+=l.pop(),b(m,y);break;case 5:for(;l.length>0;)m+=l.shift(),y+=l.shift(),i.lineTo(m,y);break;case 6:for(;l.length>0&&(m+=l.shift(),i.lineTo(m,y),0!==l.length);)y+=l.shift(),i.lineTo(m,y);break;case 7:for(;l.length>0&&(y+=l.shift(),i.lineTo(m,y),0!==l.length);)m+=l.shift(),i.lineTo(m,y);break;case 8:for(;l.length>0;)o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 10:O=l.pop()+u,w=c[O],w&&n(w);break;case 11:return;case 12:switch(B=p[M],M+=1,B){case 35:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a+l.shift(),D=k+l.shift(),C=R+l.shift(),L=D+l.shift(),I=C+l.shift(),m=L+l.shift(),y=I+l.shift(),l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 34:o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a,D=k+l.shift(),C=a,L=D+l.shift(),I=y,m=L+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 36:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a,D=k+l.shift(),C=a,L=D+l.shift(),I=C+l.shift(),m=L+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;case 37:o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),k=s+l.shift(),R=a+l.shift(),D=k+l.shift(),C=R+l.shift(),L=D+l.shift(),I=C+l.shift(),Math.abs(L-m)>Math.abs(I-y)?m=L+l.shift():y=I+l.shift(),i.curveTo(o,r,s,a,k,R),i.curveTo(D,C,L,I,m,y);break;default:console.log("Glyph "+t.index+": unknown operator 1200"+B),l.length=0}break;case 14:l.length>0&&!d&&(v=l.shift()+h,d=!0),g&&(i.closePath(),g=!1);break;case 18:S();break;case 19:case 20:S(),M+=f+7>>3;break;case 21:l.length>2&&!d&&(v=l.shift()+h,d=!0),y+=l.pop(),m+=l.pop(),b(m,y);break;case 22:l.length>1&&!d&&(v=l.shift()+h,d=!0),m+=l.pop(),b(m,y);break;case 23:S();break;case 24:for(;l.length>2;)o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);m+=l.shift(),y+=l.shift(),i.lineTo(m,y);break;case 25:for(;l.length>6;)m+=l.shift(),y+=l.shift(),i.lineTo(m,y);o=m+l.shift(),r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 26:for(l.length%2&&(m+=l.shift());l.length>0;)o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s,y=a+l.shift(),i.curveTo(o,r,s,a,m,y);break;case 27:for(l.length%2&&(y+=l.shift());l.length>0;)o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a,i.curveTo(o,r,s,a,m,y);break;case 28:x=p[M],U=p[M+1],l.push((x<<24|U<<16)>>16),M+=2;break;case 29:O=l.pop()+e.gsubrsBias,w=e.gsubrs[O],w&&n(w);break;case 30:for(;l.length>0&&(o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y),0!==l.length);)o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),y=a+l.shift(),m=s+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y);break;case 31:for(;l.length>0&&(o=m+l.shift(),r=y,s=o+l.shift(),a=r+l.shift(),y=a+l.shift(),m=s+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y),0!==l.length);)o=m,r=y+l.shift(),s=o+l.shift(),a=r+l.shift(),m=s+l.shift(),y=a+(1===l.length?l.shift():0),i.curveTo(o,r,s,a,m,y);break;default:B<32?console.log("Glyph "+t.index+": unknown operator "+B):B<247?l.push(B-139):B<251?(x=p[M],M+=1,l.push(256*(B-247)+x+108)):B<255?(x=p[M],M+=1,l.push(256*-(B-251)-x-108)):(x=p[M],U=p[M+1],T=p[M+2],E=p[M+3],M+=4,l.push((x<<24|U<<16|T<<8|E)/65536))}}}(n),t.advanceWidth=v,i}function Ve(e,t){let n,o=de.indexOf(e);return o>=0&&(n=o),o=t.indexOf(e),o>=0?n=o+de.length:(n=de.length+t.length,t.push(e)),n}function je(e,t,n){const o={};for(let r=0;r=o)throw new Error("CFF table CID Font FDSelect has bad FD index value "+s+" (FD count "+o+")");r.push(s)}else{if(3!==i)throw new Error("CFF Table CID Font FDSelect table has unsupported format "+i);{const e=a.parseCard16();let t,i=a.parseCard16();if(0!==i)throw new Error("CFF Table CID Font FDSelect format 3 range has bad initial GID "+i);for(let l=0;l=o)throw new Error("CFF table CID Font FDSelect has bad FD index value "+s+" (FD count "+o+")");if(t>n)throw new Error("CFF Table CID Font FDSelect format 3 range has bad GID "+t);for(;i=1&&(n.ulCodePageRange1=o.parseULong(),n.ulCodePageRange2=o.parseULong()),n.version>=2&&(n.sxHeight=o.parseShort(),n.sCapHeight=o.parseShort(),n.usDefaultChar=o.parseUShort(),n.usBreakChar=o.parseUShort(),n.usMaxContent=o.parseUShort()),n},make:function(e){return new oe.Table("OS/2",[{name:"version",type:"USHORT",value:3},{name:"xAvgCharWidth",type:"SHORT",value:0},{name:"usWeightClass",type:"USHORT",value:0},{name:"usWidthClass",type:"USHORT",value:0},{name:"fsType",type:"USHORT",value:0},{name:"ySubscriptXSize",type:"SHORT",value:650},{name:"ySubscriptYSize",type:"SHORT",value:699},{name:"ySubscriptXOffset",type:"SHORT",value:0},{name:"ySubscriptYOffset",type:"SHORT",value:140},{name:"ySuperscriptXSize",type:"SHORT",value:650},{name:"ySuperscriptYSize",type:"SHORT",value:699},{name:"ySuperscriptXOffset",type:"SHORT",value:0},{name:"ySuperscriptYOffset",type:"SHORT",value:479},{name:"yStrikeoutSize",type:"SHORT",value:49},{name:"yStrikeoutPosition",type:"SHORT",value:258},{name:"sFamilyClass",type:"SHORT",value:0},{name:"bFamilyType",type:"BYTE",value:0},{name:"bSerifStyle",type:"BYTE",value:0},{name:"bWeight",type:"BYTE",value:0},{name:"bProportion",type:"BYTE",value:0},{name:"bContrast",type:"BYTE",value:0},{name:"bStrokeVariation",type:"BYTE",value:0},{name:"bArmStyle",type:"BYTE",value:0},{name:"bLetterform",type:"BYTE",value:0},{name:"bMidline",type:"BYTE",value:0},{name:"bXHeight",type:"BYTE",value:0},{name:"ulUnicodeRange1",type:"ULONG",value:0},{name:"ulUnicodeRange2",type:"ULONG",value:0},{name:"ulUnicodeRange3",type:"ULONG",value:0},{name:"ulUnicodeRange4",type:"ULONG",value:0},{name:"achVendID",type:"CHARARRAY",value:"XXXX"},{name:"fsSelection",type:"USHORT",value:0},{name:"usFirstCharIndex",type:"USHORT",value:0},{name:"usLastCharIndex",type:"USHORT",value:0},{name:"sTypoAscender",type:"SHORT",value:0},{name:"sTypoDescender",type:"SHORT",value:0},{name:"sTypoLineGap",type:"SHORT",value:0},{name:"usWinAscent",type:"USHORT",value:0},{name:"usWinDescent",type:"USHORT",value:0},{name:"ulCodePageRange1",type:"ULONG",value:0},{name:"ulCodePageRange2",type:"ULONG",value:0},{name:"sxHeight",type:"SHORT",value:0},{name:"sCapHeight",type:"SHORT",value:0},{name:"usDefaultChar",type:"USHORT",value:0},{name:"usBreakChar",type:"USHORT",value:0},{name:"usMaxContext",type:"USHORT",value:0}],e)},unicodeRanges:gt,getUnicodeRange:function(e){for(let t=0;t=n.begin&&e=ye.length){const e=o.parseChar();n.names.push(o.parseString(e))}break;case 2.5:n.numberOfGlyphs=o.parseUShort(),n.offset=new Array(n.numberOfGlyphs);for(let e=0;et.value.tag?1:-1})),t.fields=t.fields.concat(o),t.fields=t.fields.concat(r),t}function kt(e,t,n){for(let n=0;n0){return e.glyphs.get(o).getMetrics()}}return n}function Rt(e){let t=0;for(let n=0;nm||void 0===l)&&m>0&&(l=m),c 123 are reserved for internal usage");f|=1<0?tt.make(w):void 0,D=yt.make(),C=$e.make(e.glyphs,{version:e.getEnglishName("version"),fullName:T,familyName:x,weightName:U,postScriptName:E,unitsPerEm:e.unitsPerEm,fontBBox:[0,d.yMin,d.ascender,d.advanceWidthMax]}),L=e.metas&&Object.keys(e.metas).length>0?Ut.make(e.metas):void 0,I=[g,m,y,v,k,S,D,C,b];R&&I.push(R),e.tables.gsub&&I.push(xt.make(e.tables.gsub)),L&&I.push(L);const M=wt(I),B=Et(M.encode()),G=M.fields;let N=!1;for(let e=0;e>>1,s=e[r].tag;if(s===t)return r;s>>1,s=e[r];if(s===t)return r;s=0)return o[r].script;if(t){const t={tag:e,script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}};return o.splice(-1-r,0,t),t.script}}},getLangSysTable:function(e,t,n){const o=this.getScriptTable(e,n);if(o){if(!t||"dflt"===t||"DFLT"===t)return o.defaultLangSys;const e=Ct(o.langSysRecords,t);if(e>=0)return o.langSysRecords[e].langSys;if(n){const n={tag:t,langSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]}};return o.langSysRecords.splice(-1-e,0,n),n.langSys}}},getFeatureTable:function(e,t,n,o){const r=this.getLangSysTable(e,t,o);if(r){let e;const t=r.featureIndexes,s=this.font.tables[this.tableName].features;for(let o=0;o=s[o-1].tag,"Features must be added in alphabetical order."),e={tag:n,feature:{params:0,lookupListIndexes:[]}},s.push(e),t.push(o),e.feature}}},getLookupTables:function(e,t,n,o,r){const s=this.getFeatureTable(e,t,n,r),a=[];if(s){let e;const t=s.lookupListIndexes,n=this.font.tables[this.tableName].lookups;for(let r=0;r=0){const e=s.ligatureSets[c];for(let t=0;t0&&e<0?n:o<0&&e>0?-n:e*o},Zt={x:1,y:0,axis:"x",distance:function(e,t,n,o){return(n?e.xo:e.x)-(o?t.xo:t.x)},interpolate:function(e,t,n,o){let r,s,a,i,l,c,u;if(!o||o===this)return r=e.xo-t.xo,s=e.xo-n.xo,l=t.x-t.xo,c=n.x-n.xo,a=Math.abs(r),i=Math.abs(s),u=a+i,0===u?void(e.x=e.xo+(l+c)/2):void(e.x=e.xo+(l*i+c*a)/u);r=o.distance(e,t,!0,!0),s=o.distance(e,n,!0,!0),l=o.distance(t,t,!1,!0),c=o.distance(n,n,!1,!0),a=Math.abs(r),i=Math.abs(s),u=a+i,0!==u?Zt.setRelative(e,e,(l*i+c*a)/u,o,!0):Zt.setRelative(e,e,(l+c)/2,o,!0)},normalSlope:Number.NEGATIVE_INFINITY,setRelative:function(e,t,n,o,r){if(!o||o===this)return void(e.x=(r?t.xo:t.x)+n);const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y;e.x=i+(e.y-l)/o.normalSlope},slope:0,touch:function(e){e.xTouched=!0},touched:function(e){return e.xTouched},untouch:function(e){e.xTouched=!1}},Qt={x:0,y:1,axis:"y",distance:function(e,t,n,o){return(n?e.yo:e.y)-(o?t.yo:t.y)},interpolate:function(e,t,n,o){let r,s,a,i,l,c,u;if(!o||o===this)return r=e.yo-t.yo,s=e.yo-n.yo,l=t.y-t.yo,c=n.y-n.yo,a=Math.abs(r),i=Math.abs(s),u=a+i,0===u?void(e.y=e.yo+(l+c)/2):void(e.y=e.yo+(l*i+c*a)/u);r=o.distance(e,t,!0,!0),s=o.distance(e,n,!0,!0),l=o.distance(t,t,!1,!0),c=o.distance(n,n,!1,!0),a=Math.abs(r),i=Math.abs(s),u=a+i,0!==u?Qt.setRelative(e,e,(l*i+c*a)/u,o,!0):Qt.setRelative(e,e,(l+c)/2,o,!0)},normalSlope:0,setRelative:function(e,t,n,o,r){if(!o||o===this)return void(e.y=(r?t.yo:t.y)+n);const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y;e.y=l+o.normalSlope*(e.x-i)},slope:Number.POSITIVE_INFINITY,touch:function(e){e.yTouched=!0},touched:function(e){return e.yTouched},untouch:function(e){e.yTouched=!1}};function $t(e,t){this.x=e,this.y=t,this.axis=void 0,this.slope=t/e,this.normalSlope=-e/t,Object.freeze(this)}function Kt(e,t){const n=Math.sqrt(e*e+t*t);return t/=n,1===(e/=n)&&0===t?Zt:0===e&&1===t?Qt:new $t(e,t)}function Jt(e,t,n,o){this.x=this.xo=Math.round(64*e)/64,this.y=this.yo=Math.round(64*t)/64,this.lastPointOfContour=n,this.onCurve=o,this.prevPointOnContour=void 0,this.nextPointOnContour=void 0,this.xTouched=!1,this.yTouched=!1,Object.preventExtensions(this)}Object.freeze(Zt),Object.freeze(Qt),$t.prototype.distance=function(e,t,n,o){return this.x*Zt.distance(e,t,n,o)+this.y*Qt.distance(e,t,n,o)},$t.prototype.interpolate=function(e,t,n,o){let r,s,a,i,l,c,u;a=o.distance(e,t,!0,!0),i=o.distance(e,n,!0,!0),r=o.distance(t,t,!1,!0),s=o.distance(n,n,!1,!0),l=Math.abs(a),c=Math.abs(i),u=l+c,0!==u?this.setRelative(e,e,(r*c+s*l)/u,o,!0):this.setRelative(e,e,(r+s)/2,o,!0)},$t.prototype.setRelative=function(e,t,n,o,r){o=o||this;const s=r?t.xo:t.x,a=r?t.yo:t.y,i=s+n*o.x,l=a+n*o.y,c=o.normalSlope,u=this.slope,p=e.x,h=e.y;e.x=(u*p-c*i+l-h)/(u-c),e.y=u*(e.x-p)+h},$t.prototype.touch=function(e){e.xTouched=!0,e.yTouched=!0},Jt.prototype.nextTouched=function(e){let t=this.nextPointOnContour;for(;!e.touched(t)&&t!==this;)t=t.nextPointOnContour;return t},Jt.prototype.prevTouched=function(e){let t=this.prevPointOnContour;for(;!e.touched(t)&&t!==this;)t=t.prevPointOnContour;return t};const en=Object.freeze(new Jt(0,0)),tn={cvCutIn:17/16,deltaBase:9,deltaShift:.125,loop:1,minDis:1,autoFlip:!0};function nn(e,t){switch(this.env=e,this.stack=[],this.prog=t,e){case"glyf":this.zp0=this.zp1=this.zp2=1,this.rp0=this.rp1=this.rp2=0;case"prep":this.fv=this.pv=this.dpv=Zt,this.round=Wt}}function on(e){const t=e.tZone=new Array(e.gZone.length);for(let e=0;e=176&&o<=183)r+=o-176+1;else if(o>=184&&o<=191)r+=2*(o-184+1);else if(t&&1===s&&27===o)break}while(s>0);e.ip=r}function sn(e,t){exports.DEBUG&&console.log(t.step,"SVTCA["+e.axis+"]"),t.fv=t.pv=t.dpv=e}function an(e,t){exports.DEBUG&&console.log(t.step,"SPVTCA["+e.axis+"]"),t.pv=t.dpv=e}function ln(e,t){exports.DEBUG&&console.log(t.step,"SFVTCA["+e.axis+"]"),t.fv=e}function cn(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SPVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.pv=t.dpv=Kt(i,l)}function un(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SFVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.fv=Kt(i,l)}function pn(e){exports.DEBUG&&console.log(e.step,"POP[]"),e.stack.pop()}function hn(e,t){const n=t.stack.pop(),o=t.z0[n],r=t.fv,s=t.pv;exports.DEBUG&&console.log(t.step,"MDAP["+e+"]",n);let a=s.distance(o,en);e&&(a=t.round(a)),r.setRelative(o,en,a,s),r.touch(o),t.rp0=t.rp1=n}function fn(e,t){const n=t.z2,o=n.length-2;let r,s,a;exports.DEBUG&&console.log(t.step,"IUP["+e.axis+"]");for(let t=0;t1?"loop "+(t.loop-i)+": ":"")+"SHP["+(e?"rp1":"rp2")+"]",o)}t.loop=1}function gn(e,t){const n=t.stack,o=e?t.rp1:t.rp2,r=(e?t.z0:t.z1)[o],s=t.fv,a=t.pv,i=n.pop(),l=t.z2[t.contours[i]];let c=l;exports.DEBUG&&console.log(t.step,"SHC["+e+"]",i);const u=a.distance(r,r,!1,!0);do{c!==r&&s.setRelative(c,c,u,a),c=c.nextPointOnContour}while(c!==l)}function mn(e,t){const n=t.stack,o=e?t.rp1:t.rp2,r=(e?t.z0:t.z1)[o],s=t.fv,a=t.pv,i=n.pop();let l,c;switch(exports.DEBUG&&console.log(t.step,"SHZ["+e+"]",i),i){case 0:l=t.tZone;break;case 1:l=t.gZone;break;default:throw new Error("Invalid zone")}const u=a.distance(r,r,!1,!0),p=l.length-2;for(let e=0;e",i),t.stack.push(Math.round(64*i))}function xn(e,t){const n=t.stack,o=n.pop(),r=t.fv,s=t.pv,a=t.ppem,i=t.deltaBase+16*(e-1),l=t.deltaShift,c=t.z0;exports.DEBUG&&console.log(t.step,"DELTAP["+e+"]",o,n);for(let e=0;e>4)!==a)continue;let u=(15&o)-8;u>=0&&u++,exports.DEBUG&&console.log(t.step,"DELTAPFIX",e,"by",u*l);const p=c[e];r.setRelative(p,p,u*l,s)}}function Un(e,t){const n=t.stack,o=n.pop();exports.DEBUG&&console.log(t.step,"ROUND[]"),n.push(64*t.round(o/64))}function Tn(e,t){const n=t.stack,o=n.pop(),r=t.ppem,s=t.deltaBase+16*(e-1),a=t.deltaShift;exports.DEBUG&&console.log(t.step,"DELTAC["+e+"]",o,n);for(let e=0;e>4)!==r)continue;let i=(15&o)-8;i>=0&&i++;const l=i*a;exports.DEBUG&&console.log(t.step,"DELTACFIX",e,"by",l),t.cvt[e]+=l}}function En(e,t){const n=t.stack,o=n.pop(),r=n.pop(),s=t.z2[o],a=t.z1[r];let i,l;exports.DEBUG&&console.log("SDPVTL["+e+"]",o,r),e?(i=s.y-a.y,l=a.x-s.x):(i=a.x-s.x,l=a.y-s.y),t.dpv=Kt(i,l)}function On(e,t){const n=t.stack,o=t.prog;let r=t.ip;exports.DEBUG&&console.log(t.step,"PUSHB["+e+"]");for(let t=0;t=0?1:-1,m=Math.abs(m),e&&(v=s.cvt[i],o&&Math.abs(m-v)":"_")+(o?"R":"_")+(0===r?"Gr":1===r?"Bl":2===r?"Wh":"")+"]",e?i+"("+s.cvt[i]+","+v+")":"",l,"(d =",g,"->",y*m,")"),s.rp1=s.rp0,s.rp2=l,t&&(s.rp0=l)}function Rn(e){(e=e||{}).empty||(Nt(e.familyName,"When creating a new Font object, familyName is required."),Nt(e.styleName,"When creating a new Font object, styleName is required."),Nt(e.unitsPerEm,"When creating a new Font object, unitsPerEm is required."),Nt(e.ascender,"When creating a new Font object, ascender is required."),Nt(e.descender,"When creating a new Font object, descender is required."),Nt(e.descender<0,"Descender should be negative (e.g. -512)."),this.names={fontFamily:{en:e.familyName||" "},fontSubfamily:{en:e.styleName||" "},fullName:{en:e.fullName||e.familyName+" "+e.styleName},postScriptName:{en:e.postScriptName||e.familyName+e.styleName},designer:{en:e.designer||" "},designerURL:{en:e.designerURL||" "},manufacturer:{en:e.manufacturer||" "},manufacturerURL:{en:e.manufacturerURL||" "},license:{en:e.license||" "},licenseURL:{en:e.licenseURL||" "},version:{en:e.version||"Version 0.1"},description:{en:e.description||" "},copyright:{en:e.copyright||" "},trademark:{en:e.trademark||" "}},this.unitsPerEm=e.unitsPerEm||1e3,this.ascender=e.ascender,this.descender=e.descender,this.createdTimestamp=e.createdTimestamp,this.tables={os2:{usWeightClass:e.weightClass||this.usWeightClasses.MEDIUM,usWidthClass:e.widthClass||this.usWidthClasses.MEDIUM,fsSelection:e.fsSelection||this.fsSelectionValues.REGULAR}}),this.supported=!0,this.glyphs=new Ie.GlyphSet(this,e.glyphs||[]),this.encoding=new ve(this),this.substitution=new It(this),this.tables=this.tables||{},Object.defineProperty(this,"hinting",{get:function(){return this._hinting?this._hinting:"truetype"===this.outlinesFormat?this._hinting=new zt(this):void 0}})}function Dn(e,t){const n=JSON.stringify(e);let o=256;for(let e in t){let r=parseInt(e);if(r&&!(r<256)){if(JSON.stringify(t[e])===n)return r;o<=r&&(o=r+1)}}return t[o]=e,o}function Cn(e,t,n){const o=Dn(t.name,n);return[{name:"tag_"+e,type:"TAG",value:t.tag},{name:"minValue_"+e,type:"FIXED",value:t.minValue<<16},{name:"defaultValue_"+e,type:"FIXED",value:t.defaultValue<<16},{name:"maxValue_"+e,type:"FIXED",value:t.maxValue<<16},{name:"flags_"+e,type:"USHORT",value:0},{name:"nameID_"+e,type:"USHORT",value:o}]}function Ln(e,t,n){const o={},r=new pe.Parser(e,t);return o.tag=r.parseTag(),o.minValue=r.parseFixed(),o.defaultValue=r.parseFixed(),o.maxValue=r.parseFixed(),r.skip("uShort",1),o.name=n[r.parseUShort()]||{},o}function In(e,t,n,o){const r=[{name:"nameID_"+e,type:"USHORT",value:Dn(t.name,o)},{name:"flags_"+e,type:"USHORT",value:0}];for(let o=0;o2)return;const n=this.font;let o=this._prepState;if(!o||o.ppem!==t){let e=this._fpgmState;if(!e){nn.prototype=tn,e=this._fpgmState=new nn("fpgm",n.tables.fpgm),e.funcs=[],e.font=n,exports.DEBUG&&(console.log("---EXEC FPGM---"),e.step=-1);try{At(e)}catch(e){return console.log("Hinting error in FPGM:"+e),void(this._errorState=3)}}nn.prototype=e,o=this._prepState=new nn("prep",n.tables.prep),o.ppem=t;const r=n.tables.cvt;if(r){const e=o.cvt=new Array(r.length),s=t/n.unitsPerEm;for(let t=0;t1))try{return Ft(e,o)}catch(e){return this._errorState<1&&(console.log("Hinting error:"+e),console.log("Note: further hinting errors are silenced")),void(this._errorState=1)}},Ft=function(e,t){const n=t.ppem/t.font.unitsPerEm,o=n;let r,s,a,i=e.components;if(nn.prototype=t,i){const l=t.font;s=[],r=[];for(let e=0;e1?"loop "+(e.loop-n)+": ":"")+"SHPIX[]",a,r),o.setRelative(i,i,r),o.touch(i)}e.loop=1},function(e){const t=e.stack,n=e.rp1,o=e.rp2;let r=e.loop;const s=e.z0[n],a=e.z1[o],i=e.fv,l=e.dpv,c=e.z2;for(;r--;){const u=t.pop(),p=c[u];exports.DEBUG&&console.log(e.step,(e.loop>1?"loop "+(e.loop-r)+": ":"")+"IP[]",u,n,"<->",o),i.interpolate(p,s,a,l),i.touch(p)}e.loop=1},yn.bind(void 0,0),yn.bind(void 0,1),function(e){const t=e.stack,n=e.rp0,o=e.z0[n];let r=e.loop;const s=e.fv,a=e.pv,i=e.z1;for(;r--;){const n=t.pop(),l=i[n];exports.DEBUG&&console.log(e.step,(e.loop>1?"loop "+(e.loop-r)+": ":"")+"ALIGNRP[]",n),s.setRelative(l,o,0,a),s.touch(l)}e.loop=1},function(e){exports.DEBUG&&console.log(e.step,"RTDG[]"),e.round=qt},vn.bind(void 0,0),vn.bind(void 0,1),function(e){const t=e.prog;let n=e.ip;const o=e.stack,r=t[++n];exports.DEBUG&&console.log(e.step,"NPUSHB[]",r);for(let e=0;en?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"GTEQ[]",n,o),t.push(o>=n?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"EQ[]",n,o),t.push(n===o?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"NEQ[]",n,o),t.push(n!==o?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"ODD[]",n),t.push(Math.trunc(n)%2?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"EVEN[]",n),t.push(Math.trunc(n)%2?0:1)},function(e){let t=e.stack.pop();exports.DEBUG&&console.log(e.step,"IF[]",t),t||(rn(e,!0),exports.DEBUG&&console.log(e.step,"EIF[]"))},function(e){exports.DEBUG&&console.log(e.step,"EIF[]")},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"AND[]",n,o),t.push(n&&o?1:0)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"OR[]",n,o),t.push(n||o?1:0)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"NOT[]",n),t.push(n?0:1)},xn.bind(void 0,1),function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SDB[]",t),e.deltaBase=t},function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SDS[]",t),e.deltaShift=Math.pow(.5,t)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"ADD[]",n,o),t.push(o+n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"SUB[]",n,o),t.push(o-n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"DIV[]",n,o),t.push(64*o/n)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MUL[]",n,o),t.push(o*n/64)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"ABS[]",n),t.push(Math.abs(n))},function(e){const t=e.stack;let n=t.pop();exports.DEBUG&&console.log(e.step,"NEG[]",n),t.push(-n)},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"FLOOR[]",n),t.push(64*Math.floor(n/64))},function(e){const t=e.stack,n=t.pop();exports.DEBUG&&console.log(e.step,"CEILING[]",n),t.push(64*Math.ceil(n/64))},Un.bind(void 0,0),Un.bind(void 0,1),Un.bind(void 0,2),Un.bind(void 0,3),void 0,void 0,void 0,void 0,function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"WCVTF[]",n,o),e.cvt[o]=n*e.ppem/e.font.unitsPerEm},xn.bind(void 0,2),xn.bind(void 0,3),Tn.bind(void 0,1),Tn.bind(void 0,2),Tn.bind(void 0,3),function(e){let t,n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"SROUND[]",n),e.round=Yt,192&n){case 0:t=.5;break;case 64:t=1;break;case 128:t=2;break;default:throw new Error("invalid SROUND value")}switch(e.srPeriod=t,48&n){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*t;break;case 32:e.srPhase=.5*t;break;case 48:e.srPhase=.75*t;break;default:throw new Error("invalid SROUND value")}n&=15,e.srThreshold=0===n?0:(n/8-.5)*t},function(e){let t,n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"S45ROUND[]",n),e.round=Yt,192&n){case 0:t=Math.sqrt(2)/2;break;case 64:t=Math.sqrt(2);break;case 128:t=2*Math.sqrt(2);break;default:throw new Error("invalid S45ROUND value")}switch(e.srPeriod=t,48&n){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*t;break;case 32:e.srPhase=.5*t;break;case 48:e.srPhase=.75*t;break;default:throw new Error("invalid S45ROUND value")}n&=15,e.srThreshold=0===n?0:(n/8-.5)*t},void 0,void 0,function(e){exports.DEBUG&&console.log(e.step,"ROFF[]"),e.round=_t},void 0,function(e){exports.DEBUG&&console.log(e.step,"RUTG[]"),e.round=Vt},function(e){exports.DEBUG&&console.log(e.step,"RDTG[]"),e.round=jt},pn,pn,void 0,void 0,void 0,void 0,void 0,function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SCANCTRL[]",t)},En.bind(void 0,0),En.bind(void 0,1),function(e){const t=e.stack,n=t.pop();let o=0;exports.DEBUG&&console.log(e.step,"GETINFO[]",n),1&n&&(o=35),32&n&&(o|=4096),t.push(o)},void 0,function(e){const t=e.stack,n=t.pop(),o=t.pop(),r=t.pop();exports.DEBUG&&console.log(e.step,"ROLL[]"),t.push(o),t.push(n),t.push(r)},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MAX[]",n,o),t.push(Math.max(o,n))},function(e){const t=e.stack,n=t.pop(),o=t.pop();exports.DEBUG&&console.log(e.step,"MIN[]",n,o),t.push(Math.min(o,n))},function(e){const t=e.stack.pop();exports.DEBUG&&console.log(e.step,"SCANTYPE[]",t)},function(e){const t=e.stack.pop();let n=e.stack.pop();switch(exports.DEBUG&&console.log(e.step,"INSTCTRL[]",t,n),t){case 1:return void(e.inhibitGridFit=!!n);case 2:return void(e.ignoreCvt=!!n);default:throw new Error("invalid INSTCTRL[] selector")}},void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,On.bind(void 0,1),On.bind(void 0,2),On.bind(void 0,3),On.bind(void 0,4),On.bind(void 0,5),On.bind(void 0,6),On.bind(void 0,7),On.bind(void 0,8),wn.bind(void 0,1),wn.bind(void 0,2),wn.bind(void 0,3),wn.bind(void 0,4),wn.bind(void 0,5),wn.bind(void 0,6),wn.bind(void 0,7),wn.bind(void 0,8),kn.bind(void 0,0,0,0,0,0),kn.bind(void 0,0,0,0,0,1),kn.bind(void 0,0,0,0,0,2),kn.bind(void 0,0,0,0,0,3),kn.bind(void 0,0,0,0,1,0),kn.bind(void 0,0,0,0,1,1),kn.bind(void 0,0,0,0,1,2),kn.bind(void 0,0,0,0,1,3),kn.bind(void 0,0,0,1,0,0),kn.bind(void 0,0,0,1,0,1),kn.bind(void 0,0,0,1,0,2),kn.bind(void 0,0,0,1,0,3),kn.bind(void 0,0,0,1,1,0),kn.bind(void 0,0,0,1,1,1),kn.bind(void 0,0,0,1,1,2),kn.bind(void 0,0,0,1,1,3),kn.bind(void 0,0,1,0,0,0),kn.bind(void 0,0,1,0,0,1),kn.bind(void 0,0,1,0,0,2),kn.bind(void 0,0,1,0,0,3),kn.bind(void 0,0,1,0,1,0),kn.bind(void 0,0,1,0,1,1),kn.bind(void 0,0,1,0,1,2),kn.bind(void 0,0,1,0,1,3),kn.bind(void 0,0,1,1,0,0),kn.bind(void 0,0,1,1,0,1),kn.bind(void 0,0,1,1,0,2),kn.bind(void 0,0,1,1,0,3),kn.bind(void 0,0,1,1,1,0),kn.bind(void 0,0,1,1,1,1),kn.bind(void 0,0,1,1,1,2),kn.bind(void 0,0,1,1,1,3),kn.bind(void 0,1,0,0,0,0),kn.bind(void 0,1,0,0,0,1),kn.bind(void 0,1,0,0,0,2),kn.bind(void 0,1,0,0,0,3),kn.bind(void 0,1,0,0,1,0),kn.bind(void 0,1,0,0,1,1),kn.bind(void 0,1,0,0,1,2),kn.bind(void 0,1,0,0,1,3),kn.bind(void 0,1,0,1,0,0),kn.bind(void 0,1,0,1,0,1),kn.bind(void 0,1,0,1,0,2),kn.bind(void 0,1,0,1,0,3),kn.bind(void 0,1,0,1,1,0),kn.bind(void 0,1,0,1,1,1),kn.bind(void 0,1,0,1,1,2),kn.bind(void 0,1,0,1,1,3),kn.bind(void 0,1,1,0,0,0),kn.bind(void 0,1,1,0,0,1),kn.bind(void 0,1,1,0,0,2),kn.bind(void 0,1,1,0,0,3),kn.bind(void 0,1,1,0,1,0),kn.bind(void 0,1,1,0,1,1),kn.bind(void 0,1,1,0,1,2),kn.bind(void 0,1,1,0,1,3),kn.bind(void 0,1,1,1,0,0),kn.bind(void 0,1,1,1,0,1),kn.bind(void 0,1,1,1,0,2),kn.bind(void 0,1,1,1,0,3),kn.bind(void 0,1,1,1,1,0),kn.bind(void 0,1,1,1,1,1),kn.bind(void 0,1,1,1,1,2),kn.bind(void 0,1,1,1,1,3)],Rn.prototype.hasChar=function(e){return null!==this.encoding.charToGlyphIndex(e)},Rn.prototype.charToGlyphIndex=function(e){return this.encoding.charToGlyphIndex(e)},Rn.prototype.charToGlyph=function(e){const t=this.charToGlyphIndex(e);let n=this.glyphs.get(t);return n||(n=this.glyphs.get(0)),n},Rn.prototype.stringToGlyphs=function(e,t){t=t||this.defaultRenderOptions;const n=[];for(let t=0;t>1;e1&&console.warn("Only the first kern subtable is supported."),e.skip("uLong");const n=255&e.parseUShort();if(e.skip("uShort"),0===n){const n=e.parseUShort();e.skip("uShort",3);for(let o=0;o{const t=jn.loadSync(e);Qn.font=t,Qn.ascender=t.ascender,Qn.descender=t.descender}};const Kn=$n.options,Jn=function(e,t){return Math.round(e+Math.random()*(t-e))};const eo=function(e,t){return{text:(e+t).toString(),equation:e+"+"+t}},to=function(e,t){return{text:(e-t).toString(),equation:e+"-"+t}};function no(e,t,n){return 6*(n=(n+1)%1)<1?e+(t-e)*n*6:2*n<1?t:3*n<2?e+(t-e)*(2/3-n)*6:e}var oo={int:Jn,greyColor:function(e,t){const n=Jn(e=e||1,t=t||9).toString(16);return`#${n}${n}${n}`},captchaText:function(e){"number"==typeof e&&(e={size:e});const t=(e=e||{}).size||4,n=e.ignoreChars||"";let o=-1,r="",s=e.charPreset||Kn.charPreset;n&&(s=function(e,t){return e.split("").filter(e=>-1===t.indexOf(e))}(s,n));const a=s.length-1;for(;++o>16,o=t>>8&255,r=255&t,s=Math.max(n,o,r),a=Math.min(n,o,r);return(s+a)/510}(e):1;let r,s;o>=.5?(r=Math.round(100*o)-45,s=Math.round(100*o)-25):(r=Math.round(100*o)+25,s=Math.round(100*o)+45);const a=Jn(r,s)/100,i=a<.5?a*(a+n):a+n-a*n,l=2*a-i,c=Math.floor(255*no(l,i,t+1/3)),u=Math.floor(255*no(l,i,t));return"#"+(Math.floor(255*no(l,i,t-1/3))|u<<8|c<<16|1<<24).toString(16).slice(1)}};const ro=$n.options,so=function(e,t){e=e||oo.captchaText();const n=(t=Object.assign({},ro,t)).width,o=t.height,r=t.background||t.backgroundColor;r&&(t.color=!0);const s=r?``:"",a=[].concat(function(e,t,n){const o=n.color,r=[],s=n.inverse?7:1,a=n.inverse?15:9;let i=-1;for(;++i`)}return r}(n,o,t)).concat(function(e,t,n,o,r){const s=e.length,a=(t-2)/(s+1),i=o.inverse?10:0,l=o.inverse?14:4;let u=-1;const p=[],h=r||o.color?oo.color(o.background):oo.greyColor(i,l);for(;++u`)}return p}(e,n,o,t)).sort(()=>Math.random()-.5).join("");return`${``}${s}${a}`};var ao=so,io=oo.captchaText,lo=function(e){const t=e.text||oo.captchaText(e);return{text:t,data:so(t,e)}},co=function(e){const t=oo.mathExpr(e.mathMin,e.mathMax,e.mathOperator);return{text:t.text,data:so(t.equation,e)}},uo=ro,po=$n.loadFont;ao.randomText=io,ao.create=lo,ao.createMathExpr=co,ao.options=uo,ao.loadFont=po;var ho=ao;const fo=Object.prototype.toString;function go(e){return"[object Object]"===fo.call(e)}function mo(){"development"===process.env.NODE_ENV&&console.log(...arguments)}const yo=async function(){};function vo(e){return yo.constructor===e.constructor?async function(){const t=await e.apply(this,arguments);return go(t)&&(t.msg&&(t.message=t.msg,t.errMsg=t.msg),0===t.code?t.errCode=t.code:t.errCode=s[t.code]||t.code),t}:function(){const t=e.apply(this,arguments);return go(t)&&(t.msg&&(t.message=t.msg,t.errMsg=t.msg),0===t.code?t.errCode=t.code:t.errCode=s[t.code]||t.code),t}}const bo=uniCloud.database(),So=bo.collection("opendb-verify-codes");class xo{async setVerifyCode({clientIP:e,deviceId:t,code:n,expiresDate:o,scene:r}){if(!t)return{code:10101,msg:"deviceId不可为空"};if(!n)return{code:10102,msg:"验证码不可为空"};o||(o=180);const s=Date.now(),a={device_uuid:t,scene:r,code:n.toLocaleLowerCase(),state:0,ip:e,created_date:s,expired_date:s+1e3*o};return mo("addRes",await So.add(a)),{code:0,deviceId:t}}async verifyCode({deviceId:e,code:t,scene:n}){if(!e)return{code:10101,msg:"deviceId不可为空"};if(!t)return{code:10102,msg:"验证码不可为空"};const o=Date.now(),r={device_uuid:e,scene:n,code:t.toLocaleLowerCase(),state:0},s=await So.where(r).orderBy("created_date","desc").limit(1).get();if(mo("verifyRecord:",s),s&&s.data&&s.data.length>0){const e=s.data[0];if(e.expired_date{e.scene&&delete e.scene,this.pluginConfig.scene[n]=Object.assign({},t,e[n])})}}}{constructor(){super(),this.DEVICEID2opts={}}mergeConfig(e){const t=go(this.pluginConfig.scene)?this.pluginConfig.scene[e.scene]:e.scene;return Object.assign({},go(t)?t:this.pluginConfig,e)}async create(e={}){if(!e.scene)throw new Error("scene验证码场景不可为空");e=this.mergeConfig(e);let{scene:t,expiresDate:n,deviceId:o,clientIP:r,...s}=e;if(o=o||__ctx__.DEVICEID,r=r||__ctx__.CLIENTIP,!o)throw new Error("deviceId不可为空");const a=new xo;try{const{text:i,base64:l}=function(e={}){const{uniPlatform:t=""}=e;let n;n=e.mathExpr?ho.createMathExpr(e):ho.create(e);let o="data:image/svg+xml;utf8,"+n.data.replace(/#/g,"%23");return(!t||["mp-toutiao","h5","web","app","app-plus"].indexOf(t)>-1)&&(o=o.replace(/"/g,"'").replace(//g,"%3E")),{text:n.text,base64:o}}(s),c=await a.setVerifyCode({clientIP:r,deviceId:o,code:i,expiresDate:n,scene:t});return c.code>0?{...c,code:10001}:(this.DEVICEID2opts[o]=e,{code:0,msg:"验证码获取成功",captchaBase64:l})}catch(e){return{code:10001,msg:"验证码生成失败:"+e.message}}}async verify({deviceId:e,captcha:t,scene:n}){if(!(e=e||__ctx__.DEVICEID))throw new Error("deviceId不可为空");if(!n)throw new Error("scene验证码场景不可为空");const o=new xo;try{const r=await o.verifyCode({deviceId:e,code:t,scene:n});return r.code>0?r:{code:0,msg:"验证码通过"}}catch(e){return{code:10002,msg:"验证码校验失败:"+e.message}}}async refresh(e={}){let{scene:t,expiresDate:n,deviceId:o,...r}=e;if(o=o||__ctx__.DEVICEID,!o)throw new Error("deviceId不可为空");if(!t)throw new Error("scene验证码场景不可为空");const s=await So.where(bo.command.or([{device_uuid:o,scene:t},{deviceId:o,scene:t}])).orderBy("created_date","desc").limit(1).get();if(s&&s.data&&s.data.length>0){const e=s.data[0];await So.doc(e._id).update({state:2}),Object.keys(r).length>0&&(this.DEVICEID2opts[o]=Object.assign({},this.DEVICEID2opts[o],r));let a={};try{a=await this.create(Object.assign({},this.DEVICEID2opts[o],{deviceId:o,scene:t,expiresDate:n}))}catch(e){return{code:50403,msg:e.message}}return a.code>0?{...a,code:50403}:{code:0,msg:"验证码刷新成功",captchaBase64:a.captchaBase64}}return{code:10003,msg:`验证码刷新失败:无此设备在 ${t} 场景信息,请重新获取`}}}const Eo=new xo;Object.keys(Eo).forEach(e=>{To.prototype[e]=vo(Eo[e])});const Oo=new To,wo=new Proxy(Oo,{get(e,t){if(t in e)return"function"==typeof e[t]?vo(e[t]).bind(wo):e[t]}});module.exports=wo; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-captcha/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;tparseInt(e)):void 0}function o(e,t){const n=r(e),i=r(t);return n?i?function(e,t){const n=Math.max(e.length,t.length);for(let i=0;ir)return 1;if(ne)throw new Error("Config error, tokenExpiresThreshold should be less than tokenExpiresIn")}get customToken(){return this.uniId.interceptorMap.get("customToken")}isTokenInDb(e){return o(e,"1.0.10")>=0}async getUserRecord(){if(this.userRecord)return this.userRecord;const e=await C.doc(this.uid).get();if(this.userRecord=e.data[0],!this.userRecord)throw{errCode:n.ACCOUNT_NOT_EXISTS};switch(this.userRecord.status){case void 0:case 0:break;case 1:throw{errCode:n.ACCOUNT_BANNED};case 2:throw{errCode:n.ACCOUNT_AUDITING};case 3:throw{errCode:n.ACCOUNT_AUDIT_FAILED};case 4:throw{errCode:n.ACCOUNT_CLOSED}}if(this.oldTokenPayload){if(this.isTokenInDb(this.oldTokenPayload.uniIdVersion)){if(-1===(this.userRecord.token||[]).indexOf(this.oldToken))throw{errCode:n.CHECK_TOKEN_FAILED}}if(this.userRecord.valid_token_date&&this.userRecord.valid_token_date>1e3*this.oldTokenPayload.iat)throw{errCode:n.TOKEN_EXPIRED}}return this.userRecord}async updateUserRecord(e){await C.doc(this.uid).update(e)}async getUserPermission(){if(this.userPermission)return this.userPermission;const e=(await this.getUserRecord()).role||[];if(0===e.length)return this.userPermission={role:[],permission:[]},this.userPermission;if(e.includes("admin"))return this.userPermission={role:["admin"],permission:[]},this.userPermission;const t=await m.where({role_id:_.in(e)}).get(),n=(i=t.data.reduce((e,t)=>(t.permission&&e.push(...t.permission),e),[]),Array.from(new Set(i)));var i;return this.userPermission={role:e,permission:n},this.userPermission}async _createToken({uid:e,role:t,permission:i}={}){if(!t||!i){const e=await this.getUserPermission();t=e.role,i=e.permission}let r={uid:e,role:t,permission:i};if(this.uniId.interceptorMap.has("customToken")){const n=this.uniId.interceptorMap.get("customToken");if("function"!=typeof n)throw new Error("Invalid custom token file");r=await n({uid:e,role:t,permission:i})}const o=Date.now(),{tokenSecret:s,tokenExpiresIn:c}=this.config,a=g({...r,uniIdVersion:"1.0.13"},s,{expiresIn:c}),u=await this.getUserRecord(),d=(u.token||[]).filter(e=>{try{const t=this._checkToken(e);if(u.valid_token_date&&u.valid_token_date>1e3*t.iat)return!1}catch(e){if(e.errCode===n.TOKEN_EXPIRED)return!1}return!0});return d.push(a),await this.updateUserRecord({last_login_ip:this.clientInfo.clientIP,last_login_date:o,token:d}),{token:a,tokenExpired:o+1e3*c}}async createToken({uid:e,role:t,permission:i}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"uid"}};this.uid=e;const{token:r,tokenExpired:o}=await this._createToken({uid:e,role:t,permission:i});return{errCode:0,token:r,tokenExpired:o}}async refreshToken({token:e}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const t=this._checkToken(e);this.uid=t.uid,this.oldTokenPayload=t;const{uid:i}=t,{role:r,permission:o}=await this.getUserPermission(),{token:s,tokenExpired:c}=await this._createToken({uid:i,role:r,permission:o});return{errCode:0,token:s,tokenExpired:c}}_checkToken(e){const{tokenSecret:t}=this.config;let i;try{i=k(e,t)}catch(e){if("TokenExpiredError"===e.name)throw{errCode:n.TOKEN_EXPIRED};throw{errCode:n.CHECK_TOKEN_FAILED}}return i}async checkToken(e,{autoRefresh:t=!0}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const i=this._checkToken(e);this.uid=i.uid,this.oldTokenPayload=i;const{tokenExpiresThreshold:r}=this.config,{uid:o,role:s,permission:c}=i,a={role:s,permission:c};if(!s&&!c){const{role:e,permission:t}=await this.getUserPermission();a.role=e,a.permission=t}if(!r||!t){const e={code:0,errCode:0,...i,...a};return delete e.uniIdVersion,e}const u=Date.now();let d={};1e3*i.exp-u<1e3*r&&(d=await this._createToken({uid:o}));const l={code:0,errCode:0,...i,...a,...d};return delete l.uniIdVersion,l}}var E=Object.freeze({__proto__:null,checkToken:async function(e,{autoRefresh:t=!0}={}){return new T({uniId:this}).checkToken(e,{autoRefresh:t})},createToken:async function({uid:e,role:t,permission:n}={}){return new T({uniId:this}).createToken({uid:e,role:t,permission:n})},refreshToken:async function({token:e}={}){return new T({uniId:this}).refreshToken({token:e})}});const w=require("uni-config-center")({pluginId:"uni-id"});class A{constructor({context:e,clientInfo:t,config:n}={}){this._clientInfo=e?function(e){return{appId:e.APPID,platform:e.PLATFORM,locale:e.LOCALE,clientIP:e.CLIENTIP,deviceId:e.DEVICEID}}(e):t,this.config=n||this._getOriginConfig(),this.interceptorMap=new Map,w.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(w.resolve("custom-token.js"))),this._i18n=uniCloud.initI18n({locale:this._clientInfo.locale,fallbackLocale:"zh-Hans",messages:d})}setInterceptor(e,t){this.interceptorMap.set(e,t)}_t(...e){return this._i18n.t(...e)}_parseOriginConfig(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getOriginConfig(){if(w.hasFile("config.json")){let e;try{e=w.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseOriginConfig(e)}try{return this._parseOriginConfig(require("uni-id/config.json"))}catch(e){throw new Error("Invalid uni-id config file")}}_getAppConfig(){const e=this._getOriginConfig();return Array.isArray(e)?e.find(e=>e.dcloudAppid===this._clientInfo.appId)||e.find(e=>e.isDefaultConfig):e}_getPlatformConfig(){const e=this._getAppConfig();if(!e)throw new Error(`Config for current app (${this._clientInfo.appId}) was not found, please check your config file or client appId`);let t;switch("app-plus"===this._clientInfo.platform&&(this._clientInfo.platform="app"),"h5"===this._clientInfo.platform&&(this._clientInfo.platform="web"),this._clientInfo.platform){case"web":t="h5";break;case"app":t="app-plus"}const n=[{tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600},e];t&&e[t]&&n.push(e[t]),n.push(e[this._clientInfo.platform]);const i=Object.assign(...n);return["tokenSecret","tokenExpiresIn"].forEach(e=>{if(!i||!i[e])throw new Error(`Config parameter missing, ${e} is required`)}),i}_getConfig(){return this._getPlatformConfig()}}for(const e in E)A.prototype[e]=E[e];function y(e){const t=new A(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(n=e[t],function(){let e;try{e=n.apply(this,arguments)}catch(e){if(a(e))return c.call(this,e),e;throw e}return i(e)?e.then(e=>(a(e)&&c.call(this,e),e),e=>{if(a(e))return c.call(this,e),e;throw e}):(a(e)&&c.call(this,e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var n}})}A.prototype.createInstance=y;const x={createInstance:y};module.exports=x; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-id-common/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t { + return (item.dcloudAppid === appid) + }) + } + return this._uniId + } + + get ready() { + return this._ready + } +} + +class AppConfig extends ConfigBase { + + constructor() { + super() + } + + get(appid, platform) { + if (!this.isSupport(platform)) { + return null + } + + let appConfig = this.getAppConfig(appid) + if (!appConfig) { + return null + } + + return this.getOauthConfig(appConfig, platform) + } + + isSupport(platformName) { + return (AppConfig.Support_Platforms.indexOf(platformName) >= 0) + } + + getOauthConfig(appConfig, platformName) { + let tree = OauthConfig[platformName] + let node = appConfig + for (let i = 0; i < tree.length; i++) { + let nodeName = tree[i] + if (node[nodeName]) { + node = node[nodeName] + } else { + node = null + break + } + } + + if (node && node.appid && node.appsecret) { + return { + appid: node.appid, + secret: node.appsecret + } + } + + return null + } +} + +AppConfig.Support_Platforms = [PlatformType.WEIXIN_MP, PlatformType.WEIXIN_H5] + + +module.exports = { + AppConfig +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/consts.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/consts.js new file mode 100644 index 0000000..6da817b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/consts.js @@ -0,0 +1,26 @@ +'use strict'; + +const TAG = "UNI_OPEN_BRIDGE" + +const HTTP_STATUS = { + SUCCESS: 200 +} + +const PlatformType = { + WEIXIN_MP: 'weixin-mp', + WEIXIN_H5: 'weixin-h5', + WEIXIN_APP: 'weixin-app', + WEIXIN_WEB: 'weixin-web', + QQ_MP: 'qq-mp', + QQ_APP: 'qq-app' +} + +const ErrorCodeType = { + SYSTEM_ERROR: TAG + "_SYSTEM_ERROR" +} + +module.exports = { + HTTP_STATUS, + PlatformType, + ErrorCodeType +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/index.js new file mode 100644 index 0000000..f39b0af --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/index.js @@ -0,0 +1,221 @@ +'use strict'; + +const { + PlatformType, + ErrorCodeType +} = require('./consts.js') + +const { + AppConfig +} = require('./config.js') + +const { + Storage, + Factory +} = require('./storage.js') + +const { + BridgeError +} = require('./bridge-error.js') + +const { + WeixinServer +} = require('./weixin-server.js') + +const appConfig = new AppConfig() + +class AccessToken extends Storage { + + constructor() { + super('access-token', ['dcloudAppid', 'platform']) + } + + async fallback(parameters) { + const oauthConfig = appConfig.get(parameters.dcloudAppid, parameters.platform) + let methodName + if (parameters.platform === PlatformType.WEIXIN_MP) { + methodName = 'GetMPAccessTokenData' + } else if (parameters.platform === PlatformType.WEIXIN_H5) { + methodName = 'GetH5AccessTokenData' + } else { + throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "platform invalid") + } + + const responseData = await WeixinServer[methodName](oauthConfig) + + const duration = responseData.expires_in || (60 * 60 * 2) + delete responseData.expires_in + + return { + value: responseData, + duration + } + } +} + +class UserAccessToken extends Storage { + + constructor() { + super('user-access-token', ['dcloudAppid', 'platform', 'openid']) + } +} + +class SessionKey extends Storage { + + constructor() { + super('session-key', ['dcloudAppid', 'platform', 'openid']) + } +} + +class Encryptkey extends Storage { + + constructor() { + super('encrypt-key', ['dcloudAppid', 'platform', 'openid']) + } + + getKeyString(key) { + return `${super.getKeyString(key)}-${key.version}` + } + + getExpiresIn(value) { + if (value <= 0) { + return 60 + } + return value + } + + async fallback(parameters) { + const accessToken = await Factory.Get(AccessToken, parameters) + const userSession = await Factory.Get(SessionKey, parameters) + + const responseData = await WeixinServer.GetUserEncryptKeyData({ + openid: parameters.openid, + access_token: accessToken.access_token, + session_key: userSession.session_key + }) + + const keyInfo = responseData.key_info_list.find((item) => { + return item.version = parameters.version + }) + + const value = { + encrypt_key: keyInfo.encrypt_key, + iv: keyInfo.iv + } + + return { + value, + duration: keyInfo.expire_in + } + } +} + +class Ticket extends Storage { + + constructor() { + super('ticket', ['dcloudAppid', 'platform']) + } + + async fallback(parameters) { + const accessToken = await Factory.Get(AccessToken, { + dcloudAppid: parameters.dcloudAppid, + platform: PlatformType.WEIXIN_H5 + }) + + const responseData = await WeixinServer.GetH5TicketData(accessToken) + + const duration = responseData.expires_in || (60 * 60 * 2) + delete responseData.expires_in + delete responseData.errcode + delete responseData.errmsg + + return { + value: responseData, + duration + } + } +} + + +// exports + +async function getAccessToken(key, fallback) { + return await Factory.Get(AccessToken, key, fallback) +} + +async function setAccessToken(key, value, expiresIn) { + await Factory.Set(AccessToken, key, value, expiresIn) +} + +async function removeAccessToken(key) { + await Factory.Remove(AccessToken, key) +} + +async function getUserAccessToken(key, fallback) { + return await Factory.Get(UserAccessToken, key, fallback) +} + +async function setUserAccessToken(key, value, expiresIn) { + await Factory.Set(UserAccessToken, key, value, expiresIn) +} + +async function removeUserAccessToken(key) { + await Factory.Remove(UserAccessToken, key) +} + +async function getSessionKey(key, fallback) { + return await Factory.Get(SessionKey, key, fallback) +} + +async function setSessionKey(key, value, expiresIn) { + await Factory.Set(SessionKey, key, value, expiresIn) +} + +async function removeSessionKey(key) { + await Factory.Remove(SessionKey, key) +} + +async function getEncryptKey(key, fallback) { + return await Factory.Get(Encryptkey, key, fallback) +} + +async function setEncryptKey(key, value, expiresIn) { + await Factory.Set(Encryptkey, key, value, expiresIn) +} + +async function removeEncryptKey(key) { + await Factory.Remove(Encryptkey, key) +} + +async function getTicket(key, fallback) { + return await Factory.Get(Ticket, key, fallback) +} + +async function setTicket(key, value, expiresIn) { + await Factory.Set(Ticket, key, value, expiresIn) +} + +async function removeTicket(key) { + await Factory.Remove(Ticket, key) +} + +module.exports = { + getAccessToken, + setAccessToken, + removeAccessToken, + getUserAccessToken, + setUserAccessToken, + removeUserAccessToken, + getSessionKey, + setSessionKey, + removeSessionKey, + getEncryptKey, + setEncryptKey, + removeEncryptKey, + getTicket, + setTicket, + removeTicket, + PlatformType, + WeixinServer, + ErrorCodeType +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t { + keyArray.push(key[name]) + }) + keyArray.push(this._type) + return keyArray.join(':') + } + + getValue(value) { + return value + } + + getExpiresIn(value) { + if (value !== undefined) { + return value + } + return -1 + } + + validateKey(key) { + Validator.Key(this._keys, key) + } + + validateValue(value) { + Validator.Value(value) + } + + create(key, fallback) { + const keyString = this.getKeyString(key) + const options = { + layers: [{ + type: 'database', + key: keyString + }, { + type: 'redis', + key: keyString + }] + } + if (fallback !== null) { + const fallbackFunction = fallback || this.fallback + if (fallbackFunction) { + options.fallback = async () => { + return await fallbackFunction(key) + } + } + } + return new CacheKeyCascade(options) + } +} +Storage.Prefix = "uni-id" + +const Factory = { + + async Get(T, key, fallback) { + return await Factory.MakeUnique(T).get(key, fallback) + }, + + async Set(T, key, value, expiresIn) { + await Factory.MakeUnique(T).set(key, value, expiresIn) + }, + + async Remove(T, key) { + await Factory.MakeUnique(T).remove(key) + }, + + MakeUnique(T) { + return new T() + } +} + +module.exports = { + Storage, + Factory +}; diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/uni-cloud-cache.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/uni-cloud-cache.js new file mode 100644 index 0000000..2e4286b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/uni-cloud-cache.js @@ -0,0 +1,324 @@ +const db = uniCloud.database() + +function getType(value) { + return Object.prototype.toString.call(value).slice(8, -1).toLowerCase() +} + +const validator = { + key: function(value) { + const err = new Error('Invalid key') + if (typeof value !== 'string') { + throw err + } + const valueTrim = value.trim() + if (!valueTrim || valueTrim !== value) { + throw err + } + }, + value: function(value) { + // 仅作简单校验 + const type = getType(value) + const validValueType = ['null', 'number', 'string', 'array', 'object'] + if (validValueType.indexOf(type) === -1) { + throw new Error('Invalid value type') + } + }, + duration: function(value) { + const err = new Error('Invalid duration') + if (value === undefined) { + return + } + if (typeof value !== 'number' || value === 0) { + throw err + } + } +} + +/** + * 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示 + * 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在 + */ +class DatabaseCache { + constructor({ + collection = 'opendb-open-data' + } = {}) { + this.type = 'db' + this.collection = db.collection(collection) + } + + _serializeValue(value) { + return value === undefined ? null : JSON.stringify(value) + } + + _deserializeValue(value) { + return value ? JSON.parse(value) : value + } + + async set(key, value, duration) { + validator.key(key) + validator.value(value) + validator.duration(duration) + value = this._serializeValue(value) + await this.collection.doc(key).set({ + value, + expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1 + }) + } + + async _getWithDuration(key) { + const getKeyRes = await this.collection.doc(key).get() + const record = getKeyRes.data[0] + if (!record) { + return { + value: null, + duration: -2 + } + } + const value = this._deserializeValue(record.value) + const expired = record.expired + if (expired === -1) { + return { + value, + duration: -1 + } + } + const duration = expired - Date.now() + if (duration <= 0) { + await this.remove(key) + return { + value: null, + duration: -2 + } + } + return { + value, + duration: Math.floor(duration / 1000) + } + } + + async get(key, { + withDuration = true + } = {}) { + const result = await this._getWithDuration(key) + if (!withDuration) { + delete result.duration + } + return result + } + + async remove(key) { + await this.collection.doc(key).remove() + } +} + +class RedisCache { + constructor() { + this.type = 'redis' + this.redis = uniCloud.redis() + } + + _serializeValue(value) { + return value === undefined ? null : JSON.stringify(value) + } + + _deserializeValue(value) { + return value ? JSON.parse(value) : value + } + + async set(key, value, duration) { + validator.key(key) + validator.value(value) + validator.duration(duration) + value = this._serializeValue(value) + if (!duration || duration === -1) { + await this.redis.set(key, value) + } else { + await this.redis.set(key, value, 'EX', duration) + } + } + + async get(key, { + withDuration = false + } = {}) { + let value = await this.redis.get(key) + value = this._deserializeValue(value) + if (!withDuration) { + return { + value + } + } + const durationSecond = await this.redis.ttl(key) + let duration + switch (durationSecond) { + case -1: + duration = -1 + break + case -2: + duration = -2 + break + default: + duration = durationSecond + break + } + return { + value, + duration + } + } + + async remove(key) { + await this.redis.del(key) + } +} + +class Cache { + constructor({ + type, + collection + } = {}) { + if (type === 'database') { + return new DatabaseCache({ + collection + }) + } else if (type === 'redis') { + return new RedisCache() + } else { + throw new Error('Invalid cache type') + } + } +} + +class CacheKey { + constructor({ + type, + collection, + cache, + key, + fallback + } = {}) { + this.cache = cache || new Cache({ + type, + collection + }) + this.key = key + this.fallback = fallback + } + + async set(value, duration) { + await this.cache.set(this.key, value, duration) + } + + async setWithSync(value, duration, syncMethod) { + await Promise.all([ + this.set(this.key, value, duration), + syncMethod(value, duration) + ]) + } + + async get() { + let { + value, + duration + } = await this.cache.get(this.key) + if (value !== null && value !== undefined) { + return { + value, + duration + } + } + if (!this.fallback) { + return { + value: null, + duration: -2 + } + } + const fallbackResult = await this.fallback() + value = fallbackResult.value + duration = fallbackResult.duration + if (value !== null && duration !== undefined) { + await this.cache.set(this.key, value, duration) + } + return { + value, + duration + } + } + + async remove() { + await this.cache.remove(this.key) + } +} + +class CacheKeyCascade { + constructor({ + layers, // [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey] + fallback + } = {}) { + this.layers = layers + this.cacheLayers = [] + let lastCacheKey + for (let i = 0; i < layers.length; i++) { + const { + type, + cache, + collection, + key + } = layers[i] + const lastCacheKeyTemp = lastCacheKey + try { + const currentCacheKey = new CacheKey({ + type, + collection, + cache, + key, + fallback: i === 0 ? fallback : function() { + return lastCacheKeyTemp.get() + } + }) + this.cacheLayers.push(currentCacheKey) + lastCacheKey = currentCacheKey + } catch (e) {} + } + this.highLevelCache = lastCacheKey + } + + async set(value, duration) { + return Promise.all( + this.cacheLayers.map(item => { + return item.set(value, duration) + }) + ) + } + + async setWithSync(value, duration, syncMethod) { + const setPromise = this.cacheLayers.map(item => { + return item.set(value, duration) + }) + return Promise.all( + [ + ...setPromise, + syncMethod(value, duration) + ] + ) + } + + async get() { + return this.highLevelCache.get() + } + + async remove() { + await Promise.all( + this.cacheLayers.map(cacheKeyItem => { + return cacheKeyItem.remove() + }) + ) + } +} + +module.exports = { + Cache, + DatabaseCache, + RedisCache, + CacheKey, + CacheKeyCascade +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/validator.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/validator.js new file mode 100644 index 0000000..47a455b --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/validator.js @@ -0,0 +1,31 @@ +const Validator = { + + Key(keyArray, parameters) { + for (let i = 0; i < keyArray.length; i++) { + const keyName = keyArray[i] + if (typeof parameters[keyName] !== 'string') { + Validator.ThrowNewError(`Invalid ${keyName}`) + } + if (parameters[keyName].length < 1) { + Validator.ThrowNewError(`Invalid ${keyName}`) + } + } + }, + + Value(value) { + if (value === undefined) { + Validator.ThrowNewError('Invalid Value') + } + if (typeof value !== 'object') { + Validator.ThrowNewError('Invalid Value Type') + } + }, + + ThrowNewError(message) { + throw new Error(message) + } +} + +module.exports = { + Validator +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/weixin-server.js b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/weixin-server.js new file mode 100644 index 0000000..0a0c811 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/node_modules/uni-open-bridge-common/weixin-server.js @@ -0,0 +1,202 @@ +'use strict'; + +const crypto = require('crypto') + +const { + HTTP_STATUS +} = require('./consts.js') + +const { + BridgeError +} = require('./bridge-error.js') + +class WeixinServer { + + constructor(options = {}) { + this._appid = options.appid + this._secret = options.secret + } + + getAccessToken() { + return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, { + dataType: 'json', + method: 'POST', + data: { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + } + }) + } + + // 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次 + codeToSession(code) { + return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, { + dataType: 'json', + data: { + appid: this._appid, + secret: this._secret, + js_code: code, + grant_type: 'authorization_code' + } + }) + } + + getUserEncryptKey({ + access_token, + openid, + session_key + }) { + console.log(access_token, openid, session_key); + const signature = crypto.createHmac('sha256', session_key).update('').digest('hex') + return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, { + dataType: 'json', + method: 'POST', + dataAsQueryString: true, + data: { + access_token, + openid: openid, + signature: signature, + sig_method: 'hmac_sha256' + } + }) + } + + getH5AccessToken() { + return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, { + dataType: 'json', + method: 'GET', + data: { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + } + }) + } + + getH5Ticket(access_token) { + return uniCloud.httpclient.request(WeixinServer.Ticket_Url, { + dataType: 'json', + dataAsQueryString: true, + method: 'POST', + data: { + access_token + } + }) + } + + getH5AccessTokenForEip() { + return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + }, { + dataType: 'json' + }) + } + + getH5TicketForEip(access_token) { + return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, { + access_token + }, { + dataType: 'json', + dataAsQueryString: true + }) + } +} + +WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/token' +WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session' +WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey' +WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token' +WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi' + +WeixinServer.GetMPAccessToken = function(options) { + return new WeixinServer(options).getAccessToken() +} + +WeixinServer.GetCodeToSession = function(options) { + return new WeixinServer(options).codeToSession(options.code) +} + +WeixinServer.GetUserEncryptKey = function(options) { + return new WeixinServer(options).getUserEncryptKey(options) +} + +WeixinServer.GetH5AccessToken = function(options) { + return new WeixinServer(options).getH5AccessToken() +} + +WeixinServer.GetH5Ticket = function(options) { + return new WeixinServer(options).getH5Ticket(options.access_token) +} + +//////////////////////////////////////////////////////////////// + +function isAliyun() { + return (uniCloud.getCloudInfos()[0].provider === 'aliyun') +} + +WeixinServer.GetResponseData = function(response) { + console.log("WeixinServer::response", response) + + if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) { + throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue) + } + + const responseData = response.data || response.body + + if (responseData.errcode !== undefined && responseData.errcode !== 0) { + throw new BridgeError(responseData.errcode, responseData.errmsg) + } + + return responseData +} + +WeixinServer.GetMPAccessTokenData = async function(options) { + const response = await new WeixinServer(options).getAccessToken() + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetCodeToSessionData = async function(options) { + const response = await new WeixinServer(options).codeToSession(options.code) + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetUserEncryptKeyData = async function(options) { + const response = await new WeixinServer(options).getUserEncryptKey(options) + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetH5AccessTokenData = async function(options) { + const ws = new WeixinServer(options) + let response + if (isAliyun()) { + response = await ws.getH5AccessTokenForEip() + if (typeof response === 'string') { + response = JSON.parse(response) + } + } else { + response = await ws.getH5AccessToken() + } + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetH5TicketData = async function(options) { + const ws = new WeixinServer(options) + let response + if (isAliyun()) { + response = await ws.getH5TicketForEip(options.access_token) + if (typeof response === 'string') { + response = JSON.parse(response) + } + } else { + response = await ws.getH5Ticket(options.access_token) + } + return WeixinServer.GetResponseData(response) +} + + +module.exports = { + WeixinServer +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json new file mode 100644 index 0000000..8142793 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json @@ -0,0 +1,148 @@ +{ + "name": "uni-id-co", + "version": "1.0.38", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "uni-captcha": { + "version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha", + "requires": { + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "dependencies": { + "uni-config-center": { + "version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + } + } + }, + "uni-config-center": { + "version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "uni-id-common": { + "version": "file:../../../../uni-id-common/uniCloud/cloudfunctions/common/uni-id-common", + "requires": { + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "dependencies": { + "uni-config-center": { + "version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + } + } + }, + "uni-open-bridge-common": { + "version": "file:../../../../uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common", + "requires": { + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + }, + "dependencies": { + "uni-config-center": { + "version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json new file mode 100644 index 0000000..e4b8b33 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json @@ -0,0 +1,23 @@ +{ + "name": "uni-id-co", + "version": "1.0.38", + "description": "", + "main": "index.js", + "keywords": [], + "author": "DCloud", + "dependencies": { + "jsonwebtoken": "8.5.1", + "lodash.merge": "4.6.2", + "uni-captcha": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha", + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center", + "uni-id-common": "file:../../../../uni-id-common/uniCloud/cloudfunctions/common/uni-id-common", + "uni-open-bridge-common": "file:../../../../uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common" + }, + "extensions": { + "uni-cloud-sms": {}, + "uni-cloud-redis": {} + }, + "cloudfunction-config": { + "keepRunningAfterReturn": false + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-department.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-department.schema.json new file mode 100644 index 0000000..000112c --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-department.schema.json @@ -0,0 +1,50 @@ +{ + "bsonType": "object", + "required": [ + "name" + ], + "permission": { + "read": true, + "create": false, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "parent_id": { + "bsonType": "string", + "description": "父级部门ID", + "parentKey": "_id" + }, + "name": { + "bsonType": "string", + "description": "部门名称", + "title": "部门名称", + "trim": "both" + }, + "level": { + "bsonType": "int", + "description": "部门层级,为提升检索效率而作的冗余设计" + }, + "sort": { + "bsonType": "int", + "description": "部门在当前层级下的顺序,由小到大", + "title": "显示顺序" + }, + "manager_uid": { + "bsonType": "string", + "description": "部门主管的userid, 参考`uni-id-users` 表", + "foreignKey": "uni-id-users._id" + }, + "create_date": { + "bsonType": "timestamp", + "description": "部门创建时间", + "forceDefaultValue": { + "$env": "now" + } + } + }, + "version": "0.1.0" +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-device.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-device.schema.json new file mode 100644 index 0000000..c3591cc --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/opendb-device.schema.json @@ -0,0 +1,142 @@ +{ + "bsonType": "object", + "required": [], + "permission": { + "read": false, + "create": true, + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "appid": { + "bsonType": "string", + "description": "DCloud appid" + }, + "device_id": { + "bsonType": "string", + "description": "设备唯一标识" + }, + "vendor": { + "bsonType": "string", + "description": "设备厂商" + }, + "push_clientid": { + "bsonType": "string", + "description": "推送设备客户端标识" + }, + "imei": { + "bsonType": "string", + "description": "国际移动设备识别码IMEI(International Mobile Equipment Identity)" + }, + "oaid": { + "bsonType": "string", + "description": "移动智能设备标识公共服务平台提供的匿名设备标识符(OAID)" + }, + "idfa": { + "bsonType": "string", + "description": "iOS平台配置应用使用广告标识(IDFA)" + }, + "imsi": { + "bsonType": "string", + "description": "国际移动用户识别码(International Mobile Subscriber Identification Number)" + }, + "model": { + "bsonType": "string", + "description": "设备型号" + }, + "platform": { + "bsonType": "string", + "description": "平台类型" + }, + "uni_platform": { + "bsonType": "string", + "description": "uni-app 运行平台,与条件编译平台相同。" + }, + "os_name": { + "bsonType": "string", + "description": "ios|android|windows|mac|linux " + }, + "os_version": { + "bsonType": "string", + "description": "操作系统版本号 " + }, + "os_language": { + "bsonType": "string", + "description": "操作系统语言 " + }, + "os_theme": { + "bsonType": "string", + "description": "操作系统主题 light|dark" + }, + "pixel_ratio": { + "bsonType": "string", + "description": "设备像素比 " + }, + "network_model": { + "bsonType": "string", + "description": "设备网络型号wifi\/3G\/4G\/" + }, + "window_width": { + "bsonType": "string", + "description": "设备窗口宽度 " + }, + "window_height": { + "bsonType": "string", + "description": "设备窗口高度" + }, + "screen_width": { + "bsonType": "string", + "description": "设备屏幕宽度" + }, + "screen_height": { + "bsonType": "string", + "description": "设备屏幕高度" + }, + "rom_name": { + "bsonType": "string", + "description": "rom 名称" + }, + "rom_version": { + "bsonType": "string", + "description": "rom 版本" + }, + "location_latitude": { + "bsonType": "double", + "description": "纬度" + }, + "location_longitude": { + "bsonType": "double", + "description": "经度" + }, + "location_country": { + "bsonType": "string", + "description": "国家" + }, + "location_province": { + "bsonType": "string", + "description": "省份" + }, + "location_city": { + "bsonType": "string", + "description": "城市" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "last_update_date": { + "bsonType": "timestamp", + "description": "最后一次修改时间", + "forceDefaultValue": { + "$env": "now" + } + } + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-device.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-device.schema.json new file mode 100644 index 0000000..4981d75 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-device.schema.json @@ -0,0 +1,83 @@ +{ + "bsonType": "object", + "required": [ + "user_id" + ], + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "user_id": { + "bsonType": "string", + "description": "用户id,参考uni-id-users表" + }, + "ua": { + "bsonType": "string", + "description": "userAgent" + }, + "uuid": { + "bsonType": "string", + "description": "设备唯一标识(需要加密存储)" + }, + "os_name": { + "bsonType": "string", + "description": "ios|android|windows|mac|linux " + }, + "os_version": { + "bsonType": "string", + "description": "操作系统版本号 " + }, + "os_language": { + "bsonType": "string", + "description": "操作系统语言 " + }, + "os_theme": { + "bsonType": "string", + "description": "操作系统主题 light|dark" + }, + "vendor": { + "bsonType": "string", + "description": "设备厂商" + }, + "push_clientid": { + "bsonType": "string", + "description": "推送设备客户端标识" + }, + "imei": { + "bsonType": "string", + "description": "国际移动设备识别码IMEI(International Mobile Equipment Identity)" + }, + "oaid": { + "bsonType": "string", + "description": "移动智能设备标识公共服务平台提供的匿名设备标识符(OAID)" + }, + "idfa": { + "bsonType": "string", + "description": "iOS平台配置应用使用广告标识(IDFA)" + }, + "model": { + "bsonType": "string", + "description": "设备型号" + }, + "platform": { + "bsonType": "string", + "description": "平台类型" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "last_active_date": { + "bsonType": "timestamp", + "description": "最后登录时间" + }, + "last_active_ip": { + "bsonType": "string", + "description": "最后登录IP" + } + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-log.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-log.schema.json new file mode 100644 index 0000000..ff4f797 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-log.schema.json @@ -0,0 +1,71 @@ +{ + "bsonType": "object", + "required": ["user_id"], + "permission": { + "read": "'READ_UNI_ID_LOG' in auth.permission" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "device_uuid": { + "bsonType": "string", + "description": "设备唯一标识" + }, + "ip": { + "bsonType": "string", + "description": "ip地址" + }, + "state": { + "bsonType": "int", + "description": "结果:0 失败、1 成功" + }, + "type": { + "bsonType": "string", + "description": "操作类型", + "enum": [ + "logout", + "login", + "register", + "reset-pwd", + "bind-mobile", + "bind-weixin", + "bind-qq", + "bind-apple", + "bind-alipay" + ] + }, + "ua": { + "bsonType": "string", + "description": "userAgent" + }, + "user_id": { + "bsonType": "string", + "foreignKey": "uni-id-users._id", + "description": "用户id,参考uni-id-users表" + }, + "username": { + "bsonType": "string", + "description": "用户名" + }, + "email": { + "bsonType": "string", + "description": "邮箱" + }, + "mobile": { + "bsonType": "string", + "description": "手机号" + }, + "appid": { + "bsonType": "string", + "description": "客户端DCloud AppId" + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-permissions.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-permissions.schema.json new file mode 100644 index 0000000..25209cb --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-permissions.schema.json @@ -0,0 +1,52 @@ +{ + "bsonType": "object", + "required": ["permission_id", "permission_name"], + "permission": { + "read": "'READ_UNI_ID_PERMISSIONS' in auth.permission", + "create": "'CREATE_UNI_ID_PERMISSIONS' in auth.permission", + "update": "'UPDATE_UNI_ID_PERMISSIONS' in auth.permission", + "delete": "'DELETE_UNI_ID_PERMISSIONS' in auth.permission" + }, + "properties": { + "_id": { + "description": "存储文档 ID,系统自动生成" + }, + "comment": { + "bsonType": "string", + "component": { + "name": "textarea" + }, + "description": "备注", + "label": "备注", + "title": "备注", + "trim": "both" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "permission_id": { + "bsonType": "string", + "component": { + "name": "input" + }, + "description": "权限唯一标识,不可修改,不允许重复", + "label": "权限标识", + "title": "权限ID", + "trim": "both" + }, + "permission_name": { + "bsonType": "string", + "component": { + "name": "input" + }, + "description": "权限名称", + "label": "权限名称", + "title": "权限名称", + "trim": "both" + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-roles.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-roles.schema.json new file mode 100644 index 0000000..e2fe322 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-roles.schema.json @@ -0,0 +1,50 @@ +{ + "bsonType": "object", + "required": ["role_id", "role_name"], + "permission": { + "read": "'READ_UNI_ID_ROLES' in auth.permission", + "create": "'CREATE_UNI_ID_ROLES' in auth.permission", + "update": "'UPDATE_UNI_ID_ROLES' in auth.permission", + "delete": "'DELETE_UNI_ID_ROLES' in auth.permission" + }, + "properties": { + "_id": { + "description": "存储文档 ID,系统自动生成" + }, + "comment": { + "title": "备注", + "bsonType": "string", + "description": "备注", + "trim": "both" + }, + "create_date": { + "bsonType": "timestamp", + "description": "创建时间", + "forceDefaultValue": { + "$env": "now" + } + }, + "permission": { + "title": "权限", + "bsonType": "array", + "foreignKey": "uni-id-permissions.permission_id", + "description": "角色拥有的权限列表", + "enum": { + "collection": "uni-id-permissions", + "field": "permission_name as text, permission_id as value" + } + }, + "role_id": { + "title": "唯一ID", + "bsonType": "string", + "description": "角色唯一标识,不可修改,不允许重复", + "trim": "both" + }, + "role_name": { + "title": "名称", + "bsonType": "string", + "description": "角色名称", + "trim": "both" + } + } +} diff --git a/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-users.schema.json b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-users.schema.json new file mode 100644 index 0000000..7f779b2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-id-pages/uniCloud/database/uni-id-users.schema.json @@ -0,0 +1,465 @@ +{ + "bsonType": "object", + "permission": { + "read": true, + "create": "'CREATE_UNI_ID_USERS' in auth.permission", + "update": "doc._id == auth.uid || 'UPDATE_UNI_ID_USERS' in auth.permission", + "delete": "'DELETE_UNI_ID_USERS' in auth.permission" + }, + "properties": { + "_id": { + "description": "存储文档 ID(用户 ID),系统自动生成" + }, + "ali_openid": { + "bsonType": "string", + "description": "支付宝平台openid", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "apple_openid": { + "bsonType": "string", + "description": "苹果登录openid", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "avatar": { + "bsonType": "string", + "description": "头像地址", + "title": "头像地址", + "trim": "both", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "doc._id == auth.uid || 'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "avatar_file": { + "bsonType": "file", + "description": "用file类型方便使用uni-file-picker组件", + "title": "头像文件", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "doc._id == auth.uid || 'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "comment": { + "bsonType": "string", + "description": "备注", + "title": "备注", + "trim": "both", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "dcloud_appid": { + "bsonType": "array", + "description": "允许登录的客户端的appid列表", + "foreignKey": "opendb-app-list.appid", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "department_id": { + "bsonType": "array", + "description": "部门ID", + "enum": { + "collection": "opendb-department", + "field": "_id as value, name as text", + "orderby": "name asc" + }, + "enumType": "tree", + "title": "部门", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "email": { + "bsonType": "string", + "description": "邮箱地址", + "format": "email", + "title": "邮箱", + "trim": "both", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "email_confirmed": { + "bsonType": "int", + "defaultValue": 0, + "description": "邮箱验证状态:0 未验证 1 已验证", + "enum": [{ + "text": "未验证", + "value": 0 + }, + { + "text": "已验证", + "value": 1 + } + ], + "title": "邮箱验证状态", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "gender": { + "bsonType": "int", + "defaultValue": 0, + "description": "用户性别:0 未知 1 男性 2 女性", + "enum": [{ + "text": "未知", + "value": 0 + }, + { + "text": "男", + "value": 1 + }, + { + "text": "女", + "value": 2 + } + ], + "title": "性别", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "invite_time": { + "bsonType": "timestamp", + "description": "受邀时间", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "inviter_uid": { + "bsonType": "array", + "description": "用户全部上级邀请者", + "trim": "both", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "last_login_date": { + "bsonType": "timestamp", + "description": "最后登录时间", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "last_login_ip": { + "bsonType": "string", + "description": "最后登录时 IP 地址", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "mobile": { + "bsonType": "string", + "description": "手机号码", + "pattern": "^\\+?[0-9-]{3,20}$", + "title": "手机号码", + "trim": "both", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "mobile_confirmed": { + "bsonType": "int", + "defaultValue": 0, + "description": "手机号验证状态:0 未验证 1 已验证", + "enum": [{ + "text": "未验证", + "value": 0 + }, + { + "text": "已验证", + "value": 1 + } + ], + "title": "手机号验证状态", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "my_invite_code": { + "bsonType": "string", + "description": "用户自身邀请码", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "nickname": { + "bsonType": "string", + "description": "用户昵称", + "title": "昵称", + "trim": "both", + "permission": { + "read": true, + "write": "doc._id == auth.uid || 'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "password": { + "bsonType": "password", + "description": "密码,加密存储", + "title": "密码", + "trim": "both" + }, + "password_secret_version": { + "bsonType": "int", + "description": "密码使用的passwordSecret版本", + "title": "passwordSecret", + "permission": { + "read": false, + "write": false + } + }, + "realname_auth": { + "bsonType": "object", + "description": "实名认证信息", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + }, + "properties": { + "auth_date": { + "bsonType": "timestamp", + "description": "认证通过时间" + }, + "auth_status": { + "bsonType": "int", + "description": "认证状态:0 未认证 1 等待认证 2 认证通过 3 认证失败", + "maximum": 3, + "minimum": 0 + }, + "contact_email": { + "bsonType": "string", + "description": "联系人邮箱" + }, + "contact_mobile": { + "bsonType": "string", + "description": "联系人手机号码" + }, + "contact_person": { + "bsonType": "string", + "description": "联系人姓名" + }, + "id_card_back": { + "bsonType": "string", + "description": "身份证反面照 URL" + }, + "id_card_front": { + "bsonType": "string", + "description": "身份证正面照 URL" + }, + "identity": { + "bsonType": "string", + "description": "身份证号码/营业执照号码" + }, + "in_hand": { + "bsonType": "string", + "description": "手持身份证照片 URL" + }, + "license": { + "bsonType": "string", + "description": "营业执照 URL" + }, + "real_name": { + "bsonType": "string", + "description": "真实姓名/企业名称" + }, + "type": { + "bsonType": "int", + "description": "用户类型:0 个人用户 1 企业用户", + "maximum": 1, + "minimum": 0 + } + }, + "required": [ + "type", + "auth_status" + ] + }, + "register_date": { + "bsonType": "timestamp", + "description": "注册时间", + "forceDefaultValue": { + "$env": "now" + }, + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "register_ip": { + "bsonType": "string", + "description": "注册时 IP 地址", + "forceDefaultValue": { + "$env": "clientIP" + }, + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "role": { + "bsonType": "array", + "description": "用户角色", + "enum": { + "collection": "uni-id-roles", + "field": "role_id as value, role_name as text" + }, + "foreignKey": "uni-id-roles.role_id", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + }, + "title": "角色" + }, + "tags":{ + "bsonType": "array", + "description": "用户标签", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + }, + "title": "标签" + }, + "score": { + "bsonType": "int", + "description": "用户积分,积分变更记录可参考:uni-id-scores表定义", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "status": { + "bsonType": "int", + "defaultValue": 0, + "description": "用户状态:0 正常 1 禁用 2 审核中 3 审核拒绝", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + }, + "enum": [{ + "text": "正常", + "value": 0 + }, + { + "text": "禁用", + "value": 1 + }, + { + "text": "审核中", + "value": 2 + }, + { + "text": "审核拒绝", + "value": 3 + } + ], + "title": "用户状态" + }, + "token": { + "bsonType": "array", + "description": "用户token", + "permission": { + "read": false, + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "username": { + "bsonType": "string", + "description": "用户名,不允许重复", + "title": "用户名", + "trim": "both", + "permission": { + "read": "doc._id == auth.uid || 'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "wx_openid": { + "bsonType": "object", + "description": "微信各个平台openid", + "properties": { + "app": { + "bsonType": "string", + "description": "app平台微信openid" + }, + "mp": { + "bsonType": "string", + "description": "微信小程序平台openid" + }, + "h5": { + "bsonType": "string", + "description": "微信公众号登录openid" + }, + "web": { + "bsonType": "string", + "description": "PC页面扫码登录openid" + } + }, + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "wx_unionid": { + "bsonType": "string", + "description": "微信unionid", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "qq_openid": { + "bsonType": "object", + "description": "QQ各个平台openid", + "properties": { + "app": { + "bsonType": "string", + "description": "app平台QQ openid" + }, + "mp": { + "bsonType": "string", + "description": "QQ小程序平台openid" + } + }, + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "qq_unionid": { + "bsonType": "string", + "description": "QQ unionid", + "permission": { + "read": "'READ_UNI_ID_USERS' in auth.permission", + "write": "'CREATE_UNI_ID_USERS' in auth.permission || 'UPDATE_UNI_ID_USERS' in auth.permission" + } + }, + "third_party": { + "bsonType": "object", + "description": "三方平台凭证", + "permission": { + "read": false, + "write": false + } + } + }, + "required": [] +} diff --git a/alpha/admin/uni_modules/uni-link/changelog.md b/alpha/admin/uni_modules/uni-link/changelog.md new file mode 100644 index 0000000..2cfbf59 --- /dev/null +++ b/alpha/admin/uni_modules/uni-link/changelog.md @@ -0,0 +1,17 @@ +## 1.0.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-link](https://uniapp.dcloud.io/component/uniui/uni-link) +## 1.1.7(2021-11-08) +## 0.0.7(2021-09-03) +- 修复 在 nvue 下不显示的 bug +## 0.0.6(2021-07-30) +- 新增 支持自定义插槽 +## 0.0.5(2021-06-21) +- 新增 download 属性,H5平台下载文件名 +## 0.0.4(2021-05-12) +- 新增 组件示例地址 +## 0.0.3(2021-03-09) +- 新增 href 属性支持 tel:|mailto: + +## 0.0.2(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-link/components/uni-link/uni-link.vue b/alpha/admin/uni_modules/uni-link/components/uni-link/uni-link.vue new file mode 100644 index 0000000..27c5468 --- /dev/null +++ b/alpha/admin/uni_modules/uni-link/components/uni-link/uni-link.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-link/package.json b/alpha/admin/uni_modules/uni-link/package.json new file mode 100644 index 0000000..77b1986 --- /dev/null +++ b/alpha/admin/uni_modules/uni-link/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-link", + "displayName": "uni-link 超链接", + "version": "1.0.0", + "description": "uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打", + "keywords": [ + "uni-ui", + "uniui", + "link", + "超链接", + "" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-link/readme.md b/alpha/admin/uni_modules/uni-link/readme.md new file mode 100644 index 0000000..7f09e94 --- /dev/null +++ b/alpha/admin/uni_modules/uni-link/readme.md @@ -0,0 +1,11 @@ + + +## Link 链接 +> **组件名:uni-link** +> 代码块: `uLink` + + +uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-link) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-list/changelog.md b/alpha/admin/uni_modules/uni-list/changelog.md new file mode 100644 index 0000000..49cbb31 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/changelog.md @@ -0,0 +1,42 @@ +## 1.2.12(2023-02-01) +- 新增 列表图标新增 customPrefix 属性 ,用法 [详见](https://uniapp.dcloud.net.cn/component/uniui/uni-icons.html#icons-props) +## 1.2.11(2023-01-31) +- 修复 无反馈效果呈现的bug +## 1.2.9(2022-11-22) +- 修复 uni-list-chat 在vue3下跳转报错的bug +## 1.2.8(2022-11-21) +- 修复 uni-list-chat avatar属性 值为本地路径时错误的问题 +## 1.2.7(2022-11-21) +- 修复 uni-list-chat avatar属性 在腾讯云版uniCloud下错误的问题 +## 1.2.6(2022-11-18) +- 修复 uni-list-chat note属性 支持:“草稿”字样功能 文本少1位的问题 +## 1.2.5(2022-11-15) +- 修复 uni-list-item 的 customStyle 属性 padding值在 H5端 无效的bug +## 1.2.4(2022-11-15) +- 修复 uni-list-item 的 customStyle 属性 padding值在nvue(vue2)下无效的bug +## 1.2.3(2022-11-14) +- uni-list-chat 新增 avatar 支持 fileId +## 1.2.2(2022-11-11) +- uni-list 新增属性 render-reverse 详情参考:[https://uniapp.dcloud.net.cn/component/list.html](https://uniapp.dcloud.net.cn/component/list.html) +- uni-list-chat note属性 支持:“草稿”字样 加红显示 详情参考uni-im:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) +- uni-list-item 新增属性 customStyle 支持设置padding、backgroundColor +## 1.2.1(2022-03-30) +- 删除无用文件 +## 1.2.0(2021-11-23) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-list](https://uniapp.dcloud.io/component/uniui/uni-list) +## 1.1.3(2021-08-30) +- 修复 在vue3中to属性在发行应用的时候报错的bug +## 1.1.2(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.1.1(2021-07-21) +- 修复 与其他组件嵌套使用时,点击失效的Bug +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.17(2021-05-12) +- 新增 组件示例地址 +## 1.0.16(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 1.0.15(2021-02-05) +- 调整为uni_modules目录规范 +- 修复 uni-list-chat 角标显示不正常的问题 diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue b/alpha/admin/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue new file mode 100644 index 0000000..b9349c2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss b/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss new file mode 100644 index 0000000..311f8d9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss @@ -0,0 +1,58 @@ +/** + * 这里是 uni-list 组件内置的常用样式变量 + * 如果需要覆盖样式,这里提供了基本的组件样式变量,您可以尝试修改这里的变量,去完成样式替换,而不用去修改源码 + * + */ + +// 背景色 +$background-color : #fff; +// 分割线颜色 +$divide-line-color : #e5e5e5; + +// 默认头像大小,如需要修改此值,注意同步修改 js 中的值 const avatarWidth = xx ,目前只支持方形头像 +// nvue 页面不支持修改头像大小 +$avatar-width : 45px ; + +// 头像边框 +$avatar-border-radius: 5px; +$avatar-border-color: #eee; +$avatar-border-width: 1px; + +// 标题文字样式 +$title-size : 16px; +$title-color : #3b4144; +$title-weight : normal; + +// 描述文字样式 +$note-size : 12px; +$note-color : #999; +$note-weight : normal; + +// 右侧额外内容默认样式 +$right-text-size : 12px; +$right-text-color : #999; +$right-text-weight : normal; + +// 角标样式 +// nvue 页面不支持修改圆点位置以及大小 +// 角标在左侧时,角标的位置,默认为 0 ,负数左/下移动,正数右/上移动 +$badge-left: 0px; +$badge-top: 0px; + +// 显示圆点时,圆点大小 +$dot-width: 10px; +$dot-height: 10px; + +// 显示角标时,角标大小和字体大小 +$badge-size : 18px; +$badge-font : 12px; +// 显示角标时,角标前景色 +$badge-color : #fff; +// 显示角标时,角标背景色 +$badge-background-color : #ff5a5f; +// 显示角标时,角标左右间距 +$badge-space : 6px; + +// 状态样式 +// 选中颜色 +$hover : #f5f5f5; diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue b/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue new file mode 100644 index 0000000..39bd8d4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue @@ -0,0 +1,586 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue b/alpha/admin/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue new file mode 100644 index 0000000..a92986f --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue @@ -0,0 +1,531 @@ + + + + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list/uni-list.vue b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-list.vue new file mode 100644 index 0000000..6ef5972 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-list.vue @@ -0,0 +1,123 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.vue b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.vue new file mode 100644 index 0000000..3b4c5a2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.wxs b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.wxs new file mode 100644 index 0000000..818a6b7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/components/uni-list/uni-refresh.wxs @@ -0,0 +1,87 @@ +var pullDown = { + threshold: 95, + maxHeight: 200, + callRefresh: 'onrefresh', + callPullingDown: 'onpullingdown', + refreshSelector: '.uni-refresh' +}; + +function ready(newValue, oldValue, ownerInstance, instance) { + var state = instance.getState() + state.canPullDown = newValue; + // console.log(newValue); +} + +function touchStart(e, instance) { + var state = instance.getState(); + state.refreshInstance = instance.selectComponent(pullDown.refreshSelector); + state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined); + if (!state.canPullDown) { + return + } + + // console.log("touchStart"); + + state.height = 0; + state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY; + state.refreshInstance.setStyle({ + 'height': 0 + }); + state.refreshInstance.callMethod("onchange", true); +} + +function touchMove(e, ownerInstance) { + var instance = e.instance; + var state = instance.getState(); + if (!state.canPullDown) { + return + } + + var oldHeight = state.height; + var endY = e.touches[0].pageY || e.changedTouches[0].pageY; + var height = endY - state.touchStartY; + if (height > pullDown.maxHeight) { + return; + } + + var refreshInstance = state.refreshInstance; + refreshInstance.setStyle({ + 'height': height + 'px' + }); + + height = height < pullDown.maxHeight ? height : pullDown.maxHeight; + state.height = height; + refreshInstance.callMethod(pullDown.callPullingDown, { + height: height + }); +} + +function touchEnd(e, ownerInstance) { + var state = e.instance.getState(); + if (!state.canPullDown) { + return + } + + state.refreshInstance.callMethod("onchange", false); + + var refreshInstance = state.refreshInstance; + if (state.height > pullDown.threshold) { + refreshInstance.callMethod(pullDown.callRefresh); + return; + } + + refreshInstance.setStyle({ + 'height': 0 + }); +} + +function propObserver(newValue, oldValue, instance) { + pullDown = newValue; +} + +module.exports = { + touchmove: touchMove, + touchstart: touchStart, + touchend: touchEnd, + propObserver: propObserver +} diff --git a/alpha/admin/uni_modules/uni-list/package.json b/alpha/admin/uni_modules/uni-list/package.json new file mode 100644 index 0000000..3f4235e --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-list", + "displayName": "uni-list 列表", + "version": "1.2.12", + "description": "List 组件 ,帮助使用者快速构建列表。", + "keywords": [ + "", + "uni-ui", + "uniui", + "列表", + "", + "list" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-badge", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-list/readme.md b/alpha/admin/uni_modules/uni-list/readme.md new file mode 100644 index 0000000..32c2865 --- /dev/null +++ b/alpha/admin/uni_modules/uni-list/readme.md @@ -0,0 +1,346 @@ +## List 列表 +> **组件名:uni-list** +> 代码块: `uList`、`uListItem` +> 关联组件:`uni-list-item`、`uni-badge`、`uni-icons`、`uni-list-chat`、`uni-list-ad` + + +List 列表组件,包含基本列表样式、可扩展插槽机制、长列表性能优化、多端兼容。 + +在vue页面里,它默认使用页面级滚动。在app-nvue页面里,它默认使用原生list组件滚动。这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。 + +uni-list组件是父容器,里面的核心是uni-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。 + +uni-list-item有很多风格,uni-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容。 + +内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表、通信录列表、聊天记录列表。 + +涉及很多大图或丰富内容的列表,比如类今日头条的新闻列表、类淘宝的电商列表,需要通过扩展插槽实现。 + +下文均有样例给出。 + +uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29) + + +### 安装方式 + +本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 + +如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) + +> **注意事项** +> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 +> - 组件需要依赖 `sass` 插件 ,请自行手动安装 +> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件 +> - `uni-list` 和 `uni-list-item` 需要配套使用,暂不支持单独使用 `uni-list-item` +> - 只有开启点击反馈后,会有点击选中效果 +> - 使用插槽时,可以完全自定义内容 +> - note 、rightText 属性暂时没做限制,不支持文字溢出隐藏,使用时应该控制长度显示或通过默认插槽自行扩展 +> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译 +> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义 +> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli` +> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + +### 基本用法 + +- 设置 `title` 属性,可以显示列表标题 +- 设置 `disabled` 属性,可以禁用当前项 + +```html + + + + + +``` + +### 多行内容显示 + +- 设置 `note` 属性 ,可以在第二行显示描述文本信息 + +```html + + + + + +``` + +### 右侧显示角标、switch + +- 设置 `show-badge` 属性 ,可以显示角标内容 +- 设置 `show-switch` 属性,可以显示 switch 开关 + +```html + + + + + +``` + +### 左侧显示略缩图、图标 + +- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图 +- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标 + +```html + + + + +``` + +### 开启点击反馈和右侧箭头 +- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 +- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头 +- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` + +```html + + + + + + + +``` + + +### 聊天列表示例 +- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 +- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` +- 设置 `to` 属性,可以跳转页面 +- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示 +- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效 +- 可以通过默认插槽自定义列表右侧内容 + +```html + + + + + + + + + + + + + + + + + 刚刚 + + + + + + + +``` + +```javascript + +export default { + components: {}, + data() { + return { + avatarList: [{ + url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' + }, { + url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' + }, { + url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' + }] + } + } +} + +``` + + +```css + +.chat-custom-right { + flex: 1; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: column; + justify-content: space-between; + align-items: flex-end; +} + +.chat-custom-text { + font-size: 12px; + color: #999; +} + +``` + +## API + +### List Props + +属性名 |类型 |默认值 | 说明 +:-: |:-: |:-: | :-: +border |Boolean |true | 是否显示边框 + + +### ListItem Props + +属性名 |类型 |默认值 | 说明 +:-: |:-: |:-: | :-: +title |String |- | 标题 +note |String |- | 描述 +ellipsis |Number |0 | title 是否溢出隐藏,可选值,0:默认; 1:显示一行; 2:显示两行;【nvue 暂不支持】 +thumb |String |- | 左侧缩略图,若thumb有值,则不会显示扩展图标 +thumbSize |String |medium | 略缩图尺寸,可选值,lg:大图; medium:一般; sm:小图; +showBadge |Boolean |false | 是否显示数字角标 +badgeText |String |- | 数字角标内容 +badgeType |String |- | 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21) +badgeStyle |Object |- | 数字角标样式,使用uni-badge的custom-style参数 +rightText |String |- | 右侧文字内容 +disabled |Boolean |false | 是否禁用 +showArrow |Boolean |true | 是否显示箭头图标 +link |String |navigateTo | 新页面跳转方式,可选值见下表 +to |String |- | 新页面跳转地址,如填写此属性,click 会返回页面是否跳转成功 +clickable |Boolean |false | 是否开启点击反馈 +showSwitch |Boolean |false | 是否显示Switch +switchChecked |Boolean |false | Switch是否被选中 +showExtraIcon |Boolean |false | 左侧是否显示扩展图标 +extraIcon |Object |- | 扩展图标参数,格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``,参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28) +direction | String |row | 排版方向,可选值,row:水平排列; column:垂直排列; 3个插槽是水平排还是垂直排,也受此属性控制 + + +#### Link Options + +属性名 | 说明 +:-: | :-: +navigateTo | 同 uni.navigateTo() +redirectTo | 同 uni.reLaunch() +reLaunch | 同 uni.reLaunch() +switchTab | 同 uni.switchTab() + +### ListItem Events + +事件称名 |说明 |返回参数 +:-: |:-: |:-: +click |点击 uniListItem 触发事件,需开启点击反馈 |- +switchChange |点击切换 Switch 时触发,需显示 switch |e={value:checked} + + + +### ListItem Slots + +名称 | 说明 +:-: | :-: +header | 左/上内容插槽,可完全自定义默认显示 +body | 中间内容插槽,可完全自定义中间内容 +footer | 右/下内容插槽,可完全自定义右侧内容 + + +> **通过插槽扩展** +> 需要注意的是当使用插槽时,内置样式将会失效,只保留排版样式,此时的样式需要开发者自己实现 +> 如果 `uni-list-item` 组件内置属性样式无法满足需求,可以使用插槽来自定义uni-list-item里的内容。 +> uni-list-item提供了3个可扩展的插槽:`header`、`body`、`footer` +> - 当 `direction` 属性为 `row` 时表示水平排列,此时 `header` 表示列表的左边部分,`body` 表示列表的中间部分,`footer` 表示列表的右边部分 +> - 当 `direction` 属性为 `column` 时表示垂直排列,此时 `header` 表示列表的上边部分,`body` 表示列表的中间部分,`footer` 表示列表的下边部分 +> 开发者可以只用1个插槽,也可以3个一起使用。在插槽中可自主编写view标签,实现自己所需的效果。 + + +**示例** + +```html + + + + + + + + + 自定义插槽 + + + + +``` + + + + + +### ListItemChat Props + +属性名 |类型 |默认值 | 说明 +:-: |:-: |:-: | :-: +title |String |- | 标题 +note |String |- | 描述 +clickable |Boolean |false | 是否开启点击反馈 +badgeText |String |- | 数字角标内容,设置为 `dot` 将显示圆点 +badgePositon |String |right | 角标位置 +link |String |navigateTo | 是否展示右侧箭头并开启点击反馈,可选值见下表 +clickable |Boolean |false | 是否开启点击反馈 +to |String |- | 跳转页面地址,如填写此属性,click 会返回页面是否跳转成功 +time |String |- | 右侧时间显示 +avatarCircle |Boolean |false | 是否显示圆形头像 +avatar |String |- | 头像地址,avatarCircle 不填时生效 +avatarList |Array |- | 头像组,格式为 [{url:''}] + +#### Link Options + +属性名 | 说明 +:-: | :-: +navigateTo | 同 uni.navigateTo() +redirectTo | 同 uni.reLaunch() +reLaunch | 同 uni.reLaunch() +switchTab | 同 uni.switchTab() + +### ListItemChat Slots + +名称 | 说明 +:- | :- +default | 自定义列表右侧内容(包括时间和角标显示) + +### ListItemChat Events +事件称名 | 说明 | 返回参数 +:-: | :-: | :-: +@click | 点击 uniListChat 触发事件 | {data:{}} ,如有 to 属性,会返回页面跳转信息 + + + + + + +## 基于uni-list扩展的页面模板 + +通过扩展插槽,可实现多种常见样式的列表 + +**新闻列表类** + +1. 云端一体混合布局:[https://ext.dcloud.net.cn/plugin?id=2546](https://ext.dcloud.net.cn/plugin?id=2546) +2. 云端一体垂直布局,大图模式:[https://ext.dcloud.net.cn/plugin?id=2583](https://ext.dcloud.net.cn/plugin?id=2583) +3. 云端一体垂直布局,多行图文混排:[https://ext.dcloud.net.cn/plugin?id=2584](https://ext.dcloud.net.cn/plugin?id=2584) +4. 云端一体垂直布局,多图模式:[https://ext.dcloud.net.cn/plugin?id=2585](https://ext.dcloud.net.cn/plugin?id=2585) +5. 云端一体水平布局,左图右文:[https://ext.dcloud.net.cn/plugin?id=2586](https://ext.dcloud.net.cn/plugin?id=2586) +6. 云端一体水平布局,左文右图:[https://ext.dcloud.net.cn/plugin?id=2587](https://ext.dcloud.net.cn/plugin?id=2587) +7. 云端一体垂直布局,无图模式,主标题+副标题:[https://ext.dcloud.net.cn/plugin?id=2588](https://ext.dcloud.net.cn/plugin?id=2588) + +**商品列表类** + +1. 云端一体列表/宫格视图互切:[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651) +2. 云端一体列表(宫格模式):[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671) +3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672) + +## 组件示例 + +点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/list/list](https://hellouniapp.dcloud.net.cn/pages/extUI/list/list) \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-load-more/changelog.md b/alpha/admin/uni_modules/uni-load-more/changelog.md new file mode 100644 index 0000000..8f03f1d --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/changelog.md @@ -0,0 +1,19 @@ +## 1.3.3(2022-01-20) +- 新增 showText属性 ,是否显示文本 +## 1.3.2(2022-01-19) +- 修复 nvue 平台下不显示文本的bug +## 1.3.1(2022-01-19) +- 修复 微信小程序平台样式选择器报警告的问题 +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more) +## 1.2.1(2021-08-24) +- 新增 支持国际化 +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.8(2021-05-12) +- 新增 组件示例地址 +## 1.1.7(2021-03-30) +- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug +## 1.1.6(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json new file mode 100644 index 0000000..a4f14a5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json @@ -0,0 +1,5 @@ +{ + "uni-load-more.contentdown": "Pull up to show more", + "uni-load-more.contentrefresh": "loading...", + "uni-load-more.contentnomore": "No more data" +} diff --git a/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json new file mode 100644 index 0000000..f15d510 --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json @@ -0,0 +1,5 @@ +{ + "uni-load-more.contentdown": "上拉显示更多", + "uni-load-more.contentrefresh": "正在加载...", + "uni-load-more.contentnomore": "没有更多数据了" +} diff --git a/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json new file mode 100644 index 0000000..a255c6d --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json @@ -0,0 +1,5 @@ +{ + "uni-load-more.contentdown": "上拉顯示更多", + "uni-load-more.contentrefresh": "正在加載...", + "uni-load-more.contentnomore": "沒有更多數據了" +} diff --git a/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue new file mode 100644 index 0000000..e5eff4d --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue @@ -0,0 +1,399 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-load-more/package.json b/alpha/admin/uni_modules/uni-load-more/package.json new file mode 100644 index 0000000..2fa6f04 --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-load-more", + "displayName": "uni-load-more 加载更多", + "version": "1.3.3", + "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。", + "keywords": [ + "uni-ui", + "uniui", + "加载更多", + "load-more" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-load-more/readme.md b/alpha/admin/uni_modules/uni-load-more/readme.md new file mode 100644 index 0000000..54dc1fa --- /dev/null +++ b/alpha/admin/uni_modules/uni-load-more/readme.md @@ -0,0 +1,14 @@ + + +### LoadMore 加载更多 +> **组件名:uni-load-more** +> 代码块: `uLoadMore` + + +用于列表中,做滚动加载使用,展示 loading 的各种状态。 + + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-notice-bar/changelog.md b/alpha/admin/uni_modules/uni-notice-bar/changelog.md new file mode 100644 index 0000000..d526811 --- /dev/null +++ b/alpha/admin/uni_modules/uni-notice-bar/changelog.md @@ -0,0 +1,18 @@ +## 1.2.1(2022-09-05) +- 新增 属性 fontSize,可修改文字大小。 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar) +## 1.1.1(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.9(2021-05-12) +- 新增 组件示例地址 +## 1.0.8(2021-04-21) +- 优化 添加依赖 uni-icons, 导入后自动下载依赖 +## 1.0.7(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 + +## 1.0.6(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue b/alpha/admin/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue new file mode 100644 index 0000000..98d4720 --- /dev/null +++ b/alpha/admin/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue @@ -0,0 +1,426 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-notice-bar/package.json b/alpha/admin/uni_modules/uni-notice-bar/package.json new file mode 100644 index 0000000..8d9b13c --- /dev/null +++ b/alpha/admin/uni_modules/uni-notice-bar/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-notice-bar", + "displayName": "uni-notice-bar 通告栏", + "version": "1.2.1", + "description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告", + "keywords": [ + "uni-ui", + "uniui", + "通告栏", + "公告", + "跑马灯" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-notice-bar/readme.md b/alpha/admin/uni_modules/uni-notice-bar/readme.md new file mode 100644 index 0000000..fb2ede2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-notice-bar/readme.md @@ -0,0 +1,13 @@ + + +## NoticeBar 通告栏 +> **组件名:uni-notice-bar** +> 代码块: `uNoticeBar` + + +通告栏组件 。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-number-box/changelog.md b/alpha/admin/uni_modules/uni-number-box/changelog.md new file mode 100644 index 0000000..5925c32 --- /dev/null +++ b/alpha/admin/uni_modules/uni-number-box/changelog.md @@ -0,0 +1,25 @@ +## 1.2.1(2021-11-22) +- 修复 vue3中某些scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box) +## 1.1.2(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-04-20) +- 修复 uni-number-box 浮点数运算不精确的 bug +- 修复 uni-number-box change 事件触发不正确的 bug +- 新增 uni-number-box v-model 双向绑定 +## 1.0.5(2021-02-05) +- 调整为uni_modules目录规范 + +## 1.0.7(2021-02-05) +- 调整为uni_modules目录规范 +- 新增 支持 v-model +- 新增 支持 focus、blur 事件 +- 新增 支持 PC 端 diff --git a/alpha/admin/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue b/alpha/admin/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue new file mode 100644 index 0000000..8d255fb --- /dev/null +++ b/alpha/admin/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue @@ -0,0 +1,220 @@ + + + diff --git a/alpha/admin/uni_modules/uni-number-box/package.json b/alpha/admin/uni_modules/uni-number-box/package.json new file mode 100644 index 0000000..ad82336 --- /dev/null +++ b/alpha/admin/uni_modules/uni-number-box/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-number-box", + "displayName": "uni-number-box 数字输入框", + "version": "1.2.1", + "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。", + "keywords": [ + "uni-ui", + "uniui", + "数字输入框" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-number-box/readme.md b/alpha/admin/uni_modules/uni-number-box/readme.md new file mode 100644 index 0000000..affc56f --- /dev/null +++ b/alpha/admin/uni_modules/uni-number-box/readme.md @@ -0,0 +1,13 @@ + + +## NumberBox 数字输入框 +> **组件名:uni-number-box** +> 代码块: `uNumberBox` + + +带加减按钮的数字输入框。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/changelog.md b/alpha/admin/uni_modules/uni-open-bridge-common/changelog.md new file mode 100644 index 0000000..b3a56b2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/changelog.md @@ -0,0 +1,8 @@ +## 1.0.4(2022-09-21) +- 新增 支持使用阿里云固定IP获取微信公众号H5凭据 access_token、ticket,开发者需要在微信公众平台配置阿里云固定IP,[固定IP详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions.html#aliyun-eip) +## 1.0.3(2022-09-06) +- 修复 过期时间问题,容错 AccessToken 默认 fallback 逻辑,当微信服务器没有返回过期时间时设置为2小时后过期 +## 1.0.2(2022-09-02) +- 新增 依赖数据表schema opendb-open-data +## 1.0.0(2022-08-22) +- 首次发布 diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/package.json b/alpha/admin/uni_modules/uni-open-bridge-common/package.json new file mode 100644 index 0000000..487f353 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/package.json @@ -0,0 +1,84 @@ +{ + "id": "uni-open-bridge-common", + "displayName": "uni-open-bridge-common", + "version": "1.0.4", + "description": "统一接管微信等三方平台认证凭据", + "keywords": [ + "uni-open-bridge-common", + "access_token", + "session_key", + "ticket" +], + "repository": "", + "engines": { + "HBuilderX": "^3.5.2" + }, + "dcloudext": { + "type": "unicloud-template-function", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "u", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/readme.md b/alpha/admin/uni_modules/uni-open-bridge-common/readme.md new file mode 100644 index 0000000..3892384 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/readme.md @@ -0,0 +1,5 @@ +# uni-open-bridge-common + +`uni-open-bridge-common` 是统一接管微信等三方平台认证凭据(包括但不限于`access_token`、`session_key`、`encrypt_key`、`ticket`)的开源库。 + +文档链接 [https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common) diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js new file mode 100644 index 0000000..95160a4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js @@ -0,0 +1,26 @@ +'use strict'; + +class BridgeError extends Error { + + constructor(code, message) { + super(message) + + this._code = code + } + + get code() { + return this._code + } + + get errCode() { + return this._code + } + + get errMsg() { + return this.message + } +} + +module.exports = { + BridgeError +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js new file mode 100644 index 0000000..2fb7d7b --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js @@ -0,0 +1,95 @@ +'use strict'; + +const { + PlatformType +} = require('./consts.js') + +const configCenter = require('uni-config-center') + +const OauthConfig = { + 'weixin-mp': ['mp-weixin', 'oauth', 'weixin'], + 'weixin-h5': ['web', 'oauth', 'weixin-h5'] +} + +class ConfigBase { + + constructor() { + this._ready = false + this._uniId = null + + const uniIdConfig = configCenter({ + pluginId: 'uni-id' + }) + + this._uniId = uniIdConfig.config() + + this._ready = true + } + + getAppConfig(appid) { + if (Array.isArray(this._uniId)) { + return this._uniId.find((item) => { + return (item.dcloudAppid === appid) + }) + } + return this._uniId + } + + get ready() { + return this._ready + } +} + +class AppConfig extends ConfigBase { + + constructor() { + super() + } + + get(appid, platform) { + if (!this.isSupport(platform)) { + return null + } + + let appConfig = this.getAppConfig(appid) + if (!appConfig) { + return null + } + + return this.getOauthConfig(appConfig, platform) + } + + isSupport(platformName) { + return (AppConfig.Support_Platforms.indexOf(platformName) >= 0) + } + + getOauthConfig(appConfig, platformName) { + let tree = OauthConfig[platformName] + let node = appConfig + for (let i = 0; i < tree.length; i++) { + let nodeName = tree[i] + if (node[nodeName]) { + node = node[nodeName] + } else { + node = null + break + } + } + + if (node && node.appid && node.appsecret) { + return { + appid: node.appid, + secret: node.appsecret + } + } + + return null + } +} + +AppConfig.Support_Platforms = [PlatformType.WEIXIN_MP, PlatformType.WEIXIN_H5] + + +module.exports = { + AppConfig +}; diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js new file mode 100644 index 0000000..6da817b --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js @@ -0,0 +1,26 @@ +'use strict'; + +const TAG = "UNI_OPEN_BRIDGE" + +const HTTP_STATUS = { + SUCCESS: 200 +} + +const PlatformType = { + WEIXIN_MP: 'weixin-mp', + WEIXIN_H5: 'weixin-h5', + WEIXIN_APP: 'weixin-app', + WEIXIN_WEB: 'weixin-web', + QQ_MP: 'qq-mp', + QQ_APP: 'qq-app' +} + +const ErrorCodeType = { + SYSTEM_ERROR: TAG + "_SYSTEM_ERROR" +} + +module.exports = { + HTTP_STATUS, + PlatformType, + ErrorCodeType +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js new file mode 100644 index 0000000..f39b0af --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js @@ -0,0 +1,221 @@ +'use strict'; + +const { + PlatformType, + ErrorCodeType +} = require('./consts.js') + +const { + AppConfig +} = require('./config.js') + +const { + Storage, + Factory +} = require('./storage.js') + +const { + BridgeError +} = require('./bridge-error.js') + +const { + WeixinServer +} = require('./weixin-server.js') + +const appConfig = new AppConfig() + +class AccessToken extends Storage { + + constructor() { + super('access-token', ['dcloudAppid', 'platform']) + } + + async fallback(parameters) { + const oauthConfig = appConfig.get(parameters.dcloudAppid, parameters.platform) + let methodName + if (parameters.platform === PlatformType.WEIXIN_MP) { + methodName = 'GetMPAccessTokenData' + } else if (parameters.platform === PlatformType.WEIXIN_H5) { + methodName = 'GetH5AccessTokenData' + } else { + throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "platform invalid") + } + + const responseData = await WeixinServer[methodName](oauthConfig) + + const duration = responseData.expires_in || (60 * 60 * 2) + delete responseData.expires_in + + return { + value: responseData, + duration + } + } +} + +class UserAccessToken extends Storage { + + constructor() { + super('user-access-token', ['dcloudAppid', 'platform', 'openid']) + } +} + +class SessionKey extends Storage { + + constructor() { + super('session-key', ['dcloudAppid', 'platform', 'openid']) + } +} + +class Encryptkey extends Storage { + + constructor() { + super('encrypt-key', ['dcloudAppid', 'platform', 'openid']) + } + + getKeyString(key) { + return `${super.getKeyString(key)}-${key.version}` + } + + getExpiresIn(value) { + if (value <= 0) { + return 60 + } + return value + } + + async fallback(parameters) { + const accessToken = await Factory.Get(AccessToken, parameters) + const userSession = await Factory.Get(SessionKey, parameters) + + const responseData = await WeixinServer.GetUserEncryptKeyData({ + openid: parameters.openid, + access_token: accessToken.access_token, + session_key: userSession.session_key + }) + + const keyInfo = responseData.key_info_list.find((item) => { + return item.version = parameters.version + }) + + const value = { + encrypt_key: keyInfo.encrypt_key, + iv: keyInfo.iv + } + + return { + value, + duration: keyInfo.expire_in + } + } +} + +class Ticket extends Storage { + + constructor() { + super('ticket', ['dcloudAppid', 'platform']) + } + + async fallback(parameters) { + const accessToken = await Factory.Get(AccessToken, { + dcloudAppid: parameters.dcloudAppid, + platform: PlatformType.WEIXIN_H5 + }) + + const responseData = await WeixinServer.GetH5TicketData(accessToken) + + const duration = responseData.expires_in || (60 * 60 * 2) + delete responseData.expires_in + delete responseData.errcode + delete responseData.errmsg + + return { + value: responseData, + duration + } + } +} + + +// exports + +async function getAccessToken(key, fallback) { + return await Factory.Get(AccessToken, key, fallback) +} + +async function setAccessToken(key, value, expiresIn) { + await Factory.Set(AccessToken, key, value, expiresIn) +} + +async function removeAccessToken(key) { + await Factory.Remove(AccessToken, key) +} + +async function getUserAccessToken(key, fallback) { + return await Factory.Get(UserAccessToken, key, fallback) +} + +async function setUserAccessToken(key, value, expiresIn) { + await Factory.Set(UserAccessToken, key, value, expiresIn) +} + +async function removeUserAccessToken(key) { + await Factory.Remove(UserAccessToken, key) +} + +async function getSessionKey(key, fallback) { + return await Factory.Get(SessionKey, key, fallback) +} + +async function setSessionKey(key, value, expiresIn) { + await Factory.Set(SessionKey, key, value, expiresIn) +} + +async function removeSessionKey(key) { + await Factory.Remove(SessionKey, key) +} + +async function getEncryptKey(key, fallback) { + return await Factory.Get(Encryptkey, key, fallback) +} + +async function setEncryptKey(key, value, expiresIn) { + await Factory.Set(Encryptkey, key, value, expiresIn) +} + +async function removeEncryptKey(key) { + await Factory.Remove(Encryptkey, key) +} + +async function getTicket(key, fallback) { + return await Factory.Get(Ticket, key, fallback) +} + +async function setTicket(key, value, expiresIn) { + await Factory.Set(Ticket, key, value, expiresIn) +} + +async function removeTicket(key) { + await Factory.Remove(Ticket, key) +} + +module.exports = { + getAccessToken, + setAccessToken, + removeAccessToken, + getUserAccessToken, + setUserAccessToken, + removeUserAccessToken, + getSessionKey, + setSessionKey, + removeSessionKey, + getEncryptKey, + setEncryptKey, + removeEncryptKey, + getTicket, + setTicket, + removeTicket, + PlatformType, + WeixinServer, + ErrorCodeType +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/index.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/index.js new file mode 100644 index 0000000..00ba62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/node_modules/uni-config-center/index.js @@ -0,0 +1 @@ +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t { + keyArray.push(key[name]) + }) + keyArray.push(this._type) + return keyArray.join(':') + } + + getValue(value) { + return value + } + + getExpiresIn(value) { + if (value !== undefined) { + return value + } + return -1 + } + + validateKey(key) { + Validator.Key(this._keys, key) + } + + validateValue(value) { + Validator.Value(value) + } + + create(key, fallback) { + const keyString = this.getKeyString(key) + const options = { + layers: [{ + type: 'database', + key: keyString + }, { + type: 'redis', + key: keyString + }] + } + if (fallback !== null) { + const fallbackFunction = fallback || this.fallback + if (fallbackFunction) { + options.fallback = async () => { + return await fallbackFunction(key) + } + } + } + return new CacheKeyCascade(options) + } +} +Storage.Prefix = "uni-id" + +const Factory = { + + async Get(T, key, fallback) { + return await Factory.MakeUnique(T).get(key, fallback) + }, + + async Set(T, key, value, expiresIn) { + await Factory.MakeUnique(T).set(key, value, expiresIn) + }, + + async Remove(T, key) { + await Factory.MakeUnique(T).remove(key) + }, + + MakeUnique(T) { + return new T() + } +} + +module.exports = { + Storage, + Factory +}; diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js new file mode 100644 index 0000000..2e4286b --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js @@ -0,0 +1,324 @@ +const db = uniCloud.database() + +function getType(value) { + return Object.prototype.toString.call(value).slice(8, -1).toLowerCase() +} + +const validator = { + key: function(value) { + const err = new Error('Invalid key') + if (typeof value !== 'string') { + throw err + } + const valueTrim = value.trim() + if (!valueTrim || valueTrim !== value) { + throw err + } + }, + value: function(value) { + // 仅作简单校验 + const type = getType(value) + const validValueType = ['null', 'number', 'string', 'array', 'object'] + if (validValueType.indexOf(type) === -1) { + throw new Error('Invalid value type') + } + }, + duration: function(value) { + const err = new Error('Invalid duration') + if (value === undefined) { + return + } + if (typeof value !== 'number' || value === 0) { + throw err + } + } +} + +/** + * 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示 + * 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在 + */ +class DatabaseCache { + constructor({ + collection = 'opendb-open-data' + } = {}) { + this.type = 'db' + this.collection = db.collection(collection) + } + + _serializeValue(value) { + return value === undefined ? null : JSON.stringify(value) + } + + _deserializeValue(value) { + return value ? JSON.parse(value) : value + } + + async set(key, value, duration) { + validator.key(key) + validator.value(value) + validator.duration(duration) + value = this._serializeValue(value) + await this.collection.doc(key).set({ + value, + expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1 + }) + } + + async _getWithDuration(key) { + const getKeyRes = await this.collection.doc(key).get() + const record = getKeyRes.data[0] + if (!record) { + return { + value: null, + duration: -2 + } + } + const value = this._deserializeValue(record.value) + const expired = record.expired + if (expired === -1) { + return { + value, + duration: -1 + } + } + const duration = expired - Date.now() + if (duration <= 0) { + await this.remove(key) + return { + value: null, + duration: -2 + } + } + return { + value, + duration: Math.floor(duration / 1000) + } + } + + async get(key, { + withDuration = true + } = {}) { + const result = await this._getWithDuration(key) + if (!withDuration) { + delete result.duration + } + return result + } + + async remove(key) { + await this.collection.doc(key).remove() + } +} + +class RedisCache { + constructor() { + this.type = 'redis' + this.redis = uniCloud.redis() + } + + _serializeValue(value) { + return value === undefined ? null : JSON.stringify(value) + } + + _deserializeValue(value) { + return value ? JSON.parse(value) : value + } + + async set(key, value, duration) { + validator.key(key) + validator.value(value) + validator.duration(duration) + value = this._serializeValue(value) + if (!duration || duration === -1) { + await this.redis.set(key, value) + } else { + await this.redis.set(key, value, 'EX', duration) + } + } + + async get(key, { + withDuration = false + } = {}) { + let value = await this.redis.get(key) + value = this._deserializeValue(value) + if (!withDuration) { + return { + value + } + } + const durationSecond = await this.redis.ttl(key) + let duration + switch (durationSecond) { + case -1: + duration = -1 + break + case -2: + duration = -2 + break + default: + duration = durationSecond + break + } + return { + value, + duration + } + } + + async remove(key) { + await this.redis.del(key) + } +} + +class Cache { + constructor({ + type, + collection + } = {}) { + if (type === 'database') { + return new DatabaseCache({ + collection + }) + } else if (type === 'redis') { + return new RedisCache() + } else { + throw new Error('Invalid cache type') + } + } +} + +class CacheKey { + constructor({ + type, + collection, + cache, + key, + fallback + } = {}) { + this.cache = cache || new Cache({ + type, + collection + }) + this.key = key + this.fallback = fallback + } + + async set(value, duration) { + await this.cache.set(this.key, value, duration) + } + + async setWithSync(value, duration, syncMethod) { + await Promise.all([ + this.set(this.key, value, duration), + syncMethod(value, duration) + ]) + } + + async get() { + let { + value, + duration + } = await this.cache.get(this.key) + if (value !== null && value !== undefined) { + return { + value, + duration + } + } + if (!this.fallback) { + return { + value: null, + duration: -2 + } + } + const fallbackResult = await this.fallback() + value = fallbackResult.value + duration = fallbackResult.duration + if (value !== null && duration !== undefined) { + await this.cache.set(this.key, value, duration) + } + return { + value, + duration + } + } + + async remove() { + await this.cache.remove(this.key) + } +} + +class CacheKeyCascade { + constructor({ + layers, // [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey] + fallback + } = {}) { + this.layers = layers + this.cacheLayers = [] + let lastCacheKey + for (let i = 0; i < layers.length; i++) { + const { + type, + cache, + collection, + key + } = layers[i] + const lastCacheKeyTemp = lastCacheKey + try { + const currentCacheKey = new CacheKey({ + type, + collection, + cache, + key, + fallback: i === 0 ? fallback : function() { + return lastCacheKeyTemp.get() + } + }) + this.cacheLayers.push(currentCacheKey) + lastCacheKey = currentCacheKey + } catch (e) {} + } + this.highLevelCache = lastCacheKey + } + + async set(value, duration) { + return Promise.all( + this.cacheLayers.map(item => { + return item.set(value, duration) + }) + ) + } + + async setWithSync(value, duration, syncMethod) { + const setPromise = this.cacheLayers.map(item => { + return item.set(value, duration) + }) + return Promise.all( + [ + ...setPromise, + syncMethod(value, duration) + ] + ) + } + + async get() { + return this.highLevelCache.get() + } + + async remove() { + await Promise.all( + this.cacheLayers.map(cacheKeyItem => { + return cacheKeyItem.remove() + }) + ) + } +} + +module.exports = { + Cache, + DatabaseCache, + RedisCache, + CacheKey, + CacheKeyCascade +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js new file mode 100644 index 0000000..47a455b --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js @@ -0,0 +1,31 @@ +const Validator = { + + Key(keyArray, parameters) { + for (let i = 0; i < keyArray.length; i++) { + const keyName = keyArray[i] + if (typeof parameters[keyName] !== 'string') { + Validator.ThrowNewError(`Invalid ${keyName}`) + } + if (parameters[keyName].length < 1) { + Validator.ThrowNewError(`Invalid ${keyName}`) + } + } + }, + + Value(value) { + if (value === undefined) { + Validator.ThrowNewError('Invalid Value') + } + if (typeof value !== 'object') { + Validator.ThrowNewError('Invalid Value Type') + } + }, + + ThrowNewError(message) { + throw new Error(message) + } +} + +module.exports = { + Validator +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js new file mode 100644 index 0000000..0a0c811 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js @@ -0,0 +1,202 @@ +'use strict'; + +const crypto = require('crypto') + +const { + HTTP_STATUS +} = require('./consts.js') + +const { + BridgeError +} = require('./bridge-error.js') + +class WeixinServer { + + constructor(options = {}) { + this._appid = options.appid + this._secret = options.secret + } + + getAccessToken() { + return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, { + dataType: 'json', + method: 'POST', + data: { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + } + }) + } + + // 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次 + codeToSession(code) { + return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, { + dataType: 'json', + data: { + appid: this._appid, + secret: this._secret, + js_code: code, + grant_type: 'authorization_code' + } + }) + } + + getUserEncryptKey({ + access_token, + openid, + session_key + }) { + console.log(access_token, openid, session_key); + const signature = crypto.createHmac('sha256', session_key).update('').digest('hex') + return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, { + dataType: 'json', + method: 'POST', + dataAsQueryString: true, + data: { + access_token, + openid: openid, + signature: signature, + sig_method: 'hmac_sha256' + } + }) + } + + getH5AccessToken() { + return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, { + dataType: 'json', + method: 'GET', + data: { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + } + }) + } + + getH5Ticket(access_token) { + return uniCloud.httpclient.request(WeixinServer.Ticket_Url, { + dataType: 'json', + dataAsQueryString: true, + method: 'POST', + data: { + access_token + } + }) + } + + getH5AccessTokenForEip() { + return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, { + appid: this._appid, + secret: this._secret, + grant_type: "client_credential" + }, { + dataType: 'json' + }) + } + + getH5TicketForEip(access_token) { + return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, { + access_token + }, { + dataType: 'json', + dataAsQueryString: true + }) + } +} + +WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/token' +WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session' +WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey' +WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token' +WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi' + +WeixinServer.GetMPAccessToken = function(options) { + return new WeixinServer(options).getAccessToken() +} + +WeixinServer.GetCodeToSession = function(options) { + return new WeixinServer(options).codeToSession(options.code) +} + +WeixinServer.GetUserEncryptKey = function(options) { + return new WeixinServer(options).getUserEncryptKey(options) +} + +WeixinServer.GetH5AccessToken = function(options) { + return new WeixinServer(options).getH5AccessToken() +} + +WeixinServer.GetH5Ticket = function(options) { + return new WeixinServer(options).getH5Ticket(options.access_token) +} + +//////////////////////////////////////////////////////////////// + +function isAliyun() { + return (uniCloud.getCloudInfos()[0].provider === 'aliyun') +} + +WeixinServer.GetResponseData = function(response) { + console.log("WeixinServer::response", response) + + if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) { + throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue) + } + + const responseData = response.data || response.body + + if (responseData.errcode !== undefined && responseData.errcode !== 0) { + throw new BridgeError(responseData.errcode, responseData.errmsg) + } + + return responseData +} + +WeixinServer.GetMPAccessTokenData = async function(options) { + const response = await new WeixinServer(options).getAccessToken() + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetCodeToSessionData = async function(options) { + const response = await new WeixinServer(options).codeToSession(options.code) + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetUserEncryptKeyData = async function(options) { + const response = await new WeixinServer(options).getUserEncryptKey(options) + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetH5AccessTokenData = async function(options) { + const ws = new WeixinServer(options) + let response + if (isAliyun()) { + response = await ws.getH5AccessTokenForEip() + if (typeof response === 'string') { + response = JSON.parse(response) + } + } else { + response = await ws.getH5AccessToken() + } + return WeixinServer.GetResponseData(response) +} + +WeixinServer.GetH5TicketData = async function(options) { + const ws = new WeixinServer(options) + let response + if (isAliyun()) { + response = await ws.getH5TicketForEip(options.access_token) + if (typeof response === 'string') { + response = JSON.parse(response) + } + } else { + response = await ws.getH5Ticket(options.access_token) + } + return WeixinServer.GetResponseData(response) +} + + +module.exports = { + WeixinServer +} diff --git a/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json new file mode 100644 index 0000000..9fc8bf9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json @@ -0,0 +1,19 @@ +// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema +{ + "bsonType": "object", + "required": ["_id", "value"], + "properties": { + "_id": { + "bsonType": "string", + "description": "key,格式:uni-id:[dcloudAppid]:[platform]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]" + }, + "value": { + "bsonType": "object", + "description": "字段_id对应的值" + }, + "expired": { + "bsonType": "date", + "description": "过期时间" + } + } +} diff --git a/alpha/admin/uni_modules/uni-pagination/changelog.md b/alpha/admin/uni_modules/uni-pagination/changelog.md new file mode 100644 index 0000000..2e94adc --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/changelog.md @@ -0,0 +1,27 @@ +## 1.2.4(2022-09-19) +- 修复,未对主题色设置默认色,导致未引入 uni-scss 变量文件报错。 +- 修复,未对移动端当前页文字做主题色适配。 +## 1.2.3(2022-09-15) +- 修复未使用 uni-scss 主题色的 bug。 +## 1.2.2(2022-07-06) +- 修复 es 语言 i18n 错误 +## 1.2.1(2021-11-22) +- 修复 vue3中某些scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-pagination](https://uniapp.dcloud.io/component/uniui/uni-pagination) +## 1.1.2(2021-10-08) +- 修复 current 、value 属性未监听,导致高亮样式失效的 bug +## 1.1.1(2021-08-20) +- 新增 支持国际化 +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-04-12) +- 新增 PC 和 移动端适配不同的 ui +## 1.0.5(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 + +## 1.0.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json new file mode 100644 index 0000000..d6e2897 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json @@ -0,0 +1,5 @@ +{ + "uni-pagination.prevText": "prev", + "uni-pagination.nextText": "next", + "uni-pagination.piecePerPage": "piece/page" +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json new file mode 100644 index 0000000..604a113 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json @@ -0,0 +1,5 @@ +{ + "uni-pagination.prevText": "anterior", + "uni-pagination.nextText": "prxima", + "uni-pagination.piecePerPage": "Artculo/Pgina" +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json new file mode 100644 index 0000000..a7a0c77 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json @@ -0,0 +1,5 @@ +{ + "uni-pagination.prevText": "précédente", + "uni-pagination.nextText": "suivante", + "uni-pagination.piecePerPage": "Articles/Pages" +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js new file mode 100644 index 0000000..2469dd0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js @@ -0,0 +1,12 @@ +import en from './en.json' +import es from './es.json' +import fr from './fr.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + es, + fr, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json new file mode 100644 index 0000000..782bbe4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json @@ -0,0 +1,5 @@ +{ + "uni-pagination.prevText": "上一页", + "uni-pagination.nextText": "下一页", + "uni-pagination.piecePerPage": "条/页" +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json new file mode 100644 index 0000000..180fddb --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json @@ -0,0 +1,5 @@ +{ + "uni-pagination.prevText": "上一頁", + "uni-pagination.nextText": "下一頁", + "uni-pagination.piecePerPage": "條/頁" +} diff --git a/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue new file mode 100644 index 0000000..5305b5f --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue @@ -0,0 +1,465 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-pagination/package.json b/alpha/admin/uni_modules/uni-pagination/package.json new file mode 100644 index 0000000..862d5ab --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-pagination", + "displayName": "uni-pagination 分页器", + "version": "1.2.4", + "description": "Pagination 分页器组件,用于展示页码、请求数据等。", + "keywords": [ + "uni-ui", + "uniui", + "分页器", + "页码" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss","uni-icons"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-pagination/readme.md b/alpha/admin/uni_modules/uni-pagination/readme.md new file mode 100644 index 0000000..97ea1d6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-pagination/readme.md @@ -0,0 +1,11 @@ + + +## Pagination 分页器 +> **组件名:uni-pagination** +> 代码块: `uPagination` + + +分页器组件,用于展示页码、请求数据等。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-pagination) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 diff --git a/alpha/admin/uni_modules/uni-popup/changelog.md b/alpha/admin/uni_modules/uni-popup/changelog.md new file mode 100644 index 0000000..511915d --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/changelog.md @@ -0,0 +1,64 @@ +## 1.8.1(2022-12-01) +- 修复 nvue 下 v-show 报错 +## 1.8.0(2022-11-29) +- 优化 主题样式 +## 1.7.9(2022-04-02) +- 修复 弹出层内部无法滚动的bug +## 1.7.8(2022-03-28) +- 修复 小程序中高度错误的bug +## 1.7.7(2022-03-17) +- 修复 快速调用open出现问题的Bug +## 1.7.6(2022-02-14) +- 修复 safeArea 属性不能设置为false的bug +## 1.7.5(2022-01-19) +- 修复 isMaskClick 失效的bug +## 1.7.4(2022-01-19) +- 新增 cancelText \ confirmText 属性 ,可自定义文本 +- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色 +- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题 +## 1.7.3(2022-01-13) +- 修复 设置 safeArea 属性不生效的bug +## 1.7.2(2021-11-26) +- 优化 组件示例 +## 1.7.1(2021-11-26) +- 修复 vuedoc 文字错误 +## 1.7.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup) +## 1.6.2(2021-08-24) +- 新增 支持国际化 +## 1.6.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.6.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.5.0(2021-06-23) +- 新增 mask-click 遮罩层点击事件 +## 1.4.5(2021-06-22) +- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug +## 1.4.4(2021-06-18) +- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug +## 1.4.3(2021-06-08) +- 修复 错误的 watch 字段 +- 修复 safeArea 属性不生效的问题 +- 修复 点击内容,再点击遮罩无法关闭的Bug +## 1.4.2(2021-05-12) +- 新增 组件示例地址 +## 1.4.1(2021-04-29) +- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题 +## 1.4.0 (2021-04-29) +- 新增 type 属性的 left\right 值,支持左右弹出 +- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗 +- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色 +- 新增 safeArea 属性,是否适配底部安全区 +- 修复 App\h5\微信小程序底部安全区占位不对的Bug +- 修复 App 端弹出等待的Bug +- 优化 提升低配设备性能,优化动画卡顿问题 +- 优化 更简单的组件自定义方式 +## 1.2.9(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 1.2.8(2021-02-05) +- 调整为uni_modules目录规范 +## 1.2.7(2021-02-05) +- 调整为uni_modules目录规范 +- 新增 支持 PC 端 +- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端 diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js new file mode 100644 index 0000000..6ef26a2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + this.$once('hook:beforeDestroy', () => { + document.removeEventListener('keyup', listener) + }) + }, + render: () => {} +} +// #endif diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue b/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue new file mode 100644 index 0000000..86e12cd --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue @@ -0,0 +1,276 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue b/alpha/admin/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue new file mode 100644 index 0000000..91370a8 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue @@ -0,0 +1,143 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue b/alpha/admin/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue new file mode 100644 index 0000000..5be7624 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue @@ -0,0 +1,187 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/en.json b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/en.json new file mode 100644 index 0000000..7f1bd06 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/en.json @@ -0,0 +1,7 @@ +{ + "uni-popup.cancel": "cancel", + "uni-popup.ok": "ok", + "uni-popup.placeholder": "pleace enter", + "uni-popup.title": "Hint", + "uni-popup.shareTitle": "Share to" +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/index.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json new file mode 100644 index 0000000..5e3003c --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json @@ -0,0 +1,7 @@ +{ + "uni-popup.cancel": "取消", + "uni-popup.ok": "确定", + "uni-popup.placeholder": "请输入", + "uni-popup.title": "提示", + "uni-popup.shareTitle": "分享到" +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json new file mode 100644 index 0000000..13e39eb --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json @@ -0,0 +1,7 @@ +{ + "uni-popup.cancel": "取消", + "uni-popup.ok": "確定", + "uni-popup.placeholder": "請輸入", + "uni-popup.title": "提示", + "uni-popup.shareTitle": "分享到" +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/keypress.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup/keypress.js new file mode 100644 index 0000000..62dda46 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + // this.$once('hook:beforeDestroy', () => { + // document.removeEventListener('keyup', listener) + // }) + }, + render: () => {} +} +// #endif diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/message.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup/message.js new file mode 100644 index 0000000..0ff9a02 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/message.js @@ -0,0 +1,22 @@ +export default { + created() { + if (this.type === 'message') { + // 不显示遮罩 + this.maskShow = false + // 获取子组件对象 + this.childrenMsg = null + } + }, + methods: { + customOpen() { + if (this.childrenMsg) { + this.childrenMsg.open() + } + }, + customClose() { + if (this.childrenMsg) { + this.childrenMsg.close() + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/popup.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup/popup.js new file mode 100644 index 0000000..c4e5781 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/popup.js @@ -0,0 +1,26 @@ + +export default { + data() { + return { + + } + }, + created(){ + this.popup = this.getParent() + }, + methods:{ + /** + * 获取父元素实例 + */ + getParent(name = 'uniPopup') { + let parent = this.$parent; + let parentName = parent.$options.name; + while (parentName !== name) { + parent = parent.$parent; + if (!parent) return false + parentName = parent.$options.name; + } + return parent; + }, + } +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/share.js b/alpha/admin/uni_modules/uni-popup/components/uni-popup/share.js new file mode 100644 index 0000000..462bb83 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/share.js @@ -0,0 +1,16 @@ +export default { + created() { + if (this.type === 'share') { + // 关闭点击 + this.mkclick = false + } + }, + methods: { + customOpen() { + console.log('share 打开了'); + }, + customClose() { + console.log('share 关闭了'); + } + } +} diff --git a/alpha/admin/uni_modules/uni-popup/components/uni-popup/uni-popup.vue b/alpha/admin/uni_modules/uni-popup/components/uni-popup/uni-popup.vue new file mode 100644 index 0000000..db90c59 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/components/uni-popup/uni-popup.vue @@ -0,0 +1,474 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-popup/package.json b/alpha/admin/uni_modules/uni-popup/package.json new file mode 100644 index 0000000..6f5f72e --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-popup", + "displayName": "uni-popup 弹出层", + "version": "1.8.1", + "description": " Popup 组件,提供常用的弹层", + "keywords": [ + "uni-ui", + "弹出层", + "弹窗", + "popup", + "弹框" + ], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-popup/readme.md b/alpha/admin/uni_modules/uni-popup/readme.md new file mode 100644 index 0000000..fdad4b3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-popup/readme.md @@ -0,0 +1,17 @@ + + +## Popup 弹出层 +> **组件名:uni-popup** +> 代码块: `uPopup` +> 关联组件:`uni-transition` + + +弹出层组件,在应用中弹出一个消息提示窗口、提示框等 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + + + + diff --git a/alpha/admin/uni_modules/uni-scss/changelog.md b/alpha/admin/uni_modules/uni-scss/changelog.md new file mode 100644 index 0000000..b863bb0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/changelog.md @@ -0,0 +1,8 @@ +## 1.0.3(2022-01-21) +- 优化 组件示例 +## 1.0.2(2021-11-22) +- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题 +## 1.0.1(2021-11-22) +- 修复 vue3中scss语法兼容问题 +## 1.0.0(2021-11-18) +- init diff --git a/alpha/admin/uni_modules/uni-scss/index.scss b/alpha/admin/uni_modules/uni-scss/index.scss new file mode 100644 index 0000000..1744a5f --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/index.scss @@ -0,0 +1 @@ +@import './styles/index.scss'; diff --git a/alpha/admin/uni_modules/uni-scss/package.json b/alpha/admin/uni_modules/uni-scss/package.json new file mode 100644 index 0000000..7cc0ccb --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/package.json @@ -0,0 +1,82 @@ +{ + "id": "uni-scss", + "displayName": "uni-scss 辅助样式", + "version": "1.0.3", + "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。", + "keywords": [ + "uni-scss", + "uni-ui", + "辅助样式" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "n", + "联盟": "n" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-scss/readme.md b/alpha/admin/uni_modules/uni-scss/readme.md new file mode 100644 index 0000000..b7d1c25 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/readme.md @@ -0,0 +1,4 @@ +`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-scss/styles/index.scss b/alpha/admin/uni_modules/uni-scss/styles/index.scss new file mode 100644 index 0000000..ffac4fe --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/index.scss @@ -0,0 +1,7 @@ +@import './setting/_variables.scss'; +@import './setting/_border.scss'; +@import './setting/_color.scss'; +@import './setting/_space.scss'; +@import './setting/_radius.scss'; +@import './setting/_text.scss'; +@import './setting/_styles.scss'; diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_border.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_border.scss new file mode 100644 index 0000000..12a11c3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_border.scss @@ -0,0 +1,3 @@ +.uni-border { + border: 1px $uni-border-1 solid; +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_color.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_color.scss new file mode 100644 index 0000000..1ededd9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_color.scss @@ -0,0 +1,66 @@ + +// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐 +// @mixin get-styles($k,$c) { +// @if $k == size or $k == weight{ +// font-#{$k}:#{$c} +// }@else{ +// #{$k}:#{$c} +// } +// } +$uni-ui-color:( + // 主色 + primary: $uni-primary, + primary-disable: $uni-primary-disable, + primary-light: $uni-primary-light, + // 辅助色 + success: $uni-success, + success-disable: $uni-success-disable, + success-light: $uni-success-light, + warning: $uni-warning, + warning-disable: $uni-warning-disable, + warning-light: $uni-warning-light, + error: $uni-error, + error-disable: $uni-error-disable, + error-light: $uni-error-light, + info: $uni-info, + info-disable: $uni-info-disable, + info-light: $uni-info-light, + // 中性色 + main-color: $uni-main-color, + base-color: $uni-base-color, + secondary-color: $uni-secondary-color, + extra-color: $uni-extra-color, + // 背景色 + bg-color: $uni-bg-color, + // 边框颜色 + border-1: $uni-border-1, + border-2: $uni-border-2, + border-3: $uni-border-3, + border-4: $uni-border-4, + // 黑色 + black:$uni-black, + // 白色 + white:$uni-white, + // 透明 + transparent:$uni-transparent +) !default; +@each $key, $child in $uni-ui-color { + .uni-#{"" + $key} { + color: $child; + } + .uni-#{"" + $key}-bg { + background-color: $child; + } +} +.uni-shadow-sm { + box-shadow: $uni-shadow-sm; +} +.uni-shadow-base { + box-shadow: $uni-shadow-base; +} +.uni-shadow-lg { + box-shadow: $uni-shadow-lg; +} +.uni-mask { + background-color:$uni-mask; +} diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_radius.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_radius.scss new file mode 100644 index 0000000..9a0428b --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_radius.scss @@ -0,0 +1,55 @@ +@mixin radius($r,$d:null ,$important: false){ + $radius-value:map-get($uni-radius, $r) if($important, !important, null); + // Key exists within the $uni-radius variable + @if (map-has-key($uni-radius, $r) and $d){ + @if $d == t { + border-top-left-radius:$radius-value; + border-top-right-radius:$radius-value; + }@else if $d == r { + border-top-right-radius:$radius-value; + border-bottom-right-radius:$radius-value; + }@else if $d == b { + border-bottom-left-radius:$radius-value; + border-bottom-right-radius:$radius-value; + }@else if $d == l { + border-top-left-radius:$radius-value; + border-bottom-left-radius:$radius-value; + }@else if $d == tl { + border-top-left-radius:$radius-value; + }@else if $d == tr { + border-top-right-radius:$radius-value; + }@else if $d == br { + border-bottom-right-radius:$radius-value; + }@else if $d == bl { + border-bottom-left-radius:$radius-value; + } + }@else{ + border-radius:$radius-value; + } +} + +@each $key, $child in $uni-radius { + @if($key){ + .uni-radius-#{"" + $key} { + @include radius($key) + } + }@else{ + .uni-radius { + @include radius($key) + } + } +} + +@each $direction in t, r, b, l,tl, tr, br, bl { + @each $key, $child in $uni-radius { + @if($key){ + .uni-radius-#{"" + $direction}-#{"" + $key} { + @include radius($key,$direction,false) + } + }@else{ + .uni-radius-#{$direction} { + @include radius($key,$direction,false) + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_space.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_space.scss new file mode 100644 index 0000000..3c89528 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_space.scss @@ -0,0 +1,56 @@ + +@mixin fn($space,$direction,$size,$n) { + @if $n { + #{$space}-#{$direction}: #{$size*$uni-space-root}px + } @else { + #{$space}-#{$direction}: #{-$size*$uni-space-root}px + } +} +@mixin get-styles($direction,$i,$space,$n){ + @if $direction == t { + @include fn($space, top,$i,$n); + } + @if $direction == r { + @include fn($space, right,$i,$n); + } + @if $direction == b { + @include fn($space, bottom,$i,$n); + } + @if $direction == l { + @include fn($space, left,$i,$n); + } + @if $direction == x { + @include fn($space, left,$i,$n); + @include fn($space, right,$i,$n); + } + @if $direction == y { + @include fn($space, top,$i,$n); + @include fn($space, bottom,$i,$n); + } + @if $direction == a { + @if $n { + #{$space}:#{$i*$uni-space-root}px; + } @else { + #{$space}:#{-$i*$uni-space-root}px; + } + } +} + +@each $orientation in m,p { + $space: margin; + @if $orientation == m { + $space: margin; + } @else { + $space: padding; + } + @for $i from 0 through 16 { + @each $direction in t, r, b, l, x, y, a { + .uni-#{$orientation}#{$direction}-#{$i} { + @include get-styles($direction,$i,$space,true); + } + .uni-#{$orientation}#{$direction}-n#{$i} { + @include get-styles($direction,$i,$space,false); + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_styles.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_styles.scss new file mode 100644 index 0000000..689afec --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_styles.scss @@ -0,0 +1,167 @@ +/* #ifndef APP-NVUE */ + +$-color-white:#fff; +$-color-black:#000; +@mixin base-style($color) { + color: #fff; + background-color: $color; + border-color: mix($-color-black, $color, 8%); + &:not([hover-class]):active { + background: mix($-color-black, $color, 10%); + border-color: mix($-color-black, $color, 20%); + color: $-color-white; + outline: none; + } +} +@mixin is-color($color) { + @include base-style($color); + &[loading] { + @include base-style($color); + &::before { + margin-right:5px; + } + } + &[disabled] { + &, + &[loading], + &:not([hover-class]):active { + color: $-color-white; + border-color: mix(darken($color,10%), $-color-white); + background-color: mix($color, $-color-white); + } + } + +} +@mixin base-plain-style($color) { + color:$color; + background-color: mix($-color-white, $color, 90%); + border-color: mix($-color-white, $color, 70%); + &:not([hover-class]):active { + background: mix($-color-white, $color, 80%); + color: $color; + outline: none; + border-color: mix($-color-white, $color, 50%); + } +} +@mixin is-plain($color){ + &[plain] { + @include base-plain-style($color); + &[loading] { + @include base-plain-style($color); + &::before { + margin-right:5px; + } + } + &[disabled] { + &, + &:active { + color: mix($-color-white, $color, 40%); + background-color: mix($-color-white, $color, 90%); + border-color: mix($-color-white, $color, 80%); + } + } + } +} + + +.uni-btn { + margin: 5px; + color: #393939; + border:1px solid #ccc; + font-size: 16px; + font-weight: 200; + background-color: #F9F9F9; + // TODO 暂时处理边框隐藏一边的问题 + overflow: visible; + &::after{ + border: none; + } + + &:not([type]),&[type=default] { + color: #999; + &[loading] { + background: none; + &::before { + margin-right:5px; + } + } + + + + &[disabled]{ + color: mix($-color-white, #999, 60%); + &, + &[loading], + &:active { + color: mix($-color-white, #999, 60%); + background-color: mix($-color-white,$-color-black , 98%); + border-color: mix($-color-white, #999, 85%); + } + } + + &[plain] { + color: #999; + background: none; + border-color: $uni-border-1; + &:not([hover-class]):active { + background: none; + color: mix($-color-white, $-color-black, 80%); + border-color: mix($-color-white, $-color-black, 90%); + outline: none; + } + &[disabled]{ + &, + &[loading], + &:active { + background: none; + color: mix($-color-white, #999, 60%); + border-color: mix($-color-white, #999, 85%); + } + } + } + } + + &:not([hover-class]):active { + color: mix($-color-white, $-color-black, 50%); + } + + &[size=mini] { + font-size: 16px; + font-weight: 200; + border-radius: 8px; + } + + + + &.uni-btn-small { + font-size: 14px; + } + &.uni-btn-mini { + font-size: 12px; + } + + &.uni-btn-radius { + border-radius: 999px; + } + &[type=primary] { + @include is-color($uni-primary); + @include is-plain($uni-primary) + } + &[type=success] { + @include is-color($uni-success); + @include is-plain($uni-success) + } + &[type=error] { + @include is-color($uni-error); + @include is-plain($uni-error) + } + &[type=warning] { + @include is-color($uni-warning); + @include is-plain($uni-warning) + } + &[type=info] { + @include is-color($uni-info); + @include is-plain($uni-info) + } +} +/* #endif */ diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_text.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_text.scss new file mode 100644 index 0000000..a34d08f --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_text.scss @@ -0,0 +1,24 @@ +@mixin get-styles($k,$c) { + @if $k == size or $k == weight{ + font-#{$k}:#{$c} + }@else{ + #{$k}:#{$c} + } +} + +@each $key, $child in $uni-headings { + /* #ifndef APP-NVUE */ + .uni-#{$key} { + @each $k, $c in $child { + @include get-styles($k,$c) + } + } + /* #endif */ + /* #ifdef APP-NVUE */ + .container .uni-#{$key} { + @each $k, $c in $child { + @include get-styles($k,$c) + } + } + /* #endif */ +} diff --git a/alpha/admin/uni_modules/uni-scss/styles/setting/_variables.scss b/alpha/admin/uni_modules/uni-scss/styles/setting/_variables.scss new file mode 100644 index 0000000..557d3d7 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/setting/_variables.scss @@ -0,0 +1,146 @@ +// @use "sass:math"; +@import '../tools/functions.scss'; +// 间距基础倍数 +$uni-space-root: 2 !default; +// 边框半径默认值 +$uni-radius-root:5px !default; +$uni-radius: () !default; +// 边框半径断点 +$uni-radius: map-deep-merge( + ( + 0: 0, + // TODO 当前版本暂时不支持 sm 属性 + // 'sm': math.div($uni-radius-root, 2), + null: $uni-radius-root, + 'lg': $uni-radius-root * 2, + 'xl': $uni-radius-root * 6, + 'pill': 9999px, + 'circle': 50% + ), + $uni-radius +); +// 字体家族 +$body-font-family: 'Roboto', sans-serif !default; +// 文本 +$heading-font-family: $body-font-family !default; +$uni-headings: () !default; +$letterSpacing: -0.01562em; +$uni-headings: map-deep-merge( + ( + 'h1': ( + size: 32px, + weight: 300, + line-height: 50px, + // letter-spacing:-0.01562em + ), + 'h2': ( + size: 28px, + weight: 300, + line-height: 40px, + // letter-spacing: -0.00833em + ), + 'h3': ( + size: 24px, + weight: 400, + line-height: 32px, + // letter-spacing: normal + ), + 'h4': ( + size: 20px, + weight: 400, + line-height: 30px, + // letter-spacing: 0.00735em + ), + 'h5': ( + size: 16px, + weight: 400, + line-height: 24px, + // letter-spacing: normal + ), + 'h6': ( + size: 14px, + weight: 500, + line-height: 18px, + // letter-spacing: 0.0125em + ), + 'subtitle': ( + size: 12px, + weight: 400, + line-height: 20px, + // letter-spacing: 0.00937em + ), + 'body': ( + font-size: 14px, + font-weight: 400, + line-height: 22px, + // letter-spacing: 0.03125em + ), + 'caption': ( + 'size': 12px, + 'weight': 400, + 'line-height': 20px, + // 'letter-spacing': 0.03333em, + // 'text-transform': false + ) + ), + $uni-headings +); + + + +// 主色 +$uni-primary: #2979ff !default; +$uni-primary-disable:lighten($uni-primary,20%) !default; +$uni-primary-light: lighten($uni-primary,25%) !default; + +// 辅助色 +// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 +$uni-success: #18bc37 !default; +$uni-success-disable:lighten($uni-success,20%) !default; +$uni-success-light: lighten($uni-success,25%) !default; + +$uni-warning: #f3a73f !default; +$uni-warning-disable:lighten($uni-warning,20%) !default; +$uni-warning-light: lighten($uni-warning,25%) !default; + +$uni-error: #e43d33 !default; +$uni-error-disable:lighten($uni-error,20%) !default; +$uni-error-light: lighten($uni-error,25%) !default; + +$uni-info: #8f939c !default; +$uni-info-disable:lighten($uni-info,20%) !default; +$uni-info-light: lighten($uni-info,25%) !default; + +// 中性色 +// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 +$uni-main-color: #3a3a3a !default; // 主要文字 +$uni-base-color: #6a6a6a !default; // 常规文字 +$uni-secondary-color: #909399 !default; // 次要文字 +$uni-extra-color: #c7c7c7 !default; // 辅助说明 + +// 边框颜色 +$uni-border-1: #F0F0F0 !default; +$uni-border-2: #EDEDED !default; +$uni-border-3: #DCDCDC !default; +$uni-border-4: #B9B9B9 !default; + +// 常规色 +$uni-black: #000000 !default; +$uni-white: #ffffff !default; +$uni-transparent: rgba($color: #000000, $alpha: 0) !default; + +// 背景色 +$uni-bg-color: #f7f7f7 !default; + +/* 水平间距 */ +$uni-spacing-sm: 8px !default; +$uni-spacing-base: 15px !default; +$uni-spacing-lg: 30px !default; + +// 阴影 +$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default; +$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default; +$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default; + +// 蒙版 +$uni-mask: rgba($color: #000000, $alpha: 0.4) !default; diff --git a/alpha/admin/uni_modules/uni-scss/styles/tools/functions.scss b/alpha/admin/uni_modules/uni-scss/styles/tools/functions.scss new file mode 100644 index 0000000..ac6f63e --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/styles/tools/functions.scss @@ -0,0 +1,19 @@ +// 合并 map +@function map-deep-merge($parent-map, $child-map){ + $result: $parent-map; + @each $key, $child in $child-map { + $parent-has-key: map-has-key($result, $key); + $parent-value: map-get($result, $key); + $parent-type: type-of($parent-value); + $child-type: type-of($child); + $parent-is-map: $parent-type == map; + $child-is-map: $child-type == map; + + @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){ + $result: map-merge($result, ( $key: $child )); + }@else { + $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) )); + } + } + @return $result; +}; diff --git a/alpha/admin/uni_modules/uni-scss/theme.scss b/alpha/admin/uni_modules/uni-scss/theme.scss new file mode 100644 index 0000000..80ee62f --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/theme.scss @@ -0,0 +1,31 @@ +// 间距基础倍数 +$uni-space-root: 2; +// 边框半径默认值 +$uni-radius-root:5px; +// 主色 +$uni-primary: #2979ff; +// 辅助色 +$uni-success: #4cd964; +// 警告色 +$uni-warning: #f0ad4e; +// 错误色 +$uni-error: #dd524d; +// 描述色 +$uni-info: #909399; +// 中性色 +$uni-main-color: #303133; +$uni-base-color: #606266; +$uni-secondary-color: #909399; +$uni-extra-color: #C0C4CC; +// 背景色 +$uni-bg-color: #f5f5f5; +// 边框颜色 +$uni-border-1: #DCDFE6; +$uni-border-2: #E4E7ED; +$uni-border-3: #EBEEF5; +$uni-border-4: #F2F6FC; + +// 常规色 +$uni-black: #000000; +$uni-white: #ffffff; +$uni-transparent: rgba($color: #000000, $alpha: 0); diff --git a/alpha/admin/uni_modules/uni-scss/variables.scss b/alpha/admin/uni_modules/uni-scss/variables.scss new file mode 100644 index 0000000..1c062d4 --- /dev/null +++ b/alpha/admin/uni_modules/uni-scss/variables.scss @@ -0,0 +1,62 @@ +@import './styles/setting/_variables.scss'; +// 间距基础倍数 +$uni-space-root: 2; +// 边框半径默认值 +$uni-radius-root:5px; + +// 主色 +$uni-primary: #2979ff; +$uni-primary-disable:mix(#fff,$uni-primary,50%); +$uni-primary-light: mix(#fff,$uni-primary,80%); + +// 辅助色 +// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 +$uni-success: #18bc37; +$uni-success-disable:mix(#fff,$uni-success,50%); +$uni-success-light: mix(#fff,$uni-success,80%); + +$uni-warning: #f3a73f; +$uni-warning-disable:mix(#fff,$uni-warning,50%); +$uni-warning-light: mix(#fff,$uni-warning,80%); + +$uni-error: #e43d33; +$uni-error-disable:mix(#fff,$uni-error,50%); +$uni-error-light: mix(#fff,$uni-error,80%); + +$uni-info: #8f939c; +$uni-info-disable:mix(#fff,$uni-info,50%); +$uni-info-light: mix(#fff,$uni-info,80%); + +// 中性色 +// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 +$uni-main-color: #3a3a3a; // 主要文字 +$uni-base-color: #6a6a6a; // 常规文字 +$uni-secondary-color: #909399; // 次要文字 +$uni-extra-color: #c7c7c7; // 辅助说明 + +// 边框颜色 +$uni-border-1: #F0F0F0; +$uni-border-2: #EDEDED; +$uni-border-3: #DCDCDC; +$uni-border-4: #B9B9B9; + +// 常规色 +$uni-black: #000000; +$uni-white: #ffffff; +$uni-transparent: rgba($color: #000000, $alpha: 0); + +// 背景色 +$uni-bg-color: #f7f7f7; + +/* 水平间距 */ +$uni-spacing-sm: 8px; +$uni-spacing-base: 15px; +$uni-spacing-lg: 30px; + +// 阴影 +$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5); +$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2); +$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5); + +// 蒙版 +$uni-mask: rgba($color: #000000, $alpha: 0.4); diff --git a/alpha/admin/uni_modules/uni-segmented-control/changelog.md b/alpha/admin/uni_modules/uni-segmented-control/changelog.md new file mode 100644 index 0000000..a44385d --- /dev/null +++ b/alpha/admin/uni_modules/uni-segmented-control/changelog.md @@ -0,0 +1,9 @@ +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-segmented-control](https://uniapp.dcloud.io/component/uniui/uni-segmented-control) +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.5(2021-05-12) +- 新增 项目示例地址 +## 1.0.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue b/alpha/admin/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue new file mode 100644 index 0000000..044a495 --- /dev/null +++ b/alpha/admin/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-segmented-control/package.json b/alpha/admin/uni_modules/uni-segmented-control/package.json new file mode 100644 index 0000000..6cae41d --- /dev/null +++ b/alpha/admin/uni_modules/uni-segmented-control/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-segmented-control", + "displayName": "uni-segmented-control 分段器", + "version": "1.2.0", + "description": "分段器由至少 2 个分段控件组成,用作不同视图的显示", + "keywords": [ + "uni-ui", + "uniui", + "分段器", + "segement", + "顶部选择" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-segmented-control/readme.md b/alpha/admin/uni_modules/uni-segmented-control/readme.md new file mode 100644 index 0000000..3527b03 --- /dev/null +++ b/alpha/admin/uni_modules/uni-segmented-control/readme.md @@ -0,0 +1,13 @@ + + +## SegmentedControl 分段器 +> **组件名:uni-segmented-control** +> 代码块: `uSegmentedControl` + + +用作不同视图的显示 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-segmented-control) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-sign-in/changelog.md b/alpha/admin/uni_modules/uni-sign-in/changelog.md new file mode 100644 index 0000000..e44cc46 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/changelog.md @@ -0,0 +1,12 @@ +## 1.0.5(2021-12-09) +修复插件没自动安装依赖的`uni-popup`和`uni-icons`组件的问题 +## 1.0.4(2021-11-29) +修复在某些情况下,签到不连续7天,也获得60积分的问题 +## 1.0.3(2021-11-20) +新增支持看激励视频广告签到 +## 1.0.2(2021-08-25) +修复时区问题 +## 1.0.1(2021-08-23) +调整签到逻辑,支持查出积分的收入支出历史记录 +## 1.0.0(2021-08-05) +1.0.0版本发布 diff --git a/alpha/admin/uni_modules/uni-sign-in/components/uni-sign-in/uni-sign-in.vue b/alpha/admin/uni_modules/uni-sign-in/components/uni-sign-in/uni-sign-in.vue new file mode 100644 index 0000000..677ef9b --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/components/uni-sign-in/uni-sign-in.vue @@ -0,0 +1,307 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-sign-in/package.json b/alpha/admin/uni_modules/uni-sign-in/package.json new file mode 100644 index 0000000..e951059 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/package.json @@ -0,0 +1,84 @@ +{ + "id": "uni-sign-in", + "displayName": "uni-starter签到插件 提升留存,激励视频变现", + "version": "1.0.5", + "description": "培养用户习惯,提升用户粘性,支持广告流量变现的签到得积分功能", + "keywords": [ + "uni-sign-in", + "签到", + "营销", + "变现", + "积分" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "uniCloud", + "云端一体页面模板" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": ["uni-popup","uni-icons"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "y", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/pages/demo/demo.vue b/alpha/admin/uni_modules/uni-sign-in/pages/demo/demo.vue new file mode 100644 index 0000000..1131d3c --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/pages/demo/demo.vue @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/readme.md b/alpha/admin/uni_modules/uni-sign-in/readme.md new file mode 100644 index 0000000..88dd9c2 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/readme.md @@ -0,0 +1,86 @@ +#### 简介:培养用户习惯,提升用户粘性,支持广告流量变现的签到得积分功能。 +#### 功能支持: +1. 每日签到奖励 (支持:普通签到、看广告签到) +2. 周期性连续7日签到,奖励翻倍 + +### 使用看广告签到功能必读 +1.`普通签到`是通过clientDb实现,如果你要使用`看广告签到`的方式, + 为了防止刷量需要修改`opendb-sign-in.schema`中`permission` -> `create` 的值设置为`false` + +> 文件路径 :`uni_modules/uni-sign-in/uniCloud/database/opendb-sign-in.schema.json` + +示例: + +```javascript +{ + "bsonType": "object", + "required": [], + "permission": { + "read": "auth.uid == doc.user_id", + "create": false, + "update": false, + "delete": false + } +} +``` + +2. 你需要看激励视频广告相关文档 +详情:[https://uniapp.dcloud.net.cn/api/a-d/rewarded-video](https://uniapp.dcloud.net.cn/api/a-d/rewarded-video) + +##### 使用方式 + +```js + + +``` + +> 详情参考[uni-starter](https://ext.dcloud.net.cn/plugin?id=5057) + + +##### 插件组成 +1. 前端组件 + + + +2. `DB Schema`表结构, + - 描述签到表字段及含义以及读写权限。 + - 路径:`/uniCloud/database/opendb-sign-in.schema.json` +> 更多表结构说明详情:[https://uniapp.dcloud.io/uniCloud/schema](https://uniapp.dcloud.io/uniCloud/schema) + +3. `uni-clientDB-actions` 一个可编程的 `clientDB` 前置后置操作 + - 前置操作,添加操作时检查今日是否未签到,否则拦截 + - 后置操作,判断是否已经连续签到7天,决定本次签到用户可得积分 + - 后置操作,输出本轮已签到几天,当前积分,已签到的日期数组,本轮签到可得多少分 +4. 两个api接口 + 普通签到`this.$refs.signIn.open()` + 看激励视频广告签到`this.$refs.signIn.showRewardedVideoAd()` + +#### 常见问题 +1. 是否支持配置积分数 + + 答:暂不支持,今后的版本有计划支持 + +2. 有没有更多玩法 + + 答:计划今后推出 + + (2.1)需要看广告才能签到 --- 已支持 + + (2.2)补签的玩法 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/static/background.png b/alpha/admin/uni_modules/uni-sign-in/static/background.png new file mode 100644 index 0000000000000000000000000000000000000000..2d7ba0999a55dea2553a7319e93c8904b51d7810 GIT binary patch literal 93495 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

L2lMOJ~ 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

68P{C-Oy@rOO?l^Tddcl|# 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 literal 0 HcmV?d00001 diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/index.js b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/index.js new file mode 100644 index 0000000..1cd87bd --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/index.js @@ -0,0 +1,106 @@ +// 开发文档:https://uniapp.dcloud.io/uniCloud/clientdb?id=action +const db = uniCloud.database(); +const dbCmd = db.command +const signInTable = db.collection('opendb-sign-in'); +const scoresTable = db.collection('uni-id-scores'); +module.exports = async function({user_id,ip}) { + let date = todayTimestamp() + let { + total + } = await signInTable.where({ + user_id, + date, + isDelete: false + }).count() + console.log(total); + if (total) { + throw new Error("今天已经签到") + } + // state.newData.date = date + // state.newData.isDelete = false + + await signInTable.add({ + ip, + date, + user_id, + create_date:Date.now(), + isDelete:false, + }) + + + // after ------------------------- + //查最近7天的签到情况 + let { + data: signInData + } = await signInTable.where({ + user_id, + date: dbCmd.gte(date - 3600 * 24 * 6 * 1000), + isDelete: false + }).get() + + let allDate = signInData.map(item => item.date) + + //今天是本轮签到的第几天 + const n = (date - Math.min(...allDate)) / 3600 / 24 / 1000 + 1; + //换成数字--第几天 + let days = signInData.map(item => { + return (n * 10000 - (date - item.date) / 3600 / 24 / 1000 * 10000) / 10000 - 1 + }) + + //查出来用户当前有多少积分 + let { + data: [userScore] + } = await scoresTable + .where({ + user_id + }) + .orderBy("create_date", "desc") + .limit(1) + .get() + let balance = 0 + if (userScore) { + balance = userScore.balance + } + + if (n == 7) { //如果已经满一轮就软删除之前的内容 + let setIsDeleteRes = await signInTable.where({ + user_id, + date: dbCmd.neq(date) + }).update({ + isDelete: true + }) + console.log({ + setIsDeleteRes + }); + } + //给加积分 + let score = n+days.length==14?60:10 //如果连续签到7天就多加50分,也就是60分 + balance += score + let addScores = await scoresTable.add({ + user_id, + balance, + score, + type: 1, + create_date: Date.now() + }) + console.log({ + addScores + }); + return { + score: balance, + signInData, + n, + days + } +} + +function todayTimestamp() { + //时区 + let timeZone = new Date().getTimezoneOffset() / 60 + //获得相对于北京时间的时间戳 + let timestamp = Date.now() + 3600 * 1000 * (8 + timeZone) + //一天一共多少毫秒 + const D = 3600 * 24 * 1000 + //去掉余数,再减去东8区的8小时 得到当天凌晨的时间戳 + return parseInt(timestamp / D) * D - 3600 * 1000 * 8 +} diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/package.json b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/package.json new file mode 100644 index 0000000..7cdbf1d --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/common/sign-in/package.json @@ -0,0 +1,12 @@ +{ + "name": "sign-in", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/index.js b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/index.js new file mode 100644 index 0000000..969eef5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/index.js @@ -0,0 +1,64 @@ +'use strict'; +const uniADConfig = require('uni-config-center')({ + pluginId: 'uni-ad' +}).config() +const signIn = require('sign-in') +let ip = null +async function nextFn(data) { + //写自己的业务逻辑 + switch (data.extra) { + case "uniSignIn": //签到 + let { + user_id + } = data; + await signIn({ + user_id, + ip + }) + break; + default: + break; + } + return { + "isValid": true //如果不返回,广点通会2次调用本云函数 + } +} + +const crypto = require('crypto'); +const db = uniCloud.database(); +exports.main = async (event, context) => { + ip = context.CLIENTIP; + //event为客户端上传的参数 + console.log('event : ', event); + const { + path, + queryStringParameters + } = event; + const data = { + adpid: event.adpid, + platform: event.platform, + provider: event.provider, + trans_id: event.trans_id, + sign: event.sign, + user_id: event.user_id, + extra: event.extra, + } + // 注意::必须验签请求来源 + const trans_id = event.trans_id; + //去uni-config-center通过adpid获取secret + const secret = uniADConfig[event.adpid] + const sign2 = crypto.createHash('sha256').update(`${secret}:${trans_id}`).digest('hex'); + if (event.sign !== sign2) { + console.log('验签失败'); + return null; + } + //自己的逻辑 + try { + return await nextFn(data) + } catch (e) { + console.error(e) + return { + "isValid": false + } + } +}; \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/package.json b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/package.json new file mode 100644 index 0000000..faa915a --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/rewarded-video-ad-notify-url/package.json @@ -0,0 +1,15 @@ +{ + "name": "rewarded-video-ad-notify-url", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "sign-in": "file:../common/sign-in", + "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" + } +} diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/uni-clientDB-actions/signIn.js b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/uni-clientDB-actions/signIn.js new file mode 100644 index 0000000..adf56bc --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/cloudfunctions/uni-clientDB-actions/signIn.js @@ -0,0 +1,90 @@ +// 开发文档:https://uniapp.dcloud.io/uniCloud/clientdb?id=action +const db = uniCloud.database(); +const dbCmd = db.command +const signInTable = db.collection('opendb-sign-in'); +const scoresTable = db.collection('uni-id-scores'); +module.exports = { + before: async (state, event) => { + // console.log({state}); + if(state.type == 'create'){ + let date = todayTimestamp() + let {total} = await signInTable.where({ + user_id:state.auth.uid, + date, + isDelete:false + }).count() + console.log(total); + if(total){ + throw new Error("今天已经签到") + } + state.newData.date = date + state.newData.isDelete = false + } + }, + after: async (state, event, error, result) => { + if (error) { + throw error + } + let date = todayTimestamp() + //查最近7天的签到情况 + let {data:signInData} = await signInTable.where({ + user_id:state.auth.uid, + date:dbCmd.gte(date-3600*24*6*1000), + isDelete:false + }).get() + + let allDate = signInData.map(item=>item.date) + + //今天是本轮签到的第几天 + const n = ( date - Math.min(...allDate) )/3600/24/1000+1; + //换成数字--第几天 + let days = signInData.map(item=>{ + return (n*10000 - (date - item.date)/3600/24/1000*10000)/10000 -1 + }) + + //查出来用户当前有多少积分 + let {data: [userScore]} = await scoresTable + .where({user_id:state.auth.uid}) + .orderBy("create_date", "desc") + .limit(1) + .get() + let balance = 0 + if(userScore){ + balance = userScore.balance + } + + if(state.type == 'create'){ + if(n == 7){ //如果已经满一轮就软删除之前的内容 + let setIsDeleteRes = await signInTable.where({ + user_id:state.auth.uid, + date:dbCmd.neq(date) + }).update({isDelete:true}) + console.log({setIsDeleteRes}); + } + //给加积分 + let score = n+days.length==14?60:10 //如果连续签到7天就多加50分,也就是60分 + balance += score + let addScores = await scoresTable.add({ + user_id:state.auth.uid, + balance, + score, + type:1, + create_date:Date.now() + }) + console.log({addScores}); + } + return {...result,score:balance,signInData,n,days} + } +} + + +function todayTimestamp(){ + //时区 + let timeZone = new Date().getTimezoneOffset()/60 + //获得相对于北京时间的时间戳 + let timestamp = Date.now()+3600*1000*(8+timeZone) + //一天一共多少毫秒 + const D = 3600*24*1000 + //去掉余数,再减去东8区的8小时 得到当天凌晨的时间戳 + return parseInt(timestamp/D)*D - 3600*1000*8 +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/uniCloud/database/opendb-sign-in.schema.json b/alpha/admin/uni_modules/uni-sign-in/uniCloud/database/opendb-sign-in.schema.json new file mode 100644 index 0000000..d70fb39 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/uniCloud/database/opendb-sign-in.schema.json @@ -0,0 +1,41 @@ +// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema +{ + "bsonType": "object", + "required": [], + "permission": { + "read": "auth.uid == doc.user_id", + "create": "auth.uid != null && 'signIn' in action", //如果你要使用`看广告签到`的方式请将这里的值改为:false + "update": false, + "delete": false + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "user_id":{ + "forceDefaultValue":{ + "$env":"uid" + } + }, + "date":{ + "bsonType":"timestamp", + "description":"签到的日期时间戳", + "permission":{ + "write":false + } + }, + "create_date":{ + "bsonType":"timestamp", + "description":"签到的时间戳", + "forceDefaultValue":{ + "$env":"now" + } + }, + "ip":{ + "bsonType":"string", + "forceDefaultValue":{ + "$env":"clientIP" + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-sign-in/utils/ad.js b/alpha/admin/uni_modules/uni-sign-in/utils/ad.js new file mode 100644 index 0000000..7a77ca5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-sign-in/utils/ad.js @@ -0,0 +1,253 @@ +// ad.js +const ADType = { + RewardedVideo: "RewardedVideo", + FullScreenVideo: "FullScreenVideo" +} + +class AdHelper { + + constructor() { + this._ads = {} + } + + load(options, onload, onerror) { + let ops = this._fixOldOptions(options) + let { + adpid + } = ops + + if (!adpid || this.isBusy(adpid)) { + return + } + + this.get(ops).load(onload, onerror) + } + + show(options, onsuccess, onfail) { + let ops = this._fixOldOptions(options) + let { + adpid + } = ops + + if (!adpid) { + return + } + + uni.showLoading({ + mask: true + }) + + var ad = this.get(ops) + + ad.load(() => { + uni.hideLoading() + ad.show((e) => { + onsuccess && onsuccess(e) + }) + }, (err) => { + uni.hideLoading() + onfail && onfail(err) + }) + } + + isBusy(adpid) { + return (this._ads[adpid] && this._ads[adpid].isLoading) + } + + get(options) { + const { + adpid, + singleton = true + } = options + if (singleton === false) { + if (this._ads[adpid]) { + this._ads[adpid].destroy() + delete this._ads[adpid] + } + } + delete options.singleton + if (!this._ads[adpid]) { + this._ads[adpid] = this._createAdInstance(options) + } + + return this._ads[adpid] + } + + _createAdInstance(options) { + const adType = options.adType || ADType.RewardedVideo + delete options.adType + + let ad = null; + if (adType === ADType.RewardedVideo) { + ad = new RewardedVideo(options) + } else if (adType === ADType.FullScreenVideo) { + ad = new FullScreenVideo(options) + } + + return ad + } + + _fixOldOptions(options) { + return (typeof options === "string") ? { + adpid: options + } : options + } +} + +const EXPIRED_TIME = 1000 * 60 * 30 +const ProviderType = { + CSJ: 'csj', + GDT: 'gdt' +} + +const RETRY_COUNT = 1 + +class AdBase { + constructor(adInstance, options = {}) { + this._isLoad = false + this._isLoading = false + this._lastLoadTime = 0 + this._lastError = null + this._retryCount = 0 + + this._loadCallback = null + this._closeCallback = null + this._errorCallback = null + + const ad = this._ad = adInstance + ad.onLoad((e) => { + this._isLoading = false + this._isLoad = true + this._lastLoadTime = Date.now() + + this.onLoad() + }) + ad.onClose((e) => { + this._isLoad = false + this.onClose(e) + }) + ad.onVerify && ad.onVerify((e) => { + // e.isValid + }) + ad.onError(({ + code, + message + }) => { + this._isLoading = false + const data = { + code: code, + errMsg: message + } + + if (code === -5008) { + this._loadAd() + return + } + + if (this._retryCount < RETRY_COUNT) { + this._retryCount += 1 + this._loadAd() + return + } + + this._lastError = data + this.onError(data) + }) + } + + get isExpired() { + return (this._lastLoadTime !== 0 && (Math.abs(Date.now() - this._lastLoadTime) > EXPIRED_TIME)) + } + + get isLoading() { + return this._isLoading + } + + getProvider() { + return this._ad.getProvider() + } + + load(onload, onerror) { + this._loadCallback = onload + this._errorCallback = onerror + + if (this._isLoading) { + return + } + + if (this._isLoad) { + this.onLoad() + return + } + + this._retryCount = 0 + + this._loadAd() + } + + show(onclose) { + this._closeCallback = onclose + + if (this._isLoading || !this._isLoad) { + return + } + + if (this._lastError !== null) { + this.onError(this._lastError) + return + } + + const provider = this.getProvider() + if (provider === ProviderType.CSJ && this.isExpired) { + this._loadAd() + return + } + + this._ad.show() + } + + onLoad(e) { + if (this._loadCallback != null) { + this._loadCallback() + } + } + + onClose(e) { + if (this._closeCallback != null) { + this._closeCallback({ + isEnded: e.isEnded + }) + } + } + + onError(e) { + if (this._errorCallback != null) { + this._errorCallback(e) + } + } + + destroy() { + this._ad.destroy() + } + + _loadAd() { + this._isLoad = false + this._isLoading = true + this._lastError = null + this._ad.load() + } +} + +class RewardedVideo extends AdBase { + constructor(options = {}) { + super(plus.ad.createRewardedVideoAd(options), options) + } +} + +class FullScreenVideo extends AdBase { + constructor(options = {}) { + super(plus.ad.createFullScreenVideoAd(options), options) + } +} + +export default new AdHelper() \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-table/changelog.md b/alpha/admin/uni_modules/uni-table/changelog.md new file mode 100644 index 0000000..9f87c67 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/changelog.md @@ -0,0 +1,27 @@ +## 1.2.3(2023-03-28) +- 修复 在vue3模式下可能会出现错误的问题 +## 1.2.2(2022-11-29) +- 优化 主题样式 +## 1.2.1(2022-06-06) +- 修复 微信小程序存在无使用组件的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-table](https://uniapp.dcloud.io/component/uniui/uni-table) +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-07-08) +- 新增 uni-th 支持 date 日期筛选范围 +## 1.0.6(2021-07-05) +- 新增 uni-th 支持 range 筛选范围 +## 1.0.5(2021-06-28) +- 新增 uni-th 筛选功能 +## 1.0.4(2021-05-12) +- 新增 示例地址 +- 修复 示例项目缺少组件的Bug +## 1.0.3(2021-04-16) +- 新增 sortable 属性,是否开启单列排序 +- 优化 表格多选逻辑 +## 1.0.2(2021-03-22) +- uni-tr 添加 disabled 属性,用于 type=selection 时,设置某行是否可由全选按钮控制 +## 1.0.1(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-table/components/uni-table/uni-table.vue b/alpha/admin/uni_modules/uni-table/components/uni-table/uni-table.vue new file mode 100644 index 0000000..21d9527 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-table/uni-table.vue @@ -0,0 +1,455 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue b/alpha/admin/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue new file mode 100644 index 0000000..fbe1bdc --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-td/uni-td.vue b/alpha/admin/uni_modules/uni-table/components/uni-td/uni-td.vue new file mode 100644 index 0000000..9ce93e9 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-td/uni-td.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-th/filter-dropdown.vue b/alpha/admin/uni_modules/uni-table/components/uni-th/filter-dropdown.vue new file mode 100644 index 0000000..df22a71 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-th/filter-dropdown.vue @@ -0,0 +1,511 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-th/uni-th.vue b/alpha/admin/uni_modules/uni-table/components/uni-th/uni-th.vue new file mode 100644 index 0000000..14889dd --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-th/uni-th.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-thead/uni-thead.vue b/alpha/admin/uni_modules/uni-table/components/uni-thead/uni-thead.vue new file mode 100644 index 0000000..0dd18cd --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-thead/uni-thead.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-tr/table-checkbox.vue b/alpha/admin/uni_modules/uni-table/components/uni-tr/table-checkbox.vue new file mode 100644 index 0000000..1089187 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-tr/table-checkbox.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/components/uni-tr/uni-tr.vue b/alpha/admin/uni_modules/uni-table/components/uni-tr/uni-tr.vue new file mode 100644 index 0000000..f9b9671 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/components/uni-tr/uni-tr.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-table/i18n/en.json b/alpha/admin/uni_modules/uni-table/i18n/en.json new file mode 100644 index 0000000..e32023c --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/en.json @@ -0,0 +1,9 @@ +{ + "filter-dropdown.reset": "Reset", + "filter-dropdown.search": "Search", + "filter-dropdown.submit": "Submit", + "filter-dropdown.filter": "Filter", + "filter-dropdown.gt": "Greater or equal to", + "filter-dropdown.lt": "Less than or equal to", + "filter-dropdown.date": "Date" +} diff --git a/alpha/admin/uni_modules/uni-table/i18n/es.json b/alpha/admin/uni_modules/uni-table/i18n/es.json new file mode 100644 index 0000000..9afd04b --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/es.json @@ -0,0 +1,9 @@ +{ + "filter-dropdown.reset": "Reiniciar", + "filter-dropdown.search": "Búsqueda", + "filter-dropdown.submit": "Entregar", + "filter-dropdown.filter": "Filtrar", + "filter-dropdown.gt": "Mayor o igual a", + "filter-dropdown.lt": "Menos que o igual a", + "filter-dropdown.date": "Fecha" +} diff --git a/alpha/admin/uni_modules/uni-table/i18n/fr.json b/alpha/admin/uni_modules/uni-table/i18n/fr.json new file mode 100644 index 0000000..b006237 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/fr.json @@ -0,0 +1,9 @@ +{ + "filter-dropdown.reset": "Réinitialiser", + "filter-dropdown.search": "Chercher", + "filter-dropdown.submit": "Soumettre", + "filter-dropdown.filter": "Filtre", + "filter-dropdown.gt": "Supérieur ou égal à", + "filter-dropdown.lt": "Inférieur ou égal à", + "filter-dropdown.date": "Date" +} diff --git a/alpha/admin/uni_modules/uni-table/i18n/index.js b/alpha/admin/uni_modules/uni-table/i18n/index.js new file mode 100644 index 0000000..2469dd0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/index.js @@ -0,0 +1,12 @@ +import en from './en.json' +import es from './es.json' +import fr from './fr.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + es, + fr, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/alpha/admin/uni_modules/uni-table/i18n/zh-Hans.json b/alpha/admin/uni_modules/uni-table/i18n/zh-Hans.json new file mode 100644 index 0000000..862af17 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/zh-Hans.json @@ -0,0 +1,9 @@ +{ + "filter-dropdown.reset": "重置", + "filter-dropdown.search": "搜索", + "filter-dropdown.submit": "确定", + "filter-dropdown.filter": "筛选", + "filter-dropdown.gt": "大于等于", + "filter-dropdown.lt": "小于等于", + "filter-dropdown.date": "日期范围" +} diff --git a/alpha/admin/uni_modules/uni-table/i18n/zh-Hant.json b/alpha/admin/uni_modules/uni-table/i18n/zh-Hant.json new file mode 100644 index 0000000..64f8061 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/i18n/zh-Hant.json @@ -0,0 +1,9 @@ +{ + "filter-dropdown.reset": "重置", + "filter-dropdown.search": "搜索", + "filter-dropdown.submit": "確定", + "filter-dropdown.filter": "篩選", + "filter-dropdown.gt": "大於等於", + "filter-dropdown.lt": "小於等於", + "filter-dropdown.date": "日期範圍" +} diff --git a/alpha/admin/uni_modules/uni-table/package.json b/alpha/admin/uni_modules/uni-table/package.json new file mode 100644 index 0000000..7c2f91c --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-table", + "displayName": "uni-table 表格", + "version": "1.2.3", + "description": "表格组件,多用于展示多条结构类似的数据,如", + "keywords": [ + "uni-ui", + "uniui", + "table", + "表格" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss","uni-datetime-picker"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "n", + "QQ": "y" + }, + "快应用": { + "华为": "n", + "联盟": "n" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-table/readme.md b/alpha/admin/uni_modules/uni-table/readme.md new file mode 100644 index 0000000..bb08c79 --- /dev/null +++ b/alpha/admin/uni_modules/uni-table/readme.md @@ -0,0 +1,13 @@ + + +## Table 表单 +> 组件名:``uni-table``,代码块: `uTable`。 + +用于展示多条结构类似的数据 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-table) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + + + diff --git a/alpha/admin/uni_modules/uni-tag/changelog.md b/alpha/admin/uni_modules/uni-tag/changelog.md new file mode 100644 index 0000000..c0c5839 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tag/changelog.md @@ -0,0 +1,21 @@ +## 2.1.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-tag](https://uniapp.dcloud.io/component/uniui/uni-tag) +## 2.0.0(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +- 移除 插槽 +- 移除 type 属性的 royal 选项 +## 1.1.1(2021-08-11) +- type 不是 default 时,size 为 small 字体大小显示不正确 +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-06-18) +- 修复 uni-tag 在字节跳动小程序上 css 类名编译错误的 bug +## 1.0.6(2021-06-04) +- 修复 未定义 sass 变量 "$uni-color-royal" 的bug +## 1.0.5(2021-05-10) +- 修复 royal 类型无效的bug +- 修复 uni-tag 宽度不自适应的bug +- 新增 uni-tag 支持属性 custom-style 自定义样式 +## 1.0.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/alpha/admin/uni_modules/uni-tag/components/uni-tag/uni-tag.vue b/alpha/admin/uni_modules/uni-tag/components/uni-tag/uni-tag.vue new file mode 100644 index 0000000..418c955 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tag/components/uni-tag/uni-tag.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-tag/package.json b/alpha/admin/uni_modules/uni-tag/package.json new file mode 100644 index 0000000..1878088 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tag/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-tag", + "displayName": "uni-tag 标签", + "version": "2.1.0", + "description": "Tag 组件,用于展示1个或多个文字标签,可点击切换选中、不选中的状态。", + "keywords": [ + "uni-ui", + "uniui", + "", + "tag", + "标签" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-tag/readme.md b/alpha/admin/uni_modules/uni-tag/readme.md new file mode 100644 index 0000000..6e78ff5 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tag/readme.md @@ -0,0 +1,13 @@ + + +## Tag 标签 +> **组件名:uni-tag** +> 代码块: `uTag` + + +用于展示1个或多个文字标签,可点击切换选中、不选中的状态 。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tag) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/alpha/admin/uni_modules/uni-tooltip/changelog.md b/alpha/admin/uni_modules/uni-tooltip/changelog.md new file mode 100644 index 0000000..00f1572 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tooltip/changelog.md @@ -0,0 +1,10 @@ +## 0.2.1(2022-05-09) +- 修复 content 为空时仍然弹出的bug +## 0.2.0(2022-05-07) +**注意:破坏性更新** +- 更新 text 属性变更为 content +- 更新 移除 width 属性 +## 0.1.1(2022-04-27) +- 修复 组件根 text 嵌套组件 warning +## 0.1.0(2022-04-21) +- 初始化 diff --git a/alpha/admin/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue b/alpha/admin/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue new file mode 100644 index 0000000..ffbb6fa --- /dev/null +++ b/alpha/admin/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue @@ -0,0 +1,68 @@ + + + + + + diff --git a/alpha/admin/uni_modules/uni-tooltip/package.json b/alpha/admin/uni_modules/uni-tooltip/package.json new file mode 100644 index 0000000..b2a7a90 --- /dev/null +++ b/alpha/admin/uni_modules/uni-tooltip/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-tooltip", + "displayName": "uni-tooltip", + "version": "0.2.1", + "description": "uni-tooltip", + "keywords": [ + "uni-tooltip", + "uni-ui", + "tooltip", + "tip", + "文字提示" +], + "repository": "", +"engines": { + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无 ", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-tooltip/readme.md b/alpha/admin/uni_modules/uni-tooltip/readme.md new file mode 100644 index 0000000..faafa2e --- /dev/null +++ b/alpha/admin/uni_modules/uni-tooltip/readme.md @@ -0,0 +1,8 @@ +## Badge 数字角标 +> **组件名:uni-tooltip** +> 代码块: `uTooltip` + +数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景, + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tooltip) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 diff --git a/alpha/admin/uni_modules/uni-transition/changelog.md b/alpha/admin/uni_modules/uni-transition/changelog.md new file mode 100644 index 0000000..b1a824b --- /dev/null +++ b/alpha/admin/uni_modules/uni-transition/changelog.md @@ -0,0 +1,20 @@ +## 1.3.1(2021-11-23) +- 修复 init 方法初始化问题 +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition) +## 1.2.1(2021-09-27) +- 修复 init 方法不生效的 Bug +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.1(2021-05-12) +- 新增 示例地址 +- 修复 示例项目缺少组件的 Bug +## 1.1.0(2021-04-22) +- 新增 通过方法自定义动画 +- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式 +- 优化 动画触发逻辑,使动画更流畅 +- 优化 支持单独的动画类型 +- 优化 文档示例 +## 1.0.2(2021-02-05) +- 调整为 uni_modules 目录规范 diff --git a/alpha/admin/uni_modules/uni-transition/components/uni-transition/createAnimation.js b/alpha/admin/uni_modules/uni-transition/components/uni-transition/createAnimation.js new file mode 100644 index 0000000..5f54365 --- /dev/null +++ b/alpha/admin/uni_modules/uni-transition/components/uni-transition/createAnimation.js @@ -0,0 +1,128 @@ +// const defaultOption = { +// duration: 300, +// timingFunction: 'linear', +// delay: 0, +// transformOrigin: '50% 50% 0' +// } +// #ifdef APP-NVUE +const nvueAnimation = uni.requireNativePlugin('animation') +// #endif +class MPAnimation { + constructor(options, _this) { + this.options = options + this.animation = uni.createAnimation(options) + this.currentStepAnimates = {} + this.next = 0 + this.$ = _this + + } + + _nvuePushAnimates(type, args) { + let aniObj = this.currentStepAnimates[this.next] + let styles = {} + if (!aniObj) { + styles = { + styles: {}, + config: {} + } + } else { + styles = aniObj + } + if (animateTypes1.includes(type)) { + if (!styles.styles.transform) { + styles.styles.transform = '' + } + let unit = '' + if(type === 'rotate'){ + unit = 'deg' + } + styles.styles.transform += `${type}(${args+unit}) ` + } else { + styles.styles[type] = `${args}` + } + this.currentStepAnimates[this.next] = styles + } + _animateRun(styles = {}, config = {}) { + let ref = this.$.$refs['ani'].ref + if (!ref) return + return new Promise((resolve, reject) => { + nvueAnimation.transition(ref, { + styles, + ...config + }, res => { + resolve() + }) + }) + } + + _nvueNextAnimate(animates, step = 0, fn) { + let obj = animates[step] + if (obj) { + let { + styles, + config + } = obj + this._animateRun(styles, config).then(() => { + step += 1 + this._nvueNextAnimate(animates, step, fn) + }) + } else { + this.currentStepAnimates = {} + typeof fn === 'function' && fn() + this.isEnd = true + } + } + + step(config = {}) { + // #ifndef APP-NVUE + this.animation.step(config) + // #endif + // #ifdef APP-NVUE + this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config) + this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin + this.next++ + // #endif + return this + } + + run(fn) { + // #ifndef APP-NVUE + this.$.animationData = this.animation.export() + this.$.timer = setTimeout(() => { + typeof fn === 'function' && fn() + }, this.$.durationTime) + // #endif + // #ifdef APP-NVUE + this.isEnd = false + let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref + if(!ref) return + this._nvueNextAnimate(this.currentStepAnimates, 0, fn) + this.next = 0 + // #endif + } +} + + +const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d', + 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY', + 'translateZ' +] +const animateTypes2 = ['opacity', 'backgroundColor'] +const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom'] +animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => { + MPAnimation.prototype[type] = function(...args) { + // #ifndef APP-NVUE + this.animation[type](...args) + // #endif + // #ifdef APP-NVUE + this._nvuePushAnimates(type, args) + // #endif + return this + } +}) + +export function createAnimation(option, _this) { + if(!_this) return + clearTimeout(_this.timer) + return new MPAnimation(option, _this) +} diff --git a/alpha/admin/uni_modules/uni-transition/components/uni-transition/uni-transition.vue b/alpha/admin/uni_modules/uni-transition/components/uni-transition/uni-transition.vue new file mode 100644 index 0000000..0d739bd --- /dev/null +++ b/alpha/admin/uni_modules/uni-transition/components/uni-transition/uni-transition.vue @@ -0,0 +1,277 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-transition/package.json b/alpha/admin/uni_modules/uni-transition/package.json new file mode 100644 index 0000000..d15fdf0 --- /dev/null +++ b/alpha/admin/uni_modules/uni-transition/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-transition", + "displayName": "uni-transition 过渡动画", + "version": "1.3.1", + "description": "元素的简单过渡动画", + "keywords": [ + "uni-ui", + "uniui", + "动画", + "过渡", + "过渡动画" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-transition/readme.md b/alpha/admin/uni_modules/uni-transition/readme.md new file mode 100644 index 0000000..2f8a77e --- /dev/null +++ b/alpha/admin/uni_modules/uni-transition/readme.md @@ -0,0 +1,11 @@ + + +## Transition 过渡动画 +> **组件名:uni-transition** +> 代码块: `uTransition` + + +元素过渡动画 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/alpha/admin/uni_modules/uni-upgrade-center/changelog.md b/alpha/admin/uni_modules/uni-upgrade-center/changelog.md new file mode 100644 index 0000000..3d9885a --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/changelog.md @@ -0,0 +1,51 @@ +## 0.6.0(2023-02-24) +- 修复 升级中心安卓应用市场不显示的Bug +## 0.5.1(2022-07-06) +- 修复 上版带出云函数不存在的Bug +- 升级 uni-admin 大于等于 1.9.0 务必更新至此版本。uni-admin 版本小于 1.9.0 请不要更新,历史版本在 Gitee 有发行版。后续 uni-admin 会集成升级中心 +## 0.5.0(2022-07-05) +- 修复 版本列表默认显示全部版本的Bug +- 升级 uni-admin 1.9.0 务必更新至此版本。uni-admin 版本小于 1.9.0 请不要更新,后续 uni-admin 会集成升级中心 + +## 0.4.2(2021-12-07) +- 更新 优化 list 页面显示,修复 list 页面报错 +## 0.4.1(2021-12-01) +- 修复 0.4.0版本带出来,发布新版时 appid、name 不会自动填充的Bug +## 0.4.0(2021-11-26) +- 更新 升级中心移除应用管理,现在由uni-admin接管。旧版本若没有应用管理请做升级处理 +## 0.3.0(2021-11-18) +- 兼容 uni-admin 新版内置 $request 函数改动 +## 0.2.2(2021-09-06) +- 解决 opendb-app-list表对应的schema名称冲突的问题 +## 0.2.1(2021-09-03) +- 修复 一个在添加菜单时报错,createdate不与默认值匹配 的Bug +## 0.2.0(2021-08-25) +- 兼容vue3.0 +## 0.1.9(2021-08-13) +- 更新 uni-forms使用validate校验字段 +- 修复 报错dirty_data、create_date在数据库中并不存在 +## 0.1.8(2021-08-09) +- 修复 默认配置项配置错误 +## 0.1.7(2021-08-09) +- 移除测试时配置项 +## 0.1.6(2021-08-09) +- 修复 修改版本信息时,上传时间丢失问题 +## 0.1.5(2021-07-21) +- 更新 :value.sync 改为 :value 和 @update:value +## 0.1.4(2021-07-13) +- 修复 uni-easyinput去除输入字符长度限制 +- 更新文档 关于 uni-id缺少配置信息 错误。请查看安装指引第13条 +## 0.1.3(2021-06-15) +- 修复 wgt更新某些情况下获取数据错误 +## 0.1.2(2021-06-04) +- 修复 上传包时根据平台筛选文件 +- 更新 文档 +## 0.1.1(2021-05-18) +- 更新uni-table中uni-tr组件的selectable属性为disabled +## 0.1.0(2021-04-07) +- 更新版本对比函数 compare +## 0.0.6(2021-04-01) +- 调整db_init.json +## 0.0.5(2021-03-25) +- 调整为uni_modules目录 +- 升级中心后台管理系统拆分为 Admin 后台管理 和 前台检查更新(uni-upgrade-center-app) diff --git a/alpha/admin/uni_modules/uni-upgrade-center/package.json b/alpha/admin/uni_modules/uni-upgrade-center/package.json new file mode 100644 index 0000000..73e401e --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/package.json @@ -0,0 +1,91 @@ +{ + "id": "uni-upgrade-center", + "displayName": "升级中心 uni-upgrade-center - Admin", + "version": "0.6.0", + "description": "uni升级中心 - 后台管理系统", + "keywords": [ + "uniCloud", + "admin", + "update", + "升级", + "wgt" +], + "repository": "https://gitee.com/dcloud/uni-upgrade-center/tree/master/uni_modules/uni-upgrade-center", + "engines": { + "HBuilderX": "^3.3.10" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "", + "type": "unicloud-admin" + }, + "uni_modules": { + "dependencies": [ + "uni-data-checkbox", + "uni-data-picker", + "uni-dateformat", + "uni-easyinput", + "uni-file-picker", + "uni-forms", + "uni-icons", + "uni-pagination", + "uni-table" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/components/show-info.vue b/alpha/admin/uni_modules/uni-upgrade-center/pages/components/show-info.vue new file mode 100644 index 0000000..459eda6 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/components/show-info.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/mixin/version_add_detail_mixin.js b/alpha/admin/uni_modules/uni-upgrade-center/pages/mixin/version_add_detail_mixin.js new file mode 100644 index 0000000..ef3247f --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/mixin/version_add_detail_mixin.js @@ -0,0 +1,185 @@ +import { + validator, + enumConverter +} from '@/js_sdk/validator/opendb-app-versions.js'; + +const platform_iOS = 'iOS'; +const platform_Android = 'Android'; +const db = uniCloud.database(); + +function getValidator(fields) { + let reuslt = {} + for (let key in validator) { + if (fields.includes(key)) { + reuslt[key] = validator[key] + } + } + return reuslt +} + +export const fields = + 'appid,name,title,contents,platform,type,version,min_uni_version,url,stable_publish,is_silently,is_mandatory,create_date,store_list' + +export default { + data() { + return { + labelWidth: '80px', + enableiOSWgt: true, // 是否开启iOS的wgt更新 + silentlyContent: '静默更新:App升级时会在后台下载wgt包并自行安装。新功能在下次启动App时生效', + mandatoryContent: '强制更新:App升级弹出框不可取消', + stablePublishContent: '同时只可有一个线上发行版,线上发行不可更设为下线。\n未上线可以设为上线发行并自动替换当前线上发行版', + stablePublishContent2: '使用本包替换当前线上发行版', + uploadFileContent: '可下载安装包地址。上传文件到云存储自动填写,也可以手动填写', + minUniVersionContent: '上次使用新Api或打包新模块的App版本', + priorityContent: '检查更新时,按照优先级从大到小依次尝试跳转商店。如果都跳转失败,则会打开浏览器使用下载链接下载apk安装包', + latestStableData: [], // 库中最新已上线版 + appFileList: null, // 上传包 + type_valuetotext: enumConverter.type_valuetotext, + preUrl: '', + formData: { + "appid": "", + "name": "", + "title": "", + "contents": "", + "platform": [], + "store_list": [], + "type": "", + "version": "", + "min_uni_version": "", + "url": "", + "stable_publish": false, + "create_date": null + }, + formOptions: { + "platform_localdata": [{ + "value": "Android", + "text": "安卓" + }, + { + "value": "iOS", + "text": "苹果" + } + ], + "type_localdata": [{ + "value": "native_app", + "text": "原生App安装包" + }, + { + "value": "wgt", + "text": "App资源包" + } + ] + }, + rules: { + ...getValidator([ + "appid", "contents", "platform", "type", + "version", "min_uni_version", "url", "stable_publish", + "title", "name", "is_silently", "is_mandatory", "store_list" + ]) + } + } + }, + onReady() { + this.$refs.form.setRules(this.rules) + }, + computed: { + isWGT() { + return this.formData.type === 'wgt' + }, + isiOS() { + return !this.isWGT ? this.formData.platform.includes(platform_iOS) : false; + }, + hasPackage() { + return this.appFileList && !!Object.keys(this.appFileList).length + }, + fileExtname() { + return this.isWGT ? ['wgt'] : ['apk'] + }, + platformLocaldata() { + return !this.isWGT ? this.formOptions.platform_localdata : this.enableiOSWgt ? this.formOptions + .platform_localdata : [this.formOptions.platform_localdata[0]] + }, + uni_platform() { + return (this.isiOS ? platform_iOS : platform_Android).toLocaleLowerCase() + } + }, + methods: { + getStoreList(appid) { + return db.collection('opendb-app-list') + .where({ + appid + }) + .get() + .then(res => { + const data = res.result.data[0] + return data.store_list || [] + }) + }, + packageUploadSuccess(res) { + uni.showToast({ + icon: 'success', + title: '上传成功', + duration: 800 + }) + this.preUrl = this.formData.url + this.formData.url = res.tempFilePaths[0] + }, + deleteFile(fileList) { + return this.$request('deleteFile', { + fileList + }, { + functionName: 'uni-upgrade-center' + }) + }, + async packageDelete(res) { + if (!this.hasPackage) return; + await this.deleteFile([res.tempFilePath]) + uni.showToast({ + icon: 'success', + title: '删除成功', + duration: 800 + }) + this.formData.url = this.preUrl + this.$refs.form.clearValidate('url') + }, + selectFile() { + if (this.hasPackage) { + uni.showToast({ + icon: 'none', + title: '只可上传一个文件,请删除已上传后重试', + duration: 1000 + }); + } + }, + createCenterRecord(value) { + return { + ...value, + uni_platform: this.uni_platform, + create_env: 'upgrade-center' + } + }, + createCenterQuery({ + appid + }) { + return { + appid, + create_env: 'upgrade-center' + } + }, + createStatQuery({ + appid, + type, + version, + uni_platform + }) { + return { + appid, + type, + version, + uni_platform: uni_platform ? uni_platform : this.uni_platform, + create_env: 'uni-stat', + stable_publish: false + } + } + } +} diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/utils.js b/alpha/admin/uni_modules/uni-upgrade-center/pages/utils.js new file mode 100644 index 0000000..df0aeb3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/utils.js @@ -0,0 +1,26 @@ +// 判断arr是否为一个数组,返回一个bool值 +function isArray(arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; +} + +// 深度克隆 +export function deepClone(obj) { + // 对常见的“非”值,直接返回原来值 + if ([null, undefined, NaN, false].includes(obj)) return obj; + if (typeof obj !== "object" && typeof obj !== 'function') { + //原始类型直接返回 + return obj; + } + var o = isArray(obj) ? [] : {}; + for (let i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; + } + } + return o; +} + +export const appListDbName = 'opendb-app-list' +export const appVersionListDbName = 'opendb-app-versions' +// 版本列表默认显示应用Appid +export const defaultDisplayApp = '' diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/version/add.vue b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/add.vue new file mode 100644 index 0000000..be19298 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/add.vue @@ -0,0 +1,413 @@ + + + + + diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/version/detail.vue b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/detail.vue new file mode 100644 index 0000000..89f3730 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/detail.vue @@ -0,0 +1,337 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-upgrade-center/pages/version/list.vue b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/list.vue new file mode 100644 index 0000000..9cdc9f3 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/pages/version/list.vue @@ -0,0 +1,368 @@ + + + + diff --git a/alpha/admin/uni_modules/uni-upgrade-center/readme.md b/alpha/admin/uni_modules/uni-upgrade-center/readme.md new file mode 100644 index 0000000..46ec891 --- /dev/null +++ b/alpha/admin/uni_modules/uni-upgrade-center/readme.md @@ -0,0 +1,233 @@ +## uni-admin 1.9.3+ 已内置,此插件不再维护 [点击查看文档](https://uniapp.dcloud.net.cn/uniCloud/upgrade-center.html) + +- `uni-admin < 1.9.0`:请前往 [Gitee](https://gitee.com/dcloud/uni-upgrade-center/releases) 下载 `tag v0.4.2` 版本使用 +-`1.9.0 <= uni-admin < 1.9.2` :请前往 [Gitee](https://gitee.com/dcloud/uni-upgrade-center/releases) 下载 `tag v0.5.1` 版本使用 +- `uni-admin >= 1.9.3` :uni-admin 已内置 升级中心,直接使用即可 [详情](https://uniapp.dcloud.io/uniCloud/admin.html#app-manager)。并且云函数 `upgrade-center` 废弃,使用 `uni-upgrade-center` 云函数。 + +# uni-upgrade-center - Admin + +### 概述 + +> 统一管理App及App在`Android`、`iOS`平台上`App安装包`和`wgt资源包`的发布升级 + +> 本插件为uni升级中心后台管理系统,客户端检查更新插件请点击查看 [uni-upgrade-center-app](https://ext.dcloud.net.cn/plugin?id=4542) + +### 基于uniCloud的App升级中心,本插件具有如下特征: + - 云端基于uniCloud云函数实现 + - 数据库遵循opendb规范 + - 遵循uni-Admin框架规范,可直接导入uni-admin项目中 + - 支持App整包升级及wgt资源包升级 + +## 升级中心解决了什么问题? + +升级中心是一款uni-admin插件,负责App版本更新业务。包含后台管理界面、更新检查逻辑,App内只要调用弹出提示即可。 + +升级中心有以下功能点: + +- 应用管理,对App的信息记录和应用版本管理 +- 版本管理,可以发布新版,也可方便直观的对当前App历史版本以及线上发行版本进行查看、编辑和删除操作 +- 版本发布信息管理,包括 更新标题,更新内容,版本号,静默更新,强制更新,灵活上线发行 的设置和修改 +- 原生App安装包,发布Apk更新,用于App的整包更新,可设置是否强制更新 +- wgt资源包,发布wgt更新,用于App的热更新,可设置是否强制更新,静默更新 +- App管理列表及App版本记录列表搜索 + +只需导入插件,初始化数据库即可拥有上述功能。 + +您也可以自己修改逻辑自定义数据库字段,和随意定制 UI 样式。 + +## 安装指引 + +1. 使用`HBuilderX 3.1.0+`,因为要使用到`uni_modules` + +2. 使用已有`uniCloud-admin`项目或新建项目:`打开HBuilderX` -> `文件` -> `新建` -> `项目` -> `uni-app` 选择 `uniCloud admin`模板,键入一个名字,确定 + +3. 鼠标右键选择`关联云服务空间`和`运行云服务空间初始化向导` + +3. 在插件市场打开本插件页面,在右侧点击`使用 HBuilderX 导入插件`,选择 `uniCloud admin` 项目点击确定 + +4. 等待下载安装完毕。由于本插件依赖一些uni-ui插件,下载完成后会显示合并插件页面,自行选择即可 + +5. 找到`/uni_modules/uni-upgrade-center/uniCloud/cloudfunctions/upgrade-center`,右键上传部署 + +7. 在`pages.json`中添加页面路径 +```json +//此结构与uniCloud admin中的pages.json结构一致 +{ + "pages": [ + // ……其他页面配置 + { + "path": "uni_modules/uni-upgrade-center/pages/version/list", + "style": { + "navigationBarTitleText": "版本列表" + } + }, { + "path": "uni_modules/uni-upgrade-center/pages/version/add", + "style": { + "navigationBarTitleText": "新版发布" + } + }, { + "path": "uni_modules/uni-upgrade-center/pages/version/detail", + "style": { + "navigationBarTitleText": "版本信息查看" + } + } + ] +} +``` + +8. 在`manifest.json -> 源码视图`中添加以下配置: + ```js + "networkTimeout":{ + "uploadFile":1200000 //ms, 如果不配置,上传大文件可能会超时 + } + ``` + +9. 运行项目到`Chrome` + +10. 添加菜单 + - `vue2` + + 运行起来uniCloud admin,菜单管理模块会自动读取`/uni_modules/uni-upgrade-center/menu.json`文件中的菜单配置,生成【待添加菜单】,选中升级中心,点击`添加选中的菜单`即可 +
+ +
+ - `vue3` + + 可将 `/uni_modules/uni-upgrade-center/menu.json` 拷贝至 `uniCloud/database/db_init.json` 中的 `opendb-admin-menus` 节点下,并右键初始化数据库即可。 +11. 添加成功后,就可以在左侧的菜单栏中找到`升级中心`菜单 + +
+ +
+ +12. 在进入`升级中心`之前: + 1. 需要到`uni-admin`的`应用管理`中添加一个应用,才可以在`升级中心`中发布对应应用的版本。 + 2. 当你有多个应用时,可以在`/uni_modules/uni-upgrade-center/pages/utils.js`中修改`defaultDisplayApp`字段来设置默认显示应用的`appid`。 + 3. 如果不设置或设置应用不存在则默认从数据库中查出来的第一个应用。 + +13. 由于插件依赖的uni-ui的一些组件,建议右键`/uni_modules/uni-upgrade-center`安装一下第三方依赖,否则可能会出现一些问题 + +14. 运行在`uniCloud`,由于本插件使用了`clientDB`,因此可能需要配置一下`uni-config-center插件`关于`uni-id`的配置信息。如提示`公用模块uni-id缺少配置信息`请这样做: + 1. 点击[uni-config-center](https://ext.dcloud.net.cn/plugin?id=4425)导入插件 + 2. 在`/uniCloud/cloudfunctions/common/uni-config-center/`下创建`uni-id`文件夹,文件夹内创建`config.json`文件。 + 3. 点击[config.json默认配置](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=start)。将内容拷贝至`config.json`中。**注:一定要把注释去除!** + +## 使用指南 + +### 升级中心 + +#### 应用列表 + +1. 点击菜单 `应用管理`,这里展示你所添加的 App,点击右上角 `新增` 可以新增一个 App + +
+ +
+ +2. 将App的信息都填写完善后,你可以在列表的操作列进行`修改`应用信息或者`删除`该应用。 + +**Tips** +- 删除应用会把该应用的所有版本记录同时删除 + +#### 版本管理 +1. 在版本管理list的右上角点击`发布新版`,可以发布`原生App安装包`和`wgt资源包`。在左上角点击`下拉列表`,可以切换展示应用。 + +
+ +
+ +- #### 发布原生App安装包 + 1. 在上传安装包界面填写此次发版信息 + +
+ +
+ + 2. `包地址` + - 可以选择手动上传一个文件到 `云存储`,会自动将地址填入该项 + + - 也可以手动填写一个地址,就可以不用再上传文件 + + - 如果是发布`苹果`版本,包地址则为 应用在`AppStore的链接` + + 3. `强制更新` + - 如果使用强制更新,App端接收到该字段后,App升级弹出框不可取消 + + 4. `上线发行` + - 可设置当前包是否上线发行,只有已上线才会进行更新检测 + + - 同时只可有一个线上发行版,线上发行不可更设为下线。未上线可以设为上线发行并自动替换当前线上发行版 + + - 修改当前包为上线发行,自动替换当前线上发行版 + + **注:版本号请填写以`.`分隔字符串,例如:`0.0.1`** +- #### 发布wgt资源包 + 1. 大部分配置与发布 `原生App安装包` 一致 + +
+ +
+ + 2. `原生App最低版本` + - 上次使用新Api或打包新模块的App版本 + + - 如果此次打包wgt使用了`新的api`或者打包了`新的模块`,则在发布 `wgt资源包` 的时候,将此版本更新为本次版本 + + - 如果已有正式版`wgt资源包`,则本次新增会自动带出 + + 2. `静默更新` + - App升级时会在后台下载wgt包并自行安装。新功能在下次启动App时生效 + - **静默更新后不重启应用,可能会导致正在访问的应用的页面数据错乱,请谨慎使用!** + + **注:版本号请填写以`.`分隔字符串,例如:`0.0.1`** + +- #### 发布完成页面 + +
+ +
+ +**Tips** + +1. `pages/system/upgradecenter/version/add.vue`中有版本对比函数(compare)。 + - 使用多段式版本格式(如:"3.0.0.0.0.1.0.1", "3.0.0.0.0.1")。如果不满足对比规则,请自行修改。 + +## 项目代码说明 + +### uniCloud 数据表 + +数据表基于 [openDB](https://gitee.com/dcloud/opendb/tree/master) 规范,它约定了一个标准用户表的表名和字段定义,并且基于 nosql 的特性,可以由开发者自行扩展字段。 + +本项目用到了 2 个表: + +- opendb-app-list:app管理列表。记录应用的 appid、name、description 用于展示。[详见](https://gitee.com/dcloud/opendb/tree/master/collection/opendb-app-list) +- opendb-app-versions:应用版本管理表。记录管理应用的版本信息。[详见](https://gitee.com/dcloud/opendb/tree/master/collection/opendb-app-versions) + +### 前端页面 + +点击`升级中心`,会进入应用管理列表,在这里你可以新增应用,或者在`应用详情`中查看、修改或删除一个已经录入的应用。 + +在应用管理列表中点击某个应用的`版本管理`,进入该应用的所有版本记录。列表排序为:先排序已上线版本,剩下已下线版本根据创建时间排列。 + +在应用版本列表中点击`详情`,即可进入该版本的信息详情中查看、修改或删除该记录。 + +**Tips** +- 升级中心设计之初就支持iOS的wgt更新 +- iOS的wgt更新肯定是违反apple政策的,注意事项: + - 审核期间请不要弹窗升级 + - 升级完后尽量不要自行重启 + - 尽量使用静默更新 +- 可以通过以下修改支持iOS的wgt更新: + > \uni_modules\uni-upgrade-center\pages\mixin\version_add_detail_mixin.js + > + > 将 `data` 中的 `enableiOSWgt: false` 中 改为 `enableiOSWgt: true` + +**常见问题** +- 以下问题可以通过升级插件版本解决: + - createdate不与默认值匹配 + - ["create_date"]在数据库中并不存在 + - 提交的字段["dirty_data"]在数据库中并不存在 + - 集合[opendb-app-list]对应的schema内存在错误,详细信息:opendb-app-list表对应的schema名称冲突,这是什么意思呢 + +- 没有/找不到 [opendb-app-list] 集合/表。**解决方案:**升级 admin 至 1.6.0+ 即可 +- 测试时发布了高版本的包,测试完了发布包提示需要大于版本号 (x.x.x)。**解决方案:**直接在控制台修改数据库 \ No newline at end of file diff --git a/alpha/admin/vue.config.js b/alpha/admin/vue.config.js new file mode 100644 index 0000000..5e35df0 --- /dev/null +++ b/alpha/admin/vue.config.js @@ -0,0 +1,28 @@ +const ignored = ['**/uni_modules/**/*.md', '**/uni_modules/**/package.json', '**/uni_modules/*/uniCloud/**/*', '**/.git'] +module.exports = { + chainWebpack: (config) => { + // 发行或运行时启用了压缩时会生效 + config.optimization.minimizer('terser').tap((args) => { + const compress = args[0].terserOptions.compress + // 非 App 平台移除 console 代码(包含所有 console 方法,如 log,debug,info...) + compress.drop_console = true + compress.pure_funcs = [ + '__f__', // App 平台 vue 移除日志代码 + // 'console.debug' // 可移除指定的 console 方法 + ] + return args + }) + }, + configureWebpack() { + return { + watchOptions: { + ignored + }, + devServer: { + watchOptions: { + ignored + } + } + } + } +} diff --git a/alpha/admin/windows/components/error-log.vue b/alpha/admin/windows/components/error-log.vue new file mode 100644 index 0000000..68b5cd3 --- /dev/null +++ b/alpha/admin/windows/components/error-log.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/alpha/admin/windows/leftWindow.vue b/alpha/admin/windows/leftWindow.vue new file mode 100644 index 0000000..e021063 --- /dev/null +++ b/alpha/admin/windows/leftWindow.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/alpha/admin/windows/topWindow.vue b/alpha/admin/windows/topWindow.vue new file mode 100644 index 0000000..40b8b52 --- /dev/null +++ b/alpha/admin/windows/topWindow.vue @@ -0,0 +1,464 @@ + + + + + -- GitLab