From 60bf30211923f97e5ae82f7be99507ef0ce24072 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=98=BF=E6=80=AA?= <690927457@qq.com>
Date: Sun, 8 Oct 2023 21:21:21 +0800
Subject: [PATCH] init
---
App.vue | 168 +
api/index.js | 404 +
api/request.js | 208 +
components/.DS_Store | Bin 0 -> 6148 bytes
.../customer-skeleton/customer-skeleton.vue | 74 +
components/emptyCard.vue | 46 +
components/goodsCard.vue | 219 +
components/goodsCart.vue | 225 +
components/goodsCartPay.vue | 169 +
components/goodsInfo.vue | 139 +
components/goodsSpecs.vue | 439 +
components/goodsSpecs2.vue | 9 +
components/i-skeleton/i-skeleton.vue | 136 +
components/mapPlat/mapPlat.nvue | 128 +
components/myButton.vue | 46 +
components/myCoupon.vue | 298 +
components/mySwiper.vue | 97 +
components/notice.vue | 71 +
components/searchBox.vue | 61 +
config/index.js | 21 +
index.html | 20 +
main.js | 24 +
manifest.json | 72 +
node_modules/.bin/vue-demi-fix | 12 +
node_modules/.bin/vue-demi-fix.cmd | 17 +
node_modules/.bin/vue-demi-fix.ps1 | 28 +
node_modules/.bin/vue-demi-switch | 12 +
node_modules/.bin/vue-demi-switch.cmd | 17 +
node_modules/.bin/vue-demi-switch.ps1 | 28 +
node_modules/.package-lock.json | 69 +
.../@vue/devtools-api/lib/cjs/api/api.js | 2 +
.../@vue/devtools-api/lib/cjs/api/app.js | 2 +
.../devtools-api/lib/cjs/api/component.js | 2 +
.../@vue/devtools-api/lib/cjs/api/context.js | 2 +
.../@vue/devtools-api/lib/cjs/api/hooks.js | 2 +
.../@vue/devtools-api/lib/cjs/api/index.js | 22 +
.../@vue/devtools-api/lib/cjs/api/util.js | 2 +
.../@vue/devtools-api/lib/cjs/const.js | 5 +
node_modules/@vue/devtools-api/lib/cjs/env.js | 17 +
.../@vue/devtools-api/lib/cjs/index.js | 44 +
.../@vue/devtools-api/lib/cjs/plugin.js | 2 +
.../@vue/devtools-api/lib/cjs/proxy.js | 111 +
.../@vue/devtools-api/lib/cjs/time.js | 28 +
.../@vue/devtools-api/lib/esm/api/api.d.ts | 108 +
.../@vue/devtools-api/lib/esm/api/api.js | 1 +
.../@vue/devtools-api/lib/esm/api/app.d.ts | 1 +
.../@vue/devtools-api/lib/esm/api/app.js | 1 +
.../devtools-api/lib/esm/api/component.d.ts | 78 +
.../devtools-api/lib/esm/api/component.js | 1 +
.../devtools-api/lib/esm/api/context.d.ts | 5 +
.../@vue/devtools-api/lib/esm/api/context.js | 1 +
.../@vue/devtools-api/lib/esm/api/hooks.d.ts | 180 +
.../@vue/devtools-api/lib/esm/api/hooks.js | 1 +
.../@vue/devtools-api/lib/esm/api/index.d.ts | 6 +
.../@vue/devtools-api/lib/esm/api/index.js | 6 +
.../@vue/devtools-api/lib/esm/api/util.d.ts | 4 +
.../@vue/devtools-api/lib/esm/api/util.js | 1 +
.../@vue/devtools-api/lib/esm/const.d.ts | 2 +
.../@vue/devtools-api/lib/esm/const.js | 2 +
.../@vue/devtools-api/lib/esm/env.d.ts | 15 +
node_modules/@vue/devtools-api/lib/esm/env.js | 12 +
.../@vue/devtools-api/lib/esm/index.d.ts | 18 +
.../@vue/devtools-api/lib/esm/index.js | 26 +
.../@vue/devtools-api/lib/esm/plugin.d.ts | 47 +
.../@vue/devtools-api/lib/esm/plugin.js | 1 +
.../@vue/devtools-api/lib/esm/proxy.d.ts | 20 +
.../@vue/devtools-api/lib/esm/proxy.js | 107 +
.../@vue/devtools-api/lib/esm/time.d.ts | 2 +
.../@vue/devtools-api/lib/esm/time.js | 23 +
node_modules/@vue/devtools-api/package.json | 37 +
node_modules/pinia/LICENSE | 21 +
node_modules/pinia/README.md | 24 +
node_modules/pinia/dist/pinia.cjs | 2019 +++
node_modules/pinia/dist/pinia.d.ts | 986 ++
node_modules/pinia/dist/pinia.esm-browser.js | 1996 +++
node_modules/pinia/dist/pinia.iife.js | 2180 +++
node_modules/pinia/dist/pinia.iife.prod.js | 6 +
node_modules/pinia/dist/pinia.mjs | 2004 +++
node_modules/pinia/dist/pinia.prod.cjs | 808 ++
node_modules/pinia/index.cjs | 7 +
node_modules/pinia/index.js | 7 +
node_modules/pinia/package.json | 100 +
node_modules/vue-demi/LICENSE | 21 +
node_modules/vue-demi/README.md | 228 +
node_modules/vue-demi/bin/vue-demi-fix.js | 3 +
node_modules/vue-demi/bin/vue-demi-switch.js | 3 +
node_modules/vue-demi/lib/index.cjs | 32 +
node_modules/vue-demi/lib/index.d.ts | 33 +
node_modules/vue-demi/lib/index.iife.js | 115 +
node_modules/vue-demi/lib/index.mjs | 49 +
node_modules/vue-demi/lib/v2.7/index.cjs | 58 +
node_modules/vue-demi/lib/v2.7/index.d.ts | 38 +
node_modules/vue-demi/lib/v2.7/index.mjs | 80 +
node_modules/vue-demi/lib/v2/index.cjs | 32 +
node_modules/vue-demi/lib/v2/index.d.ts | 33 +
node_modules/vue-demi/lib/v2/index.mjs | 49 +
node_modules/vue-demi/lib/v3/index.cjs | 29 +
node_modules/vue-demi/lib/v3/index.d.ts | 22 +
node_modules/vue-demi/lib/v3/index.mjs | 34 +
node_modules/vue-demi/package.json | 47 +
node_modules/vue-demi/scripts/postinstall.js | 19 +
node_modules/vue-demi/scripts/switch-cli.js | 18 +
node_modules/vue-demi/scripts/utils.js | 62 +
node_modules/vue/LICENSE | 21 +
node_modules/vue/README.md | 386 +
node_modules/vue/dist/README.md | 122 +
node_modules/vue/dist/vue.common.dev.js | 12008 +++++++++++++++
node_modules/vue/dist/vue.common.js | 5 +
node_modules/vue/dist/vue.common.prod.js | 6 +
node_modules/vue/dist/vue.esm.browser.js | 12059 ++++++++++++++++
node_modules/vue/dist/vue.esm.browser.min.js | 6 +
node_modules/vue/dist/vue.esm.js | 12042 +++++++++++++++
node_modules/vue/dist/vue.js | 12014 +++++++++++++++
node_modules/vue/dist/vue.min.js | 6 +
.../vue/dist/vue.runtime.common.dev.js | 8467 +++++++++++
node_modules/vue/dist/vue.runtime.common.js | 5 +
.../vue/dist/vue.runtime.common.prod.js | 6 +
node_modules/vue/dist/vue.runtime.esm.js | 8495 +++++++++++
node_modules/vue/dist/vue.runtime.js | 8473 +++++++++++
node_modules/vue/dist/vue.runtime.min.js | 6 +
node_modules/vue/package.json | 150 +
node_modules/vue/src/compiler/codeframe.js | 50 +
.../vue/src/compiler/codegen/events.js | 190 +
.../vue/src/compiler/codegen/index.js | 619 +
.../vue/src/compiler/create-compiler.js | 75 +
.../vue/src/compiler/directives/bind.js | 11 +
.../vue/src/compiler/directives/index.js | 11 +
.../vue/src/compiler/directives/model.js | 148 +
.../vue/src/compiler/directives/on.js | 10 +
.../vue/src/compiler/error-detector.js | 128 +
node_modules/vue/src/compiler/helpers.js | 231 +
node_modules/vue/src/compiler/index.js | 25 +
node_modules/vue/src/compiler/optimizer.js | 128 +
.../vue/src/compiler/parser/entity-decoder.js | 11 +
.../vue/src/compiler/parser/filter-parser.js | 97 +
.../vue/src/compiler/parser/html-parser.js | 306 +
node_modules/vue/src/compiler/parser/index.js | 979 ++
.../vue/src/compiler/parser/text-parser.js | 53 +
node_modules/vue/src/compiler/to-function.js | 114 +
node_modules/vue/src/core/components/index.js | 5 +
.../vue/src/core/components/keep-alive.js | 152 +
node_modules/vue/src/core/config.js | 130 +
.../vue/src/core/global-api/assets.js | 34 +
.../vue/src/core/global-api/extend.js | 95 +
node_modules/vue/src/core/global-api/index.js | 69 +
node_modules/vue/src/core/global-api/mixin.js | 10 +
node_modules/vue/src/core/global-api/use.js | 23 +
node_modules/vue/src/core/index.js | 26 +
node_modules/vue/src/core/instance/events.js | 143 +
node_modules/vue/src/core/instance/index.js | 23 +
node_modules/vue/src/core/instance/init.js | 128 +
node_modules/vue/src/core/instance/inject.js | 73 +
.../vue/src/core/instance/lifecycle.js | 351 +
node_modules/vue/src/core/instance/proxy.js | 92 +
.../render-helpers/bind-dynamic-keys.js | 35 +
.../render-helpers/bind-object-listeners.js | 22 +
.../render-helpers/bind-object-props.js | 64 +
.../instance/render-helpers/check-keycodes.js | 35 +
.../src/core/instance/render-helpers/index.js | 33 +
.../instance/render-helpers/render-list.js | 50 +
.../instance/render-helpers/render-slot.js | 40 +
.../instance/render-helpers/render-static.js | 60 +
.../instance/render-helpers/resolve-filter.js | 10 +
.../render-helpers/resolve-scoped-slots.js | 27 +
.../instance/render-helpers/resolve-slots.js | 50 +
node_modules/vue/src/core/instance/render.js | 129 +
node_modules/vue/src/core/instance/state.js | 370 +
node_modules/vue/src/core/observer/array.js | 45 +
node_modules/vue/src/core/observer/dep.js | 66 +
node_modules/vue/src/core/observer/index.js | 276 +
.../vue/src/core/observer/scheduler.js | 190 +
.../vue/src/core/observer/traverse.js | 40 +
node_modules/vue/src/core/observer/watcher.js | 241 +
node_modules/vue/src/core/util/debug.js | 100 +
node_modules/vue/src/core/util/env.js | 96 +
node_modules/vue/src/core/util/error.js | 83 +
node_modules/vue/src/core/util/index.js | 11 +
node_modules/vue/src/core/util/lang.js | 46 +
node_modules/vue/src/core/util/next-tick.js | 110 +
node_modules/vue/src/core/util/options.js | 468 +
node_modules/vue/src/core/util/perf.js | 24 +
node_modules/vue/src/core/util/props.js | 250 +
.../vue/src/core/vdom/create-component.js | 270 +
.../vue/src/core/vdom/create-element.js | 166 +
.../core/vdom/create-functional-component.js | 155 +
.../src/core/vdom/helpers/extract-props.js | 75 +
.../vdom/helpers/get-first-component-child.js | 15 +
.../vue/src/core/vdom/helpers/index.js | 9 +
.../core/vdom/helpers/is-async-placeholder.js | 5 +
.../vue/src/core/vdom/helpers/merge-hook.js | 38 +
.../core/vdom/helpers/normalize-children.js | 89 +
.../vdom/helpers/normalize-scoped-slots.js | 86 +
.../vdom/helpers/resolve-async-component.js | 165 +
.../src/core/vdom/helpers/update-listeners.js | 95 +
.../vue/src/core/vdom/modules/directives.js | 120 +
.../vue/src/core/vdom/modules/index.js | 7 +
node_modules/vue/src/core/vdom/modules/ref.js | 45 +
node_modules/vue/src/core/vdom/patch.js | 803 +
node_modules/vue/src/core/vdom/vnode.js | 113 +
.../platforms/web/compiler/directives/html.js | 9 +
.../web/compiler/directives/index.js | 9 +
.../web/compiler/directives/model.js | 175 +
.../platforms/web/compiler/directives/text.js | 9 +
.../vue/src/platforms/web/compiler/index.js | 8 +
.../platforms/web/compiler/modules/class.js | 49 +
.../platforms/web/compiler/modules/index.js | 9 +
.../platforms/web/compiler/modules/model.js | 94 +
.../platforms/web/compiler/modules/style.js | 52 +
.../vue/src/platforms/web/compiler/options.js | 26 +
.../vue/src/platforms/web/compiler/util.js | 24 +
.../vue/src/platforms/web/entry-compiler.js | 6 +
.../web/entry-runtime-with-compiler.js | 101 +
.../vue/src/platforms/web/entry-runtime.js | 5 +
.../web/entry-server-basic-renderer.js | 13 +
.../platforms/web/entry-server-renderer.js | 27 +
.../src/platforms/web/runtime/class-util.js | 63 +
.../platforms/web/runtime/components/index.js | 7 +
.../runtime/components/transition-group.js | 190 +
.../web/runtime/components/transition.js | 198 +
.../platforms/web/runtime/directives/index.js | 7 +
.../platforms/web/runtime/directives/model.js | 147 +
.../platforms/web/runtime/directives/show.js | 60 +
.../vue/src/platforms/web/runtime/index.js | 76 +
.../platforms/web/runtime/modules/attrs.js | 119 +
.../platforms/web/runtime/modules/class.js | 48 +
.../web/runtime/modules/dom-props.js | 116 +
.../platforms/web/runtime/modules/events.js | 120 +
.../platforms/web/runtime/modules/index.js | 15 +
.../platforms/web/runtime/modules/style.js | 93 +
.../web/runtime/modules/transition.js | 343 +
.../vue/src/platforms/web/runtime/node-ops.js | 59 +
.../vue/src/platforms/web/runtime/patch.js | 12 +
.../platforms/web/runtime/transition-util.js | 190 +
.../vue/src/platforms/web/server/compiler.js | 11 +
.../platforms/web/server/directives/index.js | 7 +
.../platforms/web/server/directives/model.js | 44 +
.../platforms/web/server/directives/show.js | 12 +
.../src/platforms/web/server/modules/attrs.js | 67 +
.../src/platforms/web/server/modules/class.js | 11 +
.../platforms/web/server/modules/dom-props.js | 50 +
.../src/platforms/web/server/modules/index.js | 11 +
.../src/platforms/web/server/modules/style.js | 41 +
.../vue/src/platforms/web/server/util.js | 101 +
.../vue/src/platforms/web/util/attrs.js | 54 +
.../vue/src/platforms/web/util/class.js | 85 +
.../vue/src/platforms/web/util/compat.js | 16 +
.../vue/src/platforms/web/util/element.js | 77 +
.../vue/src/platforms/web/util/index.js | 25 +
.../vue/src/platforms/web/util/style.js | 71 +
.../weex/compiler/directives/index.js | 5 +
.../weex/compiler/directives/model.js | 33 +
.../vue/src/platforms/weex/compiler/index.js | 52 +
.../platforms/weex/compiler/modules/append.js | 27 +
.../platforms/weex/compiler/modules/class.js | 74 +
.../platforms/weex/compiler/modules/index.js | 13 +
.../platforms/weex/compiler/modules/props.js | 37 +
.../modules/recycle-list/component-root.js | 13 +
.../modules/recycle-list/component.js | 16 +
.../compiler/modules/recycle-list/index.js | 60 +
.../modules/recycle-list/recycle-list.js | 50 +
.../compiler/modules/recycle-list/text.js | 23 +
.../compiler/modules/recycle-list/v-bind.js | 21 +
.../compiler/modules/recycle-list/v-for.js | 33 +
.../compiler/modules/recycle-list/v-if.js | 63 +
.../compiler/modules/recycle-list/v-on.js | 25 +
.../compiler/modules/recycle-list/v-once.js | 19 +
.../platforms/weex/compiler/modules/style.js | 87 +
.../vue/src/platforms/weex/entry-compiler.js | 2 +
.../vue/src/platforms/weex/entry-framework.js | 187 +
.../platforms/weex/entry-runtime-factory.js | 6 +
.../weex/runtime/components/index.js | 9 +
.../weex/runtime/components/richtext.js | 82 +
.../runtime/components/transition-group.js | 148 +
.../weex/runtime/components/transition.js | 9 +
.../weex/runtime/directives/index.js | 2 +
.../vue/src/platforms/weex/runtime/index.js | 42 +
.../platforms/weex/runtime/modules/attrs.js | 44 +
.../platforms/weex/runtime/modules/class.js | 76 +
.../platforms/weex/runtime/modules/events.js | 54 +
.../platforms/weex/runtime/modules/index.js | 13 +
.../platforms/weex/runtime/modules/style.js | 84 +
.../weex/runtime/modules/transition.js | 270 +
.../src/platforms/weex/runtime/node-ops.js | 91 +
.../vue/src/platforms/weex/runtime/patch.js | 16 +
.../recycle-list/render-component-template.js | 34 +
.../runtime/recycle-list/virtual-component.js | 136 +
.../src/platforms/weex/runtime/text-node.js | 9 +
.../vue/src/platforms/weex/util/element.js | 52 +
.../vue/src/platforms/weex/util/index.js | 40 +
.../vue/src/platforms/weex/util/parser.js | 60 +
.../bundle-renderer/create-bundle-renderer.js | 151 +
.../bundle-renderer/create-bundle-runner.js | 150 +
.../bundle-renderer/source-map-support.js | 45 +
.../vue/src/server/create-basic-renderer.js | 37 +
.../vue/src/server/create-renderer.js | 152 +
.../src/server/optimizing-compiler/codegen.js | 264 +
.../src/server/optimizing-compiler/index.js | 20 +
.../src/server/optimizing-compiler/modules.js | 124 +
.../server/optimizing-compiler/optimizer.js | 141 +
.../optimizing-compiler/runtime-helpers.js | 150 +
node_modules/vue/src/server/render-context.js | 130 +
node_modules/vue/src/server/render-stream.js | 95 +
node_modules/vue/src/server/render.js | 437 +
.../create-async-file-mapper.js | 57 +
.../vue/src/server/template-renderer/index.js | 277 +
.../template-renderer/parse-template.js | 42 +
.../template-renderer/template-stream.js | 82 +
node_modules/vue/src/server/util.js | 18 +
.../vue/src/server/webpack-plugin/client.js | 67 +
.../vue/src/server/webpack-plugin/server.js | 69 +
.../vue/src/server/webpack-plugin/util.js | 73 +
node_modules/vue/src/server/write.js | 50 +
node_modules/vue/src/sfc/parser.js | 134 +
node_modules/vue/src/shared/constants.js | 22 +
node_modules/vue/src/shared/util.js | 343 +
node_modules/vue/types/index.d.ts | 39 +
node_modules/vue/types/options.d.ts | 207 +
node_modules/vue/types/plugin.d.ts | 8 +
node_modules/vue/types/umd.d.ts | 48 +
node_modules/vue/types/vnode.d.ts | 76 +
node_modules/vue/types/vue.d.ts | 132 +
package-lock.json | 105 +
package.json | 14 +
pages.json | 55 +
pages/index/index.vue | 102 +
pages/user/index.vue | 8 +
pages/webview/webview.vue | 31 +
pages/wikipedia/index.vue | 8 +
static/logo.png | Bin 0 -> 4023 bytes
static/tabs/cart.png | Bin 0 -> 4022 bytes
static/tabs/cart2.png | Bin 0 -> 2887 bytes
static/tabs/home.png | Bin 0 -> 3831 bytes
static/tabs/home2.png | Bin 0 -> 1376 bytes
static/tabs/order.png | Bin 0 -> 968 bytes
static/tabs/order2.png | Bin 0 -> 1185 bytes
static/tabs/share.png | Bin 0 -> 1449 bytes
static/tabs/user.png | Bin 0 -> 3805 bytes
static/tabs/user2.png | Bin 0 -> 2301 bytes
static/vip2.png | Bin 0 -> 128840 bytes
store/index.js | 150 +
uni.promisify.adaptor.js | 10 +
uni.scss | 76 +
uni_modules/uni-popup/changelog.md | 68 +
.../components/uni-popup-dialog/keypress.js | 45 +
.../uni-popup-dialog/uni-popup-dialog.vue | 275 +
.../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/popup.js | 26 +
.../components/uni-popup/uni-popup.vue | 473 +
uni_modules/uni-popup/package.json | 87 +
uni_modules/uni-popup/readme.md | 17 +
uni_modules/uni-scss/changelog.md | 8 +
uni_modules/uni-scss/index.scss | 1 +
uni_modules/uni-scss/package.json | 82 +
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 +
uni_modules/uni-scss/theme.scss | 31 +
uni_modules/uni-scss/variables.scss | 62 +
uni_modules/uni-transition/changelog.md | 22 +
.../uni-transition/createAnimation.js | 131 +
.../uni-transition/uni-transition.vue | 286 +
uni_modules/uni-transition/package.json | 84 +
uni_modules/uni-transition/readme.md | 11 +
utils/index.js | 81 +
377 files changed, 111630 insertions(+)
create mode 100644 App.vue
create mode 100644 api/index.js
create mode 100644 api/request.js
create mode 100644 components/.DS_Store
create mode 100644 components/customer-skeleton/customer-skeleton.vue
create mode 100644 components/emptyCard.vue
create mode 100644 components/goodsCard.vue
create mode 100644 components/goodsCart.vue
create mode 100644 components/goodsCartPay.vue
create mode 100644 components/goodsInfo.vue
create mode 100644 components/goodsSpecs.vue
create mode 100644 components/goodsSpecs2.vue
create mode 100644 components/i-skeleton/i-skeleton.vue
create mode 100644 components/mapPlat/mapPlat.nvue
create mode 100644 components/myButton.vue
create mode 100644 components/myCoupon.vue
create mode 100644 components/mySwiper.vue
create mode 100644 components/notice.vue
create mode 100644 components/searchBox.vue
create mode 100644 config/index.js
create mode 100644 index.html
create mode 100644 main.js
create mode 100644 manifest.json
create mode 100644 node_modules/.bin/vue-demi-fix
create mode 100644 node_modules/.bin/vue-demi-fix.cmd
create mode 100644 node_modules/.bin/vue-demi-fix.ps1
create mode 100644 node_modules/.bin/vue-demi-switch
create mode 100644 node_modules/.bin/vue-demi-switch.cmd
create mode 100644 node_modules/.bin/vue-demi-switch.ps1
create mode 100644 node_modules/.package-lock.json
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/api.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/app.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/component.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/context.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/hooks.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/index.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/api/util.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/const.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/env.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/index.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/plugin.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/proxy.js
create mode 100644 node_modules/@vue/devtools-api/lib/cjs/time.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/api.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/api.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/app.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/app.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/component.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/component.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/context.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/context.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/hooks.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/index.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/index.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/util.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/api/util.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/const.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/const.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/env.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/env.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/index.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/index.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/plugin.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/plugin.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/proxy.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/proxy.js
create mode 100644 node_modules/@vue/devtools-api/lib/esm/time.d.ts
create mode 100644 node_modules/@vue/devtools-api/lib/esm/time.js
create mode 100644 node_modules/@vue/devtools-api/package.json
create mode 100644 node_modules/pinia/LICENSE
create mode 100644 node_modules/pinia/README.md
create mode 100644 node_modules/pinia/dist/pinia.cjs
create mode 100644 node_modules/pinia/dist/pinia.d.ts
create mode 100644 node_modules/pinia/dist/pinia.esm-browser.js
create mode 100644 node_modules/pinia/dist/pinia.iife.js
create mode 100644 node_modules/pinia/dist/pinia.iife.prod.js
create mode 100644 node_modules/pinia/dist/pinia.mjs
create mode 100644 node_modules/pinia/dist/pinia.prod.cjs
create mode 100644 node_modules/pinia/index.cjs
create mode 100644 node_modules/pinia/index.js
create mode 100644 node_modules/pinia/package.json
create mode 100644 node_modules/vue-demi/LICENSE
create mode 100644 node_modules/vue-demi/README.md
create mode 100644 node_modules/vue-demi/bin/vue-demi-fix.js
create mode 100644 node_modules/vue-demi/bin/vue-demi-switch.js
create mode 100644 node_modules/vue-demi/lib/index.cjs
create mode 100644 node_modules/vue-demi/lib/index.d.ts
create mode 100644 node_modules/vue-demi/lib/index.iife.js
create mode 100644 node_modules/vue-demi/lib/index.mjs
create mode 100644 node_modules/vue-demi/lib/v2.7/index.cjs
create mode 100644 node_modules/vue-demi/lib/v2.7/index.d.ts
create mode 100644 node_modules/vue-demi/lib/v2.7/index.mjs
create mode 100644 node_modules/vue-demi/lib/v2/index.cjs
create mode 100644 node_modules/vue-demi/lib/v2/index.d.ts
create mode 100644 node_modules/vue-demi/lib/v2/index.mjs
create mode 100644 node_modules/vue-demi/lib/v3/index.cjs
create mode 100644 node_modules/vue-demi/lib/v3/index.d.ts
create mode 100644 node_modules/vue-demi/lib/v3/index.mjs
create mode 100644 node_modules/vue-demi/package.json
create mode 100644 node_modules/vue-demi/scripts/postinstall.js
create mode 100644 node_modules/vue-demi/scripts/switch-cli.js
create mode 100644 node_modules/vue-demi/scripts/utils.js
create mode 100644 node_modules/vue/LICENSE
create mode 100644 node_modules/vue/README.md
create mode 100644 node_modules/vue/dist/README.md
create mode 100644 node_modules/vue/dist/vue.common.dev.js
create mode 100644 node_modules/vue/dist/vue.common.js
create mode 100644 node_modules/vue/dist/vue.common.prod.js
create mode 100644 node_modules/vue/dist/vue.esm.browser.js
create mode 100644 node_modules/vue/dist/vue.esm.browser.min.js
create mode 100644 node_modules/vue/dist/vue.esm.js
create mode 100644 node_modules/vue/dist/vue.js
create mode 100644 node_modules/vue/dist/vue.min.js
create mode 100644 node_modules/vue/dist/vue.runtime.common.dev.js
create mode 100644 node_modules/vue/dist/vue.runtime.common.js
create mode 100644 node_modules/vue/dist/vue.runtime.common.prod.js
create mode 100644 node_modules/vue/dist/vue.runtime.esm.js
create mode 100644 node_modules/vue/dist/vue.runtime.js
create mode 100644 node_modules/vue/dist/vue.runtime.min.js
create mode 100644 node_modules/vue/package.json
create mode 100644 node_modules/vue/src/compiler/codeframe.js
create mode 100644 node_modules/vue/src/compiler/codegen/events.js
create mode 100644 node_modules/vue/src/compiler/codegen/index.js
create mode 100644 node_modules/vue/src/compiler/create-compiler.js
create mode 100644 node_modules/vue/src/compiler/directives/bind.js
create mode 100644 node_modules/vue/src/compiler/directives/index.js
create mode 100644 node_modules/vue/src/compiler/directives/model.js
create mode 100644 node_modules/vue/src/compiler/directives/on.js
create mode 100644 node_modules/vue/src/compiler/error-detector.js
create mode 100644 node_modules/vue/src/compiler/helpers.js
create mode 100644 node_modules/vue/src/compiler/index.js
create mode 100644 node_modules/vue/src/compiler/optimizer.js
create mode 100644 node_modules/vue/src/compiler/parser/entity-decoder.js
create mode 100644 node_modules/vue/src/compiler/parser/filter-parser.js
create mode 100644 node_modules/vue/src/compiler/parser/html-parser.js
create mode 100644 node_modules/vue/src/compiler/parser/index.js
create mode 100644 node_modules/vue/src/compiler/parser/text-parser.js
create mode 100644 node_modules/vue/src/compiler/to-function.js
create mode 100644 node_modules/vue/src/core/components/index.js
create mode 100644 node_modules/vue/src/core/components/keep-alive.js
create mode 100644 node_modules/vue/src/core/config.js
create mode 100644 node_modules/vue/src/core/global-api/assets.js
create mode 100644 node_modules/vue/src/core/global-api/extend.js
create mode 100644 node_modules/vue/src/core/global-api/index.js
create mode 100644 node_modules/vue/src/core/global-api/mixin.js
create mode 100644 node_modules/vue/src/core/global-api/use.js
create mode 100644 node_modules/vue/src/core/index.js
create mode 100644 node_modules/vue/src/core/instance/events.js
create mode 100644 node_modules/vue/src/core/instance/index.js
create mode 100644 node_modules/vue/src/core/instance/init.js
create mode 100644 node_modules/vue/src/core/instance/inject.js
create mode 100644 node_modules/vue/src/core/instance/lifecycle.js
create mode 100644 node_modules/vue/src/core/instance/proxy.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/bind-dynamic-keys.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/bind-object-props.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/check-keycodes.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/index.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-list.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-slot.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-static.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/resolve-filter.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/resolve-scoped-slots.js
create mode 100644 node_modules/vue/src/core/instance/render-helpers/resolve-slots.js
create mode 100644 node_modules/vue/src/core/instance/render.js
create mode 100644 node_modules/vue/src/core/instance/state.js
create mode 100644 node_modules/vue/src/core/observer/array.js
create mode 100644 node_modules/vue/src/core/observer/dep.js
create mode 100644 node_modules/vue/src/core/observer/index.js
create mode 100644 node_modules/vue/src/core/observer/scheduler.js
create mode 100644 node_modules/vue/src/core/observer/traverse.js
create mode 100644 node_modules/vue/src/core/observer/watcher.js
create mode 100644 node_modules/vue/src/core/util/debug.js
create mode 100644 node_modules/vue/src/core/util/env.js
create mode 100644 node_modules/vue/src/core/util/error.js
create mode 100644 node_modules/vue/src/core/util/index.js
create mode 100644 node_modules/vue/src/core/util/lang.js
create mode 100644 node_modules/vue/src/core/util/next-tick.js
create mode 100644 node_modules/vue/src/core/util/options.js
create mode 100644 node_modules/vue/src/core/util/perf.js
create mode 100644 node_modules/vue/src/core/util/props.js
create mode 100644 node_modules/vue/src/core/vdom/create-component.js
create mode 100644 node_modules/vue/src/core/vdom/create-element.js
create mode 100644 node_modules/vue/src/core/vdom/create-functional-component.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/extract-props.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/get-first-component-child.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/index.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/merge-hook.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/normalize-children.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/normalize-scoped-slots.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/resolve-async-component.js
create mode 100644 node_modules/vue/src/core/vdom/helpers/update-listeners.js
create mode 100644 node_modules/vue/src/core/vdom/modules/directives.js
create mode 100644 node_modules/vue/src/core/vdom/modules/index.js
create mode 100644 node_modules/vue/src/core/vdom/modules/ref.js
create mode 100644 node_modules/vue/src/core/vdom/patch.js
create mode 100644 node_modules/vue/src/core/vdom/vnode.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/html.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/index.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/model.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/text.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/index.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/class.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/index.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/model.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/style.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/options.js
create mode 100644 node_modules/vue/src/platforms/web/compiler/util.js
create mode 100644 node_modules/vue/src/platforms/web/entry-compiler.js
create mode 100644 node_modules/vue/src/platforms/web/entry-runtime-with-compiler.js
create mode 100644 node_modules/vue/src/platforms/web/entry-runtime.js
create mode 100644 node_modules/vue/src/platforms/web/entry-server-basic-renderer.js
create mode 100644 node_modules/vue/src/platforms/web/entry-server-renderer.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/class-util.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/components/index.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/components/transition-group.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/components/transition.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/index.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/model.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/show.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/index.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/attrs.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/class.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/dom-props.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/events.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/index.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/style.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/transition.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/node-ops.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/patch.js
create mode 100644 node_modules/vue/src/platforms/web/runtime/transition-util.js
create mode 100644 node_modules/vue/src/platforms/web/server/compiler.js
create mode 100644 node_modules/vue/src/platforms/web/server/directives/index.js
create mode 100644 node_modules/vue/src/platforms/web/server/directives/model.js
create mode 100644 node_modules/vue/src/platforms/web/server/directives/show.js
create mode 100644 node_modules/vue/src/platforms/web/server/modules/attrs.js
create mode 100644 node_modules/vue/src/platforms/web/server/modules/class.js
create mode 100644 node_modules/vue/src/platforms/web/server/modules/dom-props.js
create mode 100644 node_modules/vue/src/platforms/web/server/modules/index.js
create mode 100644 node_modules/vue/src/platforms/web/server/modules/style.js
create mode 100644 node_modules/vue/src/platforms/web/server/util.js
create mode 100644 node_modules/vue/src/platforms/web/util/attrs.js
create mode 100644 node_modules/vue/src/platforms/web/util/class.js
create mode 100644 node_modules/vue/src/platforms/web/util/compat.js
create mode 100644 node_modules/vue/src/platforms/web/util/element.js
create mode 100644 node_modules/vue/src/platforms/web/util/index.js
create mode 100644 node_modules/vue/src/platforms/web/util/style.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/directives/index.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/directives/model.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/index.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/append.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/class.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/index.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/props.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js
create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/style.js
create mode 100644 node_modules/vue/src/platforms/weex/entry-compiler.js
create mode 100644 node_modules/vue/src/platforms/weex/entry-framework.js
create mode 100644 node_modules/vue/src/platforms/weex/entry-runtime-factory.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/index.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/richtext.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition-group.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/directives/index.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/index.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/attrs.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/class.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/events.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/index.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/style.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/transition.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/node-ops.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/patch.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/render-component-template.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/virtual-component.js
create mode 100644 node_modules/vue/src/platforms/weex/runtime/text-node.js
create mode 100644 node_modules/vue/src/platforms/weex/util/element.js
create mode 100644 node_modules/vue/src/platforms/weex/util/index.js
create mode 100644 node_modules/vue/src/platforms/weex/util/parser.js
create mode 100644 node_modules/vue/src/server/bundle-renderer/create-bundle-renderer.js
create mode 100644 node_modules/vue/src/server/bundle-renderer/create-bundle-runner.js
create mode 100644 node_modules/vue/src/server/bundle-renderer/source-map-support.js
create mode 100644 node_modules/vue/src/server/create-basic-renderer.js
create mode 100644 node_modules/vue/src/server/create-renderer.js
create mode 100644 node_modules/vue/src/server/optimizing-compiler/codegen.js
create mode 100644 node_modules/vue/src/server/optimizing-compiler/index.js
create mode 100644 node_modules/vue/src/server/optimizing-compiler/modules.js
create mode 100644 node_modules/vue/src/server/optimizing-compiler/optimizer.js
create mode 100644 node_modules/vue/src/server/optimizing-compiler/runtime-helpers.js
create mode 100644 node_modules/vue/src/server/render-context.js
create mode 100644 node_modules/vue/src/server/render-stream.js
create mode 100644 node_modules/vue/src/server/render.js
create mode 100644 node_modules/vue/src/server/template-renderer/create-async-file-mapper.js
create mode 100644 node_modules/vue/src/server/template-renderer/index.js
create mode 100644 node_modules/vue/src/server/template-renderer/parse-template.js
create mode 100644 node_modules/vue/src/server/template-renderer/template-stream.js
create mode 100644 node_modules/vue/src/server/util.js
create mode 100644 node_modules/vue/src/server/webpack-plugin/client.js
create mode 100644 node_modules/vue/src/server/webpack-plugin/server.js
create mode 100644 node_modules/vue/src/server/webpack-plugin/util.js
create mode 100644 node_modules/vue/src/server/write.js
create mode 100644 node_modules/vue/src/sfc/parser.js
create mode 100644 node_modules/vue/src/shared/constants.js
create mode 100644 node_modules/vue/src/shared/util.js
create mode 100644 node_modules/vue/types/index.d.ts
create mode 100644 node_modules/vue/types/options.d.ts
create mode 100644 node_modules/vue/types/plugin.d.ts
create mode 100644 node_modules/vue/types/umd.d.ts
create mode 100644 node_modules/vue/types/vnode.d.ts
create mode 100644 node_modules/vue/types/vue.d.ts
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 pages.json
create mode 100644 pages/index/index.vue
create mode 100644 pages/user/index.vue
create mode 100644 pages/webview/webview.vue
create mode 100644 pages/wikipedia/index.vue
create mode 100644 static/logo.png
create mode 100644 static/tabs/cart.png
create mode 100644 static/tabs/cart2.png
create mode 100644 static/tabs/home.png
create mode 100644 static/tabs/home2.png
create mode 100644 static/tabs/order.png
create mode 100644 static/tabs/order2.png
create mode 100644 static/tabs/share.png
create mode 100644 static/tabs/user.png
create mode 100644 static/tabs/user2.png
create mode 100644 static/vip2.png
create mode 100644 store/index.js
create mode 100644 uni.promisify.adaptor.js
create mode 100644 uni.scss
create mode 100644 uni_modules/uni-popup/changelog.md
create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
create mode 100644 uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
create mode 100644 uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/en.json
create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/index.js
create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
create mode 100644 uni_modules/uni-popup/components/uni-popup/keypress.js
create mode 100644 uni_modules/uni-popup/components/uni-popup/popup.js
create mode 100644 uni_modules/uni-popup/components/uni-popup/uni-popup.vue
create mode 100644 uni_modules/uni-popup/package.json
create mode 100644 uni_modules/uni-popup/readme.md
create mode 100644 uni_modules/uni-scss/changelog.md
create mode 100644 uni_modules/uni-scss/index.scss
create mode 100644 uni_modules/uni-scss/package.json
create mode 100644 uni_modules/uni-scss/readme.md
create mode 100644 uni_modules/uni-scss/styles/index.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss
create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss
create mode 100644 uni_modules/uni-scss/theme.scss
create mode 100644 uni_modules/uni-scss/variables.scss
create mode 100644 uni_modules/uni-transition/changelog.md
create mode 100644 uni_modules/uni-transition/components/uni-transition/createAnimation.js
create mode 100644 uni_modules/uni-transition/components/uni-transition/uni-transition.vue
create mode 100644 uni_modules/uni-transition/package.json
create mode 100644 uni_modules/uni-transition/readme.md
create mode 100644 utils/index.js
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..b9168e8
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,168 @@
+
+
+
diff --git a/api/index.js b/api/index.js
new file mode 100644
index 0000000..262eb57
--- /dev/null
+++ b/api/index.js
@@ -0,0 +1,404 @@
+import net from './request.js';
+
+// import store from '../store';
+
+const API = {
+ /*
+ 首页信息
+ */
+ getIndexInfo: data => net.GET('/api/index/index'), // 首页信息
+ getIndexBanner: data => net.GET('/api/banner/index',data), // 轮播图
+ getIndexNotice: data => net.GET('/api/news/notice'), // 公告
+ getGoodsDetail: data => net.GET('/api/goods/detail',data),// 商品详情(普通商品)
+ getSeckillGoodsDetail: data => net.GET('/api/seckill_goods/detail',data),// 商品详情(秒杀)
+ getGroupGoodsDetail: data => net.GET('/api/group_goods/detail',data),// 商品详情(团购)
+ getGoodsList: data => net.GET('/api/goods/lists',data),// 商品列表(普通商品)
+ getSeckillGoodsList: data => net.GET('/api/seckill_goods/lists',data),// 商品列表(限时)
+ getGroupGoodsList: data => net.GET('/api/group_goods/lists?page=&keyword=',data),// 商品列表(团购)
+ getNewinfo: data => net.GET('/api/goods/getGoodsSpec',data), // 根据商品规格更新数据
+ getCategoryList:data => net.GET('/api/goods_category/lists'), // 获取商品分类
+ getCategory:data => net.GET('/api/goods/category',data), // 根据分类Id获取分类商品
+ getCartList:data => net.GET('/api/cart/lists',data), // 获取购物车列表
+ addCart:data => net.POST('/api/cart/add',data), // 加入购物车
+ delCart:data => net.POST('/api/cart/delete',data), // 删除购物车
+ updateCart:data => net.POST('/api/cart/edit',data), // 更新购物车
+ login:data => net.POST('/api/user/wechatLogin',data), // 登录
+ login_test:data => net.GET('/api/user/testLogin?id=1'), // 登录 测试专用
+ zhuce:data => net.POST('/api/user/profile',data), // 注册
+ getOrderList:data => net.GET('/api/order/lists',data), //订单列表
+ getOrderGroupList:data => net.GET('/api/group_order/lists',data), //订单列表(团购)
+ getOrderSeckillList:data => net.GET('/api/seckill_order/lists',data), //订单列表(秒杀)
+ pay:data => net.POST('/api/order/pay',data), //支付
+ payGroup:data => net.POST('/api/group_order/pay',data), //支付(团购)
+ paySeckill:data => net.POST('/api/seckill_order/pay',data), //支付(秒杀)
+ refund:data => net.POST('/api/order/refund',data), //退款
+ getOrderInviteList:data => net.GET('/api/invite/order',data), //分销订单
+
+ getOrderBaseinfo:data => net.POST('/api/order/preview',data), //获取订单提交页面的基本信息
+ getOrderGroupBaseinfo:data => net.POST('/api/group_order/preview',data), //获取订单提交页面的基本信息(团购)
+ getOrderSeckillBaseinfo:data => net.POST('/api/seckill_order/preview',data), //获取订单提交页面的基本信息(秒杀)
+ getOrderCartinfo:data => net.POST('/api/order/cartPreview',data), //获取订单提交页面的基本信息(购物车来的)
+ getDelivery:data => net.GET('/api/index/delivery',data), //获取配送相关的选项(普通商品)
+ staffApply:data => net.POST('/api/invite/apply',data), //业务员申请
+ deliveryApply:data => net.POST('/api/staff/apply',data), //配送员申请
+ getDeliveryArea:data => net.GET('/api/staff/getDeliveryArea'), //获取配送区域
+
+ getAddressList:data => net.GET('/api/address/lists'), //地址列表
+ getAddDetail:data => net.GET('/api/address/detail',data), //地址详情
+ addAddress:data => net.POST('/api/address/add',data), //新增地址
+ editAddress:data => net.POST('/api/address/edit',data), //修改地址
+ delAddress:data => net.GET('/api/address/delete',data), //删除地址
+ getDefaultAddress:data => net.GET('/api/address/getDefault'), //获取默认地址
+
+ orderSubmitFunc:data => net.POST('/api/order/order',data), //提交订单(普通订单)
+ orderSubmitCartFunc:data => net.POST('/api/order/cartOrder',data), //提交订单(购物车)
+ orderSubmitGroupFunc:data => net.POST('/api/group_order/order',data), //提交订单(团购订单)
+ orderSubmitSeckillFunc:data => net.POST('/api/seckill_order/order',data), //提交订单(秒杀订单)
+
+ orderDetail:data => net.GET('/api/order/detail',data), //订单详情-普通订单 (顾客)
+ orderGroupDetail:data => net.GET('/api/group_order/detail',data), //订单详情-团购订单
+ orderSeckillDetail:data => net.GET('/api/seckill_order/detail',data), //订单详情-秒杀订单
+ orderStaffDetail:data => net.GET('/api/staff/orderDetail',data), //订单详情-配送订单
+ orderLeaderDetail:data => net.GET('/api/leader/orderDetail',data), //订单详情-管理员订单
+ orderCancel:data => net.POST('/api/order/cancle',data), //取消订单
+ orderCancelGroup:data => net.POST('/api/group_order/cancle',data), //取消订单 (团购)
+ orderCancelSeckill:data => net.POST('/api/seckill_order/cancle',data), //取消订单 (秒杀)
+ /*
+ 用户相关
+ */
+ getUserInfo:data => net.GET('/api/user/userInfo',data), //获取用户信息
+ updateUserInfo:data => net.POST('/api/user/profile',data), //更新用户信息
+ rechargeFunc:data => net.POST('/api/recharge/recharge',data), //充值
+ withdrawalFunc:data => net.POST('/api/withdrawl/submit',data), //提现
+ vipBuy:data => net.POST('/api/vip/order',data), //购买VIP
+ vipConfig:data => net.GET('/api/vip/config'), //会员说明
+
+ /*
+ 优惠券
+ */
+ getCouponsList:data => net.GET('/api/coupon/userCoupons',data), //优惠券
+ getCouponsCenterList:data => net.GET('/api/coupon/lists',data), //领券中心
+ couponsCenterReceive:data => net.POST('/api/coupon/receive',data), //领取优惠
+
+ getMyStars:data => net.GET('/api/collect/lists',data), //我的收藏
+ /*
+ 推广中心
+ */
+ inviteCenter:data => net.GET('/api/invite/index',data), //首页
+ inviteCenterwithdrawl:data => net.POST('/api/withdrawl/submit',data), //提现
+ inviteCenterwithdrawlDetail:data => net.GET('/api/invite/withdrawlDetail',data), //提现明细
+ inviteCenterwithdrawlRecodes:data => net.GET('/api/invite/record',data), //提现明细(佣金)
+ getShareQrcode:data => net.GET('/api/user/getShareQrcode'), //用户分销二维码
+ /*
+ 配置相关
+ */
+ getConfig:data => net.GET('/api/index/config'),
+ setDeliveryTime:data => net.POST('/api/staff/setDeliveryTime',data), // 设置配送时间
+ getDeliveryTime:data => net.GET('/api/staff/getDeliveryTime'), // 获取配送时间
+ getStaffOrder:data => net.GET('/api/staff/orderLists',data), // 获取订单管理列表(配送员)
+ getManageOrder:data => net.GET('/api/leader/orderLists',data), // 获取订单管理列表(团长)
+ deliveryPhoto:data => net.POST('/api/staff/deliveryPhoto',data), // 送达拍照
+ reveiceOrder:data => net.POST('/api/staff/reveiceOrder',data), // 接单
+ reveiceOrderOk:data => net.POST('/api/leader/assignOrder',data), // 派单
+ getStaffList:data => net.GET('/api/leader/staffList'), // 配送员列表
+ goodsBuyFunc:data => net.POST('/api/leader/goodsBuy',data), // 商品申购
+ getRecordList:data => net.GET('/api/leader/recordList',data), // 货物入库
+ /**
+ *
+ * 登录类信息
+ *
+ */
+ // 检查更新
+ getUpdateVersion:data => net.GET('/api/v1/index/version'),
+ // 获取定位
+ getLocationInfo:data => net.GET('/api/v1/index/ip',data),
+ // 验证码登陆
+ codeLogin: data => net.POST('/code/login', data),
+ // H5扫码登录邀请接口
+ inviteLogin: data => net.POST('/api/v1/invite/login', data),
+ // 发送手机验证码接口
+ sendVerifyCode: data => net.POST('/api/v1/sms/send', { send_type: 'student', ...data}),
+ // 注销账号
+ unRegister: data => net.POST('/api/v1/student/delete', data),
+ // 授权登录
+ accessLogin: (data, t = 'wx') => net.POST(`/api/v1/${t}/login`, data),
+ // 退出登录
+ logOut: data => net.POST('/api/v1/code/logout', data),
+
+ // 获取省份
+ getProvince: data => net.GET('/api/v1/colleges/getProvince', data),
+ // 根据学员所选择的教学点获取院校列表接口
+ collegesList: data => net.GET('/api/v1/colleges/list', data),
+ // 通过市反查省/自治区/直辖市
+ getProvinceByCity: data => net.GET('/api/v1/region/getProvinceByCity', data),
+
+ /**
+ *
+ * 用户信息
+ *
+ */
+
+ // 学员个人信息接口
+ selectUserInfo: data => net.GET('/api/v1/student/info', data),
+ // 登录成功后填写学员信息接口
+ userUpdate: data => net.POST('/api/v1/student/update', data),
+ // 邀请二维码
+ qrcode: data => net.POST('/api/v1/student/invite/qrcode', data),
+ uploadBase64: data => net.POST('/api/v1/student/uploadBase64', data),
+ // 获取被邀请人列表接口
+ inviteList: data => net.GET('/api/v1/student/invite/list', data),
+ // 积分列表
+ scoreList: data => net.GET('/point', data),
+ // 余额明细
+ balanceList: data => net.POST('/api/v1/balance/detail/get/list', data),
+ // 模拟测试记录
+ recordList: data => net.GET('/api/v1/test-record/mock/examination/record', data),
+ // 练习题错误集详情
+ practiceList: data => net.GET('/api/v1/test-record/practice/list', data),
+
+ /**
+ *
+ * 首页数据
+ *
+ */
+ // 首页配置获取
+ indexConfig: data => net.GET('/api/v1/index/config', data),
+ // 轮播
+ // indexBanner: data => net.GET('/app/banner', data),
+ indexBanner: data => net.POST('/api/v1/index/lbt', data),
+ // 获取咨询文章列表
+ // wzList: data => net.GET('/app/consult-wz', data),
+ wzList: data => net.POST('/api/v1/index/wz/list', data),
+ // 获取咨询文章
+ // wzInfo: id => net.GET(`/app/consult-wz/${id}`),
+ wzInfo: id => net.GET(`/api/v1/index/wz/${id}`),
+
+ // 获取课程分页
+ getCourseList: (data) => net.GET(`/app/course/page`,data),
+
+ // 获取推荐院校列表
+ // recommendwzList: data => net.GET('/app/academy', data),
+ recommendwzList: data => net.POST('/api/v1/index/academy/list', data),
+ // 获取推荐院校文章
+ // recommendwzInfo: id => net.GET(`/app/academy/${id}`),
+ recommendwzInfo: id => net.GET(`/api/v1/index/academy/${id}`),
+ // 推荐院校文章阅读量累计
+ // recomendaddReadNumber: data => net.PUT('/app/academy/num',data),
+ recomendaddReadNumber: data => net.POST('/api/v1/index/academy/add/num', data),
+
+ //获取考试大纲列表
+ syllabusList: data => net.POST('/api/v1/index/syllabus/list', data),
+
+ // 搜索
+ search: data => net.POST('/api/v1/index/search', data),
+ // 阅读量累计
+ addReadNumber: data => net.PUT('/app/consult-wz/num', data),
+ // 师资团队列表
+ lecturerList: data => net.GET('/api/v1/index/lecturer', data),
+ // 师资详情
+ lecturerDetail: id => net.GET(`/api/v1/index/lecturer/${id}`),
+ // 获取资料列表
+ indexMaterial: data => net.GET('/api/v1/index/material', data),
+ // indexMaterial: data => net.GET('/app/material', data),
+ // 获取资料详情
+ materialDetail: data => net.GET(`/api/v1/index/material/${data.id}`,{buyer_id:data.buyer_id}),
+ // 获取精品课程
+ indexBoutiqueCourse: data => net.GET('/api/v1/index/boutique/course', data),
+ // 获取精品课程详情
+ boutiqueCourseDetail: id => net.GET(`/api/v1/index/boutique/course/${id}`),
+
+ // 获取课程
+ courseList: data => net.POST('/api/v1/course/get', data),
+ // 获取套餐
+ comboList: data => net.POST('/api/v1/combo/course/get', data),
+ // courseList: data => net.GET('/app/course/page', data),
+ // 获取课程详情
+ courseDetail: (id, data) => net.GET(`/api/v1/course/${id}`, data),
+ // courseDetail: (id, data) => net.GET(`/app/course`, {id}),
+ // 获取线下课程
+ offlineCourseList: data => net.POST('/api/v1/offline/course/get', data),
+ // 获取线下课程详情
+ offlineCourseDetail: id => net.GET(`/api/v1/offline/course/${id}`),
+ // 获取套餐课程详情
+ getComboDetail: data => net.GET(`/api/v1/combo/course/${data.id}`,{buyer_id:data.buyer_id}),
+
+ // 获取直播课列表
+ // liveCourseList: data => net.GET('/api/v1/sys-course-live', data),
+ liveCourseList: data => net.GET('/api/v1/api-live-course', data),
+ // 直播课详情
+ viewCourse: (id, data) => net.GET('/api/v1/sys-course-live/'+id,{buyer_id:data.buyer_id}),
+ // 直播课详情 测试
+ viewCourse_test: (id, data) => net.GET('/api/v1/api-live-course/'+id,{buyer_id:data.buyer_id}),
+ /*题库 管理*/
+ //题库
+ getQuestionExercise:data => net.GET('/exercises', data),
+
+ // 科目
+ subjectList: data => net.GET('/api/v1/public/subject', data),
+ // subjectList: data => net.GET('/app/subject/list', data),
+ // 获取学员学习列表接口
+ learningList: data => net.GET('/api/v1/learning', data),
+ // 学习课程详情
+ learningDetail: data => net.GET(`/api/v1/learning/course/${data}`),
+ // 学习直播课程详情
+ learningLiveDetail: data => net.GET(`/api/v1/learning/course/live/${data}`),
+ // 学员学习计时接口
+ // "time_type": "stop" //计时类型 start-开始计时 stop-停止计时
+ studyDuration: data => net.POST('/api/v1/learning/course/duration', data),
+ // 学习统计API
+ courseStatistics: data => net.POST('/api/v1/learning/course/statistics', data),
+ // 题型分类
+ questionBankType: data => net.GET('/api/v1/questionBank/type', data),
+ // 网课、测试、题库详情
+ exercisesDetails: data => net.GET(`/api/v1/exercises/detail/${data}`),
+ // 测试练习题列表
+ testList: data => net.GET('/api/v1/exercises/test/list', data),
+ // 模拟试卷列表
+ examinationList: data => net.GET('/api/v1/examination/list', data),
+ // 获取题库、网课题目列表接口
+ exerciseSubjectList: data => net.GET('/api/v1/exercise/subject/list', data),
+ // 试题分类
+ exercisesType: data => net.GET('/api/v1/exercises/type', data),
+ // 模拟题详情
+ examinationDetail: id => net.GET(`/api/v1/examination/detail/${id}`),
+ // 开始答题
+ startTest: data => net.POST('/api/v1/exercises/start/answer', data),// question_bank_id
+ // 交卷
+ submitTest: data => net.POST('/api/v1/exercises/submit', data),
+ // 下一题
+ nextSubject: data => net.POST('/api/v1/exercises/next', data),
+ // 重新答题
+ againAnswer: data => net.POST('/api/v1/exercises/againAnswer', data),
+ // 答题成绩报告
+ scoreReport: data => net.GET('/api/v1/exercises/achievement/report', data),
+ // 获取团购列表
+ getGroupList: data => net.GET('/api/v1/group/page', data),
+ // 获取团购详情
+ getGroupPurchaseData: data => net.GET('/api/v1/group', data),
+ //发起拼团
+ starGroupPurchase:data => net.POST('/api/v1/group',data),
+ //加入拼团
+ joinGroupPurchase:data => net.POST('/api/v1/group/join',data),
+ /**
+ *
+ * 支付接口
+ *
+ */
+ // 支付接口
+ wxOrAlipay: data => net.POST('/api/v1/pay', data),
+ // 获取openid
+ getOpenID: data => {
+ return uni.request({
+ url:'https://api.weixin.qq.com/sns/oauth2/access_token',
+ method:'GET',
+ // header: {
+ // ...header,
+ // ...headers
+ // },
+ data
+ })
+ },
+ // 余额支付
+ yuePay: data => net.POST('/api/v1/student/pay/balance', data),
+ //H5下单API
+ // v3_pay:data => net.POST('https://api.mch.weixin.qq.com/v3/pay/transactions/h5',data)
+ v3_pay:data => {
+ return uni.request({
+ url: 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5',
+ method:'POST',
+ header: {
+ "Content-Type": "application/json",
+ },
+ data
+ })
+ },
+ //测试
+ pay_check:data => net.POST('/api/v1/wxpay/check',data),
+ pay_callback:data => net.POST('/api/v1/wxpay/callback',data),
+ /**
+ *
+ * 地址接口
+ *
+ */
+ // 列表
+ addressList: data => net.POST('/api/v1/address', data), // student_id
+ // 新增/编辑
+ addressAction: data => net.POST(`/api/v1/address/add`, data),
+ editaddressAction: data => net.PUT(`/api/v1/address`, data),
+ // 删除
+ addressDelete: data => net.DELETE('/api/v1/address', data), // id
+
+ /**
+ *
+ * 购物车接口
+ *
+ */
+ // 列表
+ cartList: data => net.POST('/api/v1/shopping/cart', data),
+ // 添加
+ cartAdd: data => net.POST('/api/v1/shopping/cart/add', data),
+ // 编辑
+ cartUpdate: data => net.POST('/api/v1/shopping/cart/update', data),
+ // 删除
+ cartDelete: data => net.POST('/api/v1/shopping/cart/delete', data), // id
+
+ /**
+ *
+ * 订单接口
+ *
+ */
+
+ // 订单查询
+ orderList: data => net.POST('/api/v1/api-order/get/my/order/list', data),
+ // 确认收货
+ orderUpdate: data => net.POST('/api/v1/api-order/update/material/order', data),
+ // 删除
+ orderDelete: data => net.POST('/api/v1/api-order/delete/order', data),
+
+ /**
+ * 商品价格合计
+ * @param { order_count_list: [{ id: '', order_type: '', num: ''}] }
+ *
+ */
+ orderCount: data => net.POST('/api/v1/api-order/order/count', data),
+
+ /**
+ * 资料,在线课程的立即购买/购物车
+ * @param { goods: [{ id: '', order_type: '', num: ''}], student_id: '' }
+ *
+ */
+ orderBuynow: data => net.POST('/api/v1/api-order/order/buynow', data),
+ // 新增资料订单
+ orderMaterialAdd: data => net.POST('/api/v1/api-order/add/material/order', data),
+ // 新增在线课程订单
+ orderOnlineAdd: data => net.POST('/api/v1/api-order/add/online/order', data),
+ // 直播课订单
+ orderLiveAdd: data => net.POST('/api/v1/api-order/add/live/order', data),
+ // 新增套餐课程订单
+ orderComboAdd: data => net.POST('/api/v1/api-order/add/combo/order', data),
+ // 新增线下订单==报名
+ orderOfflineAdd: data => net.POST('/api/v1/api-order/add/offline/order', data),
+ // 新增团购订单
+ orderGroupAdd: data => net.POST('/api/v1/api-order/add/group/order', data),
+
+ // 分享平台
+ shareProvider: () => net.getShareProvider(),
+ // 支付方式
+ paymentProvider: () => net.getPaymentProvider(),
+ // 物流查询
+ queryKuaidi: data => net.POST('/api/v1/kuaidi/poll/query', data),
+
+ // SHARE: () => net.SHARE(),
+
+ // 提现
+ transfer: data => net.POST('/api/v1/wxpay/transfer', data),
+
+ // 获取我的收藏分页列表
+ getStarList: data => net.POST('/api/v1/favorite/get', data),
+ // 取消收藏
+ cancelStar: data => net.DELETE('/api/v1/favorite',data),
+ //添加收藏
+ addStar:data => net.POST('/api/v1/favorite',data)
+};
+
+export default API
\ No newline at end of file
diff --git a/api/request.js b/api/request.js
new file mode 100644
index 0000000..58da4ab
--- /dev/null
+++ b/api/request.js
@@ -0,0 +1,208 @@
+import config from '../config'
+
+// import store from '../store'
+
+const loginUrl = 'pages/user/login';
+
+export default {
+ REQUEST(url, method = 'GET', data, checkLogin = true, header) {
+ let token = uni.getStorageSync('access_token') || '';
+ const headers = {
+ "Content-Type": "application/json",
+ "Authorization": token,
+ "x-token": token,
+ "token":token,
+ // "X-Forwarded-For":'client_ip'
+ // 'Referer':'twzxjy.com'
+ }
+ var pages = getCurrentPages();
+ var page = pages[pages.length - 1];
+
+ return uni.request({
+ url: config.baseUrl + url,
+ method,
+ header: {
+ ...header,
+ ...headers
+ },
+ data
+ }).then(res => {
+ // console.log(res)
+ if (res.statusCode === 200 && res.data) {
+ if (res.data.code === 409) {
+ uni.showModal({
+ title:"提示",
+ content:"您的账号已在其他设备登录,已强制下线!",
+ confirmColor: '#006647',
+ showCancel: false,
+ success: (res) => {
+ if (res.confirm) {
+ uni.removeStorageSync('access_token');
+ uni.removeStorageSync('user_info');
+ if (checkLogin && page.route != loginUrl) {
+ uni.navigateTo({
+ url: '/' + loginUrl
+ });
+ }
+ }
+ }
+ });
+ return {
+ ...res.data
+ }
+ }
+ if (res.data.code === 5) { // 用户认证失败
+ uni.removeStorageSync('access_token');
+ if(page.route != loginUrl && checkLogin) {
+ uni.navigateTo({
+ url: '/' + loginUrl
+ });
+ }
+ }
+ return res.data;
+ } else {
+ const reg = /abort/;
+ let code = 0;
+ let msg = (res[0] && res[0].errMsg) || '未知错误';
+ if ((res[0] && res[0].errMsg) && reg.test(res[0].errMsg)) {
+ msg = '网络请求中断'
+ }
+ return {
+ code,
+ msg,
+ data: null
+ }
+ }
+ }).catch(parmas => {
+ // console.log(params)
+ return parmas
+ // return Promise.reject()
+ })
+ },
+
+ GET(url, body, checkLogin = true, header) {
+ return this.REQUEST(url, 'GET', body, checkLogin, header);
+ },
+ POST(url, body, checkLogin = true, header) {
+ return this.REQUEST(url, 'POST', body, checkLogin, header);
+ },
+ PUT(url, body, header) {
+ return this.REQUEST(url, 'PUT', body, header);
+ },
+ DELETE(url, body, header) {
+ return this.REQUEST(url, 'DELETE', body, header);
+ },
+ UPLOAD(data) {
+ return new Promise((resolve, reject) => {
+ let token = uni.getStorageSync('access_token') || '';
+ uni.uploadFile({
+ ...data,
+ url: config.base_url + data.url,
+ header: {
+ "Access-Token": token
+ },
+ success(res) {
+ res.data = JSON.parse(res.data);
+ if (res.data.code === 401) {
+ uni.removeStorageSync('access_token');
+ uni.removeStorageSync('userInfo');
+
+ uni.navigateTo({
+ url: '/pages/login/login'
+ });
+ }
+ resolve(res);
+ },
+ fail(e) {
+ console.log(e);
+ reject(e)
+ },
+ });
+ });
+ },
+ getShareProvider: () => {
+ return uni.getProvider({
+ service: "share"
+ }).then(res => {
+ let data = []
+ for (let i = 0; i < res.provider.length; i++) {
+ switch (res.provider[i]) {
+ case 'weixin':
+ data.push({
+ name: '微信好友',
+ id: 'weixin',
+ icon: '/static/wx.png'
+ })
+ data.push({
+ name: '朋友圈',
+ id: 'weixin',
+ type: 'WXSenceTimeline',
+ icon: '/static/pyq.png'
+ })
+ break;
+ case 'qq':
+ data.push({
+ name: 'QQ好友',
+ id: 'qq',
+ icon: '/static/qq.png'
+ })
+ break;
+ default:
+ break;
+ }
+ }
+ return data;
+ }).catch(parmas => {
+ return Promise.reject()
+ });
+ },
+ getPaymentProvider: () => {
+ return uni.getProvider({
+ service: "payment"
+ }).then(res => {
+ let data = [];
+ const aliPay = {
+ name: '支付宝支付',
+ id: 'alipay',
+ icon: '/static/order/zfbp@3x.png'
+ };
+
+ const wxPay = {
+ name: '微信支付',
+ id: 'wxpay',
+ icon: '/static/order/wxp@3x.png'
+ };
+
+ const yuePay = {
+ name: '余额支付',
+ id: 'yepay',
+ icon: '/static/order/yep@3x.png'
+ }
+
+ for (let i = 0; i < res[1].provider.length; i++) {
+ switch (res[1].provider[i]) {
+ case 'alipay':
+ data.push({
+ ...aliPay
+ })
+ break
+ case 'wxpay':
+ data.push({
+ ...wxPay
+ })
+ break;
+ default:
+ break;
+ }
+ }
+
+ //#ifdef H5
+ return [aliPay, wxPay, yuePay];
+ //#endif
+
+ return [...data, yuePay];
+ }).catch(parmas => {
+ return Promise.reject()
+ });
+ }
+}
diff --git a/components/.DS_Store b/components/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..fab258072ad8b8e771369928787c83a16eed7d43
GIT binary patch
literal 6148
zcmeHK%}OId5U!3{)1xc|QOL1juMrdfAb1&L6uj<;d)SqjaRwcnOb?lfIfTHR_2$#~
z0v^5Y>#Ws3k<}RRB+F6-)n9dW)%5h&L-!N_u=X%$0#pHjqbe*p*t{cZTOdb?1*3wC3daqb#*K
z4}Ka)S>9;;W~GJlm&FRN@MV7HUCEJ`_wr%Z?hSsb-ieg4Kec=QX%vpS)zt%;{f
z2Rb1NLJax!BT51}YRh2~WIER~1KiD9;Pzwri1ER#!|bGpXAUYSf{fEXYKGz0d0;LF4ZF+dCu18*2m=Yv31=vpic>Z1c2
zT>>DM(X9n-^}DEYghkh4VGu`9m`O!6smzub%%r1V*f`f>VbG)lv&9FqGc#MEFg-gy
zU+8dPu0d*v0b<}a0}G~GRrmkl{QCcO67`4yV&K1GfR#I5r;SUpck9gJ)Lko3&ry}A
oxWeE|3L5$<##nU~*HE>fUnm37wOANL4+{MVXd0*?20oR6XaD4W_y7O^
literal 0
HcmV?d00001
diff --git a/components/customer-skeleton/customer-skeleton.vue b/components/customer-skeleton/customer-skeleton.vue
new file mode 100644
index 0000000..9db4ff8
--- /dev/null
+++ b/components/customer-skeleton/customer-skeleton.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/emptyCard.vue b/components/emptyCard.vue
new file mode 100644
index 0000000..e6896c4
--- /dev/null
+++ b/components/emptyCard.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+ {{title?title:'暂无数据...'}}
+ {{message?message:''}}
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsCard.vue b/components/goodsCard.vue
new file mode 100644
index 0000000..39d8605
--- /dev/null
+++ b/components/goodsCard.vue
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+ {{item.goods_name}}
+
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsCart.vue b/components/goodsCart.vue
new file mode 100644
index 0000000..fd295b7
--- /dev/null
+++ b/components/goodsCart.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsCartPay.vue b/components/goodsCartPay.vue
new file mode 100644
index 0000000..16e093f
--- /dev/null
+++ b/components/goodsCartPay.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+ {{cart_list.length}}
+
+
+
+ ¥{{totalprice}}
+
+
+
+
+
+
+
+ 去结算
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsInfo.vue b/components/goodsInfo.vue
new file mode 100644
index 0000000..6007912
--- /dev/null
+++ b/components/goodsInfo.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+ {{info?.goods_name}}
+
+ {{info?.desc}}
+
+
+
+ ¥{{info?.sell_price}}
+
+ ¥{{info?.market_price}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{info?.goods_name}}
+
+ {{info?.desc}}
+
+
+
+ ¥{{info?.sell_price}}
+
+ ¥{{info?.market_price}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsSpecs.vue b/components/goodsSpecs.vue
new file mode 100644
index 0000000..ada8f5e
--- /dev/null
+++ b/components/goodsSpecs.vue
@@ -0,0 +1,439 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/goodsSpecs2.vue b/components/goodsSpecs2.vue
new file mode 100644
index 0000000..7cbd4e0
--- /dev/null
+++ b/components/goodsSpecs2.vue
@@ -0,0 +1,9 @@
+
+
+
+ 测试
+
+
+
\ No newline at end of file
diff --git a/components/i-skeleton/i-skeleton.vue b/components/i-skeleton/i-skeleton.vue
new file mode 100644
index 0000000..f056c5d
--- /dev/null
+++ b/components/i-skeleton/i-skeleton.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/mapPlat/mapPlat.nvue b/components/mapPlat/mapPlat.nvue
new file mode 100644
index 0000000..27ff583
--- /dev/null
+++ b/components/mapPlat/mapPlat.nvue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/myButton.vue b/components/myButton.vue
new file mode 100644
index 0000000..f77d399
--- /dev/null
+++ b/components/myButton.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/myCoupon.vue b/components/myCoupon.vue
new file mode 100644
index 0000000..229d835
--- /dev/null
+++ b/components/myCoupon.vue
@@ -0,0 +1,298 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/mySwiper.vue b/components/mySwiper.vue
new file mode 100644
index 0000000..c1811ce
--- /dev/null
+++ b/components/mySwiper.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/notice.vue b/components/notice.vue
new file mode 100644
index 0000000..efd7cef
--- /dev/null
+++ b/components/notice.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+ {{list[0]?.content}}
+
+
+
+ 更多
+
+
+
+
+
+
+
+
+ {{item?.content}}
+
+
+
+
+ 收起
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/searchBox.vue b/components/searchBox.vue
new file mode 100644
index 0000000..65a765c
--- /dev/null
+++ b/components/searchBox.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/index.js b/config/index.js
new file mode 100644
index 0000000..84dfcd8
--- /dev/null
+++ b/config/index.js
@@ -0,0 +1,21 @@
+// isdev 为 true 表示开发环境 false 表示发布环境
+const isdev = true;
+const baseUrl = isdev ? 'http://niunai.zhitou1688.com' : 'http://niunai.zhitou1688.com';// 办公室接口 & 测试环境
+// const baseUrl = isdev ? 'http://192.168.1.133:8899' : 'https://api.gwkjxb.com';// 办公室接口 & 正式环境
+// const baseUrl = 'https://api.gwkjxb.com';// 正式环境(由于本地测试后台没有启动,暂时通用正式服)
+
+// const baseUrl = isdev ? 'http://1.117.68.37:8000' : 'https://apiwx.twzxjy.com';// 支付测试接口
+const shareUrl = isdev ? 'https://h5.gwkjxb.com/' : 'http://test_h5.gwkjxb.com/';
+const teacher_admin_url = 'http://teacher.gwkjxb.com/#/login'
+const config = {
+ appName: '牛奶配送',
+ baseUrl,
+ appVersion: '1.0.6',
+ developer: '牛奶配送',
+ // appLogo: require('../static/logo.png'),
+ shareUrl,
+ teacher_admin_url,
+ appID:'wx2a050f9a5c87a6dc',
+ isdev
+}
+export default config
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c3ff205
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..6983d08
--- /dev/null
+++ b/main.js
@@ -0,0 +1,24 @@
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import * as Pinia from 'pinia';
+import { createSSRApp } from 'vue'
+export function createApp() {
+ const app = createSSRApp(App)
+ app.use(Pinia.createPinia())
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..0f88dd7
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,72 @@
+{
+ "name" : "vision-record",
+ "appid" : "__UNI__A2B2065",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "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
+ },
+ "vueVersion" : "3"
+}
diff --git a/node_modules/.bin/vue-demi-fix b/node_modules/.bin/vue-demi-fix
new file mode 100644
index 0000000..dba2771
--- /dev/null
+++ b/node_modules/.bin/vue-demi-fix
@@ -0,0 +1,12 @@
+#!/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
+ exec "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@"
+else
+ exec node "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@"
+fi
diff --git a/node_modules/.bin/vue-demi-fix.cmd b/node_modules/.bin/vue-demi-fix.cmd
new file mode 100644
index 0000000..567cf78
--- /dev/null
+++ b/node_modules/.bin/vue-demi-fix.cmd
@@ -0,0 +1,17 @@
+@ECHO off
+GOTO start
+:find_dp0
+SET dp0=%~dp0
+EXIT /b
+:start
+SETLOCAL
+CALL :find_dp0
+
+IF EXIST "%dp0%\node.exe" (
+ SET "_prog=%dp0%\node.exe"
+) ELSE (
+ SET "_prog=node"
+ SET PATHEXT=%PATHEXT:;.JS;=;%
+)
+
+endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-fix.js" %*
diff --git a/node_modules/.bin/vue-demi-fix.ps1 b/node_modules/.bin/vue-demi-fix.ps1
new file mode 100644
index 0000000..adecc34
--- /dev/null
+++ b/node_modules/.bin/vue-demi-fix.ps1
@@ -0,0 +1,28 @@
+#!/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") {
+ # Support pipeline input
+ if ($MyInvocation.ExpectingInput) {
+ $input | & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
+ } else {
+ & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
+ }
+ $ret=$LASTEXITCODE
+} else {
+ # Support pipeline input
+ if ($MyInvocation.ExpectingInput) {
+ $input | & "node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
+ } else {
+ & "node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
+ }
+ $ret=$LASTEXITCODE
+}
+exit $ret
diff --git a/node_modules/.bin/vue-demi-switch b/node_modules/.bin/vue-demi-switch
new file mode 100644
index 0000000..458c052
--- /dev/null
+++ b/node_modules/.bin/vue-demi-switch
@@ -0,0 +1,12 @@
+#!/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
+ exec "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@"
+else
+ exec node "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@"
+fi
diff --git a/node_modules/.bin/vue-demi-switch.cmd b/node_modules/.bin/vue-demi-switch.cmd
new file mode 100644
index 0000000..fce7991
--- /dev/null
+++ b/node_modules/.bin/vue-demi-switch.cmd
@@ -0,0 +1,17 @@
+@ECHO off
+GOTO start
+:find_dp0
+SET dp0=%~dp0
+EXIT /b
+:start
+SETLOCAL
+CALL :find_dp0
+
+IF EXIST "%dp0%\node.exe" (
+ SET "_prog=%dp0%\node.exe"
+) ELSE (
+ SET "_prog=node"
+ SET PATHEXT=%PATHEXT:;.JS;=;%
+)
+
+endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-switch.js" %*
diff --git a/node_modules/.bin/vue-demi-switch.ps1 b/node_modules/.bin/vue-demi-switch.ps1
new file mode 100644
index 0000000..fbb4d69
--- /dev/null
+++ b/node_modules/.bin/vue-demi-switch.ps1
@@ -0,0 +1,28 @@
+#!/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") {
+ # Support pipeline input
+ if ($MyInvocation.ExpectingInput) {
+ $input | & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
+ } else {
+ & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
+ }
+ $ret=$LASTEXITCODE
+} else {
+ # Support pipeline input
+ if ($MyInvocation.ExpectingInput) {
+ $input | & "node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
+ } else {
+ & "node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
+ }
+ $ret=$LASTEXITCODE
+}
+exit $ret
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
new file mode 100644
index 0000000..58bb735
--- /dev/null
+++ b/node_modules/.package-lock.json
@@ -0,0 +1,69 @@
+{
+ "name": "version-record",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "node_modules/@vue/devtools-api": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+ "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+ },
+ "node_modules/pinia": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz",
+ "integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.5.0",
+ "vue-demi": ">=0.14.5"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.4.0",
+ "typescript": ">=4.4.4",
+ "vue": "^2.6.14 || ^3.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "2.6.14",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
+ "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==",
+ "peer": true
+ },
+ "node_modules/vue-demi": {
+ "version": "0.14.6",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
+ "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/api.js b/node_modules/@vue/devtools-api/lib/cjs/api/api.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/api.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/app.js b/node_modules/@vue/devtools-api/lib/cjs/api/app.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/app.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/component.js b/node_modules/@vue/devtools-api/lib/cjs/api/component.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/component.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/context.js b/node_modules/@vue/devtools-api/lib/cjs/api/context.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/context.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js b/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/index.js b/node_modules/@vue/devtools-api/lib/cjs/api/index.js
new file mode 100644
index 0000000..22f7589
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/index.js
@@ -0,0 +1,22 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./api.js"), exports);
+__exportStar(require("./app.js"), exports);
+__exportStar(require("./component.js"), exports);
+__exportStar(require("./context.js"), exports);
+__exportStar(require("./hooks.js"), exports);
+__exportStar(require("./util.js"), exports);
diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/util.js b/node_modules/@vue/devtools-api/lib/cjs/api/util.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/api/util.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/const.js b/node_modules/@vue/devtools-api/lib/cjs/const.js
new file mode 100644
index 0000000..84d408c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/const.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HOOK_PLUGIN_SETTINGS_SET = exports.HOOK_SETUP = void 0;
+exports.HOOK_SETUP = 'devtools-plugin:setup';
+exports.HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';
diff --git a/node_modules/@vue/devtools-api/lib/cjs/env.js b/node_modules/@vue/devtools-api/lib/cjs/env.js
new file mode 100644
index 0000000..178d457
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/env.js
@@ -0,0 +1,17 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.isProxyAvailable = exports.getTarget = exports.getDevtoolsGlobalHook = void 0;
+function getDevtoolsGlobalHook() {
+ return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+}
+exports.getDevtoolsGlobalHook = getDevtoolsGlobalHook;
+function getTarget() {
+ // @ts-ignore
+ return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {};
+}
+exports.getTarget = getTarget;
+exports.isProxyAvailable = typeof Proxy === 'function';
diff --git a/node_modules/@vue/devtools-api/lib/cjs/index.js b/node_modules/@vue/devtools-api/lib/cjs/index.js
new file mode 100644
index 0000000..249ac4d
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/index.js
@@ -0,0 +1,44 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.setupDevtoolsPlugin = void 0;
+const env_js_1 = require("./env.js");
+const const_js_1 = require("./const.js");
+const proxy_js_1 = require("./proxy.js");
+__exportStar(require("./api/index.js"), exports);
+__exportStar(require("./plugin.js"), exports);
+__exportStar(require("./time.js"), exports);
+function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+ const descriptor = pluginDescriptor;
+ const target = (0, env_js_1.getTarget)();
+ const hook = (0, env_js_1.getDevtoolsGlobalHook)();
+ const enableProxy = env_js_1.isProxyAvailable && descriptor.enableEarlyProxy;
+ if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+ hook.emit(const_js_1.HOOK_SETUP, pluginDescriptor, setupFn);
+ }
+ else {
+ const proxy = enableProxy ? new proxy_js_1.ApiProxy(descriptor, hook) : null;
+ const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+ list.push({
+ pluginDescriptor: descriptor,
+ setupFn,
+ proxy,
+ });
+ if (proxy)
+ setupFn(proxy.proxiedTarget);
+ }
+}
+exports.setupDevtoolsPlugin = setupDevtoolsPlugin;
diff --git a/node_modules/@vue/devtools-api/lib/cjs/plugin.js b/node_modules/@vue/devtools-api/lib/cjs/plugin.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/plugin.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/@vue/devtools-api/lib/cjs/proxy.js b/node_modules/@vue/devtools-api/lib/cjs/proxy.js
new file mode 100644
index 0000000..5385e60
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/proxy.js
@@ -0,0 +1,111 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ApiProxy = void 0;
+const const_js_1 = require("./const.js");
+const time_js_1 = require("./time.js");
+class ApiProxy {
+ constructor(plugin, hook) {
+ this.target = null;
+ this.targetQueue = [];
+ this.onQueue = [];
+ this.plugin = plugin;
+ this.hook = hook;
+ const defaultSettings = {};
+ if (plugin.settings) {
+ for (const id in plugin.settings) {
+ const item = plugin.settings[id];
+ defaultSettings[id] = item.defaultValue;
+ }
+ }
+ const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+ let currentSettings = Object.assign({}, defaultSettings);
+ try {
+ const raw = localStorage.getItem(localSettingsSaveId);
+ const data = JSON.parse(raw);
+ Object.assign(currentSettings, data);
+ }
+ catch (e) {
+ // noop
+ }
+ this.fallbacks = {
+ getSettings() {
+ return currentSettings;
+ },
+ setSettings(value) {
+ try {
+ localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+ }
+ catch (e) {
+ // noop
+ }
+ currentSettings = value;
+ },
+ now() {
+ return (0, time_js_1.now)();
+ },
+ };
+ if (hook) {
+ hook.on(const_js_1.HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+ if (pluginId === this.plugin.id) {
+ this.fallbacks.setSettings(value);
+ }
+ });
+ }
+ this.proxiedOn = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target.on[prop];
+ }
+ else {
+ return (...args) => {
+ this.onQueue.push({
+ method: prop,
+ args,
+ });
+ };
+ }
+ },
+ });
+ this.proxiedTarget = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target[prop];
+ }
+ else if (prop === 'on') {
+ return this.proxiedOn;
+ }
+ else if (Object.keys(this.fallbacks).includes(prop)) {
+ return (...args) => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve: () => { },
+ });
+ return this.fallbacks[prop](...args);
+ };
+ }
+ else {
+ return (...args) => {
+ return new Promise(resolve => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve,
+ });
+ });
+ };
+ }
+ },
+ });
+ }
+ async setRealTarget(target) {
+ this.target = target;
+ for (const item of this.onQueue) {
+ this.target.on[item.method](...item.args);
+ }
+ for (const item of this.targetQueue) {
+ item.resolve(await this.target[item.method](...item.args));
+ }
+ }
+}
+exports.ApiProxy = ApiProxy;
diff --git a/node_modules/@vue/devtools-api/lib/cjs/time.js b/node_modules/@vue/devtools-api/lib/cjs/time.js
new file mode 100644
index 0000000..5b17a25
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/cjs/time.js
@@ -0,0 +1,28 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.now = exports.isPerformanceSupported = void 0;
+let supported;
+let perf;
+function isPerformanceSupported() {
+ var _a;
+ if (supported !== undefined) {
+ return supported;
+ }
+ if (typeof window !== 'undefined' && window.performance) {
+ supported = true;
+ perf = window.performance;
+ }
+ else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+ supported = true;
+ perf = global.perf_hooks.performance;
+ }
+ else {
+ supported = false;
+ }
+ return supported;
+}
+exports.isPerformanceSupported = isPerformanceSupported;
+function now() {
+ return isPerformanceSupported() ? perf.now() : Date.now();
+}
+exports.now = now;
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts
new file mode 100644
index 0000000..071312a
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts
@@ -0,0 +1,108 @@
+import type { ComponentBounds, Hookable } from './hooks.js';
+import type { Context } from './context.js';
+import type { ComponentInstance, ComponentState, StateBase } from './component.js';
+import type { App } from './app.js';
+import type { ID } from './util.js';
+export interface DevtoolsPluginApi {
+ on: Hookable;
+ notifyComponentUpdate(instance?: ComponentInstance): void;
+ addTimelineLayer(options: TimelineLayerOptions): void;
+ addTimelineEvent(options: TimelineEventOptions): void;
+ addInspector(options: CustomInspectorOptions): void;
+ sendInspectorTree(inspectorId: string): void;
+ sendInspectorState(inspectorId: string): void;
+ selectInspectorNode(inspectorId: string, nodeId: string): void;
+ getComponentBounds(instance: ComponentInstance): Promise;
+ getComponentName(instance: ComponentInstance): Promise;
+ getComponentInstances(app: App): Promise;
+ highlightElement(instance: ComponentInstance): void;
+ unhighlightElement(): void;
+ getSettings(pluginId?: string): TSettings;
+ now(): number;
+ /**
+ * @private Not implemented yet
+ */
+ setSettings(values: TSettings): void;
+}
+export interface AppRecord {
+ id: string;
+ name: string;
+ instanceMap: Map;
+ rootInstance: ComponentInstance;
+}
+export interface TimelineLayerOptions {
+ id: string;
+ label: string;
+ color: number;
+ skipScreenshots?: boolean;
+ groupsOnly?: boolean;
+ ignoreNoDurationGroups?: boolean;
+ screenshotOverlayRender?: (event: TimelineEvent & ScreenshotOverlayEvent, ctx: ScreenshotOverlayRenderContext) => ScreenshotOverlayRenderResult | Promise;
+}
+export interface ScreenshotOverlayEvent {
+ layerId: string;
+ renderMeta: any;
+}
+export interface ScreenshotOverlayRenderContext {
+ screenshot: ScreenshotData;
+ events: (TimelineEvent & ScreenshotOverlayEvent)[];
+ index: number;
+}
+export declare type ScreenshotOverlayRenderResult = HTMLElement | string | false;
+export interface ScreenshotData {
+ time: number;
+}
+export interface TimelineEventOptions {
+ layerId: string;
+ event: TimelineEvent;
+ all?: boolean;
+}
+export interface TimelineEvent {
+ time: number;
+ data: TData;
+ logType?: 'default' | 'warning' | 'error';
+ meta?: TMeta;
+ groupId?: ID;
+ title?: string;
+ subtitle?: string;
+}
+export interface TimelineMarkerOptions {
+ id: string;
+ time: number;
+ color: number;
+ label: string;
+ all?: boolean;
+}
+export interface CustomInspectorOptions {
+ id: string;
+ label: string;
+ icon?: string;
+ treeFilterPlaceholder?: string;
+ stateFilterPlaceholder?: string;
+ noSelectionText?: string;
+ actions?: {
+ icon: string;
+ tooltip?: string;
+ action: () => void | Promise;
+ }[];
+ nodeActions?: {
+ icon: string;
+ tooltip?: string;
+ action: (nodeId: string) => void | Promise;
+ }[];
+}
+export interface CustomInspectorNode {
+ id: string;
+ label: string;
+ children?: CustomInspectorNode[];
+ tags?: InspectorNodeTag[];
+}
+export interface InspectorNodeTag {
+ label: string;
+ textColor: number;
+ backgroundColor: number;
+ tooltip?: string;
+}
+export interface CustomInspectorState {
+ [key: string]: (StateBase | Omit)[];
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/api.js b/node_modules/@vue/devtools-api/lib/esm/api/api.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/api.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts
new file mode 100644
index 0000000..42638c0
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts
@@ -0,0 +1 @@
+export declare type App = any;
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/app.js b/node_modules/@vue/devtools-api/lib/esm/api/app.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/app.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts
new file mode 100644
index 0000000..335dd04
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts
@@ -0,0 +1,78 @@
+import type { InspectorNodeTag } from './api.js';
+import type { ID } from './util.js';
+export declare type ComponentInstance = any;
+export interface ComponentTreeNode {
+ uid: ID;
+ id: string;
+ name: string;
+ renderKey: string | number;
+ inactive: boolean;
+ isFragment: boolean;
+ hasChildren: boolean;
+ children: ComponentTreeNode[];
+ domOrder?: number[];
+ consoleId?: string;
+ isRouterView?: boolean;
+ macthedRouteSegment?: string;
+ tags: InspectorNodeTag[];
+ autoOpen: boolean;
+ meta?: any;
+}
+export interface InspectedComponentData {
+ id: string;
+ name: string;
+ file: string;
+ state: ComponentState[];
+ functional?: boolean;
+}
+export interface StateBase {
+ key: string;
+ value: any;
+ editable?: boolean;
+ objectType?: 'ref' | 'reactive' | 'computed' | 'other';
+ raw?: string;
+}
+export interface ComponentStateBase extends StateBase {
+ type: string;
+}
+export interface ComponentPropState extends ComponentStateBase {
+ meta?: {
+ type: string;
+ required: boolean;
+ /** Vue 1 only */
+ mode?: 'default' | 'sync' | 'once';
+ };
+}
+export declare type ComponentBuiltinCustomStateTypes = 'function' | 'map' | 'set' | 'reference' | 'component' | 'component-definition' | 'router' | 'store';
+export interface ComponentCustomState extends ComponentStateBase {
+ value: CustomState;
+}
+export declare type CustomState = {
+ _custom: {
+ type: ComponentBuiltinCustomStateTypes | string;
+ objectType?: string;
+ display?: string;
+ tooltip?: string;
+ value?: any;
+ abstract?: boolean;
+ file?: string;
+ uid?: number;
+ readOnly?: boolean;
+ /** Configure immediate child fields */
+ fields?: {
+ abstract?: boolean;
+ };
+ id?: any;
+ actions?: {
+ icon: string;
+ tooltip?: string;
+ action: () => void | Promise;
+ }[];
+ /** internal */
+ _reviveId?: number;
+ };
+};
+export declare type ComponentState = ComponentStateBase | ComponentPropState | ComponentCustomState;
+export interface ComponentDevtoolsOptions {
+ hide?: boolean;
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/component.js b/node_modules/@vue/devtools-api/lib/esm/api/component.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/component.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts
new file mode 100644
index 0000000..29388f1
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts
@@ -0,0 +1,5 @@
+import type { AppRecord } from './api.js';
+export interface Context {
+ currentTab: string;
+ currentAppRecord: AppRecord;
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/context.js b/node_modules/@vue/devtools-api/lib/esm/api/context.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/context.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts
new file mode 100644
index 0000000..c980b13
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts
@@ -0,0 +1,180 @@
+import type { ComponentTreeNode, InspectedComponentData, ComponentInstance, ComponentDevtoolsOptions } from './component.js';
+import type { App } from './app.js';
+import type { CustomInspectorNode, CustomInspectorState, TimelineEvent } from './api.js';
+export declare const enum Hooks {
+ TRANSFORM_CALL = "transformCall",
+ GET_APP_RECORD_NAME = "getAppRecordName",
+ GET_APP_ROOT_INSTANCE = "getAppRootInstance",
+ REGISTER_APPLICATION = "registerApplication",
+ WALK_COMPONENT_TREE = "walkComponentTree",
+ VISIT_COMPONENT_TREE = "visitComponentTree",
+ WALK_COMPONENT_PARENTS = "walkComponentParents",
+ INSPECT_COMPONENT = "inspectComponent",
+ GET_COMPONENT_BOUNDS = "getComponentBounds",
+ GET_COMPONENT_NAME = "getComponentName",
+ GET_COMPONENT_INSTANCES = "getComponentInstances",
+ GET_ELEMENT_COMPONENT = "getElementComponent",
+ GET_COMPONENT_ROOT_ELEMENTS = "getComponentRootElements",
+ EDIT_COMPONENT_STATE = "editComponentState",
+ GET_COMPONENT_DEVTOOLS_OPTIONS = "getAppDevtoolsOptions",
+ GET_COMPONENT_RENDER_CODE = "getComponentRenderCode",
+ INSPECT_TIMELINE_EVENT = "inspectTimelineEvent",
+ TIMELINE_CLEARED = "timelineCleared",
+ GET_INSPECTOR_TREE = "getInspectorTree",
+ GET_INSPECTOR_STATE = "getInspectorState",
+ EDIT_INSPECTOR_STATE = "editInspectorState",
+ SET_PLUGIN_SETTINGS = "setPluginSettings"
+}
+export interface ComponentBounds {
+ left: number;
+ top: number;
+ width: number;
+ height: number;
+}
+export declare type HookPayloads = {
+ [Hooks.TRANSFORM_CALL]: {
+ callName: string;
+ inArgs: any[];
+ outArgs: any[];
+ };
+ [Hooks.GET_APP_RECORD_NAME]: {
+ app: App;
+ name: string;
+ };
+ [Hooks.GET_APP_ROOT_INSTANCE]: {
+ app: App;
+ root: ComponentInstance;
+ };
+ [Hooks.REGISTER_APPLICATION]: {
+ app: App;
+ };
+ [Hooks.WALK_COMPONENT_TREE]: {
+ componentInstance: ComponentInstance;
+ componentTreeData: ComponentTreeNode[];
+ maxDepth: number;
+ filter: string;
+ recursively: boolean;
+ };
+ [Hooks.VISIT_COMPONENT_TREE]: {
+ app: App;
+ componentInstance: ComponentInstance;
+ treeNode: ComponentTreeNode;
+ filter: string;
+ };
+ [Hooks.WALK_COMPONENT_PARENTS]: {
+ componentInstance: ComponentInstance;
+ parentInstances: ComponentInstance[];
+ };
+ [Hooks.INSPECT_COMPONENT]: {
+ app: App;
+ componentInstance: ComponentInstance;
+ instanceData: InspectedComponentData;
+ };
+ [Hooks.GET_COMPONENT_BOUNDS]: {
+ componentInstance: ComponentInstance;
+ bounds: ComponentBounds;
+ };
+ [Hooks.GET_COMPONENT_NAME]: {
+ componentInstance: ComponentInstance;
+ name: string;
+ };
+ [Hooks.GET_COMPONENT_INSTANCES]: {
+ app: App;
+ componentInstances: ComponentInstance[];
+ };
+ [Hooks.GET_ELEMENT_COMPONENT]: {
+ element: HTMLElement | any;
+ componentInstance: ComponentInstance;
+ };
+ [Hooks.GET_COMPONENT_ROOT_ELEMENTS]: {
+ componentInstance: ComponentInstance;
+ rootElements: (HTMLElement | any)[];
+ };
+ [Hooks.EDIT_COMPONENT_STATE]: {
+ app: App;
+ componentInstance: ComponentInstance;
+ path: string[];
+ type: string;
+ state: EditStatePayload;
+ set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
+ };
+ [Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS]: {
+ componentInstance: ComponentInstance;
+ options: ComponentDevtoolsOptions;
+ };
+ [Hooks.GET_COMPONENT_RENDER_CODE]: {
+ componentInstance: ComponentInstance;
+ code: string;
+ };
+ [Hooks.INSPECT_TIMELINE_EVENT]: {
+ app: App;
+ layerId: string;
+ event: TimelineEvent;
+ all?: boolean;
+ data: any;
+ };
+ [Hooks.TIMELINE_CLEARED]: Record;
+ [Hooks.GET_INSPECTOR_TREE]: {
+ app: App;
+ inspectorId: string;
+ filter: string;
+ rootNodes: CustomInspectorNode[];
+ };
+ [Hooks.GET_INSPECTOR_STATE]: {
+ app: App;
+ inspectorId: string;
+ nodeId: string;
+ state: CustomInspectorState;
+ };
+ [Hooks.EDIT_INSPECTOR_STATE]: {
+ app: App;
+ inspectorId: string;
+ nodeId: string;
+ path: string[];
+ type: string;
+ state: EditStatePayload;
+ set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
+ };
+ [Hooks.SET_PLUGIN_SETTINGS]: {
+ app: App;
+ pluginId: string;
+ key: string;
+ newValue: any;
+ oldValue: any;
+ settings: any;
+ };
+};
+export declare type EditStatePayload = {
+ value: any;
+ newKey?: string | null;
+ remove?: undefined | false;
+} | {
+ value?: undefined;
+ newKey?: undefined;
+ remove: true;
+};
+export declare type HookHandler = (payload: TPayload, ctx: TContext) => void | Promise;
+export interface Hookable {
+ transformCall(handler: HookHandler): any;
+ getAppRecordName(handler: HookHandler): any;
+ getAppRootInstance(handler: HookHandler): any;
+ registerApplication(handler: HookHandler): any;
+ walkComponentTree(handler: HookHandler): any;
+ visitComponentTree(handler: HookHandler): any;
+ walkComponentParents(handler: HookHandler): any;
+ inspectComponent(handler: HookHandler): any;
+ getComponentBounds(handler: HookHandler): any;
+ getComponentName(handler: HookHandler): any;
+ getComponentInstances(handler: HookHandler): any;
+ getElementComponent(handler: HookHandler): any;
+ getComponentRootElements(handler: HookHandler): any;
+ editComponentState(handler: HookHandler): any;
+ getComponentDevtoolsOptions(handler: HookHandler): any;
+ getComponentRenderCode(handler: HookHandler): any;
+ inspectTimelineEvent(handler: HookHandler): any;
+ timelineCleared(handler: HookHandler): any;
+ getInspectorTree(handler: HookHandler): any;
+ getInspectorState(handler: HookHandler): any;
+ editInspectorState(handler: HookHandler): any;
+ setPluginSettings(handler: HookHandler): any;
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/hooks.js b/node_modules/@vue/devtools-api/lib/esm/api/hooks.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/hooks.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts
new file mode 100644
index 0000000..70d09d2
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts
@@ -0,0 +1,6 @@
+export * from './api.js';
+export * from './app.js';
+export * from './component.js';
+export * from './context.js';
+export * from './hooks.js';
+export * from './util.js';
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/index.js b/node_modules/@vue/devtools-api/lib/esm/api/index.js
new file mode 100644
index 0000000..70d09d2
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/index.js
@@ -0,0 +1,6 @@
+export * from './api.js';
+export * from './app.js';
+export * from './component.js';
+export * from './context.js';
+export * from './hooks.js';
+export * from './util.js';
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts
new file mode 100644
index 0000000..7c437e5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts
@@ -0,0 +1,4 @@
+export declare type ID = number | string;
+export interface WithId {
+ id: ID;
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/api/util.js b/node_modules/@vue/devtools-api/lib/esm/api/util.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/api/util.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/const.d.ts b/node_modules/@vue/devtools-api/lib/esm/const.d.ts
new file mode 100644
index 0000000..289b254
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/const.d.ts
@@ -0,0 +1,2 @@
+export declare const HOOK_SETUP = "devtools-plugin:setup";
+export declare const HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set";
diff --git a/node_modules/@vue/devtools-api/lib/esm/const.js b/node_modules/@vue/devtools-api/lib/esm/const.js
new file mode 100644
index 0000000..872ea3e
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/const.js
@@ -0,0 +1,2 @@
+export const HOOK_SETUP = 'devtools-plugin:setup';
+export const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';
diff --git a/node_modules/@vue/devtools-api/lib/esm/env.d.ts b/node_modules/@vue/devtools-api/lib/esm/env.d.ts
new file mode 100644
index 0000000..16c1399
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/env.d.ts
@@ -0,0 +1,15 @@
+import type { PluginDescriptor, SetupFunction } from './index.js';
+import type { ApiProxy } from './proxy.js';
+export interface PluginQueueItem {
+ pluginDescriptor: PluginDescriptor;
+ setupFn: SetupFunction;
+ proxy?: ApiProxy;
+}
+interface GlobalTarget {
+ __VUE_DEVTOOLS_PLUGINS__?: PluginQueueItem[];
+ __VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__?: boolean;
+}
+export declare function getDevtoolsGlobalHook(): any;
+export declare function getTarget(): GlobalTarget;
+export declare const isProxyAvailable: boolean;
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/env.js b/node_modules/@vue/devtools-api/lib/esm/env.js
new file mode 100644
index 0000000..6713a93
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/env.js
@@ -0,0 +1,12 @@
+export function getDevtoolsGlobalHook() {
+ return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+}
+export function getTarget() {
+ // @ts-ignore
+ return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {};
+}
+export const isProxyAvailable = typeof Proxy === 'function';
diff --git a/node_modules/@vue/devtools-api/lib/esm/index.d.ts b/node_modules/@vue/devtools-api/lib/esm/index.d.ts
new file mode 100644
index 0000000..6833324
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/index.d.ts
@@ -0,0 +1,18 @@
+import type { DevtoolsPluginApi } from './api/index.js';
+import type { PluginDescriptor, ExtractSettingsTypes, PluginSettingsItem } from './plugin.js';
+export * from './api/index.js';
+export * from './plugin.js';
+export * from './time.js';
+export { PluginQueueItem } from './env.js';
+declare type Cast = A extends B ? A : B;
+declare type Narrowable = string | number | bigint | boolean;
+declare type Narrow = Cast;
+})>;
+declare type Exact = {
+ [K in keyof C]: K extends keyof T ? T[K] : never;
+};
+export declare type SetupFunction = (api: DevtoolsPluginApi) => void;
+export declare function setupDevtoolsPlugin, TSettings = ExtractSettingsTypes ? S : Record : Record>>(pluginDescriptor: Narrow, setupFn: SetupFunction): void;
diff --git a/node_modules/@vue/devtools-api/lib/esm/index.js b/node_modules/@vue/devtools-api/lib/esm/index.js
new file mode 100644
index 0000000..39259bc
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/index.js
@@ -0,0 +1,26 @@
+import { getTarget, getDevtoolsGlobalHook, isProxyAvailable } from './env.js';
+import { HOOK_SETUP } from './const.js';
+import { ApiProxy } from './proxy.js';
+export * from './api/index.js';
+export * from './plugin.js';
+export * from './time.js';
+export function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+ const descriptor = pluginDescriptor;
+ const target = getTarget();
+ const hook = getDevtoolsGlobalHook();
+ const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
+ if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+ hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
+ }
+ else {
+ const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
+ const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+ list.push({
+ pluginDescriptor: descriptor,
+ setupFn,
+ proxy,
+ });
+ if (proxy)
+ setupFn(proxy.proxiedTarget);
+ }
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts b/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts
new file mode 100644
index 0000000..dd182ca
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts
@@ -0,0 +1,47 @@
+import type { App } from './api/index.js';
+export interface PluginDescriptor {
+ id: string;
+ label: string;
+ app: App;
+ packageName?: string;
+ homepage?: string;
+ componentStateTypes?: string[];
+ logo?: string;
+ disableAppScope?: boolean;
+ disablePluginScope?: boolean;
+ /**
+ * Run the plugin setup and expose the api even if the devtools is not opened yet.
+ * Useful to record timeline events early.
+ */
+ enableEarlyProxy?: boolean;
+ settings?: Record;
+}
+export declare type PluginSettingsItem = {
+ label: string;
+ description?: string;
+} & ({
+ type: 'boolean';
+ defaultValue: boolean;
+} | {
+ type: 'choice';
+ defaultValue: string | number;
+ options: {
+ value: string | number;
+ label: string;
+ }[];
+ component?: 'select' | 'button-group';
+} | {
+ type: 'text';
+ defaultValue: string;
+});
+declare type InferSettingsType = [T] extends [{
+ type: 'boolean';
+}] ? boolean : [T] extends [{
+ type: 'choice';
+}] ? T['options'][number]['value'] : [T] extends [{
+ type: 'text';
+}] ? string : unknown;
+export declare type ExtractSettingsTypes> = {
+ [K in keyof O]: InferSettingsType;
+};
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/plugin.js b/node_modules/@vue/devtools-api/lib/esm/plugin.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/plugin.js
@@ -0,0 +1 @@
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts b/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts
new file mode 100644
index 0000000..38ff867
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts
@@ -0,0 +1,20 @@
+import type { Context, DevtoolsPluginApi, Hookable } from './api/index.js';
+import type { PluginDescriptor } from './plugin.js';
+interface QueueItem {
+ method: string;
+ args: any[];
+ resolve?: (value?: any) => void;
+}
+export declare class ApiProxy = DevtoolsPluginApi> {
+ target: TTarget | null;
+ targetQueue: QueueItem[];
+ proxiedTarget: TTarget;
+ onQueue: QueueItem[];
+ proxiedOn: Hookable;
+ plugin: PluginDescriptor;
+ hook: any;
+ fallbacks: Record;
+ constructor(plugin: PluginDescriptor, hook: any);
+ setRealTarget(target: TTarget): Promise;
+}
+export {};
diff --git a/node_modules/@vue/devtools-api/lib/esm/proxy.js b/node_modules/@vue/devtools-api/lib/esm/proxy.js
new file mode 100644
index 0000000..639077e
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/proxy.js
@@ -0,0 +1,107 @@
+import { HOOK_PLUGIN_SETTINGS_SET } from './const.js';
+import { now } from './time.js';
+export class ApiProxy {
+ constructor(plugin, hook) {
+ this.target = null;
+ this.targetQueue = [];
+ this.onQueue = [];
+ this.plugin = plugin;
+ this.hook = hook;
+ const defaultSettings = {};
+ if (plugin.settings) {
+ for (const id in plugin.settings) {
+ const item = plugin.settings[id];
+ defaultSettings[id] = item.defaultValue;
+ }
+ }
+ const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+ let currentSettings = Object.assign({}, defaultSettings);
+ try {
+ const raw = localStorage.getItem(localSettingsSaveId);
+ const data = JSON.parse(raw);
+ Object.assign(currentSettings, data);
+ }
+ catch (e) {
+ // noop
+ }
+ this.fallbacks = {
+ getSettings() {
+ return currentSettings;
+ },
+ setSettings(value) {
+ try {
+ localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+ }
+ catch (e) {
+ // noop
+ }
+ currentSettings = value;
+ },
+ now() {
+ return now();
+ },
+ };
+ if (hook) {
+ hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+ if (pluginId === this.plugin.id) {
+ this.fallbacks.setSettings(value);
+ }
+ });
+ }
+ this.proxiedOn = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target.on[prop];
+ }
+ else {
+ return (...args) => {
+ this.onQueue.push({
+ method: prop,
+ args,
+ });
+ };
+ }
+ },
+ });
+ this.proxiedTarget = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target[prop];
+ }
+ else if (prop === 'on') {
+ return this.proxiedOn;
+ }
+ else if (Object.keys(this.fallbacks).includes(prop)) {
+ return (...args) => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve: () => { },
+ });
+ return this.fallbacks[prop](...args);
+ };
+ }
+ else {
+ return (...args) => {
+ return new Promise(resolve => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve,
+ });
+ });
+ };
+ }
+ },
+ });
+ }
+ async setRealTarget(target) {
+ this.target = target;
+ for (const item of this.onQueue) {
+ this.target.on[item.method](...item.args);
+ }
+ for (const item of this.targetQueue) {
+ item.resolve(await this.target[item.method](...item.args));
+ }
+ }
+}
diff --git a/node_modules/@vue/devtools-api/lib/esm/time.d.ts b/node_modules/@vue/devtools-api/lib/esm/time.d.ts
new file mode 100644
index 0000000..1aebade
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/time.d.ts
@@ -0,0 +1,2 @@
+export declare function isPerformanceSupported(): boolean;
+export declare function now(): number;
diff --git a/node_modules/@vue/devtools-api/lib/esm/time.js b/node_modules/@vue/devtools-api/lib/esm/time.js
new file mode 100644
index 0000000..99bedb5
--- /dev/null
+++ b/node_modules/@vue/devtools-api/lib/esm/time.js
@@ -0,0 +1,23 @@
+let supported;
+let perf;
+export function isPerformanceSupported() {
+ var _a;
+ if (supported !== undefined) {
+ return supported;
+ }
+ if (typeof window !== 'undefined' && window.performance) {
+ supported = true;
+ perf = window.performance;
+ }
+ else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+ supported = true;
+ perf = global.perf_hooks.performance;
+ }
+ else {
+ supported = false;
+ }
+ return supported;
+}
+export function now() {
+ return isPerformanceSupported() ? perf.now() : Date.now();
+}
diff --git a/node_modules/@vue/devtools-api/package.json b/node_modules/@vue/devtools-api/package.json
new file mode 100644
index 0000000..0fe878b
--- /dev/null
+++ b/node_modules/@vue/devtools-api/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@vue/devtools-api",
+ "version": "6.5.0",
+ "description": "Interact with the Vue devtools from the page",
+ "main": "lib/cjs/index.js",
+ "browser": "lib/esm/index.js",
+ "module": "lib/esm/index.js",
+ "types": "lib/esm/index.d.ts",
+ "sideEffects": false,
+ "author": {
+ "name": "Guillaume Chau"
+ },
+ "files": [
+ "lib/esm",
+ "lib/cjs"
+ ],
+ "license": "MIT",
+ "repository": {
+ "url": "https://github.com/vuejs/vue-devtools.git",
+ "type": "git",
+ "directory": "packages/api"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "scripts": {
+ "build": "rimraf lib && yarn build:esm && yarn build:cjs",
+ "build:esm": "tsc --module es2015 --outDir lib/esm -d",
+ "build:cjs": "tsc --module commonjs --outDir lib/cjs",
+ "build:watch": "yarn tsc --module es2015 --outDir lib/esm -d -w --sourceMap"
+ },
+ "devDependencies": {
+ "@types/node": "^13.9.1",
+ "@types/webpack-env": "^1.15.1",
+ "typescript": "^4.5.2"
+ }
+}
\ No newline at end of file
diff --git a/node_modules/pinia/LICENSE b/node_modules/pinia/LICENSE
new file mode 100644
index 0000000..0c77562
--- /dev/null
+++ b/node_modules/pinia/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019-present Eduardo San Martin Morote
+
+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/node_modules/pinia/README.md b/node_modules/pinia/README.md
new file mode 100644
index 0000000..d73d322
--- /dev/null
+++ b/node_modules/pinia/README.md
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+# Pinia
+
+> Intuitive, type safe and flexible Store for Vue
+
+## 👉 [Demo with Vue 3 on StackBlitz](https://stackblitz.com/github/piniajs/example-vue-3-vite)
+
+## Help me keep working on this project 💚
+
+- [Become a Sponsor on GitHub](https://github.com/sponsors/posva)
+- [One-time donation via PayPal](https://paypal.me/posva)
+
+## Documentation
+
+To learn more about Pinia, check [its documentation](https://pinia.vuejs.org).
+
+## License
+
+[MIT](http://opensource.org/licenses/MIT)
diff --git a/node_modules/pinia/dist/pinia.cjs b/node_modules/pinia/dist/pinia.cjs
new file mode 100644
index 0000000..859b41a
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.cjs
@@ -0,0 +1,2019 @@
+/*!
+ * pinia v2.1.6
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+'use strict';
+
+var vueDemi = require('vue-demi');
+var devtoolsApi = require('@vue/devtools-api');
+
+/**
+ * setActivePinia must be called to handle SSR at the top of functions like
+ * `fetch`, `setup`, `serverPrefetch` and others
+ */
+let activePinia;
+/**
+ * Sets or unsets the active pinia. Used in SSR and internally when calling
+ * actions and getters
+ *
+ * @param pinia - Pinia instance
+ */
+// @ts-expect-error: cannot constrain the type of the return
+const setActivePinia = (pinia) => (activePinia = pinia);
+/**
+ * Get the currently active pinia if there is any.
+ */
+const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia;
+const piniaSymbol = ((process.env.NODE_ENV !== 'production') ? Symbol('pinia') : /* istanbul ignore next */ Symbol());
+
+function isPlainObject(
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+o) {
+ return (o &&
+ typeof o === 'object' &&
+ Object.prototype.toString.call(o) === '[object Object]' &&
+ typeof o.toJSON !== 'function');
+}
+// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly }
+// TODO: can we change these to numbers?
+/**
+ * Possible types for SubscriptionCallback
+ */
+exports.MutationType = void 0;
+(function (MutationType) {
+ /**
+ * Direct mutation of the state:
+ *
+ * - `store.name = 'new name'`
+ * - `store.$state.name = 'new name'`
+ * - `store.list.push('new item')`
+ */
+ MutationType["direct"] = "direct";
+ /**
+ * Mutated the state with `$patch` and an object
+ *
+ * - `store.$patch({ name: 'newName' })`
+ */
+ MutationType["patchObject"] = "patch object";
+ /**
+ * Mutated the state with `$patch` and a function
+ *
+ * - `store.$patch(state => state.name = 'newName')`
+ */
+ MutationType["patchFunction"] = "patch function";
+ // maybe reset? for $state = {} and $reset
+})(exports.MutationType || (exports.MutationType = {}));
+
+const IS_CLIENT = typeof window !== 'undefined';
+/**
+ * Should we add the devtools plugins.
+ * - only if dev mode or forced through the prod devtools flag
+ * - not in test
+ * - only if window exists (could change in the future)
+ */
+const USE_DEVTOOLS = ((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test') && IS_CLIENT;
+
+/*
+ * FileSaver.js A saveAs() FileSaver implementation.
+ *
+ * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin
+ * Morote.
+ *
+ * License : MIT
+ */
+// The one and only way of getting global scope in all environments
+// https://stackoverflow.com/q/3277182/1008999
+const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window
+ ? window
+ : typeof self === 'object' && self.self === self
+ ? self
+ : typeof global === 'object' && global.global === global
+ ? global
+ : typeof globalThis === 'object'
+ ? globalThis
+ : { HTMLElement: null })();
+function bom(blob, { autoBom = false } = {}) {
+ // prepend BOM for UTF-8 XML and text/* types (including HTML)
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+ if (autoBom &&
+ /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+ return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type });
+ }
+ return blob;
+}
+function download(url, name, opts) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'blob';
+ xhr.onload = function () {
+ saveAs(xhr.response, name, opts);
+ };
+ xhr.onerror = function () {
+ console.error('could not download file');
+ };
+ xhr.send();
+}
+function corsEnabled(url) {
+ const xhr = new XMLHttpRequest();
+ // use sync to avoid popup blocker
+ xhr.open('HEAD', url, false);
+ try {
+ xhr.send();
+ }
+ catch (e) { }
+ return xhr.status >= 200 && xhr.status <= 299;
+}
+// `a.click()` doesn't work for all browsers (#465)
+function click(node) {
+ try {
+ node.dispatchEvent(new MouseEvent('click'));
+ }
+ catch (e) {
+ const evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+ node.dispatchEvent(evt);
+ }
+}
+const _navigator =
+ typeof navigator === 'object' ? navigator : { userAgent: '' };
+// Detect WebView inside a native macOS app by ruling out all browsers
+// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
+// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
+const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) &&
+ /AppleWebKit/.test(_navigator.userAgent) &&
+ !/Safari/.test(_navigator.userAgent))();
+const saveAs = !IS_CLIENT
+ ? () => { } // noop
+ : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program
+ typeof HTMLAnchorElement !== 'undefined' &&
+ 'download' in HTMLAnchorElement.prototype &&
+ !isMacOSWebView
+ ? downloadSaveAs
+ : // Use msSaveOrOpenBlob as a second approach
+ 'msSaveOrOpenBlob' in _navigator
+ ? msSaveAs
+ : // Fallback to using FileReader and a popup
+ fileSaverSaveAs;
+function downloadSaveAs(blob, name = 'download', opts) {
+ const a = document.createElement('a');
+ a.download = name;
+ a.rel = 'noopener'; // tabnabbing
+ // TODO: detect chrome extensions & packaged apps
+ // a.target = '_blank'
+ if (typeof blob === 'string') {
+ // Support regular links
+ a.href = blob;
+ if (a.origin !== location.origin) {
+ if (corsEnabled(a.href)) {
+ download(blob, name, opts);
+ }
+ else {
+ a.target = '_blank';
+ click(a);
+ }
+ }
+ else {
+ click(a);
+ }
+ }
+ else {
+ // Support blobs
+ a.href = URL.createObjectURL(blob);
+ setTimeout(function () {
+ URL.revokeObjectURL(a.href);
+ }, 4e4); // 40s
+ setTimeout(function () {
+ click(a);
+ }, 0);
+ }
+}
+function msSaveAs(blob, name = 'download', opts) {
+ if (typeof blob === 'string') {
+ if (corsEnabled(blob)) {
+ download(blob, name, opts);
+ }
+ else {
+ const a = document.createElement('a');
+ a.href = blob;
+ a.target = '_blank';
+ setTimeout(function () {
+ click(a);
+ });
+ }
+ }
+ else {
+ // @ts-ignore: works on windows
+ navigator.msSaveOrOpenBlob(bom(blob, opts), name);
+ }
+}
+function fileSaverSaveAs(blob, name, opts, popup) {
+ // Open a popup immediately do go around popup blocker
+ // Mostly only available on user interaction and the fileReader is async so...
+ popup = popup || open('', '_blank');
+ if (popup) {
+ popup.document.title = popup.document.body.innerText = 'downloading...';
+ }
+ if (typeof blob === 'string')
+ return download(blob, name, opts);
+ const force = blob.type === 'application/octet-stream';
+ const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global;
+ const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
+ if ((isChromeIOS || (force && isSafari) || isMacOSWebView) &&
+ typeof FileReader !== 'undefined') {
+ // Safari doesn't allow downloading of blob URLs
+ const reader = new FileReader();
+ reader.onloadend = function () {
+ let url = reader.result;
+ if (typeof url !== 'string') {
+ popup = null;
+ throw new Error('Wrong reader.result type');
+ }
+ url = isChromeIOS
+ ? url
+ : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
+ if (popup) {
+ popup.location.href = url;
+ }
+ else {
+ location.assign(url);
+ }
+ popup = null; // reverse-tabnabbing #460
+ };
+ reader.readAsDataURL(blob);
+ }
+ else {
+ const url = URL.createObjectURL(blob);
+ if (popup)
+ popup.location.assign(url);
+ else
+ location.href = url;
+ popup = null; // reverse-tabnabbing #460
+ setTimeout(function () {
+ URL.revokeObjectURL(url);
+ }, 4e4); // 40s
+ }
+}
+
+/**
+ * Shows a toast or console.log
+ *
+ * @param message - message to log
+ * @param type - different color of the tooltip
+ */
+function toastMessage(message, type) {
+ const piniaMessage = '🍍 ' + message;
+ if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') {
+ // No longer available :(
+ __VUE_DEVTOOLS_TOAST__(piniaMessage, type);
+ }
+ else if (type === 'error') {
+ console.error(piniaMessage);
+ }
+ else if (type === 'warn') {
+ console.warn(piniaMessage);
+ }
+ else {
+ console.log(piniaMessage);
+ }
+}
+function isPinia(o) {
+ return '_a' in o && 'install' in o;
+}
+
+/**
+ * This file contain devtools actions, they are not Pinia actions.
+ */
+// ---
+function checkClipboardAccess() {
+ if (!('clipboard' in navigator)) {
+ toastMessage(`Your browser doesn't support the Clipboard API`, 'error');
+ return true;
+ }
+}
+function checkNotFocusedError(error) {
+ if (error instanceof Error &&
+ error.message.toLowerCase().includes('document is not focused')) {
+ toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn');
+ return true;
+ }
+ return false;
+}
+async function actionGlobalCopyState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ await navigator.clipboard.writeText(JSON.stringify(pinia.state.value));
+ toastMessage('Global state copied to clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+async function actionGlobalPasteState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText()));
+ toastMessage('Global state pasted from clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+async function actionGlobalSaveState(pinia) {
+ try {
+ saveAs(new Blob([JSON.stringify(pinia.state.value)], {
+ type: 'text/plain;charset=utf-8',
+ }), 'pinia-state.json');
+ }
+ catch (error) {
+ toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+let fileInput;
+function getFileOpener() {
+ if (!fileInput) {
+ fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '.json';
+ }
+ function openFile() {
+ return new Promise((resolve, reject) => {
+ fileInput.onchange = async () => {
+ const files = fileInput.files;
+ if (!files)
+ return resolve(null);
+ const file = files.item(0);
+ if (!file)
+ return resolve(null);
+ return resolve({ text: await file.text(), file });
+ };
+ // @ts-ignore: TODO: changed from 4.3 to 4.4
+ fileInput.oncancel = () => resolve(null);
+ fileInput.onerror = reject;
+ fileInput.click();
+ });
+ }
+ return openFile;
+}
+async function actionGlobalOpenStateFile(pinia) {
+ try {
+ const open = getFileOpener();
+ const result = await open();
+ if (!result)
+ return;
+ const { text, file } = result;
+ loadStoresState(pinia, JSON.parse(text));
+ toastMessage(`Global state imported from "${file.name}".`);
+ }
+ catch (error) {
+ toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+function loadStoresState(pinia, state) {
+ for (const key in state) {
+ const storeState = pinia.state.value[key];
+ if (storeState) {
+ Object.assign(storeState, state[key]);
+ }
+ }
+}
+
+function formatDisplay(display) {
+ return {
+ _custom: {
+ display,
+ },
+ };
+}
+const PINIA_ROOT_LABEL = '🍍 Pinia (root)';
+const PINIA_ROOT_ID = '_root';
+function formatStoreForInspectorTree(store) {
+ return isPinia(store)
+ ? {
+ id: PINIA_ROOT_ID,
+ label: PINIA_ROOT_LABEL,
+ }
+ : {
+ id: store.$id,
+ label: store.$id,
+ };
+}
+function formatStoreForInspectorState(store) {
+ if (isPinia(store)) {
+ const storeNames = Array.from(store._s.keys());
+ const storeMap = store._s;
+ const state = {
+ state: storeNames.map((storeId) => ({
+ editable: true,
+ key: storeId,
+ value: store.state.value[storeId],
+ })),
+ getters: storeNames
+ .filter((id) => storeMap.get(id)._getters)
+ .map((id) => {
+ const store = storeMap.get(id);
+ return {
+ editable: false,
+ key: id,
+ value: store._getters.reduce((getters, key) => {
+ getters[key] = store[key];
+ return getters;
+ }, {}),
+ };
+ }),
+ };
+ return state;
+ }
+ const state = {
+ state: Object.keys(store.$state).map((key) => ({
+ editable: true,
+ key,
+ value: store.$state[key],
+ })),
+ };
+ // avoid adding empty getters
+ if (store._getters && store._getters.length) {
+ state.getters = store._getters.map((getterName) => ({
+ editable: false,
+ key: getterName,
+ value: store[getterName],
+ }));
+ }
+ if (store._customProperties.size) {
+ state.customProperties = Array.from(store._customProperties).map((key) => ({
+ editable: true,
+ key,
+ value: store[key],
+ }));
+ }
+ return state;
+}
+function formatEventData(events) {
+ if (!events)
+ return {};
+ if (Array.isArray(events)) {
+ // TODO: handle add and delete for arrays and objects
+ return events.reduce((data, event) => {
+ data.keys.push(event.key);
+ data.operations.push(event.type);
+ data.oldValue[event.key] = event.oldValue;
+ data.newValue[event.key] = event.newValue;
+ return data;
+ }, {
+ oldValue: {},
+ keys: [],
+ operations: [],
+ newValue: {},
+ });
+ }
+ else {
+ return {
+ operation: formatDisplay(events.type),
+ key: formatDisplay(events.key),
+ oldValue: events.oldValue,
+ newValue: events.newValue,
+ };
+ }
+}
+function formatMutationType(type) {
+ switch (type) {
+ case exports.MutationType.direct:
+ return 'mutation';
+ case exports.MutationType.patchFunction:
+ return '$patch';
+ case exports.MutationType.patchObject:
+ return '$patch';
+ default:
+ return 'unknown';
+ }
+}
+
+// timeline can be paused when directly changing the state
+let isTimelineActive = true;
+const componentStateTypes = [];
+const MUTATIONS_LAYER_ID = 'pinia:mutations';
+const INSPECTOR_ID = 'pinia';
+const { assign: assign$1 } = Object;
+/**
+ * Gets the displayed name of a store in devtools
+ *
+ * @param id - id of the store
+ * @returns a formatted string
+ */
+const getStoreType = (id) => '🍍 ' + id;
+/**
+ * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab
+ * as soon as it is added to the application.
+ *
+ * @param app - Vue application
+ * @param pinia - pinia instance
+ */
+function registerPiniaDevtools(app, pinia) {
+ devtoolsApi.setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ }, (api) => {
+ if (typeof api.now !== 'function') {
+ toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.');
+ }
+ api.addTimelineLayer({
+ id: MUTATIONS_LAYER_ID,
+ label: `Pinia 🍍`,
+ color: 0xe5df88,
+ });
+ api.addInspector({
+ id: INSPECTOR_ID,
+ label: 'Pinia 🍍',
+ icon: 'storage',
+ treeFilterPlaceholder: 'Search stores',
+ actions: [
+ {
+ icon: 'content_copy',
+ action: () => {
+ actionGlobalCopyState(pinia);
+ },
+ tooltip: 'Serialize and copy the state',
+ },
+ {
+ icon: 'content_paste',
+ action: async () => {
+ await actionGlobalPasteState(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Replace the state with the content of your clipboard',
+ },
+ {
+ icon: 'save',
+ action: () => {
+ actionGlobalSaveState(pinia);
+ },
+ tooltip: 'Save the state as a JSON file',
+ },
+ {
+ icon: 'folder_open',
+ action: async () => {
+ await actionGlobalOpenStateFile(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Import the state from a JSON file',
+ },
+ ],
+ nodeActions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state (with "$reset")',
+ action: (nodeId) => {
+ const store = pinia._s.get(nodeId);
+ if (!store) {
+ toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn');
+ }
+ else if (typeof store.$reset !== 'function') {
+ toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn');
+ }
+ else {
+ store.$reset();
+ toastMessage(`Store "${nodeId}" reset.`);
+ }
+ },
+ },
+ ],
+ });
+ api.on.inspectComponent((payload, ctx) => {
+ const proxy = (payload.componentInstance &&
+ payload.componentInstance.proxy);
+ if (proxy && proxy._pStores) {
+ const piniaStores = payload.componentInstance.proxy._pStores;
+ Object.values(piniaStores).forEach((store) => {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'state',
+ editable: true,
+ value: store._isOptionsAPI
+ ? {
+ _custom: {
+ value: vueDemi.toRaw(store.$state),
+ actions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state of this store',
+ action: () => store.$reset(),
+ },
+ ],
+ },
+ }
+ : // NOTE: workaround to unwrap transferred refs
+ Object.keys(store.$state).reduce((state, key) => {
+ state[key] = store.$state[key];
+ return state;
+ }, {}),
+ });
+ if (store._getters && store._getters.length) {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'getters',
+ editable: false,
+ value: store._getters.reduce((getters, key) => {
+ try {
+ getters[key] = store[key];
+ }
+ catch (error) {
+ // @ts-expect-error: we just want to show it in devtools
+ getters[key] = error;
+ }
+ return getters;
+ }, {}),
+ });
+ }
+ });
+ }
+ });
+ api.on.getInspectorTree((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ let stores = [pinia];
+ stores = stores.concat(Array.from(pinia._s.values()));
+ payload.rootNodes = (payload.filter
+ ? stores.filter((store) => '$id' in store
+ ? store.$id
+ .toLowerCase()
+ .includes(payload.filter.toLowerCase())
+ : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase()))
+ : stores).map(formatStoreForInspectorTree);
+ }
+ });
+ api.on.getInspectorState((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ // this could be the selected store restored for a different project
+ // so it's better not to say anything here
+ return;
+ }
+ if (inspectedStore) {
+ payload.state = formatStoreForInspectorState(inspectedStore);
+ }
+ }
+ });
+ api.on.editInspectorState((payload, ctx) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ return toastMessage(`store "${payload.nodeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (!isPinia(inspectedStore)) {
+ // access only the state
+ if (path.length !== 1 ||
+ !inspectedStore._customProperties.has(path[0]) ||
+ path[0] in inspectedStore.$state) {
+ path.unshift('$state');
+ }
+ }
+ else {
+ // Root access, we can omit the `.value` because the devtools API does it for us
+ path.unshift('state');
+ }
+ isTimelineActive = false;
+ payload.set(inspectedStore, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ api.on.editComponentState((payload) => {
+ if (payload.type.startsWith('🍍')) {
+ const storeId = payload.type.replace(/^🍍\s*/, '');
+ const store = pinia._s.get(storeId);
+ if (!store) {
+ return toastMessage(`store "${storeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (path[0] !== 'state') {
+ return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`);
+ }
+ // rewrite the first entry to be able to directly set the state as
+ // well as any other path
+ path[0] = '$state';
+ isTimelineActive = false;
+ payload.set(store, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ });
+}
+function addStoreToDevtools(app, store) {
+ if (!componentStateTypes.includes(getStoreType(store.$id))) {
+ componentStateTypes.push(getStoreType(store.$id));
+ }
+ devtoolsApi.setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ settings: {
+ logStoreChanges: {
+ label: 'Notify about new/deleted stores',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ // useEmojis: {
+ // label: 'Use emojis in messages ⚡️',
+ // type: 'boolean',
+ // defaultValue: true,
+ // },
+ },
+ }, (api) => {
+ // gracefully handle errors
+ const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now;
+ store.$onAction(({ after, onError, name, args }) => {
+ const groupId = runningActionId++;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛫 ' + name,
+ subtitle: 'start',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ },
+ groupId,
+ },
+ });
+ after((result) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛬 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ result,
+ },
+ groupId,
+ },
+ });
+ });
+ onError((error) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ logType: 'error',
+ title: '💥 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ error,
+ },
+ groupId,
+ },
+ });
+ });
+ }, true);
+ store._customProperties.forEach((name) => {
+ vueDemi.watch(() => vueDemi.unref(store[name]), (newValue, oldValue) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (isTimelineActive) {
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: 'Change',
+ subtitle: name,
+ data: {
+ newValue,
+ oldValue,
+ },
+ groupId: activeAction,
+ },
+ });
+ }
+ }, { deep: true });
+ });
+ store.$subscribe(({ events, type }, state) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (!isTimelineActive)
+ return;
+ // rootStore.state[store.id] = state
+ const eventData = {
+ time: now(),
+ title: formatMutationType(type),
+ data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)),
+ groupId: activeAction,
+ };
+ if (type === exports.MutationType.patchFunction) {
+ eventData.subtitle = '⤵️';
+ }
+ else if (type === exports.MutationType.patchObject) {
+ eventData.subtitle = '🧩';
+ }
+ else if (events && !Array.isArray(events)) {
+ eventData.subtitle = events.type;
+ }
+ if (events) {
+ eventData.data['rawEvent(s)'] = {
+ _custom: {
+ display: 'DebuggerEvent',
+ type: 'object',
+ tooltip: 'raw DebuggerEvent[]',
+ value: events,
+ },
+ };
+ }
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: eventData,
+ });
+ }, { detached: true, flush: 'sync' });
+ const hotUpdate = store._hotUpdate;
+ store._hotUpdate = vueDemi.markRaw((newStore) => {
+ hotUpdate(newStore);
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🔥 ' + store.$id,
+ subtitle: 'HMR update',
+ data: {
+ store: formatDisplay(store.$id),
+ info: formatDisplay(`HMR update`),
+ },
+ },
+ });
+ // update the devtools too
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ });
+ const { $dispose } = store;
+ store.$dispose = () => {
+ $dispose();
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`Disposed "${store.$id}" store 🗑`);
+ };
+ // trigger an update so it can display new registered stores
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`"${store.$id}" store installed 🆕`);
+ });
+}
+let runningActionId = 0;
+let activeAction;
+/**
+ * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the
+ * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state
+ * mutation to the action.
+ *
+ * @param store - store to patch
+ * @param actionNames - list of actionst to patch
+ */
+function patchActionForGrouping(store, actionNames, wrapWithProxy) {
+ // original actions of the store as they are given by pinia. We are going to override them
+ const actions = actionNames.reduce((storeActions, actionName) => {
+ // use toRaw to avoid tracking #541
+ storeActions[actionName] = vueDemi.toRaw(store)[actionName];
+ return storeActions;
+ }, {});
+ for (const actionName in actions) {
+ store[actionName] = function () {
+ // the running action id is incremented in a before action hook
+ const _actionId = runningActionId;
+ const trackedStore = wrapWithProxy
+ ? new Proxy(store, {
+ get(...args) {
+ activeAction = _actionId;
+ return Reflect.get(...args);
+ },
+ set(...args) {
+ activeAction = _actionId;
+ return Reflect.set(...args);
+ },
+ })
+ : store;
+ // For Setup Stores we need https://github.com/tc39/proposal-async-context
+ activeAction = _actionId;
+ const retValue = actions[actionName].apply(trackedStore, arguments);
+ // this is safer as async actions in Setup Stores would associate mutations done outside of the action
+ activeAction = undefined;
+ return retValue;
+ };
+ }
+}
+/**
+ * pinia.use(devtoolsPlugin)
+ */
+function devtoolsPlugin({ app, store, options }) {
+ // HMR module
+ if (store.$id.startsWith('__hot:')) {
+ return;
+ }
+ // detect option api vs setup api
+ store._isOptionsAPI = !!options.state;
+ patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI);
+ // Upgrade the HMR to also update the new actions
+ const originalHotUpdate = store._hotUpdate;
+ vueDemi.toRaw(store)._hotUpdate = function (newStore) {
+ originalHotUpdate.apply(this, arguments);
+ patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI);
+ };
+ addStoreToDevtools(app,
+ // FIXME: is there a way to allow the assignment from Store to StoreGeneric?
+ store);
+}
+
+/**
+ * Creates a Pinia instance to be used by the application
+ */
+function createPinia() {
+ const scope = vueDemi.effectScope(true);
+ // NOTE: here we could check the window object for a state and directly set it
+ // if there is anything like it with Vue 3 SSR
+ const state = scope.run(() => vueDemi.ref({}));
+ let _p = [];
+ // plugins added before calling app.use(pinia)
+ let toBeInstalled = [];
+ const pinia = vueDemi.markRaw({
+ install(app) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ if (!vueDemi.isVue2) {
+ pinia._a = app;
+ app.provide(piniaSymbol, pinia);
+ app.config.globalProperties.$pinia = pinia;
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(app, pinia);
+ }
+ toBeInstalled.forEach((plugin) => _p.push(plugin));
+ toBeInstalled = [];
+ }
+ },
+ use(plugin) {
+ if (!this._a && !vueDemi.isVue2) {
+ toBeInstalled.push(plugin);
+ }
+ else {
+ _p.push(plugin);
+ }
+ return this;
+ },
+ _p,
+ // it's actually undefined here
+ // @ts-expect-error
+ _a: null,
+ _e: scope,
+ _s: new Map(),
+ state,
+ });
+ // pinia devtools rely on dev only features so they cannot be forced unless
+ // the dev build of Vue is used. Avoid old browsers like IE11.
+ if (USE_DEVTOOLS && typeof Proxy !== 'undefined') {
+ pinia.use(devtoolsPlugin);
+ }
+ return pinia;
+}
+
+/**
+ * Checks if a function is a `StoreDefinition`.
+ *
+ * @param fn - object to test
+ * @returns true if `fn` is a StoreDefinition
+ */
+const isUseStore = (fn) => {
+ return typeof fn === 'function' && typeof fn.$id === 'string';
+};
+/**
+ * Mutates in place `newState` with `oldState` to _hot update_ it. It will
+ * remove any key not existing in `newState` and recursively merge plain
+ * objects.
+ *
+ * @param newState - new state object to be patched
+ * @param oldState - old state that should be used to patch newState
+ * @returns - newState
+ */
+function patchObject(newState, oldState) {
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in oldState) {
+ const subPatch = oldState[key];
+ // skip the whole sub tree
+ if (!(key in newState)) {
+ continue;
+ }
+ const targetValue = newState[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ !vueDemi.isRef(subPatch) &&
+ !vueDemi.isReactive(subPatch)) {
+ newState[key] = patchObject(targetValue, subPatch);
+ }
+ else {
+ // objects are either a bit more complex (e.g. refs) or primitives, so we
+ // just set the whole thing
+ if (vueDemi.isVue2) {
+ vueDemi.set(newState, key, subPatch);
+ }
+ else {
+ newState[key] = subPatch;
+ }
+ }
+ }
+ return newState;
+}
+/**
+ * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
+ *
+ * @example
+ * ```js
+ * const useUser = defineStore(...)
+ * if (import.meta.hot) {
+ * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
+ * }
+ * ```
+ *
+ * @param initialUseStore - return of the defineStore to hot update
+ * @param hot - `import.meta.hot`
+ */
+function acceptHMRUpdate(initialUseStore, hot) {
+ // strip as much as possible from iife.prod
+ if (!(process.env.NODE_ENV !== 'production')) {
+ return () => { };
+ }
+ return (newModule) => {
+ const pinia = hot.data.pinia || initialUseStore._pinia;
+ if (!pinia) {
+ // this store is still not used
+ return;
+ }
+ // preserve the pinia instance across loads
+ hot.data.pinia = pinia;
+ // console.log('got data', newStore)
+ for (const exportName in newModule) {
+ const useStore = newModule[exportName];
+ // console.log('checking for', exportName)
+ if (isUseStore(useStore) && pinia._s.has(useStore.$id)) {
+ // console.log('Accepting update for', useStore.$id)
+ const id = useStore.$id;
+ if (id !== initialUseStore.$id) {
+ console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`);
+ // return import.meta.hot.invalidate()
+ return hot.invalidate();
+ }
+ const existingStore = pinia._s.get(id);
+ if (!existingStore) {
+ console.log(`[Pinia]: skipping hmr because store doesn't exist yet`);
+ return;
+ }
+ useStore(pinia, existingStore);
+ }
+ }
+ };
+}
+
+const noop = () => { };
+function addSubscription(subscriptions, callback, detached, onCleanup = noop) {
+ subscriptions.push(callback);
+ const removeSubscription = () => {
+ const idx = subscriptions.indexOf(callback);
+ if (idx > -1) {
+ subscriptions.splice(idx, 1);
+ onCleanup();
+ }
+ };
+ if (!detached && vueDemi.getCurrentScope()) {
+ vueDemi.onScopeDispose(removeSubscription);
+ }
+ return removeSubscription;
+}
+function triggerSubscriptions(subscriptions, ...args) {
+ subscriptions.slice().forEach((callback) => {
+ callback(...args);
+ });
+}
+
+const fallbackRunWithContext = (fn) => fn();
+function mergeReactiveObjects(target, patchToApply) {
+ // Handle Map instances
+ if (target instanceof Map && patchToApply instanceof Map) {
+ patchToApply.forEach((value, key) => target.set(key, value));
+ }
+ // Handle Set instances
+ if (target instanceof Set && patchToApply instanceof Set) {
+ patchToApply.forEach(target.add, target);
+ }
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in patchToApply) {
+ if (!patchToApply.hasOwnProperty(key))
+ continue;
+ const subPatch = patchToApply[key];
+ const targetValue = target[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ target.hasOwnProperty(key) &&
+ !vueDemi.isRef(subPatch) &&
+ !vueDemi.isReactive(subPatch)) {
+ // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might
+ // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that
+ // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`.
+ target[key] = mergeReactiveObjects(targetValue, subPatch);
+ }
+ else {
+ // @ts-expect-error: subPatch is a valid value
+ target[key] = subPatch;
+ }
+ }
+ return target;
+}
+const skipHydrateSymbol = (process.env.NODE_ENV !== 'production')
+ ? Symbol('pinia:skipHydration')
+ : /* istanbul ignore next */ Symbol();
+const skipHydrateMap = /*#__PURE__*/ new WeakMap();
+/**
+ * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
+ * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
+ *
+ * @param obj - target object
+ * @returns obj
+ */
+function skipHydrate(obj) {
+ return vueDemi.isVue2
+ ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work...
+ /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj
+ : Object.defineProperty(obj, skipHydrateSymbol, {});
+}
+/**
+ * Returns whether a value should be hydrated
+ *
+ * @param obj - target variable
+ * @returns true if `obj` should be hydrated
+ */
+function shouldHydrate(obj) {
+ return vueDemi.isVue2
+ ? /* istanbul ignore next */ !skipHydrateMap.has(obj)
+ : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
+}
+const { assign } = Object;
+function isComputed(o) {
+ return !!(vueDemi.isRef(o) && o.effect);
+}
+function createOptionsStore(id, options, pinia, hot) {
+ const { state, actions, getters } = options;
+ const initialState = pinia.state.value[id];
+ let store;
+ function setup() {
+ if (!initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) {
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value, id, state ? state() : {});
+ }
+ else {
+ pinia.state.value[id] = state ? state() : {};
+ }
+ }
+ // avoid creating a state in pinia.state.value
+ const localState = (process.env.NODE_ENV !== 'production') && hot
+ ? // use ref() to unwrap refs inside state TODO: check if this is still necessary
+ vueDemi.toRefs(vueDemi.ref(state ? state() : {}).value)
+ : vueDemi.toRefs(pinia.state.value[id]);
+ return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {
+ if ((process.env.NODE_ENV !== 'production') && name in localState) {
+ console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`);
+ }
+ computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => {
+ setActivePinia(pinia);
+ // it was created just before
+ const store = pinia._s.get(id);
+ // allow cross using stores
+ /* istanbul ignore next */
+ if (vueDemi.isVue2 && !store._r)
+ return;
+ // @ts-expect-error
+ // return getters![name].call(context, context)
+ // TODO: avoid reading the getter while assigning with a global variable
+ return getters[name].call(store, store);
+ }));
+ return computedGetters;
+ }, {}));
+ }
+ store = createSetupStore(id, setup, options, pinia, hot, true);
+ return store;
+}
+function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {
+ let scope;
+ const optionsForPlugin = assign({ actions: {} }, options);
+ /* istanbul ignore if */
+ if ((process.env.NODE_ENV !== 'production') && !pinia._e.active) {
+ throw new Error('Pinia destroyed');
+ }
+ // watcher options for $subscribe
+ const $subscribeOptions = {
+ deep: true,
+ // flush: 'post',
+ };
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production') && !vueDemi.isVue2) {
+ $subscribeOptions.onTrigger = (event) => {
+ /* istanbul ignore else */
+ if (isListening) {
+ debuggerEvents = event;
+ // avoid triggering this while the store is being built and the state is being set in pinia
+ }
+ else if (isListening == false && !store._hotUpdating) {
+ // let patch send all the events together later
+ /* istanbul ignore else */
+ if (Array.isArray(debuggerEvents)) {
+ debuggerEvents.push(event);
+ }
+ else {
+ console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.');
+ }
+ }
+ };
+ }
+ // internal state
+ let isListening; // set to true at the end
+ let isSyncListening; // set to true at the end
+ let subscriptions = [];
+ let actionSubscriptions = [];
+ let debuggerEvents;
+ const initialState = pinia.state.value[$id];
+ // avoid setting the state for option stores if it is set
+ // by the setup
+ if (!isOptionsStore && !initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) {
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value, $id, {});
+ }
+ else {
+ pinia.state.value[$id] = {};
+ }
+ }
+ const hotState = vueDemi.ref({});
+ // avoid triggering too many listeners
+ // https://github.com/vuejs/pinia/issues/1129
+ let activeListener;
+ function $patch(partialStateOrMutator) {
+ let subscriptionMutation;
+ isListening = isSyncListening = false;
+ // reset the debugger events since patches are sync
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production')) {
+ debuggerEvents = [];
+ }
+ if (typeof partialStateOrMutator === 'function') {
+ partialStateOrMutator(pinia.state.value[$id]);
+ subscriptionMutation = {
+ type: exports.MutationType.patchFunction,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ else {
+ mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);
+ subscriptionMutation = {
+ type: exports.MutationType.patchObject,
+ payload: partialStateOrMutator,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ const myListenerId = (activeListener = Symbol());
+ vueDemi.nextTick().then(() => {
+ if (activeListener === myListenerId) {
+ isListening = true;
+ }
+ });
+ isSyncListening = true;
+ // because we paused the watcher, we need to manually call the subscriptions
+ triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);
+ }
+ const $reset = isOptionsStore
+ ? function $reset() {
+ const { state } = options;
+ const newState = state ? state() : {};
+ // we use a patch to group all changes into one single subscription
+ this.$patch(($state) => {
+ assign($state, newState);
+ });
+ }
+ : /* istanbul ignore next */
+ (process.env.NODE_ENV !== 'production')
+ ? () => {
+ throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`);
+ }
+ : noop;
+ function $dispose() {
+ scope.stop();
+ subscriptions = [];
+ actionSubscriptions = [];
+ pinia._s.delete($id);
+ }
+ /**
+ * Wraps an action to handle subscriptions.
+ *
+ * @param name - name of the action
+ * @param action - action to wrap
+ * @returns a wrapped action to handle subscriptions
+ */
+ function wrapAction(name, action) {
+ return function () {
+ setActivePinia(pinia);
+ const args = Array.from(arguments);
+ const afterCallbackList = [];
+ const onErrorCallbackList = [];
+ function after(callback) {
+ afterCallbackList.push(callback);
+ }
+ function onError(callback) {
+ onErrorCallbackList.push(callback);
+ }
+ // @ts-expect-error
+ triggerSubscriptions(actionSubscriptions, {
+ args,
+ name,
+ store,
+ after,
+ onError,
+ });
+ let ret;
+ try {
+ ret = action.apply(this && this.$id === $id ? this : store, args);
+ // handle sync errors
+ }
+ catch (error) {
+ triggerSubscriptions(onErrorCallbackList, error);
+ throw error;
+ }
+ if (ret instanceof Promise) {
+ return ret
+ .then((value) => {
+ triggerSubscriptions(afterCallbackList, value);
+ return value;
+ })
+ .catch((error) => {
+ triggerSubscriptions(onErrorCallbackList, error);
+ return Promise.reject(error);
+ });
+ }
+ // trigger after callbacks
+ triggerSubscriptions(afterCallbackList, ret);
+ return ret;
+ };
+ }
+ const _hmrPayload = /*#__PURE__*/ vueDemi.markRaw({
+ actions: {},
+ getters: {},
+ state: [],
+ hotState,
+ });
+ const partialStore = {
+ _p: pinia,
+ // _s: scope,
+ $id,
+ $onAction: addSubscription.bind(null, actionSubscriptions),
+ $patch,
+ $reset,
+ $subscribe(callback, options = {}) {
+ const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher());
+ const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => {
+ if (options.flush === 'sync' ? isSyncListening : isListening) {
+ callback({
+ storeId: $id,
+ type: exports.MutationType.direct,
+ events: debuggerEvents,
+ }, state);
+ }
+ }, assign({}, $subscribeOptions, options)));
+ return removeSubscription;
+ },
+ $dispose,
+ };
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ // start as non ready
+ partialStore._r = false;
+ }
+ const store = vueDemi.reactive((process.env.NODE_ENV !== 'production') || USE_DEVTOOLS
+ ? assign({
+ _hmrPayload,
+ _customProperties: vueDemi.markRaw(new Set()), // devtools custom properties
+ }, partialStore
+ // must be added later
+ // setupStore
+ )
+ : partialStore);
+ // store the partial store now so the setup of stores can instantiate each other before they are finished without
+ // creating infinite loops.
+ pinia._s.set($id, store);
+ const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext;
+ // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped
+ const setupStore = pinia._e.run(() => {
+ scope = vueDemi.effectScope();
+ return runWithContext(() => scope.run(setup));
+ });
+ // overwrite existing actions to support $onAction
+ for (const key in setupStore) {
+ const prop = setupStore[key];
+ if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) {
+ // mark it as a piece of state to be serialized
+ if ((process.env.NODE_ENV !== 'production') && hot) {
+ vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key));
+ // createOptionStore directly sets the state in pinia.state.value so we
+ // can just skip that
+ }
+ else if (!isOptionsStore) {
+ // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created
+ if (initialState && shouldHydrate(prop)) {
+ if (vueDemi.isRef(prop)) {
+ prop.value = initialState[key];
+ }
+ else {
+ // probably a reactive object, lets recursively assign
+ // @ts-expect-error: prop is unknown
+ mergeReactiveObjects(prop, initialState[key]);
+ }
+ }
+ // transfer the ref to the pinia state to keep everything in sync
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value[$id], key, prop);
+ }
+ else {
+ pinia.state.value[$id][key] = prop;
+ }
+ }
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production')) {
+ _hmrPayload.state.push(key);
+ }
+ // action
+ }
+ else if (typeof prop === 'function') {
+ // @ts-expect-error: we are overriding the function we avoid wrapping if
+ const actionValue = (process.env.NODE_ENV !== 'production') && hot ? prop : wrapAction(key, prop);
+ // this a hot module replacement store because the hotUpdate method needs
+ // to do it with the right context
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(setupStore, key, actionValue);
+ }
+ else {
+ // @ts-expect-error
+ setupStore[key] = actionValue;
+ }
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production')) {
+ _hmrPayload.actions[key] = prop;
+ }
+ // list actions so they can be used in plugins
+ // @ts-expect-error
+ optionsForPlugin.actions[key] = prop;
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ // add getters for devtools
+ if (isComputed(prop)) {
+ _hmrPayload.getters[key] = isOptionsStore
+ ? // @ts-expect-error
+ options.getters[key]
+ : prop;
+ if (IS_CLIENT) {
+ const getters = setupStore._getters ||
+ // @ts-expect-error: same
+ (setupStore._getters = vueDemi.markRaw([]));
+ getters.push(key);
+ }
+ }
+ }
+ }
+ // add the state, getters, and action properties
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ Object.keys(setupStore).forEach((key) => {
+ vueDemi.set(store, key, setupStore[key]);
+ });
+ }
+ else {
+ assign(store, setupStore);
+ // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object.
+ // Make `storeToRefs()` work with `reactive()` #799
+ assign(vueDemi.toRaw(store), setupStore);
+ }
+ // use this instead of a computed with setter to be able to create it anywhere
+ // without linking the computed lifespan to wherever the store is first
+ // created.
+ Object.defineProperty(store, '$state', {
+ get: () => ((process.env.NODE_ENV !== 'production') && hot ? hotState.value : pinia.state.value[$id]),
+ set: (state) => {
+ /* istanbul ignore if */
+ if ((process.env.NODE_ENV !== 'production') && hot) {
+ throw new Error('cannot set hotState');
+ }
+ $patch(($state) => {
+ assign($state, state);
+ });
+ },
+ });
+ // add the hotUpdate before plugins to allow them to override it
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production')) {
+ store._hotUpdate = vueDemi.markRaw((newStore) => {
+ store._hotUpdating = true;
+ newStore._hmrPayload.state.forEach((stateKey) => {
+ if (stateKey in store.$state) {
+ const newStateTarget = newStore.$state[stateKey];
+ const oldStateSource = store.$state[stateKey];
+ if (typeof newStateTarget === 'object' &&
+ isPlainObject(newStateTarget) &&
+ isPlainObject(oldStateSource)) {
+ patchObject(newStateTarget, oldStateSource);
+ }
+ else {
+ // transfer the ref
+ newStore.$state[stateKey] = oldStateSource;
+ }
+ }
+ // patch direct access properties to allow store.stateProperty to work as
+ // store.$state.stateProperty
+ vueDemi.set(store, stateKey, vueDemi.toRef(newStore.$state, stateKey));
+ });
+ // remove deleted state properties
+ Object.keys(store.$state).forEach((stateKey) => {
+ if (!(stateKey in newStore.$state)) {
+ vueDemi.del(store, stateKey);
+ }
+ });
+ // avoid devtools logging this as a mutation
+ isListening = false;
+ isSyncListening = false;
+ pinia.state.value[$id] = vueDemi.toRef(newStore._hmrPayload, 'hotState');
+ isSyncListening = true;
+ vueDemi.nextTick().then(() => {
+ isListening = true;
+ });
+ for (const actionName in newStore._hmrPayload.actions) {
+ const action = newStore[actionName];
+ vueDemi.set(store, actionName, wrapAction(actionName, action));
+ }
+ // TODO: does this work in both setup and option store?
+ for (const getterName in newStore._hmrPayload.getters) {
+ const getter = newStore._hmrPayload.getters[getterName];
+ const getterValue = isOptionsStore
+ ? // special handling of options api
+ vueDemi.computed(() => {
+ setActivePinia(pinia);
+ return getter.call(store, store);
+ })
+ : getter;
+ vueDemi.set(store, getterName, getterValue);
+ }
+ // remove deleted getters
+ Object.keys(store._hmrPayload.getters).forEach((key) => {
+ if (!(key in newStore._hmrPayload.getters)) {
+ vueDemi.del(store, key);
+ }
+ });
+ // remove old actions
+ Object.keys(store._hmrPayload.actions).forEach((key) => {
+ if (!(key in newStore._hmrPayload.actions)) {
+ vueDemi.del(store, key);
+ }
+ });
+ // update the values used in devtools and to allow deleting new properties later on
+ store._hmrPayload = newStore._hmrPayload;
+ store._getters = newStore._getters;
+ store._hotUpdating = false;
+ });
+ }
+ if (USE_DEVTOOLS) {
+ const nonEnumerable = {
+ writable: true,
+ configurable: true,
+ // avoid warning on devtools trying to display this property
+ enumerable: false,
+ };
+ ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => {
+ Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable));
+ });
+ }
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ // mark the store as ready before plugins
+ store._r = true;
+ }
+ // apply all plugins
+ pinia._p.forEach((extender) => {
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ const extensions = scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ }));
+ Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key));
+ assign(store, extensions);
+ }
+ else {
+ assign(store, scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ })));
+ }
+ });
+ if ((process.env.NODE_ENV !== 'production') &&
+ store.$state &&
+ typeof store.$state === 'object' &&
+ typeof store.$state.constructor === 'function' &&
+ !store.$state.constructor.toString().includes('[native code]')) {
+ console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` +
+ `\tstate: () => new MyClass()\n` +
+ `Found in store "${store.$id}".`);
+ }
+ // only apply hydrate to option stores with an initial state in pinia
+ if (initialState &&
+ isOptionsStore &&
+ options.hydrate) {
+ options.hydrate(store.$state, initialState);
+ }
+ isListening = true;
+ isSyncListening = true;
+ return store;
+}
+function defineStore(
+// TODO: add proper types from above
+idOrOptions, setup, setupOptions) {
+ let id;
+ let options;
+ const isSetupStore = typeof setup === 'function';
+ if (typeof idOrOptions === 'string') {
+ id = idOrOptions;
+ // the option store setup will contain the actual options in this case
+ options = isSetupStore ? setupOptions : setup;
+ }
+ else {
+ options = idOrOptions;
+ id = idOrOptions.id;
+ if ((process.env.NODE_ENV !== 'production') && typeof id !== 'string') {
+ throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`);
+ }
+ }
+ function useStore(pinia, hot) {
+ const hasContext = vueDemi.hasInjectionContext();
+ pinia =
+ // in test mode, ignore the argument provided as we can always retrieve a
+ // pinia instance with getActivePinia()
+ ((process.env.NODE_ENV === 'test') && activePinia && activePinia._testing ? null : pinia) ||
+ (hasContext ? vueDemi.inject(piniaSymbol, null) : null);
+ if (pinia)
+ setActivePinia(pinia);
+ if ((process.env.NODE_ENV !== 'production') && !activePinia) {
+ throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Did you forget to install pinia?\n` +
+ `\tconst pinia = createPinia()\n` +
+ `\tapp.use(pinia)\n` +
+ `This will fail in production.`);
+ }
+ pinia = activePinia;
+ if (!pinia._s.has(id)) {
+ // creating the store registers it in `pinia._s`
+ if (isSetupStore) {
+ createSetupStore(id, setup, options, pinia);
+ }
+ else {
+ createOptionsStore(id, options, pinia);
+ }
+ /* istanbul ignore else */
+ if ((process.env.NODE_ENV !== 'production')) {
+ // @ts-expect-error: not the right inferred type
+ useStore._pinia = pinia;
+ }
+ }
+ const store = pinia._s.get(id);
+ if ((process.env.NODE_ENV !== 'production') && hot) {
+ const hotId = '__hot:' + id;
+ const newStore = isSetupStore
+ ? createSetupStore(hotId, setup, options, pinia, true)
+ : createOptionsStore(hotId, assign({}, options), pinia, true);
+ hot._hotUpdate(newStore);
+ // cleanup the state properties and the store from the cache
+ delete pinia.state.value[hotId];
+ pinia._s.delete(hotId);
+ }
+ if ((process.env.NODE_ENV !== 'production') && IS_CLIENT) {
+ const currentInstance = vueDemi.getCurrentInstance();
+ // save stores in instances to access them devtools
+ if (currentInstance &&
+ currentInstance.proxy &&
+ // avoid adding stores that are just built for hot module replacement
+ !hot) {
+ const vm = currentInstance.proxy;
+ const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {});
+ cache[id] = store;
+ }
+ }
+ // StoreGeneric cannot be casted towards Store
+ return store;
+ }
+ useStore.$id = id;
+ return useStore;
+}
+
+let mapStoreSuffix = 'Store';
+/**
+ * Changes the suffix added by `mapStores()`. Can be set to an empty string.
+ * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
+ * interface if you are using TypeScript.
+ *
+ * @param suffix - new suffix
+ */
+function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS
+) {
+ mapStoreSuffix = suffix;
+}
+/**
+ * Allows using stores without the composition API (`setup()`) by generating an
+ * object to be spread in the `computed` field of a component. It accepts a list
+ * of store definitions.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * ...mapStores(useUserStore, useCartStore)
+ * },
+ *
+ * created() {
+ * this.userStore // store with id "user"
+ * this.cartStore // store with id "cart"
+ * }
+ * }
+ * ```
+ *
+ * @param stores - list of stores to map to an object
+ */
+function mapStores(...stores) {
+ if ((process.env.NODE_ENV !== 'production') && Array.isArray(stores[0])) {
+ console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` +
+ `Replace\n` +
+ `\tmapStores([useAuthStore, useCartStore])\n` +
+ `with\n` +
+ `\tmapStores(useAuthStore, useCartStore)\n` +
+ `This will fail in production if not fixed.`);
+ stores = stores[0];
+ }
+ return stores.reduce((reduced, useStore) => {
+ // @ts-expect-error: $id is added by defineStore
+ reduced[useStore.$id + mapStoreSuffix] = function () {
+ return useStore(this.$pinia);
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ reduced[key] = function () {
+ return useStore(this.$pinia)[key];
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function () {
+ const store = useStore(this.$pinia);
+ const storeKey = keysOrMapper[key];
+ // for some reason TS is unable to infer the type of storeKey to be a
+ // function
+ return typeof storeKey === 'function'
+ ? storeKey.call(this, store)
+ : store[storeKey];
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Alias for `mapState()`. You should use `mapState()` instead.
+ * @deprecated use `mapState()` instead.
+ */
+const mapGetters = mapState;
+/**
+ * Allows directly using actions from your store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `methods` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapActions(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[key](...args);
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[keysOrMapper[key]](...args);
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapWritableState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[key];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[key] = value);
+ },
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[keysOrMapper[key]];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[keysOrMapper[key]] = value);
+ },
+ };
+ return reduced;
+ }, {});
+}
+
+/**
+ * Creates an object of references with all the state, getters, and plugin-added
+ * state properties of the store. Similar to `toRefs()` but specifically
+ * designed for Pinia stores so methods and non reactive properties are
+ * completely ignored.
+ *
+ * @param store - store to extract the refs from
+ */
+function storeToRefs(store) {
+ // See https://github.com/vuejs/pinia/issues/852
+ // It's easier to just use toRefs() even if it includes more stuff
+ if (vueDemi.isVue2) {
+ // @ts-expect-error: toRefs include methods and others
+ return vueDemi.toRefs(store);
+ }
+ else {
+ store = vueDemi.toRaw(store);
+ const refs = {};
+ for (const key in store) {
+ const value = store[key];
+ if (vueDemi.isRef(value) || vueDemi.isReactive(value)) {
+ // @ts-expect-error: the key is state or getter
+ refs[key] =
+ // ---
+ vueDemi.toRef(store, key);
+ }
+ }
+ return refs;
+ }
+}
+
+/**
+ * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
+ * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
+ * https://pinia.vuejs.org/ssr/nuxt.html.
+ *
+ * @example
+ * ```js
+ * import Vue from 'vue'
+ * import { PiniaVuePlugin, createPinia } from 'pinia'
+ *
+ * Vue.use(PiniaVuePlugin)
+ * const pinia = createPinia()
+ *
+ * new Vue({
+ * el: '#app',
+ * // ...
+ * pinia,
+ * })
+ * ```
+ *
+ * @param _Vue - `Vue` imported from 'vue'.
+ */
+const PiniaVuePlugin = function (_Vue) {
+ // Equivalent of
+ // app.config.globalProperties.$pinia = pinia
+ _Vue.mixin({
+ beforeCreate() {
+ const options = this.$options;
+ if (options.pinia) {
+ const pinia = options.pinia;
+ // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31
+ /* istanbul ignore else */
+ if (!this._provided) {
+ const provideCache = {};
+ Object.defineProperty(this, '_provided', {
+ get: () => provideCache,
+ set: (v) => Object.assign(provideCache, v),
+ });
+ }
+ this._provided[piniaSymbol] = pinia;
+ // propagate the pinia instance in an SSR friendly way
+ // avoid adding it to nuxt twice
+ /* istanbul ignore else */
+ if (!this.$pinia) {
+ this.$pinia = pinia;
+ }
+ pinia._a = this;
+ if (IS_CLIENT) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ }
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(pinia._a, pinia);
+ }
+ }
+ else if (!this.$pinia && options.parent && options.parent.$pinia) {
+ this.$pinia = options.parent.$pinia;
+ }
+ },
+ destroyed() {
+ delete this._pStores;
+ },
+ });
+};
+
+exports.PiniaVuePlugin = PiniaVuePlugin;
+exports.acceptHMRUpdate = acceptHMRUpdate;
+exports.createPinia = createPinia;
+exports.defineStore = defineStore;
+exports.getActivePinia = getActivePinia;
+exports.mapActions = mapActions;
+exports.mapGetters = mapGetters;
+exports.mapState = mapState;
+exports.mapStores = mapStores;
+exports.mapWritableState = mapWritableState;
+exports.setActivePinia = setActivePinia;
+exports.setMapStoreSuffix = setMapStoreSuffix;
+exports.skipHydrate = skipHydrate;
+exports.storeToRefs = storeToRefs;
diff --git a/node_modules/pinia/dist/pinia.d.ts b/node_modules/pinia/dist/pinia.d.ts
new file mode 100644
index 0000000..0b3851f
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.d.ts
@@ -0,0 +1,986 @@
+import { App } from 'vue-demi';
+import { ComputedRef } from 'vue-demi';
+import type { DebuggerEvent } from 'vue-demi';
+import { EffectScope } from 'vue-demi';
+import type { Plugin as Plugin_2 } from 'vue-demi';
+import { Ref } from 'vue-demi';
+import { ToRef } from 'vue-demi';
+import { ToRefs } from 'vue-demi';
+import { UnwrapRef } from 'vue-demi';
+import type { WatchOptions } from 'vue-demi';
+
+/**
+ * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
+ *
+ * @example
+ * ```js
+ * const useUser = defineStore(...)
+ * if (import.meta.hot) {
+ * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
+ * }
+ * ```
+ *
+ * @param initialUseStore - return of the defineStore to hot update
+ * @param hot - `import.meta.hot`
+ */
+export declare function acceptHMRUpdate = _GettersTree, A = _ActionsTree>(initialUseStore: StoreDefinition, hot: any): (newModule: any) => any;
+
+/**
+ * Type of an object of Actions. For internal usage only.
+ * For internal use **only**
+ */
+export declare type _ActionsTree = Record;
+
+export declare type _Awaited = T extends null | undefined ? T : T extends object & {
+ then(onfulfilled: infer F): any;
+} ? F extends (value: infer V, ...args: any) => any ? _Awaited : never : T;
+
+/**
+ * Creates a Pinia instance to be used by the application
+ */
+export declare function createPinia(): Pinia;
+
+/**
+ * Recursive `Partial`. Used by {@link Store['$patch']}.
+ *
+ * For internal use **only**
+ */
+export declare type _DeepPartial = {
+ [K in keyof T]?: _DeepPartial;
+};
+
+/**
+ * Options parameter of `defineStore()` for setup stores. Can be extended to
+ * augment stores with the plugin API. @see {@link DefineStoreOptionsBase}.
+ */
+export declare interface DefineSetupStoreOptions extends DefineStoreOptionsBase> {
+ /**
+ * Extracted actions. Added by useStore(). SHOULD NOT be added by the user when
+ * creating the store. Can be used in plugins to get the list of actions in a
+ * store defined with a setup function. Note this is always defined
+ */
+ actions?: A;
+}
+
+/**
+ * Creates a `useStore` function that retrieves the store instance
+ *
+ * @param id - id of the store (must be unique)
+ * @param options - options to define the store
+ */
+export declare function defineStore = {}, A = {}>(id: Id, options: Omit, 'id'>): StoreDefinition;
+
+/**
+ * Creates a `useStore` function that retrieves the store instance
+ *
+ * @param options - options to define the store
+ */
+export declare function defineStore = {}, A = {}>(options: DefineStoreOptions): StoreDefinition;
+
+/**
+ * Creates a `useStore` function that retrieves the store instance
+ *
+ * @param id - id of the store (must be unique)
+ * @param storeSetup - function that defines the store
+ * @param options - extra options
+ */
+export declare function defineStore(id: Id, storeSetup: () => SS, options?: DefineSetupStoreOptions, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore>): StoreDefinition, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore>;
+
+/**
+ * Options parameter of `defineStore()` for option stores. Can be extended to
+ * augment stores with the plugin API. @see {@link DefineStoreOptionsBase}.
+ */
+export declare interface DefineStoreOptions extends DefineStoreOptionsBase> {
+ /**
+ * Unique string key to identify the store across the application.
+ */
+ id: Id;
+ /**
+ * Function to create a fresh state. **Must be an arrow function** to ensure
+ * correct typings!
+ */
+ state?: () => S;
+ /**
+ * Optional object of getters.
+ */
+ getters?: G & ThisType & _StoreWithGetters & PiniaCustomProperties> & _GettersTree;
+ /**
+ * Optional object of actions.
+ */
+ actions?: A & ThisType & _StoreWithState & _StoreWithGetters & PiniaCustomProperties>;
+ /**
+ * Allows hydrating the store during SSR when complex state (like client side only refs) are used in the store
+ * definition and copying the value from `pinia.state` isn't enough.
+ *
+ * @example
+ * If in your `state`, you use any `customRef`s, any `computed`s, or any `ref`s that have a different value on
+ * Server and Client, you need to manually hydrate them. e.g., a custom ref that is stored in the local
+ * storage:
+ *
+ * ```ts
+ * const useStore = defineStore('main', {
+ * state: () => ({
+ * n: useLocalStorage('key', 0)
+ * }),
+ * hydrate(storeState, initialState) {
+ * // @ts-expect-error: https://github.com/microsoft/TypeScript/issues/43826
+ * storeState.n = useLocalStorage('key', 0)
+ * }
+ * })
+ * ```
+ *
+ * @param storeState - the current state in the store
+ * @param initialState - initialState
+ */
+ hydrate?(storeState: UnwrapRef, initialState: UnwrapRef): void;
+}
+
+/**
+ * Options passed to `defineStore()` that are common between option and setup
+ * stores. Extend this interface if you want to add custom options to both kinds
+ * of stores.
+ */
+export declare interface DefineStoreOptionsBase {
+}
+
+/**
+ * Available `options` when creating a pinia plugin.
+ */
+export declare interface DefineStoreOptionsInPlugin extends Omit, 'id' | 'actions'> {
+ /**
+ * Extracted object of actions. Added by useStore() when the store is built
+ * using the setup API, otherwise uses the one passed to `defineStore()`.
+ * Defaults to an empty object if no actions are defined.
+ */
+ actions: A;
+}
+
+/**
+ * For internal use **only**
+ */
+export declare type _ExtractActionsFromSetupStore = SS extends undefined | void ? {} : _ExtractActionsFromSetupStore_Keys extends keyof SS ? Pick> : never;
+
+/**
+ * Type that enables refactoring through IDE.
+ * For internal use **only**
+ */
+export declare type _ExtractActionsFromSetupStore_Keys = keyof {
+ [K in keyof SS as SS[K] extends _Method ? K : never]: any;
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _ExtractGettersFromSetupStore = SS extends undefined | void ? {} : _ExtractGettersFromSetupStore_Keys extends keyof SS ? Pick> : never;
+
+/**
+ * Type that enables refactoring through IDE.
+ * For internal use **only**
+ */
+export declare type _ExtractGettersFromSetupStore_Keys = keyof {
+ [K in keyof SS as SS[K] extends ComputedRef ? K : never]: any;
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _ExtractStateFromSetupStore = SS extends undefined | void ? {} : _ExtractStateFromSetupStore_Keys extends keyof SS ? _UnwrapAll>> : never;
+
+/**
+ * Type that enables refactoring through IDE.
+ * For internal use **only**
+ */
+export declare type _ExtractStateFromSetupStore_Keys = keyof {
+ [K in keyof SS as SS[K] extends _Method | ComputedRef ? never : K]: any;
+};
+
+/**
+ * Get the currently active pinia if there is any.
+ */
+export declare const getActivePinia: () => Pinia | undefined;
+
+/**
+ * Type of an object of Getters that infers the argument. For internal usage only.
+ * For internal use **only**
+ */
+export declare type _GettersTree = Record & UnwrapRef>) => any) | (() => any)>;
+
+/**
+ * Allows directly using actions from your store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `methods` field
+ * of a component. The values of the object are the actions while the keys are
+ * the names of the resulting methods.
+ *
+ * @example
+ * ```js
+ * export default {
+ * methods: {
+ * // other methods properties
+ * // useCounterStore has two actions named `increment` and `setCount`
+ * ...mapActions(useCounterStore, { moar: 'increment', setIt: 'setCount' })
+ * },
+ *
+ * created() {
+ * this.moar()
+ * this.setIt(2)
+ * }
+ * }
+ * ```
+ *
+ * @param useStore - store to map from
+ * @param keyMapper - object to define new names for the actions
+ */
+export declare function mapActions, A, KeyMapper extends Record>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapActionsObjectReturn;
+
+/**
+ * Allows directly using actions from your store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `methods` field
+ * of a component.
+ *
+ * @example
+ * ```js
+ * export default {
+ * methods: {
+ * // other methods properties
+ * ...mapActions(useCounterStore, ['increment', 'setCount'])
+ * },
+ *
+ * created() {
+ * this.increment()
+ * this.setCount(2) // pass arguments as usual
+ * }
+ * }
+ * ```
+ *
+ * @param useStore - store to map from
+ * @param keys - array of action names to map
+ */
+export declare function mapActions, A>(useStore: StoreDefinition, keys: Array): _MapActionsReturn;
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapActionsObjectReturn> = {
+ [key in keyof T]: A[T[key]];
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapActionsReturn = {
+ [key in keyof A]: A[key];
+};
+
+/**
+ * Alias for `mapState()`. You should use `mapState()` instead.
+ * @deprecated use `mapState()` instead.
+ */
+export declare const mapGetters: typeof mapState;
+
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component. The values of the object are the state properties/getters
+ * while the keys are the names of the resulting computed properties.
+ * Optionally, you can also pass a custom function that will receive the store
+ * as its first argument. Note that while it has access to the component
+ * instance via `this`, it won't be typed.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * // useCounterStore has a state property named `count` and a getter `double`
+ * ...mapState(useCounterStore, {
+ * n: 'count',
+ * triple: store => store.n * 3,
+ * // note we can't use an arrow function if we want to use `this`
+ * custom(store) {
+ * return this.someComponentValue + store.n
+ * },
+ * doubleN: 'double'
+ * })
+ * },
+ *
+ * created() {
+ * this.n // 2
+ * this.doubleN // 4
+ * }
+ * }
+ * ```
+ *
+ * @param useStore - store to map from
+ * @param keyMapper - object of state properties or getters
+ */
+export declare function mapState, A, KeyMapper extends Record) => any)>>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapStateObjectReturn;
+
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * ...mapState(useCounterStore, ['count', 'double'])
+ * },
+ *
+ * created() {
+ * this.count // 2
+ * this.double // 4
+ * }
+ * }
+ * ```
+ *
+ * @param useStore - store to map from
+ * @param keys - array of state properties or getters
+ */
+export declare function mapState, A, Keys extends keyof S | keyof G>(useStore: StoreDefinition, keys: readonly Keys[]): _MapStateReturn;
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapStateObjectReturn, A, T extends Record) => any)> = {}> = {
+ [key in keyof T]: () => T[key] extends (store: any) => infer R ? R : T[key] extends keyof Store ? Store[T[key]] : never;
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapStateReturn, Keys extends keyof S | keyof G = keyof S | keyof G> = {
+ [key in Keys]: () => Store[key];
+};
+
+/**
+ * Allows using stores without the composition API (`setup()`) by generating an
+ * object to be spread in the `computed` field of a component. It accepts a list
+ * of store definitions.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * ...mapStores(useUserStore, useCartStore)
+ * },
+ *
+ * created() {
+ * this.userStore // store with id "user"
+ * this.cartStore // store with id "cart"
+ * }
+ * }
+ * ```
+ *
+ * @param stores - list of stores to map to an object
+ */
+export declare function mapStores(...stores: [...Stores]): _Spread;
+
+/**
+ * Interface to allow customizing map helpers. Extend this interface with the
+ * following properties:
+ *
+ * - `suffix`: string. Affects the suffix of `mapStores()`, defaults to `Store`.
+ */
+export declare interface MapStoresCustomization {
+}
+
+/**
+ * Same as `mapState()` but creates computed setters as well so the state can be
+ * modified. Differently from `mapState()`, only `state` properties can be
+ * added.
+ *
+ * @param useStore - store to map from
+ * @param keyMapper - object of state properties
+ */
+export declare function mapWritableState, A, KeyMapper extends Record>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapWritableStateObjectReturn;
+
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keys - array of state properties
+ */
+export declare function mapWritableState, A, Keys extends keyof S>(useStore: StoreDefinition, keys: readonly Keys[]): {
+ [K in Keys]: {
+ get: () => S[K];
+ set: (value: S[K]) => any;
+ };
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapWritableStateObjectReturn> = {
+ [key in keyof T]: {
+ get: () => S[T[key]];
+ set: (value: S[T[key]]) => any;
+ };
+};
+
+/**
+ * For internal use **only**
+ */
+export declare type _MapWritableStateReturn = {
+ [key in keyof S]: {
+ get: () => S[key];
+ set: (value: S[key]) => any;
+ };
+};
+
+/**
+ * Generic type for a function that can infer arguments and return type
+ *
+ * For internal use **only**
+ */
+export declare type _Method = (...args: any[]) => any;
+
+/**
+ * Possible types for SubscriptionCallback
+ */
+export declare enum MutationType {
+ /**
+ * Direct mutation of the state:
+ *
+ * - `store.name = 'new name'`
+ * - `store.$state.name = 'new name'`
+ * - `store.list.push('new item')`
+ */
+ direct = "direct",
+ /**
+ * Mutated the state with `$patch` and an object
+ *
+ * - `store.$patch({ name: 'newName' })`
+ */
+ patchObject = "patch object",
+ /**
+ * Mutated the state with `$patch` and a function
+ *
+ * - `store.$patch(state => state.name = 'newName')`
+ */
+ patchFunction = "patch function"
+}
+
+/**
+ * Every application must own its own pinia to be able to create stores
+ */
+export declare interface Pinia {
+ install: (app: App) => void;
+ /**
+ * root state
+ */
+ state: Ref>;
+ /**
+ * Adds a store plugin to extend every store
+ *
+ * @param plugin - store plugin to add
+ */
+ use(plugin: PiniaPlugin): Pinia;
+ /* Excluded from this release type: _p */
+ /* Excluded from this release type: _a */
+ /* Excluded from this release type: _e */
+ /* Excluded from this release type: _s */
+ /* Excluded from this release type: _testing */
+}
+
+/**
+ * Interface to be extended by the user when they add properties through plugins.
+ */
+export declare interface PiniaCustomProperties, A = _ActionsTree> {
+}
+
+/**
+ * Properties that are added to every `store.$state` by `pinia.use()`.
+ */
+export declare interface PiniaCustomStateProperties {
+}
+
+/**
+ * Plugin to extend every store.
+ */
+export declare interface PiniaPlugin {
+ /**
+ * Plugin to extend every store. Returns an object to extend the store or
+ * nothing.
+ *
+ * @param context - Context
+ */
+ (context: PiniaPluginContext): Partial | void;
+}
+
+/**
+ * Context argument passed to Pinia plugins.
+ */
+export declare interface PiniaPluginContext, A = _ActionsTree> {
+ /**
+ * pinia instance.
+ */
+ pinia: Pinia;
+ /**
+ * Current app created with `Vue.createApp()`.
+ */
+ app: App;
+ /**
+ * Current store being extended.
+ */
+ store: Store;
+ /**
+ * Initial options defining the store when calling `defineStore()`.
+ */
+ options: DefineStoreOptionsInPlugin;
+}
+
+/**
+ * Plugin to extend every store.
+ * @deprecated use PiniaPlugin instead
+ */
+export declare type PiniaStorePlugin = PiniaPlugin;
+
+/**
+ * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
+ * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
+ * https://pinia.vuejs.org/ssr/nuxt.html.
+ *
+ * @example
+ * ```js
+ * import Vue from 'vue'
+ * import { PiniaVuePlugin, createPinia } from 'pinia'
+ *
+ * Vue.use(PiniaVuePlugin)
+ * const pinia = createPinia()
+ *
+ * new Vue({
+ * el: '#app',
+ * // ...
+ * pinia,
+ * })
+ * ```
+ *
+ * @param _Vue - `Vue` imported from 'vue'.
+ */
+export declare const PiniaVuePlugin: Plugin_2;
+
+declare interface _SetActivePinia {
+ (pinia: Pinia): Pinia;
+ (pinia: undefined): undefined;
+ (pinia: Pinia | undefined): Pinia | undefined;
+}
+
+/**
+ * Sets or unsets the active pinia. Used in SSR and internally when calling
+ * actions and getters
+ *
+ * @param pinia - Pinia instance
+ */
+export declare const setActivePinia: _SetActivePinia;
+
+/**
+ * Changes the suffix added by `mapStores()`. Can be set to an empty string.
+ * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
+ * interface if you are using TypeScript.
+ *
+ * @param suffix - new suffix
+ */
+export declare function setMapStoreSuffix(suffix: MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : string): void;
+
+/**
+ * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
+ * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
+ *
+ * @param obj - target object
+ * @returns obj
+ */
+export declare function skipHydrate(obj: T): T;
+
+/**
+ * For internal use **only**.
+ */
+export declare type _Spread = A extends [infer L, ...infer R] ? _StoreObject & _Spread : unknown;
+
+/**
+ * Generic state of a Store
+ */
+export declare type StateTree = Record;
+
+/**
+ * Store type to build a store.
+ */
+export declare type Store = _StoreWithState & UnwrapRef & _StoreWithGetters & (_ActionsTree extends A ? {} : A) & PiniaCustomProperties & PiniaCustomStateProperties;
+
+/**
+ * Extract the actions of a store type. Works with both a Setup Store or an
+ * Options Store.
+ */
+export declare type StoreActions = SS extends Store, infer A> ? A : _ExtractActionsFromSetupStore;
+
+/**
+ * Return type of `defineStore()`. Function that allows instantiating a store.
+ */
+export declare interface StoreDefinition, A = _ActionsTree> {
+ /**
+ * Returns a store, creates it if necessary.
+ *
+ * @param pinia - Pinia instance to retrieve the store
+ * @param hot - dev only hot module replacement
+ */
+ (pinia?: Pinia | null | undefined, hot?: StoreGeneric): Store;
+ /**
+ * Id of the store. Used by map helpers.
+ */
+ $id: Id;
+ /* Excluded from this release type: _pinia */
+}
+
+/**
+ * Generic and type-unsafe version of Store. Doesn't fail on access with
+ * strings, making it much easier to write generic functions that do not care
+ * about the kind of store that is passed.
+ */
+export declare type StoreGeneric = Store, _ActionsTree>;
+
+/**
+ * Extract the getters of a store type. Works with both a Setup Store or an
+ * Options Store.
+ */
+export declare type StoreGetters = SS extends Store ? _StoreWithGetters : _ExtractGettersFromSetupStore;
+
+/**
+ * For internal use **only**.
+ */
+export declare type _StoreObject = S extends StoreDefinition ? {
+ [Id in `${Ids}${MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : 'Store'}`]: () => Store ? Suffix : 'Store'}` ? RealId : string, State, Getters, Actions>;
+} : {};
+
+/**
+ * Argument of `store.$onAction()`
+ */
+export declare type StoreOnActionListener = (context: StoreOnActionListenerContext) => void;
+
+/**
+ * Context object passed to callbacks of `store.$onAction(context => {})`
+ * TODO: should have only the Id, the Store and Actions to generate the proper object
+ */
+export declare type StoreOnActionListenerContext = _ActionsTree extends A ? _StoreOnActionListenerContext : {
+ [Name in keyof A]: Name extends string ? _StoreOnActionListenerContext, Name, A> : never;
+}[keyof A];
+
+/**
+ * Actual type for {@link StoreOnActionListenerContext}. Exists for refactoring
+ * purposes. For internal use only.
+ * For internal use **only**
+ */
+export declare interface _StoreOnActionListenerContext {
+ /**
+ * Name of the action
+ */
+ name: ActionName;
+ /**
+ * Store that is invoking the action
+ */
+ store: Store;
+ /**
+ * Parameters passed to the action
+ */
+ args: A extends Record ? Parameters : unknown[];
+ /**
+ * Sets up a hook once the action is finished. It receives the return value
+ * of the action, if it's a Promise, it will be unwrapped.
+ */
+ after: (callback: A extends Record ? (resolvedReturn: _Awaited>) => void : () => void) => void;
+ /**
+ * Sets up a hook if the action fails. Return `false` to catch the error and
+ * stop it from propagating.
+ */
+ onError: (callback: (error: unknown) => void) => void;
+}
+
+/**
+ * Properties of a store.
+ */
+export declare interface StoreProperties {
+ /**
+ * Unique identifier of the store
+ */
+ $id: Id;
+ /* Excluded from this release type: _p */
+ /* Excluded from this release type: _getters */
+ /* Excluded from this release type: _isOptionsAPI */
+ /**
+ * Used by devtools plugin to retrieve properties added with plugins. Removed
+ * in production. Can be used by the user to add property keys of the store
+ * that should be displayed in devtools.
+ */
+ _customProperties: Set;
+ /* Excluded from this release type: _hotUpdate */
+ /* Excluded from this release type: _hotUpdating */
+ /* Excluded from this release type: _hmrPayload */
+}
+
+/**
+ * Extract the state of a store type. Works with both a Setup Store or an
+ * Options Store. Note this unwraps refs.
+ */
+export declare type StoreState = SS extends Store, _ActionsTree> ? UnwrapRef : _ExtractStateFromSetupStore;
+
+/**
+ * Extracts the return type for `storeToRefs`.
+ * Will convert any `getters` into `ComputedRef`.
+ */
+declare type StoreToRefs = ToRefs & PiniaCustomStateProperties>> & ToComputedRefs>;
+
+/**
+ * Creates an object of references with all the state, getters, and plugin-added
+ * state properties of the store. Similar to `toRefs()` but specifically
+ * designed for Pinia stores so methods and non reactive properties are
+ * completely ignored.
+ *
+ * @param store - store to extract the refs from
+ */
+export declare function storeToRefs(store: SS): StoreToRefs;
+
+/**
+ * Store augmented for actions. For internal usage only.
+ * For internal use **only**
+ */
+export declare type _StoreWithActions = {
+ [k in keyof A]: A[k] extends (...args: infer P) => infer R ? (...args: P) => R : never;
+};
+
+/**
+ * Store augmented with getters. For internal usage only.
+ * For internal use **only**
+ */
+export declare type _StoreWithGetters = {
+ readonly [k in keyof G]: G[k] extends (...args: any[]) => infer R ? R : UnwrapRef;
+};
+
+/**
+ * Base store with state and functions. Should not be used directly.
+ */
+export declare interface _StoreWithState extends StoreProperties {
+ /**
+ * State of the Store. Setting it will internally call `$patch()` to update the state.
+ */
+ $state: UnwrapRef & PiniaCustomStateProperties;
+ /**
+ * Applies a state patch to current state. Allows passing nested values
+ *
+ * @param partialState - patch to apply to the state
+ */
+ $patch(partialState: _DeepPartial>): void;
+ /**
+ * Group multiple changes into one function. Useful when mutating objects like
+ * Sets or arrays and applying an object patch isn't practical, e.g. appending
+ * to an array. The function passed to `$patch()` **must be synchronous**.
+ *
+ * @param stateMutator - function that mutates `state`, cannot be asynchronous
+ */
+ $patch) => any>(stateMutator: ReturnType extends Promise ? never : F): void;
+ /**
+ * Resets the store to its initial state by building a new state object.
+ * TODO: make this options only
+ */
+ $reset(): void;
+ /**
+ * Setups a callback to be called whenever the state changes. It also returns a function to remove the callback. Note
+ * that when calling `store.$subscribe()` inside of a component, it will be automatically cleaned up when the
+ * component gets unmounted unless `detached` is set to true.
+ *
+ * @param callback - callback passed to the watcher
+ * @param options - `watch` options + `detached` to detach the subscription from the context (usually a component)
+ * this is called from. Note that the `flush` option does not affect calls to `store.$patch()`.
+ * @returns function that removes the watcher
+ */
+ $subscribe(callback: SubscriptionCallback, options?: {
+ detached?: boolean;
+ } & WatchOptions): () => void;
+ /**
+ * Setups a callback to be called every time an action is about to get
+ * invoked. The callback receives an object with all the relevant information
+ * of the invoked action:
+ * - `store`: the store it is invoked on
+ * - `name`: The name of the action
+ * - `args`: The parameters passed to the action
+ *
+ * On top of these, it receives two functions that allow setting up a callback
+ * once the action finishes or when it fails.
+ *
+ * It also returns a function to remove the callback. Note than when calling
+ * `store.$onAction()` inside of a component, it will be automatically cleaned
+ * up when the component gets unmounted unless `detached` is set to true.
+ *
+ * @example
+ *
+ *```js
+ *store.$onAction(({ after, onError }) => {
+ * // Here you could share variables between all of the hooks as well as
+ * // setting up watchers and clean them up
+ * after((resolvedValue) => {
+ * // can be used to cleanup side effects
+ * . // `resolvedValue` is the value returned by the action, if it's a
+ * . // Promise, it will be the resolved value instead of the Promise
+ * })
+ * onError((error) => {
+ * // can be used to pass up errors
+ * })
+ *})
+ *```
+ *
+ * @param callback - callback called before every action
+ * @param detached - detach the subscription from the context this is called from
+ * @returns function that removes the watcher
+ */
+ $onAction(callback: StoreOnActionListener, detached?: boolean): () => void;
+ /**
+ * Stops the associated effect scope of the store and remove it from the store
+ * registry. Plugins can override this method to cleanup any added effects.
+ * e.g. devtools plugin stops displaying disposed stores from devtools.
+ * Note this doesn't delete the state of the store, you have to do it manually with
+ * `delete pinia.state.value[store.$id]` if you want to. If you don't and the
+ * store is used again, it will reuse the previous state.
+ */
+ $dispose(): void;
+ /* Excluded from this release type: _r */
+}
+
+/**
+ * Callback of a subscription
+ */
+export declare type SubscriptionCallback = (
+/**
+ * Object with information relative to the store mutation that triggered the
+ * subscription.
+ */
+mutation: SubscriptionCallbackMutation,
+/**
+ * State of the store when the subscription is triggered. Same as
+ * `store.$state`.
+ */
+state: UnwrapRef) => void;
+
+/**
+ * Context object passed to a subscription callback.
+ */
+export declare type SubscriptionCallbackMutation = SubscriptionCallbackMutationDirect | SubscriptionCallbackMutationPatchObject | SubscriptionCallbackMutationPatchFunction;
+
+/**
+ * Base type for the context passed to a subscription callback. Internal type.
+ */
+export declare interface _SubscriptionCallbackMutationBase {
+ /**
+ * Type of the mutation.
+ */
+ type: MutationType;
+ /**
+ * `id` of the store doing the mutation.
+ */
+ storeId: string;
+ /**
+ * 🔴 DEV ONLY, DO NOT use for production code. Different mutation calls. Comes from
+ * https://vuejs.org/guide/extras/reactivity-in-depth.html#reactivity-debugging and allows to track mutations in
+ * devtools and plugins **during development only**.
+ */
+ events?: DebuggerEvent[] | DebuggerEvent;
+}
+
+/**
+ * Context passed to a subscription callback when directly mutating the state of
+ * a store with `store.someState = newValue` or `store.$state.someState =
+ * newValue`.
+ */
+export declare interface SubscriptionCallbackMutationDirect extends _SubscriptionCallbackMutationBase {
+ type: MutationType.direct;
+ events: DebuggerEvent;
+}
+
+/**
+ * Context passed to a subscription callback when `store.$patch()` is called
+ * with a function.
+ */
+export declare interface SubscriptionCallbackMutationPatchFunction extends _SubscriptionCallbackMutationBase {
+ type: MutationType.patchFunction;
+ events: DebuggerEvent[];
+}
+
+/**
+ * Context passed to a subscription callback when `store.$patch()` is called
+ * with an object.
+ */
+export declare interface SubscriptionCallbackMutationPatchObject extends _SubscriptionCallbackMutationBase {
+ type: MutationType.patchObject;
+ events: DebuggerEvent[];
+ /**
+ * Object passed to `store.$patch()`.
+ */
+ payload: _DeepPartial;
+}
+
+declare type ToComputedRefs = {
+ [K in keyof T]: ToRef extends Ref ? ComputedRef : ToRef;
+};
+
+/**
+ * Type that enables refactoring through IDE.
+ * For internal use **only**
+ */
+export declare type _UnwrapAll = {
+ [K in keyof SS]: UnwrapRef;
+};
+
+export { }
+
+// Extensions of Vue types to be appended manually
+// https://github.com/microsoft/rushstack/issues/2090
+// https://github.com/microsoft/rushstack/issues/1709
+
+// @ts-ignore: works on Vue 2, fails in Vue 3
+declare module 'vue/types/vue' {
+ interface Vue {
+ /**
+ * Currently installed pinia instance.
+ */
+ $pinia: Pinia
+
+ /**
+ * Cache of stores instantiated by the current instance. Used by map
+ * helpers. Used internally by Pinia.
+ *
+ * @internal
+ */
+ _pStores?: Record
+ }
+}
+
+// @ts-ignore: works on Vue 2, fails in Vue 3
+declare module 'vue/types/options' {
+ interface ComponentOptions {
+ /**
+ * Pinia instance to install in your application. Should be passed to the
+ * root Vue.
+ */
+ pinia?: Pinia
+ }
+}
+
+// TODO: figure out why it cannot be 'vue'
+// @ts-ignore: works on Vue 3, fails in Vue 2
+declare module '@vue/runtime-core' {
+ export interface ComponentCustomProperties {
+ /**
+ * Access to the application's Pinia
+ */
+ $pinia: Pinia
+
+ /**
+ * Cache of stores instantiated by the current instance. Used by devtools to
+ * list currently used stores. Used internally by Pinia.
+ *
+ * @internal
+ */
+ _pStores?: Record
+ }
+}
diff --git a/node_modules/pinia/dist/pinia.esm-browser.js b/node_modules/pinia/dist/pinia.esm-browser.js
new file mode 100644
index 0000000..5e50d7d
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.esm-browser.js
@@ -0,0 +1,1996 @@
+/*!
+ * pinia v2.1.6
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+import { hasInjectionContext, inject, toRaw, watch, unref, markRaw, effectScope, ref, isVue2, isRef, isReactive, set, getCurrentScope, onScopeDispose, getCurrentInstance, reactive, toRef, del, nextTick, computed, toRefs } from 'vue-demi';
+import { setupDevtoolsPlugin } from '@vue/devtools-api';
+
+/**
+ * setActivePinia must be called to handle SSR at the top of functions like
+ * `fetch`, `setup`, `serverPrefetch` and others
+ */
+let activePinia;
+/**
+ * Sets or unsets the active pinia. Used in SSR and internally when calling
+ * actions and getters
+ *
+ * @param pinia - Pinia instance
+ */
+// @ts-expect-error: cannot constrain the type of the return
+const setActivePinia = (pinia) => (activePinia = pinia);
+/**
+ * Get the currently active pinia if there is any.
+ */
+const getActivePinia = () => (hasInjectionContext() && inject(piniaSymbol)) || activePinia;
+const piniaSymbol = (Symbol('pinia') );
+
+function isPlainObject(
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+o) {
+ return (o &&
+ typeof o === 'object' &&
+ Object.prototype.toString.call(o) === '[object Object]' &&
+ typeof o.toJSON !== 'function');
+}
+// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly }
+// TODO: can we change these to numbers?
+/**
+ * Possible types for SubscriptionCallback
+ */
+var MutationType;
+(function (MutationType) {
+ /**
+ * Direct mutation of the state:
+ *
+ * - `store.name = 'new name'`
+ * - `store.$state.name = 'new name'`
+ * - `store.list.push('new item')`
+ */
+ MutationType["direct"] = "direct";
+ /**
+ * Mutated the state with `$patch` and an object
+ *
+ * - `store.$patch({ name: 'newName' })`
+ */
+ MutationType["patchObject"] = "patch object";
+ /**
+ * Mutated the state with `$patch` and a function
+ *
+ * - `store.$patch(state => state.name = 'newName')`
+ */
+ MutationType["patchFunction"] = "patch function";
+ // maybe reset? for $state = {} and $reset
+})(MutationType || (MutationType = {}));
+
+const IS_CLIENT = typeof window !== 'undefined';
+/**
+ * Should we add the devtools plugins.
+ * - only if dev mode or forced through the prod devtools flag
+ * - not in test
+ * - only if window exists (could change in the future)
+ */
+const USE_DEVTOOLS = IS_CLIENT;
+
+/*
+ * FileSaver.js A saveAs() FileSaver implementation.
+ *
+ * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin
+ * Morote.
+ *
+ * License : MIT
+ */
+// The one and only way of getting global scope in all environments
+// https://stackoverflow.com/q/3277182/1008999
+const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window
+ ? window
+ : typeof self === 'object' && self.self === self
+ ? self
+ : typeof global === 'object' && global.global === global
+ ? global
+ : typeof globalThis === 'object'
+ ? globalThis
+ : { HTMLElement: null })();
+function bom(blob, { autoBom = false } = {}) {
+ // prepend BOM for UTF-8 XML and text/* types (including HTML)
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+ if (autoBom &&
+ /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+ return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type });
+ }
+ return blob;
+}
+function download(url, name, opts) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'blob';
+ xhr.onload = function () {
+ saveAs(xhr.response, name, opts);
+ };
+ xhr.onerror = function () {
+ console.error('could not download file');
+ };
+ xhr.send();
+}
+function corsEnabled(url) {
+ const xhr = new XMLHttpRequest();
+ // use sync to avoid popup blocker
+ xhr.open('HEAD', url, false);
+ try {
+ xhr.send();
+ }
+ catch (e) { }
+ return xhr.status >= 200 && xhr.status <= 299;
+}
+// `a.click()` doesn't work for all browsers (#465)
+function click(node) {
+ try {
+ node.dispatchEvent(new MouseEvent('click'));
+ }
+ catch (e) {
+ const evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+ node.dispatchEvent(evt);
+ }
+}
+const _navigator =
+ typeof navigator === 'object' ? navigator : { userAgent: '' };
+// Detect WebView inside a native macOS app by ruling out all browsers
+// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
+// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
+const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) &&
+ /AppleWebKit/.test(_navigator.userAgent) &&
+ !/Safari/.test(_navigator.userAgent))();
+const saveAs = !IS_CLIENT
+ ? () => { } // noop
+ : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program
+ typeof HTMLAnchorElement !== 'undefined' &&
+ 'download' in HTMLAnchorElement.prototype &&
+ !isMacOSWebView
+ ? downloadSaveAs
+ : // Use msSaveOrOpenBlob as a second approach
+ 'msSaveOrOpenBlob' in _navigator
+ ? msSaveAs
+ : // Fallback to using FileReader and a popup
+ fileSaverSaveAs;
+function downloadSaveAs(blob, name = 'download', opts) {
+ const a = document.createElement('a');
+ a.download = name;
+ a.rel = 'noopener'; // tabnabbing
+ // TODO: detect chrome extensions & packaged apps
+ // a.target = '_blank'
+ if (typeof blob === 'string') {
+ // Support regular links
+ a.href = blob;
+ if (a.origin !== location.origin) {
+ if (corsEnabled(a.href)) {
+ download(blob, name, opts);
+ }
+ else {
+ a.target = '_blank';
+ click(a);
+ }
+ }
+ else {
+ click(a);
+ }
+ }
+ else {
+ // Support blobs
+ a.href = URL.createObjectURL(blob);
+ setTimeout(function () {
+ URL.revokeObjectURL(a.href);
+ }, 4e4); // 40s
+ setTimeout(function () {
+ click(a);
+ }, 0);
+ }
+}
+function msSaveAs(blob, name = 'download', opts) {
+ if (typeof blob === 'string') {
+ if (corsEnabled(blob)) {
+ download(blob, name, opts);
+ }
+ else {
+ const a = document.createElement('a');
+ a.href = blob;
+ a.target = '_blank';
+ setTimeout(function () {
+ click(a);
+ });
+ }
+ }
+ else {
+ // @ts-ignore: works on windows
+ navigator.msSaveOrOpenBlob(bom(blob, opts), name);
+ }
+}
+function fileSaverSaveAs(blob, name, opts, popup) {
+ // Open a popup immediately do go around popup blocker
+ // Mostly only available on user interaction and the fileReader is async so...
+ popup = popup || open('', '_blank');
+ if (popup) {
+ popup.document.title = popup.document.body.innerText = 'downloading...';
+ }
+ if (typeof blob === 'string')
+ return download(blob, name, opts);
+ const force = blob.type === 'application/octet-stream';
+ const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global;
+ const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
+ if ((isChromeIOS || (force && isSafari) || isMacOSWebView) &&
+ typeof FileReader !== 'undefined') {
+ // Safari doesn't allow downloading of blob URLs
+ const reader = new FileReader();
+ reader.onloadend = function () {
+ let url = reader.result;
+ if (typeof url !== 'string') {
+ popup = null;
+ throw new Error('Wrong reader.result type');
+ }
+ url = isChromeIOS
+ ? url
+ : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
+ if (popup) {
+ popup.location.href = url;
+ }
+ else {
+ location.assign(url);
+ }
+ popup = null; // reverse-tabnabbing #460
+ };
+ reader.readAsDataURL(blob);
+ }
+ else {
+ const url = URL.createObjectURL(blob);
+ if (popup)
+ popup.location.assign(url);
+ else
+ location.href = url;
+ popup = null; // reverse-tabnabbing #460
+ setTimeout(function () {
+ URL.revokeObjectURL(url);
+ }, 4e4); // 40s
+ }
+}
+
+/**
+ * Shows a toast or console.log
+ *
+ * @param message - message to log
+ * @param type - different color of the tooltip
+ */
+function toastMessage(message, type) {
+ const piniaMessage = '🍍 ' + message;
+ if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') {
+ // No longer available :(
+ __VUE_DEVTOOLS_TOAST__(piniaMessage, type);
+ }
+ else if (type === 'error') {
+ console.error(piniaMessage);
+ }
+ else if (type === 'warn') {
+ console.warn(piniaMessage);
+ }
+ else {
+ console.log(piniaMessage);
+ }
+}
+function isPinia(o) {
+ return '_a' in o && 'install' in o;
+}
+
+/**
+ * This file contain devtools actions, they are not Pinia actions.
+ */
+// ---
+function checkClipboardAccess() {
+ if (!('clipboard' in navigator)) {
+ toastMessage(`Your browser doesn't support the Clipboard API`, 'error');
+ return true;
+ }
+}
+function checkNotFocusedError(error) {
+ if (error instanceof Error &&
+ error.message.toLowerCase().includes('document is not focused')) {
+ toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn');
+ return true;
+ }
+ return false;
+}
+async function actionGlobalCopyState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ await navigator.clipboard.writeText(JSON.stringify(pinia.state.value));
+ toastMessage('Global state copied to clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+async function actionGlobalPasteState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText()));
+ toastMessage('Global state pasted from clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+async function actionGlobalSaveState(pinia) {
+ try {
+ saveAs(new Blob([JSON.stringify(pinia.state.value)], {
+ type: 'text/plain;charset=utf-8',
+ }), 'pinia-state.json');
+ }
+ catch (error) {
+ toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+let fileInput;
+function getFileOpener() {
+ if (!fileInput) {
+ fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '.json';
+ }
+ function openFile() {
+ return new Promise((resolve, reject) => {
+ fileInput.onchange = async () => {
+ const files = fileInput.files;
+ if (!files)
+ return resolve(null);
+ const file = files.item(0);
+ if (!file)
+ return resolve(null);
+ return resolve({ text: await file.text(), file });
+ };
+ // @ts-ignore: TODO: changed from 4.3 to 4.4
+ fileInput.oncancel = () => resolve(null);
+ fileInput.onerror = reject;
+ fileInput.click();
+ });
+ }
+ return openFile;
+}
+async function actionGlobalOpenStateFile(pinia) {
+ try {
+ const open = getFileOpener();
+ const result = await open();
+ if (!result)
+ return;
+ const { text, file } = result;
+ loadStoresState(pinia, JSON.parse(text));
+ toastMessage(`Global state imported from "${file.name}".`);
+ }
+ catch (error) {
+ toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+}
+function loadStoresState(pinia, state) {
+ for (const key in state) {
+ const storeState = pinia.state.value[key];
+ if (storeState) {
+ Object.assign(storeState, state[key]);
+ }
+ }
+}
+
+function formatDisplay(display) {
+ return {
+ _custom: {
+ display,
+ },
+ };
+}
+const PINIA_ROOT_LABEL = '🍍 Pinia (root)';
+const PINIA_ROOT_ID = '_root';
+function formatStoreForInspectorTree(store) {
+ return isPinia(store)
+ ? {
+ id: PINIA_ROOT_ID,
+ label: PINIA_ROOT_LABEL,
+ }
+ : {
+ id: store.$id,
+ label: store.$id,
+ };
+}
+function formatStoreForInspectorState(store) {
+ if (isPinia(store)) {
+ const storeNames = Array.from(store._s.keys());
+ const storeMap = store._s;
+ const state = {
+ state: storeNames.map((storeId) => ({
+ editable: true,
+ key: storeId,
+ value: store.state.value[storeId],
+ })),
+ getters: storeNames
+ .filter((id) => storeMap.get(id)._getters)
+ .map((id) => {
+ const store = storeMap.get(id);
+ return {
+ editable: false,
+ key: id,
+ value: store._getters.reduce((getters, key) => {
+ getters[key] = store[key];
+ return getters;
+ }, {}),
+ };
+ }),
+ };
+ return state;
+ }
+ const state = {
+ state: Object.keys(store.$state).map((key) => ({
+ editable: true,
+ key,
+ value: store.$state[key],
+ })),
+ };
+ // avoid adding empty getters
+ if (store._getters && store._getters.length) {
+ state.getters = store._getters.map((getterName) => ({
+ editable: false,
+ key: getterName,
+ value: store[getterName],
+ }));
+ }
+ if (store._customProperties.size) {
+ state.customProperties = Array.from(store._customProperties).map((key) => ({
+ editable: true,
+ key,
+ value: store[key],
+ }));
+ }
+ return state;
+}
+function formatEventData(events) {
+ if (!events)
+ return {};
+ if (Array.isArray(events)) {
+ // TODO: handle add and delete for arrays and objects
+ return events.reduce((data, event) => {
+ data.keys.push(event.key);
+ data.operations.push(event.type);
+ data.oldValue[event.key] = event.oldValue;
+ data.newValue[event.key] = event.newValue;
+ return data;
+ }, {
+ oldValue: {},
+ keys: [],
+ operations: [],
+ newValue: {},
+ });
+ }
+ else {
+ return {
+ operation: formatDisplay(events.type),
+ key: formatDisplay(events.key),
+ oldValue: events.oldValue,
+ newValue: events.newValue,
+ };
+ }
+}
+function formatMutationType(type) {
+ switch (type) {
+ case MutationType.direct:
+ return 'mutation';
+ case MutationType.patchFunction:
+ return '$patch';
+ case MutationType.patchObject:
+ return '$patch';
+ default:
+ return 'unknown';
+ }
+}
+
+// timeline can be paused when directly changing the state
+let isTimelineActive = true;
+const componentStateTypes = [];
+const MUTATIONS_LAYER_ID = 'pinia:mutations';
+const INSPECTOR_ID = 'pinia';
+const { assign: assign$1 } = Object;
+/**
+ * Gets the displayed name of a store in devtools
+ *
+ * @param id - id of the store
+ * @returns a formatted string
+ */
+const getStoreType = (id) => '🍍 ' + id;
+/**
+ * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab
+ * as soon as it is added to the application.
+ *
+ * @param app - Vue application
+ * @param pinia - pinia instance
+ */
+function registerPiniaDevtools(app, pinia) {
+ setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ }, (api) => {
+ if (typeof api.now !== 'function') {
+ toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.');
+ }
+ api.addTimelineLayer({
+ id: MUTATIONS_LAYER_ID,
+ label: `Pinia 🍍`,
+ color: 0xe5df88,
+ });
+ api.addInspector({
+ id: INSPECTOR_ID,
+ label: 'Pinia 🍍',
+ icon: 'storage',
+ treeFilterPlaceholder: 'Search stores',
+ actions: [
+ {
+ icon: 'content_copy',
+ action: () => {
+ actionGlobalCopyState(pinia);
+ },
+ tooltip: 'Serialize and copy the state',
+ },
+ {
+ icon: 'content_paste',
+ action: async () => {
+ await actionGlobalPasteState(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Replace the state with the content of your clipboard',
+ },
+ {
+ icon: 'save',
+ action: () => {
+ actionGlobalSaveState(pinia);
+ },
+ tooltip: 'Save the state as a JSON file',
+ },
+ {
+ icon: 'folder_open',
+ action: async () => {
+ await actionGlobalOpenStateFile(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Import the state from a JSON file',
+ },
+ ],
+ nodeActions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state (with "$reset")',
+ action: (nodeId) => {
+ const store = pinia._s.get(nodeId);
+ if (!store) {
+ toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn');
+ }
+ else if (typeof store.$reset !== 'function') {
+ toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn');
+ }
+ else {
+ store.$reset();
+ toastMessage(`Store "${nodeId}" reset.`);
+ }
+ },
+ },
+ ],
+ });
+ api.on.inspectComponent((payload, ctx) => {
+ const proxy = (payload.componentInstance &&
+ payload.componentInstance.proxy);
+ if (proxy && proxy._pStores) {
+ const piniaStores = payload.componentInstance.proxy._pStores;
+ Object.values(piniaStores).forEach((store) => {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'state',
+ editable: true,
+ value: store._isOptionsAPI
+ ? {
+ _custom: {
+ value: toRaw(store.$state),
+ actions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state of this store',
+ action: () => store.$reset(),
+ },
+ ],
+ },
+ }
+ : // NOTE: workaround to unwrap transferred refs
+ Object.keys(store.$state).reduce((state, key) => {
+ state[key] = store.$state[key];
+ return state;
+ }, {}),
+ });
+ if (store._getters && store._getters.length) {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'getters',
+ editable: false,
+ value: store._getters.reduce((getters, key) => {
+ try {
+ getters[key] = store[key];
+ }
+ catch (error) {
+ // @ts-expect-error: we just want to show it in devtools
+ getters[key] = error;
+ }
+ return getters;
+ }, {}),
+ });
+ }
+ });
+ }
+ });
+ api.on.getInspectorTree((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ let stores = [pinia];
+ stores = stores.concat(Array.from(pinia._s.values()));
+ payload.rootNodes = (payload.filter
+ ? stores.filter((store) => '$id' in store
+ ? store.$id
+ .toLowerCase()
+ .includes(payload.filter.toLowerCase())
+ : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase()))
+ : stores).map(formatStoreForInspectorTree);
+ }
+ });
+ api.on.getInspectorState((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ // this could be the selected store restored for a different project
+ // so it's better not to say anything here
+ return;
+ }
+ if (inspectedStore) {
+ payload.state = formatStoreForInspectorState(inspectedStore);
+ }
+ }
+ });
+ api.on.editInspectorState((payload, ctx) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ return toastMessage(`store "${payload.nodeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (!isPinia(inspectedStore)) {
+ // access only the state
+ if (path.length !== 1 ||
+ !inspectedStore._customProperties.has(path[0]) ||
+ path[0] in inspectedStore.$state) {
+ path.unshift('$state');
+ }
+ }
+ else {
+ // Root access, we can omit the `.value` because the devtools API does it for us
+ path.unshift('state');
+ }
+ isTimelineActive = false;
+ payload.set(inspectedStore, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ api.on.editComponentState((payload) => {
+ if (payload.type.startsWith('🍍')) {
+ const storeId = payload.type.replace(/^🍍\s*/, '');
+ const store = pinia._s.get(storeId);
+ if (!store) {
+ return toastMessage(`store "${storeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (path[0] !== 'state') {
+ return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`);
+ }
+ // rewrite the first entry to be able to directly set the state as
+ // well as any other path
+ path[0] = '$state';
+ isTimelineActive = false;
+ payload.set(store, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ });
+}
+function addStoreToDevtools(app, store) {
+ if (!componentStateTypes.includes(getStoreType(store.$id))) {
+ componentStateTypes.push(getStoreType(store.$id));
+ }
+ setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ settings: {
+ logStoreChanges: {
+ label: 'Notify about new/deleted stores',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ // useEmojis: {
+ // label: 'Use emojis in messages ⚡️',
+ // type: 'boolean',
+ // defaultValue: true,
+ // },
+ },
+ }, (api) => {
+ // gracefully handle errors
+ const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now;
+ store.$onAction(({ after, onError, name, args }) => {
+ const groupId = runningActionId++;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛫 ' + name,
+ subtitle: 'start',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ },
+ groupId,
+ },
+ });
+ after((result) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛬 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ result,
+ },
+ groupId,
+ },
+ });
+ });
+ onError((error) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ logType: 'error',
+ title: '💥 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ error,
+ },
+ groupId,
+ },
+ });
+ });
+ }, true);
+ store._customProperties.forEach((name) => {
+ watch(() => unref(store[name]), (newValue, oldValue) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (isTimelineActive) {
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: 'Change',
+ subtitle: name,
+ data: {
+ newValue,
+ oldValue,
+ },
+ groupId: activeAction,
+ },
+ });
+ }
+ }, { deep: true });
+ });
+ store.$subscribe(({ events, type }, state) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (!isTimelineActive)
+ return;
+ // rootStore.state[store.id] = state
+ const eventData = {
+ time: now(),
+ title: formatMutationType(type),
+ data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)),
+ groupId: activeAction,
+ };
+ if (type === MutationType.patchFunction) {
+ eventData.subtitle = '⤵️';
+ }
+ else if (type === MutationType.patchObject) {
+ eventData.subtitle = '🧩';
+ }
+ else if (events && !Array.isArray(events)) {
+ eventData.subtitle = events.type;
+ }
+ if (events) {
+ eventData.data['rawEvent(s)'] = {
+ _custom: {
+ display: 'DebuggerEvent',
+ type: 'object',
+ tooltip: 'raw DebuggerEvent[]',
+ value: events,
+ },
+ };
+ }
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: eventData,
+ });
+ }, { detached: true, flush: 'sync' });
+ const hotUpdate = store._hotUpdate;
+ store._hotUpdate = markRaw((newStore) => {
+ hotUpdate(newStore);
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🔥 ' + store.$id,
+ subtitle: 'HMR update',
+ data: {
+ store: formatDisplay(store.$id),
+ info: formatDisplay(`HMR update`),
+ },
+ },
+ });
+ // update the devtools too
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ });
+ const { $dispose } = store;
+ store.$dispose = () => {
+ $dispose();
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`Disposed "${store.$id}" store 🗑`);
+ };
+ // trigger an update so it can display new registered stores
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`"${store.$id}" store installed 🆕`);
+ });
+}
+let runningActionId = 0;
+let activeAction;
+/**
+ * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the
+ * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state
+ * mutation to the action.
+ *
+ * @param store - store to patch
+ * @param actionNames - list of actionst to patch
+ */
+function patchActionForGrouping(store, actionNames, wrapWithProxy) {
+ // original actions of the store as they are given by pinia. We are going to override them
+ const actions = actionNames.reduce((storeActions, actionName) => {
+ // use toRaw to avoid tracking #541
+ storeActions[actionName] = toRaw(store)[actionName];
+ return storeActions;
+ }, {});
+ for (const actionName in actions) {
+ store[actionName] = function () {
+ // the running action id is incremented in a before action hook
+ const _actionId = runningActionId;
+ const trackedStore = wrapWithProxy
+ ? new Proxy(store, {
+ get(...args) {
+ activeAction = _actionId;
+ return Reflect.get(...args);
+ },
+ set(...args) {
+ activeAction = _actionId;
+ return Reflect.set(...args);
+ },
+ })
+ : store;
+ // For Setup Stores we need https://github.com/tc39/proposal-async-context
+ activeAction = _actionId;
+ const retValue = actions[actionName].apply(trackedStore, arguments);
+ // this is safer as async actions in Setup Stores would associate mutations done outside of the action
+ activeAction = undefined;
+ return retValue;
+ };
+ }
+}
+/**
+ * pinia.use(devtoolsPlugin)
+ */
+function devtoolsPlugin({ app, store, options }) {
+ // HMR module
+ if (store.$id.startsWith('__hot:')) {
+ return;
+ }
+ // detect option api vs setup api
+ store._isOptionsAPI = !!options.state;
+ patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI);
+ // Upgrade the HMR to also update the new actions
+ const originalHotUpdate = store._hotUpdate;
+ toRaw(store)._hotUpdate = function (newStore) {
+ originalHotUpdate.apply(this, arguments);
+ patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI);
+ };
+ addStoreToDevtools(app,
+ // FIXME: is there a way to allow the assignment from Store to StoreGeneric?
+ store);
+}
+
+/**
+ * Creates a Pinia instance to be used by the application
+ */
+function createPinia() {
+ const scope = effectScope(true);
+ // NOTE: here we could check the window object for a state and directly set it
+ // if there is anything like it with Vue 3 SSR
+ const state = scope.run(() => ref({}));
+ let _p = [];
+ // plugins added before calling app.use(pinia)
+ let toBeInstalled = [];
+ const pinia = markRaw({
+ install(app) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ if (!isVue2) {
+ pinia._a = app;
+ app.provide(piniaSymbol, pinia);
+ app.config.globalProperties.$pinia = pinia;
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(app, pinia);
+ }
+ toBeInstalled.forEach((plugin) => _p.push(plugin));
+ toBeInstalled = [];
+ }
+ },
+ use(plugin) {
+ if (!this._a && !isVue2) {
+ toBeInstalled.push(plugin);
+ }
+ else {
+ _p.push(plugin);
+ }
+ return this;
+ },
+ _p,
+ // it's actually undefined here
+ // @ts-expect-error
+ _a: null,
+ _e: scope,
+ _s: new Map(),
+ state,
+ });
+ // pinia devtools rely on dev only features so they cannot be forced unless
+ // the dev build of Vue is used. Avoid old browsers like IE11.
+ if (USE_DEVTOOLS && typeof Proxy !== 'undefined') {
+ pinia.use(devtoolsPlugin);
+ }
+ return pinia;
+}
+
+/**
+ * Checks if a function is a `StoreDefinition`.
+ *
+ * @param fn - object to test
+ * @returns true if `fn` is a StoreDefinition
+ */
+const isUseStore = (fn) => {
+ return typeof fn === 'function' && typeof fn.$id === 'string';
+};
+/**
+ * Mutates in place `newState` with `oldState` to _hot update_ it. It will
+ * remove any key not existing in `newState` and recursively merge plain
+ * objects.
+ *
+ * @param newState - new state object to be patched
+ * @param oldState - old state that should be used to patch newState
+ * @returns - newState
+ */
+function patchObject(newState, oldState) {
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in oldState) {
+ const subPatch = oldState[key];
+ // skip the whole sub tree
+ if (!(key in newState)) {
+ continue;
+ }
+ const targetValue = newState[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ !isRef(subPatch) &&
+ !isReactive(subPatch)) {
+ newState[key] = patchObject(targetValue, subPatch);
+ }
+ else {
+ // objects are either a bit more complex (e.g. refs) or primitives, so we
+ // just set the whole thing
+ if (isVue2) {
+ set(newState, key, subPatch);
+ }
+ else {
+ newState[key] = subPatch;
+ }
+ }
+ }
+ return newState;
+}
+/**
+ * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
+ *
+ * @example
+ * ```js
+ * const useUser = defineStore(...)
+ * if (import.meta.hot) {
+ * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
+ * }
+ * ```
+ *
+ * @param initialUseStore - return of the defineStore to hot update
+ * @param hot - `import.meta.hot`
+ */
+function acceptHMRUpdate(initialUseStore, hot) {
+ return (newModule) => {
+ const pinia = hot.data.pinia || initialUseStore._pinia;
+ if (!pinia) {
+ // this store is still not used
+ return;
+ }
+ // preserve the pinia instance across loads
+ hot.data.pinia = pinia;
+ // console.log('got data', newStore)
+ for (const exportName in newModule) {
+ const useStore = newModule[exportName];
+ // console.log('checking for', exportName)
+ if (isUseStore(useStore) && pinia._s.has(useStore.$id)) {
+ // console.log('Accepting update for', useStore.$id)
+ const id = useStore.$id;
+ if (id !== initialUseStore.$id) {
+ console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`);
+ // return import.meta.hot.invalidate()
+ return hot.invalidate();
+ }
+ const existingStore = pinia._s.get(id);
+ if (!existingStore) {
+ console.log(`[Pinia]: skipping hmr because store doesn't exist yet`);
+ return;
+ }
+ useStore(pinia, existingStore);
+ }
+ }
+ };
+}
+
+const noop = () => { };
+function addSubscription(subscriptions, callback, detached, onCleanup = noop) {
+ subscriptions.push(callback);
+ const removeSubscription = () => {
+ const idx = subscriptions.indexOf(callback);
+ if (idx > -1) {
+ subscriptions.splice(idx, 1);
+ onCleanup();
+ }
+ };
+ if (!detached && getCurrentScope()) {
+ onScopeDispose(removeSubscription);
+ }
+ return removeSubscription;
+}
+function triggerSubscriptions(subscriptions, ...args) {
+ subscriptions.slice().forEach((callback) => {
+ callback(...args);
+ });
+}
+
+const fallbackRunWithContext = (fn) => fn();
+function mergeReactiveObjects(target, patchToApply) {
+ // Handle Map instances
+ if (target instanceof Map && patchToApply instanceof Map) {
+ patchToApply.forEach((value, key) => target.set(key, value));
+ }
+ // Handle Set instances
+ if (target instanceof Set && patchToApply instanceof Set) {
+ patchToApply.forEach(target.add, target);
+ }
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in patchToApply) {
+ if (!patchToApply.hasOwnProperty(key))
+ continue;
+ const subPatch = patchToApply[key];
+ const targetValue = target[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ target.hasOwnProperty(key) &&
+ !isRef(subPatch) &&
+ !isReactive(subPatch)) {
+ // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might
+ // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that
+ // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`.
+ target[key] = mergeReactiveObjects(targetValue, subPatch);
+ }
+ else {
+ // @ts-expect-error: subPatch is a valid value
+ target[key] = subPatch;
+ }
+ }
+ return target;
+}
+const skipHydrateSymbol = Symbol('pinia:skipHydration')
+ ;
+const skipHydrateMap = /*#__PURE__*/ new WeakMap();
+/**
+ * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
+ * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
+ *
+ * @param obj - target object
+ * @returns obj
+ */
+function skipHydrate(obj) {
+ return isVue2
+ ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work...
+ /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj
+ : Object.defineProperty(obj, skipHydrateSymbol, {});
+}
+/**
+ * Returns whether a value should be hydrated
+ *
+ * @param obj - target variable
+ * @returns true if `obj` should be hydrated
+ */
+function shouldHydrate(obj) {
+ return isVue2
+ ? /* istanbul ignore next */ !skipHydrateMap.has(obj)
+ : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
+}
+const { assign } = Object;
+function isComputed(o) {
+ return !!(isRef(o) && o.effect);
+}
+function createOptionsStore(id, options, pinia, hot) {
+ const { state, actions, getters } = options;
+ const initialState = pinia.state.value[id];
+ let store;
+ function setup() {
+ if (!initialState && (!hot)) {
+ /* istanbul ignore if */
+ if (isVue2) {
+ set(pinia.state.value, id, state ? state() : {});
+ }
+ else {
+ pinia.state.value[id] = state ? state() : {};
+ }
+ }
+ // avoid creating a state in pinia.state.value
+ const localState = hot
+ ? // use ref() to unwrap refs inside state TODO: check if this is still necessary
+ toRefs(ref(state ? state() : {}).value)
+ : toRefs(pinia.state.value[id]);
+ return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {
+ if (name in localState) {
+ console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`);
+ }
+ computedGetters[name] = markRaw(computed(() => {
+ setActivePinia(pinia);
+ // it was created just before
+ const store = pinia._s.get(id);
+ // allow cross using stores
+ /* istanbul ignore next */
+ if (isVue2 && !store._r)
+ return;
+ // @ts-expect-error
+ // return getters![name].call(context, context)
+ // TODO: avoid reading the getter while assigning with a global variable
+ return getters[name].call(store, store);
+ }));
+ return computedGetters;
+ }, {}));
+ }
+ store = createSetupStore(id, setup, options, pinia, hot, true);
+ return store;
+}
+function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {
+ let scope;
+ const optionsForPlugin = assign({ actions: {} }, options);
+ /* istanbul ignore if */
+ if (!pinia._e.active) {
+ throw new Error('Pinia destroyed');
+ }
+ // watcher options for $subscribe
+ const $subscribeOptions = {
+ deep: true,
+ // flush: 'post',
+ };
+ /* istanbul ignore else */
+ if (!isVue2) {
+ $subscribeOptions.onTrigger = (event) => {
+ /* istanbul ignore else */
+ if (isListening) {
+ debuggerEvents = event;
+ // avoid triggering this while the store is being built and the state is being set in pinia
+ }
+ else if (isListening == false && !store._hotUpdating) {
+ // let patch send all the events together later
+ /* istanbul ignore else */
+ if (Array.isArray(debuggerEvents)) {
+ debuggerEvents.push(event);
+ }
+ else {
+ console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.');
+ }
+ }
+ };
+ }
+ // internal state
+ let isListening; // set to true at the end
+ let isSyncListening; // set to true at the end
+ let subscriptions = [];
+ let actionSubscriptions = [];
+ let debuggerEvents;
+ const initialState = pinia.state.value[$id];
+ // avoid setting the state for option stores if it is set
+ // by the setup
+ if (!isOptionsStore && !initialState && (!hot)) {
+ /* istanbul ignore if */
+ if (isVue2) {
+ set(pinia.state.value, $id, {});
+ }
+ else {
+ pinia.state.value[$id] = {};
+ }
+ }
+ const hotState = ref({});
+ // avoid triggering too many listeners
+ // https://github.com/vuejs/pinia/issues/1129
+ let activeListener;
+ function $patch(partialStateOrMutator) {
+ let subscriptionMutation;
+ isListening = isSyncListening = false;
+ // reset the debugger events since patches are sync
+ /* istanbul ignore else */
+ {
+ debuggerEvents = [];
+ }
+ if (typeof partialStateOrMutator === 'function') {
+ partialStateOrMutator(pinia.state.value[$id]);
+ subscriptionMutation = {
+ type: MutationType.patchFunction,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ else {
+ mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);
+ subscriptionMutation = {
+ type: MutationType.patchObject,
+ payload: partialStateOrMutator,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ const myListenerId = (activeListener = Symbol());
+ nextTick().then(() => {
+ if (activeListener === myListenerId) {
+ isListening = true;
+ }
+ });
+ isSyncListening = true;
+ // because we paused the watcher, we need to manually call the subscriptions
+ triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);
+ }
+ const $reset = isOptionsStore
+ ? function $reset() {
+ const { state } = options;
+ const newState = state ? state() : {};
+ // we use a patch to group all changes into one single subscription
+ this.$patch(($state) => {
+ assign($state, newState);
+ });
+ }
+ : /* istanbul ignore next */
+ () => {
+ throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`);
+ }
+ ;
+ function $dispose() {
+ scope.stop();
+ subscriptions = [];
+ actionSubscriptions = [];
+ pinia._s.delete($id);
+ }
+ /**
+ * Wraps an action to handle subscriptions.
+ *
+ * @param name - name of the action
+ * @param action - action to wrap
+ * @returns a wrapped action to handle subscriptions
+ */
+ function wrapAction(name, action) {
+ return function () {
+ setActivePinia(pinia);
+ const args = Array.from(arguments);
+ const afterCallbackList = [];
+ const onErrorCallbackList = [];
+ function after(callback) {
+ afterCallbackList.push(callback);
+ }
+ function onError(callback) {
+ onErrorCallbackList.push(callback);
+ }
+ // @ts-expect-error
+ triggerSubscriptions(actionSubscriptions, {
+ args,
+ name,
+ store,
+ after,
+ onError,
+ });
+ let ret;
+ try {
+ ret = action.apply(this && this.$id === $id ? this : store, args);
+ // handle sync errors
+ }
+ catch (error) {
+ triggerSubscriptions(onErrorCallbackList, error);
+ throw error;
+ }
+ if (ret instanceof Promise) {
+ return ret
+ .then((value) => {
+ triggerSubscriptions(afterCallbackList, value);
+ return value;
+ })
+ .catch((error) => {
+ triggerSubscriptions(onErrorCallbackList, error);
+ return Promise.reject(error);
+ });
+ }
+ // trigger after callbacks
+ triggerSubscriptions(afterCallbackList, ret);
+ return ret;
+ };
+ }
+ const _hmrPayload = /*#__PURE__*/ markRaw({
+ actions: {},
+ getters: {},
+ state: [],
+ hotState,
+ });
+ const partialStore = {
+ _p: pinia,
+ // _s: scope,
+ $id,
+ $onAction: addSubscription.bind(null, actionSubscriptions),
+ $patch,
+ $reset,
+ $subscribe(callback, options = {}) {
+ const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher());
+ const stopWatcher = scope.run(() => watch(() => pinia.state.value[$id], (state) => {
+ if (options.flush === 'sync' ? isSyncListening : isListening) {
+ callback({
+ storeId: $id,
+ type: MutationType.direct,
+ events: debuggerEvents,
+ }, state);
+ }
+ }, assign({}, $subscribeOptions, options)));
+ return removeSubscription;
+ },
+ $dispose,
+ };
+ /* istanbul ignore if */
+ if (isVue2) {
+ // start as non ready
+ partialStore._r = false;
+ }
+ const store = reactive(assign({
+ _hmrPayload,
+ _customProperties: markRaw(new Set()), // devtools custom properties
+ }, partialStore
+ // must be added later
+ // setupStore
+ )
+ );
+ // store the partial store now so the setup of stores can instantiate each other before they are finished without
+ // creating infinite loops.
+ pinia._s.set($id, store);
+ const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext;
+ // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped
+ const setupStore = pinia._e.run(() => {
+ scope = effectScope();
+ return runWithContext(() => scope.run(setup));
+ });
+ // overwrite existing actions to support $onAction
+ for (const key in setupStore) {
+ const prop = setupStore[key];
+ if ((isRef(prop) && !isComputed(prop)) || isReactive(prop)) {
+ // mark it as a piece of state to be serialized
+ if (hot) {
+ set(hotState.value, key, toRef(setupStore, key));
+ // createOptionStore directly sets the state in pinia.state.value so we
+ // can just skip that
+ }
+ else if (!isOptionsStore) {
+ // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created
+ if (initialState && shouldHydrate(prop)) {
+ if (isRef(prop)) {
+ prop.value = initialState[key];
+ }
+ else {
+ // probably a reactive object, lets recursively assign
+ // @ts-expect-error: prop is unknown
+ mergeReactiveObjects(prop, initialState[key]);
+ }
+ }
+ // transfer the ref to the pinia state to keep everything in sync
+ /* istanbul ignore if */
+ if (isVue2) {
+ set(pinia.state.value[$id], key, prop);
+ }
+ else {
+ pinia.state.value[$id][key] = prop;
+ }
+ }
+ /* istanbul ignore else */
+ {
+ _hmrPayload.state.push(key);
+ }
+ // action
+ }
+ else if (typeof prop === 'function') {
+ // @ts-expect-error: we are overriding the function we avoid wrapping if
+ const actionValue = hot ? prop : wrapAction(key, prop);
+ // this a hot module replacement store because the hotUpdate method needs
+ // to do it with the right context
+ /* istanbul ignore if */
+ if (isVue2) {
+ set(setupStore, key, actionValue);
+ }
+ else {
+ // @ts-expect-error
+ setupStore[key] = actionValue;
+ }
+ /* istanbul ignore else */
+ {
+ _hmrPayload.actions[key] = prop;
+ }
+ // list actions so they can be used in plugins
+ // @ts-expect-error
+ optionsForPlugin.actions[key] = prop;
+ }
+ else {
+ // add getters for devtools
+ if (isComputed(prop)) {
+ _hmrPayload.getters[key] = isOptionsStore
+ ? // @ts-expect-error
+ options.getters[key]
+ : prop;
+ if (IS_CLIENT) {
+ const getters = setupStore._getters ||
+ // @ts-expect-error: same
+ (setupStore._getters = markRaw([]));
+ getters.push(key);
+ }
+ }
+ }
+ }
+ // add the state, getters, and action properties
+ /* istanbul ignore if */
+ if (isVue2) {
+ Object.keys(setupStore).forEach((key) => {
+ set(store, key, setupStore[key]);
+ });
+ }
+ else {
+ assign(store, setupStore);
+ // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object.
+ // Make `storeToRefs()` work with `reactive()` #799
+ assign(toRaw(store), setupStore);
+ }
+ // use this instead of a computed with setter to be able to create it anywhere
+ // without linking the computed lifespan to wherever the store is first
+ // created.
+ Object.defineProperty(store, '$state', {
+ get: () => (hot ? hotState.value : pinia.state.value[$id]),
+ set: (state) => {
+ /* istanbul ignore if */
+ if (hot) {
+ throw new Error('cannot set hotState');
+ }
+ $patch(($state) => {
+ assign($state, state);
+ });
+ },
+ });
+ // add the hotUpdate before plugins to allow them to override it
+ /* istanbul ignore else */
+ {
+ store._hotUpdate = markRaw((newStore) => {
+ store._hotUpdating = true;
+ newStore._hmrPayload.state.forEach((stateKey) => {
+ if (stateKey in store.$state) {
+ const newStateTarget = newStore.$state[stateKey];
+ const oldStateSource = store.$state[stateKey];
+ if (typeof newStateTarget === 'object' &&
+ isPlainObject(newStateTarget) &&
+ isPlainObject(oldStateSource)) {
+ patchObject(newStateTarget, oldStateSource);
+ }
+ else {
+ // transfer the ref
+ newStore.$state[stateKey] = oldStateSource;
+ }
+ }
+ // patch direct access properties to allow store.stateProperty to work as
+ // store.$state.stateProperty
+ set(store, stateKey, toRef(newStore.$state, stateKey));
+ });
+ // remove deleted state properties
+ Object.keys(store.$state).forEach((stateKey) => {
+ if (!(stateKey in newStore.$state)) {
+ del(store, stateKey);
+ }
+ });
+ // avoid devtools logging this as a mutation
+ isListening = false;
+ isSyncListening = false;
+ pinia.state.value[$id] = toRef(newStore._hmrPayload, 'hotState');
+ isSyncListening = true;
+ nextTick().then(() => {
+ isListening = true;
+ });
+ for (const actionName in newStore._hmrPayload.actions) {
+ const action = newStore[actionName];
+ set(store, actionName, wrapAction(actionName, action));
+ }
+ // TODO: does this work in both setup and option store?
+ for (const getterName in newStore._hmrPayload.getters) {
+ const getter = newStore._hmrPayload.getters[getterName];
+ const getterValue = isOptionsStore
+ ? // special handling of options api
+ computed(() => {
+ setActivePinia(pinia);
+ return getter.call(store, store);
+ })
+ : getter;
+ set(store, getterName, getterValue);
+ }
+ // remove deleted getters
+ Object.keys(store._hmrPayload.getters).forEach((key) => {
+ if (!(key in newStore._hmrPayload.getters)) {
+ del(store, key);
+ }
+ });
+ // remove old actions
+ Object.keys(store._hmrPayload.actions).forEach((key) => {
+ if (!(key in newStore._hmrPayload.actions)) {
+ del(store, key);
+ }
+ });
+ // update the values used in devtools and to allow deleting new properties later on
+ store._hmrPayload = newStore._hmrPayload;
+ store._getters = newStore._getters;
+ store._hotUpdating = false;
+ });
+ }
+ if (USE_DEVTOOLS) {
+ const nonEnumerable = {
+ writable: true,
+ configurable: true,
+ // avoid warning on devtools trying to display this property
+ enumerable: false,
+ };
+ ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => {
+ Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable));
+ });
+ }
+ /* istanbul ignore if */
+ if (isVue2) {
+ // mark the store as ready before plugins
+ store._r = true;
+ }
+ // apply all plugins
+ pinia._p.forEach((extender) => {
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ const extensions = scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ }));
+ Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key));
+ assign(store, extensions);
+ }
+ else {
+ assign(store, scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ })));
+ }
+ });
+ if (store.$state &&
+ typeof store.$state === 'object' &&
+ typeof store.$state.constructor === 'function' &&
+ !store.$state.constructor.toString().includes('[native code]')) {
+ console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` +
+ `\tstate: () => new MyClass()\n` +
+ `Found in store "${store.$id}".`);
+ }
+ // only apply hydrate to option stores with an initial state in pinia
+ if (initialState &&
+ isOptionsStore &&
+ options.hydrate) {
+ options.hydrate(store.$state, initialState);
+ }
+ isListening = true;
+ isSyncListening = true;
+ return store;
+}
+function defineStore(
+// TODO: add proper types from above
+idOrOptions, setup, setupOptions) {
+ let id;
+ let options;
+ const isSetupStore = typeof setup === 'function';
+ if (typeof idOrOptions === 'string') {
+ id = idOrOptions;
+ // the option store setup will contain the actual options in this case
+ options = isSetupStore ? setupOptions : setup;
+ }
+ else {
+ options = idOrOptions;
+ id = idOrOptions.id;
+ if (typeof id !== 'string') {
+ throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`);
+ }
+ }
+ function useStore(pinia, hot) {
+ const hasContext = hasInjectionContext();
+ pinia =
+ // in test mode, ignore the argument provided as we can always retrieve a
+ // pinia instance with getActivePinia()
+ (pinia) ||
+ (hasContext ? inject(piniaSymbol, null) : null);
+ if (pinia)
+ setActivePinia(pinia);
+ if (!activePinia) {
+ throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Did you forget to install pinia?\n` +
+ `\tconst pinia = createPinia()\n` +
+ `\tapp.use(pinia)\n` +
+ `This will fail in production.`);
+ }
+ pinia = activePinia;
+ if (!pinia._s.has(id)) {
+ // creating the store registers it in `pinia._s`
+ if (isSetupStore) {
+ createSetupStore(id, setup, options, pinia);
+ }
+ else {
+ createOptionsStore(id, options, pinia);
+ }
+ /* istanbul ignore else */
+ {
+ // @ts-expect-error: not the right inferred type
+ useStore._pinia = pinia;
+ }
+ }
+ const store = pinia._s.get(id);
+ if (hot) {
+ const hotId = '__hot:' + id;
+ const newStore = isSetupStore
+ ? createSetupStore(hotId, setup, options, pinia, true)
+ : createOptionsStore(hotId, assign({}, options), pinia, true);
+ hot._hotUpdate(newStore);
+ // cleanup the state properties and the store from the cache
+ delete pinia.state.value[hotId];
+ pinia._s.delete(hotId);
+ }
+ if (IS_CLIENT) {
+ const currentInstance = getCurrentInstance();
+ // save stores in instances to access them devtools
+ if (currentInstance &&
+ currentInstance.proxy &&
+ // avoid adding stores that are just built for hot module replacement
+ !hot) {
+ const vm = currentInstance.proxy;
+ const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {});
+ cache[id] = store;
+ }
+ }
+ // StoreGeneric cannot be casted towards Store
+ return store;
+ }
+ useStore.$id = id;
+ return useStore;
+}
+
+let mapStoreSuffix = 'Store';
+/**
+ * Changes the suffix added by `mapStores()`. Can be set to an empty string.
+ * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
+ * interface if you are using TypeScript.
+ *
+ * @param suffix - new suffix
+ */
+function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS
+) {
+ mapStoreSuffix = suffix;
+}
+/**
+ * Allows using stores without the composition API (`setup()`) by generating an
+ * object to be spread in the `computed` field of a component. It accepts a list
+ * of store definitions.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * ...mapStores(useUserStore, useCartStore)
+ * },
+ *
+ * created() {
+ * this.userStore // store with id "user"
+ * this.cartStore // store with id "cart"
+ * }
+ * }
+ * ```
+ *
+ * @param stores - list of stores to map to an object
+ */
+function mapStores(...stores) {
+ if (Array.isArray(stores[0])) {
+ console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` +
+ `Replace\n` +
+ `\tmapStores([useAuthStore, useCartStore])\n` +
+ `with\n` +
+ `\tmapStores(useAuthStore, useCartStore)\n` +
+ `This will fail in production if not fixed.`);
+ stores = stores[0];
+ }
+ return stores.reduce((reduced, useStore) => {
+ // @ts-expect-error: $id is added by defineStore
+ reduced[useStore.$id + mapStoreSuffix] = function () {
+ return useStore(this.$pinia);
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ reduced[key] = function () {
+ return useStore(this.$pinia)[key];
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function () {
+ const store = useStore(this.$pinia);
+ const storeKey = keysOrMapper[key];
+ // for some reason TS is unable to infer the type of storeKey to be a
+ // function
+ return typeof storeKey === 'function'
+ ? storeKey.call(this, store)
+ : store[storeKey];
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Alias for `mapState()`. You should use `mapState()` instead.
+ * @deprecated use `mapState()` instead.
+ */
+const mapGetters = mapState;
+/**
+ * Allows directly using actions from your store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `methods` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapActions(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[key](...args);
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[keysOrMapper[key]](...args);
+ };
+ return reduced;
+ }, {});
+}
+/**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+function mapWritableState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[key];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[key] = value);
+ },
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[keysOrMapper[key]];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[keysOrMapper[key]] = value);
+ },
+ };
+ return reduced;
+ }, {});
+}
+
+/**
+ * Creates an object of references with all the state, getters, and plugin-added
+ * state properties of the store. Similar to `toRefs()` but specifically
+ * designed for Pinia stores so methods and non reactive properties are
+ * completely ignored.
+ *
+ * @param store - store to extract the refs from
+ */
+function storeToRefs(store) {
+ // See https://github.com/vuejs/pinia/issues/852
+ // It's easier to just use toRefs() even if it includes more stuff
+ if (isVue2) {
+ // @ts-expect-error: toRefs include methods and others
+ return toRefs(store);
+ }
+ else {
+ store = toRaw(store);
+ const refs = {};
+ for (const key in store) {
+ const value = store[key];
+ if (isRef(value) || isReactive(value)) {
+ // @ts-expect-error: the key is state or getter
+ refs[key] =
+ // ---
+ toRef(store, key);
+ }
+ }
+ return refs;
+ }
+}
+
+/**
+ * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
+ * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
+ * https://pinia.vuejs.org/ssr/nuxt.html.
+ *
+ * @example
+ * ```js
+ * import Vue from 'vue'
+ * import { PiniaVuePlugin, createPinia } from 'pinia'
+ *
+ * Vue.use(PiniaVuePlugin)
+ * const pinia = createPinia()
+ *
+ * new Vue({
+ * el: '#app',
+ * // ...
+ * pinia,
+ * })
+ * ```
+ *
+ * @param _Vue - `Vue` imported from 'vue'.
+ */
+const PiniaVuePlugin = function (_Vue) {
+ // Equivalent of
+ // app.config.globalProperties.$pinia = pinia
+ _Vue.mixin({
+ beforeCreate() {
+ const options = this.$options;
+ if (options.pinia) {
+ const pinia = options.pinia;
+ // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31
+ /* istanbul ignore else */
+ if (!this._provided) {
+ const provideCache = {};
+ Object.defineProperty(this, '_provided', {
+ get: () => provideCache,
+ set: (v) => Object.assign(provideCache, v),
+ });
+ }
+ this._provided[piniaSymbol] = pinia;
+ // propagate the pinia instance in an SSR friendly way
+ // avoid adding it to nuxt twice
+ /* istanbul ignore else */
+ if (!this.$pinia) {
+ this.$pinia = pinia;
+ }
+ pinia._a = this;
+ if (IS_CLIENT) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ }
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(pinia._a, pinia);
+ }
+ }
+ else if (!this.$pinia && options.parent && options.parent.$pinia) {
+ this.$pinia = options.parent.$pinia;
+ }
+ },
+ destroyed() {
+ delete this._pStores;
+ },
+ });
+};
+
+export { MutationType, PiniaVuePlugin, acceptHMRUpdate, createPinia, defineStore, getActivePinia, mapActions, mapGetters, mapState, mapStores, mapWritableState, setActivePinia, setMapStoreSuffix, skipHydrate, storeToRefs };
diff --git a/node_modules/pinia/dist/pinia.iife.js b/node_modules/pinia/dist/pinia.iife.js
new file mode 100644
index 0000000..64f1c55
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.iife.js
@@ -0,0 +1,2180 @@
+/*!
+ * pinia v2.1.6
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+var Pinia = (function (exports, vueDemi) {
+ 'use strict';
+
+ /**
+ * setActivePinia must be called to handle SSR at the top of functions like
+ * `fetch`, `setup`, `serverPrefetch` and others
+ */
+ let activePinia;
+ /**
+ * Sets or unsets the active pinia. Used in SSR and internally when calling
+ * actions and getters
+ *
+ * @param pinia - Pinia instance
+ */
+ // @ts-expect-error: cannot constrain the type of the return
+ const setActivePinia = (pinia) => (activePinia = pinia);
+ /**
+ * Get the currently active pinia if there is any.
+ */
+ const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia;
+ const piniaSymbol = (Symbol('pinia') );
+
+ function getDevtoolsGlobalHook() {
+ return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+ }
+ function getTarget() {
+ // @ts-ignore
+ return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {};
+ }
+ const isProxyAvailable = typeof Proxy === 'function';
+
+ const HOOK_SETUP = 'devtools-plugin:setup';
+ const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';
+
+ let supported;
+ let perf;
+ function isPerformanceSupported() {
+ var _a;
+ if (supported !== undefined) {
+ return supported;
+ }
+ if (typeof window !== 'undefined' && window.performance) {
+ supported = true;
+ perf = window.performance;
+ }
+ else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+ supported = true;
+ perf = global.perf_hooks.performance;
+ }
+ else {
+ supported = false;
+ }
+ return supported;
+ }
+ function now() {
+ return isPerformanceSupported() ? perf.now() : Date.now();
+ }
+
+ class ApiProxy {
+ constructor(plugin, hook) {
+ this.target = null;
+ this.targetQueue = [];
+ this.onQueue = [];
+ this.plugin = plugin;
+ this.hook = hook;
+ const defaultSettings = {};
+ if (plugin.settings) {
+ for (const id in plugin.settings) {
+ const item = plugin.settings[id];
+ defaultSettings[id] = item.defaultValue;
+ }
+ }
+ const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+ let currentSettings = Object.assign({}, defaultSettings);
+ try {
+ const raw = localStorage.getItem(localSettingsSaveId);
+ const data = JSON.parse(raw);
+ Object.assign(currentSettings, data);
+ }
+ catch (e) {
+ // noop
+ }
+ this.fallbacks = {
+ getSettings() {
+ return currentSettings;
+ },
+ setSettings(value) {
+ try {
+ localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+ }
+ catch (e) {
+ // noop
+ }
+ currentSettings = value;
+ },
+ now() {
+ return now();
+ },
+ };
+ if (hook) {
+ hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+ if (pluginId === this.plugin.id) {
+ this.fallbacks.setSettings(value);
+ }
+ });
+ }
+ this.proxiedOn = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target.on[prop];
+ }
+ else {
+ return (...args) => {
+ this.onQueue.push({
+ method: prop,
+ args,
+ });
+ };
+ }
+ },
+ });
+ this.proxiedTarget = new Proxy({}, {
+ get: (_target, prop) => {
+ if (this.target) {
+ return this.target[prop];
+ }
+ else if (prop === 'on') {
+ return this.proxiedOn;
+ }
+ else if (Object.keys(this.fallbacks).includes(prop)) {
+ return (...args) => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve: () => { },
+ });
+ return this.fallbacks[prop](...args);
+ };
+ }
+ else {
+ return (...args) => {
+ return new Promise(resolve => {
+ this.targetQueue.push({
+ method: prop,
+ args,
+ resolve,
+ });
+ });
+ };
+ }
+ },
+ });
+ }
+ async setRealTarget(target) {
+ this.target = target;
+ for (const item of this.onQueue) {
+ this.target.on[item.method](...item.args);
+ }
+ for (const item of this.targetQueue) {
+ item.resolve(await this.target[item.method](...item.args));
+ }
+ }
+ }
+
+ function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+ const descriptor = pluginDescriptor;
+ const target = getTarget();
+ const hook = getDevtoolsGlobalHook();
+ const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
+ if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+ hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
+ }
+ else {
+ const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
+ const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+ list.push({
+ pluginDescriptor: descriptor,
+ setupFn,
+ proxy,
+ });
+ if (proxy)
+ setupFn(proxy.proxiedTarget);
+ }
+ }
+
+ function isPlainObject(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ o) {
+ return (o &&
+ typeof o === 'object' &&
+ Object.prototype.toString.call(o) === '[object Object]' &&
+ typeof o.toJSON !== 'function');
+ }
+ // type DeepReadonly = { readonly [P in keyof T]: DeepReadonly }
+ // TODO: can we change these to numbers?
+ /**
+ * Possible types for SubscriptionCallback
+ */
+ exports.MutationType = void 0;
+ (function (MutationType) {
+ /**
+ * Direct mutation of the state:
+ *
+ * - `store.name = 'new name'`
+ * - `store.$state.name = 'new name'`
+ * - `store.list.push('new item')`
+ */
+ MutationType["direct"] = "direct";
+ /**
+ * Mutated the state with `$patch` and an object
+ *
+ * - `store.$patch({ name: 'newName' })`
+ */
+ MutationType["patchObject"] = "patch object";
+ /**
+ * Mutated the state with `$patch` and a function
+ *
+ * - `store.$patch(state => state.name = 'newName')`
+ */
+ MutationType["patchFunction"] = "patch function";
+ // maybe reset? for $state = {} and $reset
+ })(exports.MutationType || (exports.MutationType = {}));
+
+ const IS_CLIENT = typeof window !== 'undefined';
+ /**
+ * Should we add the devtools plugins.
+ * - only if dev mode or forced through the prod devtools flag
+ * - not in test
+ * - only if window exists (could change in the future)
+ */
+ const USE_DEVTOOLS = IS_CLIENT;
+
+ /*
+ * FileSaver.js A saveAs() FileSaver implementation.
+ *
+ * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin
+ * Morote.
+ *
+ * License : MIT
+ */
+ // The one and only way of getting global scope in all environments
+ // https://stackoverflow.com/q/3277182/1008999
+ const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window
+ ? window
+ : typeof self === 'object' && self.self === self
+ ? self
+ : typeof global === 'object' && global.global === global
+ ? global
+ : typeof globalThis === 'object'
+ ? globalThis
+ : { HTMLElement: null })();
+ function bom(blob, { autoBom = false } = {}) {
+ // prepend BOM for UTF-8 XML and text/* types (including HTML)
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+ if (autoBom &&
+ /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+ return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type });
+ }
+ return blob;
+ }
+ function download(url, name, opts) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'blob';
+ xhr.onload = function () {
+ saveAs(xhr.response, name, opts);
+ };
+ xhr.onerror = function () {
+ console.error('could not download file');
+ };
+ xhr.send();
+ }
+ function corsEnabled(url) {
+ const xhr = new XMLHttpRequest();
+ // use sync to avoid popup blocker
+ xhr.open('HEAD', url, false);
+ try {
+ xhr.send();
+ }
+ catch (e) { }
+ return xhr.status >= 200 && xhr.status <= 299;
+ }
+ // `a.click()` doesn't work for all browsers (#465)
+ function click(node) {
+ try {
+ node.dispatchEvent(new MouseEvent('click'));
+ }
+ catch (e) {
+ const evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+ node.dispatchEvent(evt);
+ }
+ }
+ const _navigator =
+ typeof navigator === 'object' ? navigator : { userAgent: '' };
+ // Detect WebView inside a native macOS app by ruling out all browsers
+ // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
+ // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
+ const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) &&
+ /AppleWebKit/.test(_navigator.userAgent) &&
+ !/Safari/.test(_navigator.userAgent))();
+ const saveAs = !IS_CLIENT
+ ? () => { } // noop
+ : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program
+ typeof HTMLAnchorElement !== 'undefined' &&
+ 'download' in HTMLAnchorElement.prototype &&
+ !isMacOSWebView
+ ? downloadSaveAs
+ : // Use msSaveOrOpenBlob as a second approach
+ 'msSaveOrOpenBlob' in _navigator
+ ? msSaveAs
+ : // Fallback to using FileReader and a popup
+ fileSaverSaveAs;
+ function downloadSaveAs(blob, name = 'download', opts) {
+ const a = document.createElement('a');
+ a.download = name;
+ a.rel = 'noopener'; // tabnabbing
+ // TODO: detect chrome extensions & packaged apps
+ // a.target = '_blank'
+ if (typeof blob === 'string') {
+ // Support regular links
+ a.href = blob;
+ if (a.origin !== location.origin) {
+ if (corsEnabled(a.href)) {
+ download(blob, name, opts);
+ }
+ else {
+ a.target = '_blank';
+ click(a);
+ }
+ }
+ else {
+ click(a);
+ }
+ }
+ else {
+ // Support blobs
+ a.href = URL.createObjectURL(blob);
+ setTimeout(function () {
+ URL.revokeObjectURL(a.href);
+ }, 4e4); // 40s
+ setTimeout(function () {
+ click(a);
+ }, 0);
+ }
+ }
+ function msSaveAs(blob, name = 'download', opts) {
+ if (typeof blob === 'string') {
+ if (corsEnabled(blob)) {
+ download(blob, name, opts);
+ }
+ else {
+ const a = document.createElement('a');
+ a.href = blob;
+ a.target = '_blank';
+ setTimeout(function () {
+ click(a);
+ });
+ }
+ }
+ else {
+ // @ts-ignore: works on windows
+ navigator.msSaveOrOpenBlob(bom(blob, opts), name);
+ }
+ }
+ function fileSaverSaveAs(blob, name, opts, popup) {
+ // Open a popup immediately do go around popup blocker
+ // Mostly only available on user interaction and the fileReader is async so...
+ popup = popup || open('', '_blank');
+ if (popup) {
+ popup.document.title = popup.document.body.innerText = 'downloading...';
+ }
+ if (typeof blob === 'string')
+ return download(blob, name, opts);
+ const force = blob.type === 'application/octet-stream';
+ const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global;
+ const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
+ if ((isChromeIOS || (force && isSafari) || isMacOSWebView) &&
+ typeof FileReader !== 'undefined') {
+ // Safari doesn't allow downloading of blob URLs
+ const reader = new FileReader();
+ reader.onloadend = function () {
+ let url = reader.result;
+ if (typeof url !== 'string') {
+ popup = null;
+ throw new Error('Wrong reader.result type');
+ }
+ url = isChromeIOS
+ ? url
+ : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
+ if (popup) {
+ popup.location.href = url;
+ }
+ else {
+ location.assign(url);
+ }
+ popup = null; // reverse-tabnabbing #460
+ };
+ reader.readAsDataURL(blob);
+ }
+ else {
+ const url = URL.createObjectURL(blob);
+ if (popup)
+ popup.location.assign(url);
+ else
+ location.href = url;
+ popup = null; // reverse-tabnabbing #460
+ setTimeout(function () {
+ URL.revokeObjectURL(url);
+ }, 4e4); // 40s
+ }
+ }
+
+ /**
+ * Shows a toast or console.log
+ *
+ * @param message - message to log
+ * @param type - different color of the tooltip
+ */
+ function toastMessage(message, type) {
+ const piniaMessage = '🍍 ' + message;
+ if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') {
+ // No longer available :(
+ __VUE_DEVTOOLS_TOAST__(piniaMessage, type);
+ }
+ else if (type === 'error') {
+ console.error(piniaMessage);
+ }
+ else if (type === 'warn') {
+ console.warn(piniaMessage);
+ }
+ else {
+ console.log(piniaMessage);
+ }
+ }
+ function isPinia(o) {
+ return '_a' in o && 'install' in o;
+ }
+
+ /**
+ * This file contain devtools actions, they are not Pinia actions.
+ */
+ // ---
+ function checkClipboardAccess() {
+ if (!('clipboard' in navigator)) {
+ toastMessage(`Your browser doesn't support the Clipboard API`, 'error');
+ return true;
+ }
+ }
+ function checkNotFocusedError(error) {
+ if (error instanceof Error &&
+ error.message.toLowerCase().includes('document is not focused')) {
+ toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn');
+ return true;
+ }
+ return false;
+ }
+ async function actionGlobalCopyState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ await navigator.clipboard.writeText(JSON.stringify(pinia.state.value));
+ toastMessage('Global state copied to clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+ }
+ async function actionGlobalPasteState(pinia) {
+ if (checkClipboardAccess())
+ return;
+ try {
+ loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText()));
+ toastMessage('Global state pasted from clipboard.');
+ }
+ catch (error) {
+ if (checkNotFocusedError(error))
+ return;
+ toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+ }
+ async function actionGlobalSaveState(pinia) {
+ try {
+ saveAs(new Blob([JSON.stringify(pinia.state.value)], {
+ type: 'text/plain;charset=utf-8',
+ }), 'pinia-state.json');
+ }
+ catch (error) {
+ toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+ }
+ let fileInput;
+ function getFileOpener() {
+ if (!fileInput) {
+ fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '.json';
+ }
+ function openFile() {
+ return new Promise((resolve, reject) => {
+ fileInput.onchange = async () => {
+ const files = fileInput.files;
+ if (!files)
+ return resolve(null);
+ const file = files.item(0);
+ if (!file)
+ return resolve(null);
+ return resolve({ text: await file.text(), file });
+ };
+ // @ts-ignore: TODO: changed from 4.3 to 4.4
+ fileInput.oncancel = () => resolve(null);
+ fileInput.onerror = reject;
+ fileInput.click();
+ });
+ }
+ return openFile;
+ }
+ async function actionGlobalOpenStateFile(pinia) {
+ try {
+ const open = getFileOpener();
+ const result = await open();
+ if (!result)
+ return;
+ const { text, file } = result;
+ loadStoresState(pinia, JSON.parse(text));
+ toastMessage(`Global state imported from "${file.name}".`);
+ }
+ catch (error) {
+ toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error');
+ console.error(error);
+ }
+ }
+ function loadStoresState(pinia, state) {
+ for (const key in state) {
+ const storeState = pinia.state.value[key];
+ if (storeState) {
+ Object.assign(storeState, state[key]);
+ }
+ }
+ }
+
+ function formatDisplay(display) {
+ return {
+ _custom: {
+ display,
+ },
+ };
+ }
+ const PINIA_ROOT_LABEL = '🍍 Pinia (root)';
+ const PINIA_ROOT_ID = '_root';
+ function formatStoreForInspectorTree(store) {
+ return isPinia(store)
+ ? {
+ id: PINIA_ROOT_ID,
+ label: PINIA_ROOT_LABEL,
+ }
+ : {
+ id: store.$id,
+ label: store.$id,
+ };
+ }
+ function formatStoreForInspectorState(store) {
+ if (isPinia(store)) {
+ const storeNames = Array.from(store._s.keys());
+ const storeMap = store._s;
+ const state = {
+ state: storeNames.map((storeId) => ({
+ editable: true,
+ key: storeId,
+ value: store.state.value[storeId],
+ })),
+ getters: storeNames
+ .filter((id) => storeMap.get(id)._getters)
+ .map((id) => {
+ const store = storeMap.get(id);
+ return {
+ editable: false,
+ key: id,
+ value: store._getters.reduce((getters, key) => {
+ getters[key] = store[key];
+ return getters;
+ }, {}),
+ };
+ }),
+ };
+ return state;
+ }
+ const state = {
+ state: Object.keys(store.$state).map((key) => ({
+ editable: true,
+ key,
+ value: store.$state[key],
+ })),
+ };
+ // avoid adding empty getters
+ if (store._getters && store._getters.length) {
+ state.getters = store._getters.map((getterName) => ({
+ editable: false,
+ key: getterName,
+ value: store[getterName],
+ }));
+ }
+ if (store._customProperties.size) {
+ state.customProperties = Array.from(store._customProperties).map((key) => ({
+ editable: true,
+ key,
+ value: store[key],
+ }));
+ }
+ return state;
+ }
+ function formatEventData(events) {
+ if (!events)
+ return {};
+ if (Array.isArray(events)) {
+ // TODO: handle add and delete for arrays and objects
+ return events.reduce((data, event) => {
+ data.keys.push(event.key);
+ data.operations.push(event.type);
+ data.oldValue[event.key] = event.oldValue;
+ data.newValue[event.key] = event.newValue;
+ return data;
+ }, {
+ oldValue: {},
+ keys: [],
+ operations: [],
+ newValue: {},
+ });
+ }
+ else {
+ return {
+ operation: formatDisplay(events.type),
+ key: formatDisplay(events.key),
+ oldValue: events.oldValue,
+ newValue: events.newValue,
+ };
+ }
+ }
+ function formatMutationType(type) {
+ switch (type) {
+ case exports.MutationType.direct:
+ return 'mutation';
+ case exports.MutationType.patchFunction:
+ return '$patch';
+ case exports.MutationType.patchObject:
+ return '$patch';
+ default:
+ return 'unknown';
+ }
+ }
+
+ // timeline can be paused when directly changing the state
+ let isTimelineActive = true;
+ const componentStateTypes = [];
+ const MUTATIONS_LAYER_ID = 'pinia:mutations';
+ const INSPECTOR_ID = 'pinia';
+ const { assign: assign$1 } = Object;
+ /**
+ * Gets the displayed name of a store in devtools
+ *
+ * @param id - id of the store
+ * @returns a formatted string
+ */
+ const getStoreType = (id) => '🍍 ' + id;
+ /**
+ * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab
+ * as soon as it is added to the application.
+ *
+ * @param app - Vue application
+ * @param pinia - pinia instance
+ */
+ function registerPiniaDevtools(app, pinia) {
+ setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ }, (api) => {
+ if (typeof api.now !== 'function') {
+ toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.');
+ }
+ api.addTimelineLayer({
+ id: MUTATIONS_LAYER_ID,
+ label: `Pinia 🍍`,
+ color: 0xe5df88,
+ });
+ api.addInspector({
+ id: INSPECTOR_ID,
+ label: 'Pinia 🍍',
+ icon: 'storage',
+ treeFilterPlaceholder: 'Search stores',
+ actions: [
+ {
+ icon: 'content_copy',
+ action: () => {
+ actionGlobalCopyState(pinia);
+ },
+ tooltip: 'Serialize and copy the state',
+ },
+ {
+ icon: 'content_paste',
+ action: async () => {
+ await actionGlobalPasteState(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Replace the state with the content of your clipboard',
+ },
+ {
+ icon: 'save',
+ action: () => {
+ actionGlobalSaveState(pinia);
+ },
+ tooltip: 'Save the state as a JSON file',
+ },
+ {
+ icon: 'folder_open',
+ action: async () => {
+ await actionGlobalOpenStateFile(pinia);
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ },
+ tooltip: 'Import the state from a JSON file',
+ },
+ ],
+ nodeActions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state (with "$reset")',
+ action: (nodeId) => {
+ const store = pinia._s.get(nodeId);
+ if (!store) {
+ toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn');
+ }
+ else if (typeof store.$reset !== 'function') {
+ toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn');
+ }
+ else {
+ store.$reset();
+ toastMessage(`Store "${nodeId}" reset.`);
+ }
+ },
+ },
+ ],
+ });
+ api.on.inspectComponent((payload, ctx) => {
+ const proxy = (payload.componentInstance &&
+ payload.componentInstance.proxy);
+ if (proxy && proxy._pStores) {
+ const piniaStores = payload.componentInstance.proxy._pStores;
+ Object.values(piniaStores).forEach((store) => {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'state',
+ editable: true,
+ value: store._isOptionsAPI
+ ? {
+ _custom: {
+ value: vueDemi.toRaw(store.$state),
+ actions: [
+ {
+ icon: 'restore',
+ tooltip: 'Reset the state of this store',
+ action: () => store.$reset(),
+ },
+ ],
+ },
+ }
+ : // NOTE: workaround to unwrap transferred refs
+ Object.keys(store.$state).reduce((state, key) => {
+ state[key] = store.$state[key];
+ return state;
+ }, {}),
+ });
+ if (store._getters && store._getters.length) {
+ payload.instanceData.state.push({
+ type: getStoreType(store.$id),
+ key: 'getters',
+ editable: false,
+ value: store._getters.reduce((getters, key) => {
+ try {
+ getters[key] = store[key];
+ }
+ catch (error) {
+ // @ts-expect-error: we just want to show it in devtools
+ getters[key] = error;
+ }
+ return getters;
+ }, {}),
+ });
+ }
+ });
+ }
+ });
+ api.on.getInspectorTree((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ let stores = [pinia];
+ stores = stores.concat(Array.from(pinia._s.values()));
+ payload.rootNodes = (payload.filter
+ ? stores.filter((store) => '$id' in store
+ ? store.$id
+ .toLowerCase()
+ .includes(payload.filter.toLowerCase())
+ : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase()))
+ : stores).map(formatStoreForInspectorTree);
+ }
+ });
+ api.on.getInspectorState((payload) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ // this could be the selected store restored for a different project
+ // so it's better not to say anything here
+ return;
+ }
+ if (inspectedStore) {
+ payload.state = formatStoreForInspectorState(inspectedStore);
+ }
+ }
+ });
+ api.on.editInspectorState((payload, ctx) => {
+ if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
+ const inspectedStore = payload.nodeId === PINIA_ROOT_ID
+ ? pinia
+ : pinia._s.get(payload.nodeId);
+ if (!inspectedStore) {
+ return toastMessage(`store "${payload.nodeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (!isPinia(inspectedStore)) {
+ // access only the state
+ if (path.length !== 1 ||
+ !inspectedStore._customProperties.has(path[0]) ||
+ path[0] in inspectedStore.$state) {
+ path.unshift('$state');
+ }
+ }
+ else {
+ // Root access, we can omit the `.value` because the devtools API does it for us
+ path.unshift('state');
+ }
+ isTimelineActive = false;
+ payload.set(inspectedStore, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ api.on.editComponentState((payload) => {
+ if (payload.type.startsWith('🍍')) {
+ const storeId = payload.type.replace(/^🍍\s*/, '');
+ const store = pinia._s.get(storeId);
+ if (!store) {
+ return toastMessage(`store "${storeId}" not found`, 'error');
+ }
+ const { path } = payload;
+ if (path[0] !== 'state') {
+ return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`);
+ }
+ // rewrite the first entry to be able to directly set the state as
+ // well as any other path
+ path[0] = '$state';
+ isTimelineActive = false;
+ payload.set(store, path, payload.state.value);
+ isTimelineActive = true;
+ }
+ });
+ });
+ }
+ function addStoreToDevtools(app, store) {
+ if (!componentStateTypes.includes(getStoreType(store.$id))) {
+ componentStateTypes.push(getStoreType(store.$id));
+ }
+ setupDevtoolsPlugin({
+ id: 'dev.esm.pinia',
+ label: 'Pinia 🍍',
+ logo: 'https://pinia.vuejs.org/logo.svg',
+ packageName: 'pinia',
+ homepage: 'https://pinia.vuejs.org',
+ componentStateTypes,
+ app,
+ settings: {
+ logStoreChanges: {
+ label: 'Notify about new/deleted stores',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ // useEmojis: {
+ // label: 'Use emojis in messages ⚡️',
+ // type: 'boolean',
+ // defaultValue: true,
+ // },
+ },
+ }, (api) => {
+ // gracefully handle errors
+ const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now;
+ store.$onAction(({ after, onError, name, args }) => {
+ const groupId = runningActionId++;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛫 ' + name,
+ subtitle: 'start',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ },
+ groupId,
+ },
+ });
+ after((result) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🛬 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ result,
+ },
+ groupId,
+ },
+ });
+ });
+ onError((error) => {
+ activeAction = undefined;
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ logType: 'error',
+ title: '💥 ' + name,
+ subtitle: 'end',
+ data: {
+ store: formatDisplay(store.$id),
+ action: formatDisplay(name),
+ args,
+ error,
+ },
+ groupId,
+ },
+ });
+ });
+ }, true);
+ store._customProperties.forEach((name) => {
+ vueDemi.watch(() => vueDemi.unref(store[name]), (newValue, oldValue) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (isTimelineActive) {
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: 'Change',
+ subtitle: name,
+ data: {
+ newValue,
+ oldValue,
+ },
+ groupId: activeAction,
+ },
+ });
+ }
+ }, { deep: true });
+ });
+ store.$subscribe(({ events, type }, state) => {
+ api.notifyComponentUpdate();
+ api.sendInspectorState(INSPECTOR_ID);
+ if (!isTimelineActive)
+ return;
+ // rootStore.state[store.id] = state
+ const eventData = {
+ time: now(),
+ title: formatMutationType(type),
+ data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)),
+ groupId: activeAction,
+ };
+ if (type === exports.MutationType.patchFunction) {
+ eventData.subtitle = '⤵️';
+ }
+ else if (type === exports.MutationType.patchObject) {
+ eventData.subtitle = '🧩';
+ }
+ else if (events && !Array.isArray(events)) {
+ eventData.subtitle = events.type;
+ }
+ if (events) {
+ eventData.data['rawEvent(s)'] = {
+ _custom: {
+ display: 'DebuggerEvent',
+ type: 'object',
+ tooltip: 'raw DebuggerEvent[]',
+ value: events,
+ },
+ };
+ }
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: eventData,
+ });
+ }, { detached: true, flush: 'sync' });
+ const hotUpdate = store._hotUpdate;
+ store._hotUpdate = vueDemi.markRaw((newStore) => {
+ hotUpdate(newStore);
+ api.addTimelineEvent({
+ layerId: MUTATIONS_LAYER_ID,
+ event: {
+ time: now(),
+ title: '🔥 ' + store.$id,
+ subtitle: 'HMR update',
+ data: {
+ store: formatDisplay(store.$id),
+ info: formatDisplay(`HMR update`),
+ },
+ },
+ });
+ // update the devtools too
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ });
+ const { $dispose } = store;
+ store.$dispose = () => {
+ $dispose();
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`Disposed "${store.$id}" store 🗑`);
+ };
+ // trigger an update so it can display new registered stores
+ api.notifyComponentUpdate();
+ api.sendInspectorTree(INSPECTOR_ID);
+ api.sendInspectorState(INSPECTOR_ID);
+ api.getSettings().logStoreChanges &&
+ toastMessage(`"${store.$id}" store installed 🆕`);
+ });
+ }
+ let runningActionId = 0;
+ let activeAction;
+ /**
+ * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the
+ * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state
+ * mutation to the action.
+ *
+ * @param store - store to patch
+ * @param actionNames - list of actionst to patch
+ */
+ function patchActionForGrouping(store, actionNames, wrapWithProxy) {
+ // original actions of the store as they are given by pinia. We are going to override them
+ const actions = actionNames.reduce((storeActions, actionName) => {
+ // use toRaw to avoid tracking #541
+ storeActions[actionName] = vueDemi.toRaw(store)[actionName];
+ return storeActions;
+ }, {});
+ for (const actionName in actions) {
+ store[actionName] = function () {
+ // the running action id is incremented in a before action hook
+ const _actionId = runningActionId;
+ const trackedStore = wrapWithProxy
+ ? new Proxy(store, {
+ get(...args) {
+ activeAction = _actionId;
+ return Reflect.get(...args);
+ },
+ set(...args) {
+ activeAction = _actionId;
+ return Reflect.set(...args);
+ },
+ })
+ : store;
+ // For Setup Stores we need https://github.com/tc39/proposal-async-context
+ activeAction = _actionId;
+ const retValue = actions[actionName].apply(trackedStore, arguments);
+ // this is safer as async actions in Setup Stores would associate mutations done outside of the action
+ activeAction = undefined;
+ return retValue;
+ };
+ }
+ }
+ /**
+ * pinia.use(devtoolsPlugin)
+ */
+ function devtoolsPlugin({ app, store, options }) {
+ // HMR module
+ if (store.$id.startsWith('__hot:')) {
+ return;
+ }
+ // detect option api vs setup api
+ store._isOptionsAPI = !!options.state;
+ patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI);
+ // Upgrade the HMR to also update the new actions
+ const originalHotUpdate = store._hotUpdate;
+ vueDemi.toRaw(store)._hotUpdate = function (newStore) {
+ originalHotUpdate.apply(this, arguments);
+ patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI);
+ };
+ addStoreToDevtools(app,
+ // FIXME: is there a way to allow the assignment from Store to StoreGeneric?
+ store);
+ }
+
+ /**
+ * Creates a Pinia instance to be used by the application
+ */
+ function createPinia() {
+ const scope = vueDemi.effectScope(true);
+ // NOTE: here we could check the window object for a state and directly set it
+ // if there is anything like it with Vue 3 SSR
+ const state = scope.run(() => vueDemi.ref({}));
+ let _p = [];
+ // plugins added before calling app.use(pinia)
+ let toBeInstalled = [];
+ const pinia = vueDemi.markRaw({
+ install(app) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ if (!vueDemi.isVue2) {
+ pinia._a = app;
+ app.provide(piniaSymbol, pinia);
+ app.config.globalProperties.$pinia = pinia;
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(app, pinia);
+ }
+ toBeInstalled.forEach((plugin) => _p.push(plugin));
+ toBeInstalled = [];
+ }
+ },
+ use(plugin) {
+ if (!this._a && !vueDemi.isVue2) {
+ toBeInstalled.push(plugin);
+ }
+ else {
+ _p.push(plugin);
+ }
+ return this;
+ },
+ _p,
+ // it's actually undefined here
+ // @ts-expect-error
+ _a: null,
+ _e: scope,
+ _s: new Map(),
+ state,
+ });
+ // pinia devtools rely on dev only features so they cannot be forced unless
+ // the dev build of Vue is used. Avoid old browsers like IE11.
+ if (USE_DEVTOOLS && typeof Proxy !== 'undefined') {
+ pinia.use(devtoolsPlugin);
+ }
+ return pinia;
+ }
+
+ /**
+ * Checks if a function is a `StoreDefinition`.
+ *
+ * @param fn - object to test
+ * @returns true if `fn` is a StoreDefinition
+ */
+ const isUseStore = (fn) => {
+ return typeof fn === 'function' && typeof fn.$id === 'string';
+ };
+ /**
+ * Mutates in place `newState` with `oldState` to _hot update_ it. It will
+ * remove any key not existing in `newState` and recursively merge plain
+ * objects.
+ *
+ * @param newState - new state object to be patched
+ * @param oldState - old state that should be used to patch newState
+ * @returns - newState
+ */
+ function patchObject(newState, oldState) {
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in oldState) {
+ const subPatch = oldState[key];
+ // skip the whole sub tree
+ if (!(key in newState)) {
+ continue;
+ }
+ const targetValue = newState[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ !vueDemi.isRef(subPatch) &&
+ !vueDemi.isReactive(subPatch)) {
+ newState[key] = patchObject(targetValue, subPatch);
+ }
+ else {
+ // objects are either a bit more complex (e.g. refs) or primitives, so we
+ // just set the whole thing
+ if (vueDemi.isVue2) {
+ vueDemi.set(newState, key, subPatch);
+ }
+ else {
+ newState[key] = subPatch;
+ }
+ }
+ }
+ return newState;
+ }
+ /**
+ * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
+ *
+ * @example
+ * ```js
+ * const useUser = defineStore(...)
+ * if (import.meta.hot) {
+ * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
+ * }
+ * ```
+ *
+ * @param initialUseStore - return of the defineStore to hot update
+ * @param hot - `import.meta.hot`
+ */
+ function acceptHMRUpdate(initialUseStore, hot) {
+ return (newModule) => {
+ const pinia = hot.data.pinia || initialUseStore._pinia;
+ if (!pinia) {
+ // this store is still not used
+ return;
+ }
+ // preserve the pinia instance across loads
+ hot.data.pinia = pinia;
+ // console.log('got data', newStore)
+ for (const exportName in newModule) {
+ const useStore = newModule[exportName];
+ // console.log('checking for', exportName)
+ if (isUseStore(useStore) && pinia._s.has(useStore.$id)) {
+ // console.log('Accepting update for', useStore.$id)
+ const id = useStore.$id;
+ if (id !== initialUseStore.$id) {
+ console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`);
+ // return import.meta.hot.invalidate()
+ return hot.invalidate();
+ }
+ const existingStore = pinia._s.get(id);
+ if (!existingStore) {
+ console.log(`[Pinia]: skipping hmr because store doesn't exist yet`);
+ return;
+ }
+ useStore(pinia, existingStore);
+ }
+ }
+ };
+ }
+
+ const noop = () => { };
+ function addSubscription(subscriptions, callback, detached, onCleanup = noop) {
+ subscriptions.push(callback);
+ const removeSubscription = () => {
+ const idx = subscriptions.indexOf(callback);
+ if (idx > -1) {
+ subscriptions.splice(idx, 1);
+ onCleanup();
+ }
+ };
+ if (!detached && vueDemi.getCurrentScope()) {
+ vueDemi.onScopeDispose(removeSubscription);
+ }
+ return removeSubscription;
+ }
+ function triggerSubscriptions(subscriptions, ...args) {
+ subscriptions.slice().forEach((callback) => {
+ callback(...args);
+ });
+ }
+
+ const fallbackRunWithContext = (fn) => fn();
+ function mergeReactiveObjects(target, patchToApply) {
+ // Handle Map instances
+ if (target instanceof Map && patchToApply instanceof Map) {
+ patchToApply.forEach((value, key) => target.set(key, value));
+ }
+ // Handle Set instances
+ if (target instanceof Set && patchToApply instanceof Set) {
+ patchToApply.forEach(target.add, target);
+ }
+ // no need to go through symbols because they cannot be serialized anyway
+ for (const key in patchToApply) {
+ if (!patchToApply.hasOwnProperty(key))
+ continue;
+ const subPatch = patchToApply[key];
+ const targetValue = target[key];
+ if (isPlainObject(targetValue) &&
+ isPlainObject(subPatch) &&
+ target.hasOwnProperty(key) &&
+ !vueDemi.isRef(subPatch) &&
+ !vueDemi.isReactive(subPatch)) {
+ // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might
+ // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that
+ // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`.
+ target[key] = mergeReactiveObjects(targetValue, subPatch);
+ }
+ else {
+ // @ts-expect-error: subPatch is a valid value
+ target[key] = subPatch;
+ }
+ }
+ return target;
+ }
+ const skipHydrateSymbol = Symbol('pinia:skipHydration')
+ ;
+ const skipHydrateMap = /*#__PURE__*/ new WeakMap();
+ /**
+ * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
+ * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
+ *
+ * @param obj - target object
+ * @returns obj
+ */
+ function skipHydrate(obj) {
+ return vueDemi.isVue2
+ ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work...
+ /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj
+ : Object.defineProperty(obj, skipHydrateSymbol, {});
+ }
+ /**
+ * Returns whether a value should be hydrated
+ *
+ * @param obj - target variable
+ * @returns true if `obj` should be hydrated
+ */
+ function shouldHydrate(obj) {
+ return vueDemi.isVue2
+ ? /* istanbul ignore next */ !skipHydrateMap.has(obj)
+ : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
+ }
+ const { assign } = Object;
+ function isComputed(o) {
+ return !!(vueDemi.isRef(o) && o.effect);
+ }
+ function createOptionsStore(id, options, pinia, hot) {
+ const { state, actions, getters } = options;
+ const initialState = pinia.state.value[id];
+ let store;
+ function setup() {
+ if (!initialState && (!hot)) {
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value, id, state ? state() : {});
+ }
+ else {
+ pinia.state.value[id] = state ? state() : {};
+ }
+ }
+ // avoid creating a state in pinia.state.value
+ const localState = hot
+ ? // use ref() to unwrap refs inside state TODO: check if this is still necessary
+ vueDemi.toRefs(vueDemi.ref(state ? state() : {}).value)
+ : vueDemi.toRefs(pinia.state.value[id]);
+ return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {
+ if (name in localState) {
+ console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`);
+ }
+ computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => {
+ setActivePinia(pinia);
+ // it was created just before
+ const store = pinia._s.get(id);
+ // allow cross using stores
+ /* istanbul ignore next */
+ if (vueDemi.isVue2 && !store._r)
+ return;
+ // @ts-expect-error
+ // return getters![name].call(context, context)
+ // TODO: avoid reading the getter while assigning with a global variable
+ return getters[name].call(store, store);
+ }));
+ return computedGetters;
+ }, {}));
+ }
+ store = createSetupStore(id, setup, options, pinia, hot, true);
+ return store;
+ }
+ function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {
+ let scope;
+ const optionsForPlugin = assign({ actions: {} }, options);
+ /* istanbul ignore if */
+ if (!pinia._e.active) {
+ throw new Error('Pinia destroyed');
+ }
+ // watcher options for $subscribe
+ const $subscribeOptions = {
+ deep: true,
+ // flush: 'post',
+ };
+ /* istanbul ignore else */
+ if (!vueDemi.isVue2) {
+ $subscribeOptions.onTrigger = (event) => {
+ /* istanbul ignore else */
+ if (isListening) {
+ debuggerEvents = event;
+ // avoid triggering this while the store is being built and the state is being set in pinia
+ }
+ else if (isListening == false && !store._hotUpdating) {
+ // let patch send all the events together later
+ /* istanbul ignore else */
+ if (Array.isArray(debuggerEvents)) {
+ debuggerEvents.push(event);
+ }
+ else {
+ console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.');
+ }
+ }
+ };
+ }
+ // internal state
+ let isListening; // set to true at the end
+ let isSyncListening; // set to true at the end
+ let subscriptions = [];
+ let actionSubscriptions = [];
+ let debuggerEvents;
+ const initialState = pinia.state.value[$id];
+ // avoid setting the state for option stores if it is set
+ // by the setup
+ if (!isOptionsStore && !initialState && (!hot)) {
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value, $id, {});
+ }
+ else {
+ pinia.state.value[$id] = {};
+ }
+ }
+ const hotState = vueDemi.ref({});
+ // avoid triggering too many listeners
+ // https://github.com/vuejs/pinia/issues/1129
+ let activeListener;
+ function $patch(partialStateOrMutator) {
+ let subscriptionMutation;
+ isListening = isSyncListening = false;
+ // reset the debugger events since patches are sync
+ /* istanbul ignore else */
+ {
+ debuggerEvents = [];
+ }
+ if (typeof partialStateOrMutator === 'function') {
+ partialStateOrMutator(pinia.state.value[$id]);
+ subscriptionMutation = {
+ type: exports.MutationType.patchFunction,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ else {
+ mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);
+ subscriptionMutation = {
+ type: exports.MutationType.patchObject,
+ payload: partialStateOrMutator,
+ storeId: $id,
+ events: debuggerEvents,
+ };
+ }
+ const myListenerId = (activeListener = Symbol());
+ vueDemi.nextTick().then(() => {
+ if (activeListener === myListenerId) {
+ isListening = true;
+ }
+ });
+ isSyncListening = true;
+ // because we paused the watcher, we need to manually call the subscriptions
+ triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);
+ }
+ const $reset = isOptionsStore
+ ? function $reset() {
+ const { state } = options;
+ const newState = state ? state() : {};
+ // we use a patch to group all changes into one single subscription
+ this.$patch(($state) => {
+ assign($state, newState);
+ });
+ }
+ : /* istanbul ignore next */
+ () => {
+ throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`);
+ }
+ ;
+ function $dispose() {
+ scope.stop();
+ subscriptions = [];
+ actionSubscriptions = [];
+ pinia._s.delete($id);
+ }
+ /**
+ * Wraps an action to handle subscriptions.
+ *
+ * @param name - name of the action
+ * @param action - action to wrap
+ * @returns a wrapped action to handle subscriptions
+ */
+ function wrapAction(name, action) {
+ return function () {
+ setActivePinia(pinia);
+ const args = Array.from(arguments);
+ const afterCallbackList = [];
+ const onErrorCallbackList = [];
+ function after(callback) {
+ afterCallbackList.push(callback);
+ }
+ function onError(callback) {
+ onErrorCallbackList.push(callback);
+ }
+ // @ts-expect-error
+ triggerSubscriptions(actionSubscriptions, {
+ args,
+ name,
+ store,
+ after,
+ onError,
+ });
+ let ret;
+ try {
+ ret = action.apply(this && this.$id === $id ? this : store, args);
+ // handle sync errors
+ }
+ catch (error) {
+ triggerSubscriptions(onErrorCallbackList, error);
+ throw error;
+ }
+ if (ret instanceof Promise) {
+ return ret
+ .then((value) => {
+ triggerSubscriptions(afterCallbackList, value);
+ return value;
+ })
+ .catch((error) => {
+ triggerSubscriptions(onErrorCallbackList, error);
+ return Promise.reject(error);
+ });
+ }
+ // trigger after callbacks
+ triggerSubscriptions(afterCallbackList, ret);
+ return ret;
+ };
+ }
+ const _hmrPayload = /*#__PURE__*/ vueDemi.markRaw({
+ actions: {},
+ getters: {},
+ state: [],
+ hotState,
+ });
+ const partialStore = {
+ _p: pinia,
+ // _s: scope,
+ $id,
+ $onAction: addSubscription.bind(null, actionSubscriptions),
+ $patch,
+ $reset,
+ $subscribe(callback, options = {}) {
+ const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher());
+ const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => {
+ if (options.flush === 'sync' ? isSyncListening : isListening) {
+ callback({
+ storeId: $id,
+ type: exports.MutationType.direct,
+ events: debuggerEvents,
+ }, state);
+ }
+ }, assign({}, $subscribeOptions, options)));
+ return removeSubscription;
+ },
+ $dispose,
+ };
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ // start as non ready
+ partialStore._r = false;
+ }
+ const store = vueDemi.reactive(assign({
+ _hmrPayload,
+ _customProperties: vueDemi.markRaw(new Set()), // devtools custom properties
+ }, partialStore
+ // must be added later
+ // setupStore
+ )
+ );
+ // store the partial store now so the setup of stores can instantiate each other before they are finished without
+ // creating infinite loops.
+ pinia._s.set($id, store);
+ const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext;
+ // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped
+ const setupStore = pinia._e.run(() => {
+ scope = vueDemi.effectScope();
+ return runWithContext(() => scope.run(setup));
+ });
+ // overwrite existing actions to support $onAction
+ for (const key in setupStore) {
+ const prop = setupStore[key];
+ if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) {
+ // mark it as a piece of state to be serialized
+ if (hot) {
+ vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key));
+ // createOptionStore directly sets the state in pinia.state.value so we
+ // can just skip that
+ }
+ else if (!isOptionsStore) {
+ // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created
+ if (initialState && shouldHydrate(prop)) {
+ if (vueDemi.isRef(prop)) {
+ prop.value = initialState[key];
+ }
+ else {
+ // probably a reactive object, lets recursively assign
+ // @ts-expect-error: prop is unknown
+ mergeReactiveObjects(prop, initialState[key]);
+ }
+ }
+ // transfer the ref to the pinia state to keep everything in sync
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(pinia.state.value[$id], key, prop);
+ }
+ else {
+ pinia.state.value[$id][key] = prop;
+ }
+ }
+ /* istanbul ignore else */
+ {
+ _hmrPayload.state.push(key);
+ }
+ // action
+ }
+ else if (typeof prop === 'function') {
+ // @ts-expect-error: we are overriding the function we avoid wrapping if
+ const actionValue = hot ? prop : wrapAction(key, prop);
+ // this a hot module replacement store because the hotUpdate method needs
+ // to do it with the right context
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ vueDemi.set(setupStore, key, actionValue);
+ }
+ else {
+ // @ts-expect-error
+ setupStore[key] = actionValue;
+ }
+ /* istanbul ignore else */
+ {
+ _hmrPayload.actions[key] = prop;
+ }
+ // list actions so they can be used in plugins
+ // @ts-expect-error
+ optionsForPlugin.actions[key] = prop;
+ }
+ else {
+ // add getters for devtools
+ if (isComputed(prop)) {
+ _hmrPayload.getters[key] = isOptionsStore
+ ? // @ts-expect-error
+ options.getters[key]
+ : prop;
+ if (IS_CLIENT) {
+ const getters = setupStore._getters ||
+ // @ts-expect-error: same
+ (setupStore._getters = vueDemi.markRaw([]));
+ getters.push(key);
+ }
+ }
+ }
+ }
+ // add the state, getters, and action properties
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ Object.keys(setupStore).forEach((key) => {
+ vueDemi.set(store, key, setupStore[key]);
+ });
+ }
+ else {
+ assign(store, setupStore);
+ // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object.
+ // Make `storeToRefs()` work with `reactive()` #799
+ assign(vueDemi.toRaw(store), setupStore);
+ }
+ // use this instead of a computed with setter to be able to create it anywhere
+ // without linking the computed lifespan to wherever the store is first
+ // created.
+ Object.defineProperty(store, '$state', {
+ get: () => (hot ? hotState.value : pinia.state.value[$id]),
+ set: (state) => {
+ /* istanbul ignore if */
+ if (hot) {
+ throw new Error('cannot set hotState');
+ }
+ $patch(($state) => {
+ assign($state, state);
+ });
+ },
+ });
+ // add the hotUpdate before plugins to allow them to override it
+ /* istanbul ignore else */
+ {
+ store._hotUpdate = vueDemi.markRaw((newStore) => {
+ store._hotUpdating = true;
+ newStore._hmrPayload.state.forEach((stateKey) => {
+ if (stateKey in store.$state) {
+ const newStateTarget = newStore.$state[stateKey];
+ const oldStateSource = store.$state[stateKey];
+ if (typeof newStateTarget === 'object' &&
+ isPlainObject(newStateTarget) &&
+ isPlainObject(oldStateSource)) {
+ patchObject(newStateTarget, oldStateSource);
+ }
+ else {
+ // transfer the ref
+ newStore.$state[stateKey] = oldStateSource;
+ }
+ }
+ // patch direct access properties to allow store.stateProperty to work as
+ // store.$state.stateProperty
+ vueDemi.set(store, stateKey, vueDemi.toRef(newStore.$state, stateKey));
+ });
+ // remove deleted state properties
+ Object.keys(store.$state).forEach((stateKey) => {
+ if (!(stateKey in newStore.$state)) {
+ vueDemi.del(store, stateKey);
+ }
+ });
+ // avoid devtools logging this as a mutation
+ isListening = false;
+ isSyncListening = false;
+ pinia.state.value[$id] = vueDemi.toRef(newStore._hmrPayload, 'hotState');
+ isSyncListening = true;
+ vueDemi.nextTick().then(() => {
+ isListening = true;
+ });
+ for (const actionName in newStore._hmrPayload.actions) {
+ const action = newStore[actionName];
+ vueDemi.set(store, actionName, wrapAction(actionName, action));
+ }
+ // TODO: does this work in both setup and option store?
+ for (const getterName in newStore._hmrPayload.getters) {
+ const getter = newStore._hmrPayload.getters[getterName];
+ const getterValue = isOptionsStore
+ ? // special handling of options api
+ vueDemi.computed(() => {
+ setActivePinia(pinia);
+ return getter.call(store, store);
+ })
+ : getter;
+ vueDemi.set(store, getterName, getterValue);
+ }
+ // remove deleted getters
+ Object.keys(store._hmrPayload.getters).forEach((key) => {
+ if (!(key in newStore._hmrPayload.getters)) {
+ vueDemi.del(store, key);
+ }
+ });
+ // remove old actions
+ Object.keys(store._hmrPayload.actions).forEach((key) => {
+ if (!(key in newStore._hmrPayload.actions)) {
+ vueDemi.del(store, key);
+ }
+ });
+ // update the values used in devtools and to allow deleting new properties later on
+ store._hmrPayload = newStore._hmrPayload;
+ store._getters = newStore._getters;
+ store._hotUpdating = false;
+ });
+ }
+ if (USE_DEVTOOLS) {
+ const nonEnumerable = {
+ writable: true,
+ configurable: true,
+ // avoid warning on devtools trying to display this property
+ enumerable: false,
+ };
+ ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => {
+ Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable));
+ });
+ }
+ /* istanbul ignore if */
+ if (vueDemi.isVue2) {
+ // mark the store as ready before plugins
+ store._r = true;
+ }
+ // apply all plugins
+ pinia._p.forEach((extender) => {
+ /* istanbul ignore else */
+ if (USE_DEVTOOLS) {
+ const extensions = scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ }));
+ Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key));
+ assign(store, extensions);
+ }
+ else {
+ assign(store, scope.run(() => extender({
+ store,
+ app: pinia._a,
+ pinia,
+ options: optionsForPlugin,
+ })));
+ }
+ });
+ if (store.$state &&
+ typeof store.$state === 'object' &&
+ typeof store.$state.constructor === 'function' &&
+ !store.$state.constructor.toString().includes('[native code]')) {
+ console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` +
+ `\tstate: () => new MyClass()\n` +
+ `Found in store "${store.$id}".`);
+ }
+ // only apply hydrate to option stores with an initial state in pinia
+ if (initialState &&
+ isOptionsStore &&
+ options.hydrate) {
+ options.hydrate(store.$state, initialState);
+ }
+ isListening = true;
+ isSyncListening = true;
+ return store;
+ }
+ function defineStore(
+ // TODO: add proper types from above
+ idOrOptions, setup, setupOptions) {
+ let id;
+ let options;
+ const isSetupStore = typeof setup === 'function';
+ if (typeof idOrOptions === 'string') {
+ id = idOrOptions;
+ // the option store setup will contain the actual options in this case
+ options = isSetupStore ? setupOptions : setup;
+ }
+ else {
+ options = idOrOptions;
+ id = idOrOptions.id;
+ if (typeof id !== 'string') {
+ throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`);
+ }
+ }
+ function useStore(pinia, hot) {
+ const hasContext = vueDemi.hasInjectionContext();
+ pinia =
+ // in test mode, ignore the argument provided as we can always retrieve a
+ // pinia instance with getActivePinia()
+ (pinia) ||
+ (hasContext ? vueDemi.inject(piniaSymbol, null) : null);
+ if (pinia)
+ setActivePinia(pinia);
+ if (!activePinia) {
+ throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Did you forget to install pinia?\n` +
+ `\tconst pinia = createPinia()\n` +
+ `\tapp.use(pinia)\n` +
+ `This will fail in production.`);
+ }
+ pinia = activePinia;
+ if (!pinia._s.has(id)) {
+ // creating the store registers it in `pinia._s`
+ if (isSetupStore) {
+ createSetupStore(id, setup, options, pinia);
+ }
+ else {
+ createOptionsStore(id, options, pinia);
+ }
+ /* istanbul ignore else */
+ {
+ // @ts-expect-error: not the right inferred type
+ useStore._pinia = pinia;
+ }
+ }
+ const store = pinia._s.get(id);
+ if (hot) {
+ const hotId = '__hot:' + id;
+ const newStore = isSetupStore
+ ? createSetupStore(hotId, setup, options, pinia, true)
+ : createOptionsStore(hotId, assign({}, options), pinia, true);
+ hot._hotUpdate(newStore);
+ // cleanup the state properties and the store from the cache
+ delete pinia.state.value[hotId];
+ pinia._s.delete(hotId);
+ }
+ if (IS_CLIENT) {
+ const currentInstance = vueDemi.getCurrentInstance();
+ // save stores in instances to access them devtools
+ if (currentInstance &&
+ currentInstance.proxy &&
+ // avoid adding stores that are just built for hot module replacement
+ !hot) {
+ const vm = currentInstance.proxy;
+ const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {});
+ cache[id] = store;
+ }
+ }
+ // StoreGeneric cannot be casted towards Store
+ return store;
+ }
+ useStore.$id = id;
+ return useStore;
+ }
+
+ let mapStoreSuffix = 'Store';
+ /**
+ * Changes the suffix added by `mapStores()`. Can be set to an empty string.
+ * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
+ * interface if you are using TypeScript.
+ *
+ * @param suffix - new suffix
+ */
+ function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS
+ ) {
+ mapStoreSuffix = suffix;
+ }
+ /**
+ * Allows using stores without the composition API (`setup()`) by generating an
+ * object to be spread in the `computed` field of a component. It accepts a list
+ * of store definitions.
+ *
+ * @example
+ * ```js
+ * export default {
+ * computed: {
+ * // other computed properties
+ * ...mapStores(useUserStore, useCartStore)
+ * },
+ *
+ * created() {
+ * this.userStore // store with id "user"
+ * this.cartStore // store with id "cart"
+ * }
+ * }
+ * ```
+ *
+ * @param stores - list of stores to map to an object
+ */
+ function mapStores(...stores) {
+ if (Array.isArray(stores[0])) {
+ console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` +
+ `Replace\n` +
+ `\tmapStores([useAuthStore, useCartStore])\n` +
+ `with\n` +
+ `\tmapStores(useAuthStore, useCartStore)\n` +
+ `This will fail in production if not fixed.`);
+ stores = stores[0];
+ }
+ return stores.reduce((reduced, useStore) => {
+ // @ts-expect-error: $id is added by defineStore
+ reduced[useStore.$id + mapStoreSuffix] = function () {
+ return useStore(this.$pinia);
+ };
+ return reduced;
+ }, {});
+ }
+ /**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+ function mapState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ reduced[key] = function () {
+ return useStore(this.$pinia)[key];
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function () {
+ const store = useStore(this.$pinia);
+ const storeKey = keysOrMapper[key];
+ // for some reason TS is unable to infer the type of storeKey to be a
+ // function
+ return typeof storeKey === 'function'
+ ? storeKey.call(this, store)
+ : store[storeKey];
+ };
+ return reduced;
+ }, {});
+ }
+ /**
+ * Alias for `mapState()`. You should use `mapState()` instead.
+ * @deprecated use `mapState()` instead.
+ */
+ const mapGetters = mapState;
+ /**
+ * Allows directly using actions from your store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `methods` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+ function mapActions(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[key](...args);
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-expect-error
+ reduced[key] = function (...args) {
+ return useStore(this.$pinia)[keysOrMapper[key]](...args);
+ };
+ return reduced;
+ }, {});
+ }
+ /**
+ * Allows using state and getters from one store without using the composition
+ * API (`setup()`) by generating an object to be spread in the `computed` field
+ * of a component.
+ *
+ * @param useStore - store to map from
+ * @param keysOrMapper - array or object
+ */
+ function mapWritableState(useStore, keysOrMapper) {
+ return Array.isArray(keysOrMapper)
+ ? keysOrMapper.reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[key];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[key] = value);
+ },
+ };
+ return reduced;
+ }, {})
+ : Object.keys(keysOrMapper).reduce((reduced, key) => {
+ // @ts-ignore
+ reduced[key] = {
+ get() {
+ return useStore(this.$pinia)[keysOrMapper[key]];
+ },
+ set(value) {
+ // it's easier to type it here as any
+ return (useStore(this.$pinia)[keysOrMapper[key]] = value);
+ },
+ };
+ return reduced;
+ }, {});
+ }
+
+ /**
+ * Creates an object of references with all the state, getters, and plugin-added
+ * state properties of the store. Similar to `toRefs()` but specifically
+ * designed for Pinia stores so methods and non reactive properties are
+ * completely ignored.
+ *
+ * @param store - store to extract the refs from
+ */
+ function storeToRefs(store) {
+ // See https://github.com/vuejs/pinia/issues/852
+ // It's easier to just use toRefs() even if it includes more stuff
+ if (vueDemi.isVue2) {
+ // @ts-expect-error: toRefs include methods and others
+ return vueDemi.toRefs(store);
+ }
+ else {
+ store = vueDemi.toRaw(store);
+ const refs = {};
+ for (const key in store) {
+ const value = store[key];
+ if (vueDemi.isRef(value) || vueDemi.isReactive(value)) {
+ // @ts-expect-error: the key is state or getter
+ refs[key] =
+ // ---
+ vueDemi.toRef(store, key);
+ }
+ }
+ return refs;
+ }
+ }
+
+ /**
+ * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
+ * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
+ * https://pinia.vuejs.org/ssr/nuxt.html.
+ *
+ * @example
+ * ```js
+ * import Vue from 'vue'
+ * import { PiniaVuePlugin, createPinia } from 'pinia'
+ *
+ * Vue.use(PiniaVuePlugin)
+ * const pinia = createPinia()
+ *
+ * new Vue({
+ * el: '#app',
+ * // ...
+ * pinia,
+ * })
+ * ```
+ *
+ * @param _Vue - `Vue` imported from 'vue'.
+ */
+ const PiniaVuePlugin = function (_Vue) {
+ // Equivalent of
+ // app.config.globalProperties.$pinia = pinia
+ _Vue.mixin({
+ beforeCreate() {
+ const options = this.$options;
+ if (options.pinia) {
+ const pinia = options.pinia;
+ // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31
+ /* istanbul ignore else */
+ if (!this._provided) {
+ const provideCache = {};
+ Object.defineProperty(this, '_provided', {
+ get: () => provideCache,
+ set: (v) => Object.assign(provideCache, v),
+ });
+ }
+ this._provided[piniaSymbol] = pinia;
+ // propagate the pinia instance in an SSR friendly way
+ // avoid adding it to nuxt twice
+ /* istanbul ignore else */
+ if (!this.$pinia) {
+ this.$pinia = pinia;
+ }
+ pinia._a = this;
+ if (IS_CLIENT) {
+ // this allows calling useStore() outside of a component setup after
+ // installing pinia's plugin
+ setActivePinia(pinia);
+ }
+ if (USE_DEVTOOLS) {
+ registerPiniaDevtools(pinia._a, pinia);
+ }
+ }
+ else if (!this.$pinia && options.parent && options.parent.$pinia) {
+ this.$pinia = options.parent.$pinia;
+ }
+ },
+ destroyed() {
+ delete this._pStores;
+ },
+ });
+ };
+
+ exports.PiniaVuePlugin = PiniaVuePlugin;
+ exports.acceptHMRUpdate = acceptHMRUpdate;
+ exports.createPinia = createPinia;
+ exports.defineStore = defineStore;
+ exports.getActivePinia = getActivePinia;
+ exports.mapActions = mapActions;
+ exports.mapGetters = mapGetters;
+ exports.mapState = mapState;
+ exports.mapStores = mapStores;
+ exports.mapWritableState = mapWritableState;
+ exports.setActivePinia = setActivePinia;
+ exports.setMapStoreSuffix = setMapStoreSuffix;
+ exports.skipHydrate = skipHydrate;
+ exports.storeToRefs = storeToRefs;
+
+ return exports;
+
+})({}, VueDemi);
diff --git a/node_modules/pinia/dist/pinia.iife.prod.js b/node_modules/pinia/dist/pinia.iife.prod.js
new file mode 100644
index 0000000..bee640a
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.iife.prod.js
@@ -0,0 +1,6 @@
+/*!
+ * pinia v2.1.6
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+var Pinia=function(t,e){"use strict";let n;const i=t=>n=t,s=Symbol();function o(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var r;t.MutationType=void 0,(r=t.MutationType||(t.MutationType={})).direct="direct",r.patchObject="patch object",r.patchFunction="patch function";const c="undefined"!=typeof window;const a=()=>{};function u(t,n,i,s=a){t.push(n);const o=()=>{const e=t.indexOf(n);e>-1&&(t.splice(e,1),s())};return!i&&e.getCurrentScope()&&e.onScopeDispose(o),o}function p(t,...e){t.slice().forEach((t=>{t(...e)}))}const f=t=>t();function h(t,n){t instanceof Map&&n instanceof Map&&n.forEach(((e,n)=>t.set(n,e))),t instanceof Set&&n instanceof Set&&n.forEach(t.add,t);for(const i in n){if(!n.hasOwnProperty(i))continue;const s=n[i],r=t[i];t[i]=o(r)&&o(s)&&t.hasOwnProperty(i)&&!e.isRef(s)&&!e.isReactive(s)?h(r,s):s}return t}const l=Symbol(),d=new WeakMap;const{assign:y}=Object;function v(n,s,r={},c,v,$){let b;const _=y({actions:{}},r),j={deep:!0};let O,S,g,m=[],R=[];const P=c.state.value[n];let V;function w(i){let s;O=S=!1,"function"==typeof i?(i(c.state.value[n]),s={type:t.MutationType.patchFunction,storeId:n,events:g}):(h(c.state.value[n],i),s={type:t.MutationType.patchObject,payload:i,storeId:n,events:g});const o=V=Symbol();e.nextTick().then((()=>{V===o&&(O=!0)})),S=!0,p(m,s,c.state.value[n])}$||P||(e.isVue2?e.set(c.state.value,n,{}):c.state.value[n]={}),e.ref({});const M=$?function(){const{state:t}=r,e=t?t():{};this.$patch((t=>{y(t,e)}))}:a;function A(t,e){return function(){i(c);const s=Array.from(arguments),o=[],r=[];let a;p(R,{args:s,name:t,store:T,after:function(t){o.push(t)},onError:function(t){r.push(t)}});try{a=e.apply(this&&this.$id===n?this:T,s)}catch(t){throw p(r,t),t}return a instanceof Promise?a.then((t=>(p(o,t),t))).catch((t=>(p(r,t),Promise.reject(t)))):(p(o,a),a)}}const k={_p:c,$id:n,$onAction:u.bind(null,R),$patch:w,$reset:M,$subscribe(i,s={}){const o=u(m,i,s.detached,(()=>r())),r=b.run((()=>e.watch((()=>c.state.value[n]),(e=>{("sync"===s.flush?S:O)&&i({storeId:n,type:t.MutationType.direct,events:g},e)}),y({},j,s))));return o},$dispose:function(){b.stop(),m=[],R=[],c._s.delete(n)}};e.isVue2&&(k._r=!1);const T=e.reactive(k);c._s.set(n,T);const x=c._a&&c._a.runWithContext||f,E=c._e.run((()=>(b=e.effectScope(),x((()=>b.run(s))))));for(const t in E){const i=E[t];if(e.isRef(i)&&(!e.isRef(I=i)||!I.effect)||e.isReactive(i))$||(!P||(C=i,e.isVue2?d.has(C):o(C)&&C.hasOwnProperty(l))||(e.isRef(i)?i.value=P[t]:h(i,P[t])),e.isVue2?e.set(c.state.value[n],t,i):c.state.value[n][t]=i);else if("function"==typeof i){const n=A(t,i);e.isVue2?e.set(E,t,n):E[t]=n,_.actions[t]=i}}var C,I;return e.isVue2?Object.keys(E).forEach((t=>{e.set(T,t,E[t])})):(y(T,E),y(e.toRaw(T),E)),Object.defineProperty(T,"$state",{get:()=>c.state.value[n],set:t=>{w((e=>{y(e,t)}))}}),e.isVue2&&(T._r=!0),c._p.forEach((t=>{y(T,b.run((()=>t({store:T,app:c._a,pinia:c,options:_}))))})),P&&$&&r.hydrate&&r.hydrate(T.$state,P),O=!0,S=!0,T}let $="Store";function b(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]=function(){return t(this.$pinia)[n]},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]=function(){const n=t(this.$pinia),s=e[i];return"function"==typeof s?s.call(this,n):n[s]},n)),{})}const _=b;return t.PiniaVuePlugin=function(t){t.mixin({beforeCreate(){const t=this.$options;if(t.pinia){const e=t.pinia;if(!this._provided){const t={};Object.defineProperty(this,"_provided",{get:()=>t,set:e=>Object.assign(t,e)})}this._provided[s]=e,this.$pinia||(this.$pinia=e),e._a=this,c&&i(e)}else!this.$pinia&&t.parent&&t.parent.$pinia&&(this.$pinia=t.parent.$pinia)},destroyed(){delete this._pStores}})},t.acceptHMRUpdate=function(t,e){return()=>{}},t.createPinia=function(){const t=e.effectScope(!0),n=t.run((()=>e.ref({})));let o=[],r=[];const c=e.markRaw({install(t){i(c),e.isVue2||(c._a=t,t.provide(s,c),t.config.globalProperties.$pinia=c,r.forEach((t=>o.push(t))),r=[])},use(t){return this._a||e.isVue2?o.push(t):r.push(t),this},_p:o,_a:null,_e:t,_s:new Map,state:n});return c},t.defineStore=function(t,o,r){let c,a;const u="function"==typeof o;function p(t,r){const p=e.hasInjectionContext();(t=t||(p?e.inject(s,null):null))&&i(t),(t=n)._s.has(c)||(u?v(c,o,a,t):function(t,n,s,o){const{state:r,actions:c,getters:a}=n,u=s.state.value[t];let p;p=v(t,(function(){u||(e.isVue2?e.set(s.state.value,t,r?r():{}):s.state.value[t]=r?r():{});const n=e.toRefs(s.state.value[t]);return y(n,c,Object.keys(a||{}).reduce(((n,o)=>(n[o]=e.markRaw(e.computed((()=>{i(s);const n=s._s.get(t);if(!e.isVue2||n._r)return a[o].call(n,n)}))),n)),{}))}),n,s,0,!0)}(c,a,t));return t._s.get(c)}return"string"==typeof t?(c=t,a=u?r:o):(a=t,c=t.id),p.$id=c,p},t.getActivePinia=()=>e.hasInjectionContext()&&e.inject(s)||n,t.mapActions=function(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]=function(...e){return t(this.$pinia)[n](...e)},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]=function(...n){return t(this.$pinia)[e[i]](...n)},n)),{})},t.mapGetters=_,t.mapState=b,t.mapStores=function(...t){return t.reduce(((t,e)=>(t[e.$id+$]=function(){return e(this.$pinia)},t)),{})},t.mapWritableState=function(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]={get(){return t(this.$pinia)[n]},set(e){return t(this.$pinia)[n]=e}},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]={get(){return t(this.$pinia)[e[i]]},set(n){return t(this.$pinia)[e[i]]=n}},n)),{})},t.setActivePinia=i,t.setMapStoreSuffix=function(t){$=t},t.skipHydrate=function(t){return e.isVue2?d.set(t,1)&&t:Object.defineProperty(t,l,{})},t.storeToRefs=function(t){if(e.isVue2)return e.toRefs(t);{t=e.toRaw(t);const n={};for(const i in t){const s=t[i];(e.isRef(s)||e.isReactive(s))&&(n[i]=e.toRef(t,i))}return n}},t}({},VueDemi);
diff --git a/node_modules/pinia/dist/pinia.mjs b/node_modules/pinia/dist/pinia.mjs
new file mode 100644
index 0000000..4b52ecd
--- /dev/null
+++ b/node_modules/pinia/dist/pinia.mjs
@@ -0,0 +1,2004 @@
+/*!
+ * pinia v2.1.6
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+import { hasInjectionContext, inject, toRaw, watch, unref, markRaw, effectScope, ref, isVue2, isRef, isReactive, set, getCurrentScope, onScopeDispose, getCurrentInstance, reactive, toRef, del, nextTick, computed, toRefs } from 'vue-demi';
+import { setupDevtoolsPlugin } from '@vue/devtools-api';
+
+/**
+ * setActivePinia must be called to handle SSR at the top of functions like
+ * `fetch`, `setup`, `serverPrefetch` and others
+ */
+let activePinia;
+/**
+ * Sets or unsets the active pinia. Used in SSR and internally when calling
+ * actions and getters
+ *
+ * @param pinia - Pinia instance
+ */
+// @ts-expect-error: cannot constrain the type of the return
+const setActivePinia = (pinia) => (activePinia = pinia);
+/**
+ * Get the currently active pinia if there is any.
+ */
+const getActivePinia = () => (hasInjectionContext() && inject(piniaSymbol)) || activePinia;
+const piniaSymbol = ((process.env.NODE_ENV !== 'production') ? Symbol('pinia') : /* istanbul ignore next */ Symbol());
+
+function isPlainObject(
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+o) {
+ return (o &&
+ typeof o === 'object' &&
+ Object.prototype.toString.call(o) === '[object Object]' &&
+ typeof o.toJSON !== 'function');
+}
+// type DeepReadonly