diff --git a/package.json b/package.json index a0a1cc7c79e953eb18e0b04d0921c26a7e2eb535..fe7a5ddb425800941dca379d79e414bda6be7d44 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@typescript-eslint/parser": "^4.12.0", "@vitejs/plugin-vue": "^1.2.2", "@vitejs/plugin-vue-jsx": "^1.1.4", + "@vue/compiler-sfc": "^3.1.0-beta.2", "eslint": "^7.17.0", "fs-extra": "^9.0.1", "jest": "^26.6.3", @@ -77,7 +78,7 @@ "ts-jest": "^26.4.4", "typescript": "~4.1.3", "vite": "^2.3.0", - "vue": "3.0.11", + "vue": "^3.1.0-beta.2", "yorkie": "^2.0.0" } } diff --git a/packages/playground/ssr/package.json b/packages/playground/ssr/package.json index 0ca0d5e98baea38b17778877c0bd2d46e1a5f2f7..bdb0bc72a7bc997b3f91c3cd2b3ad5a6ad70d54a 100644 --- a/packages/playground/ssr/package.json +++ b/packages/playground/ssr/package.json @@ -3,9 +3,9 @@ "private": true, "version": "0.0.0", "scripts": { - "dev": "uni", + "dev": "uni -d uni:*", "build": "uni build", - "dev:ssr": "uni --ssr", + "dev:ssr": "uni -d uni:* --ssr", "build:ssr": "uni build --ssr" }, "dependencies": { @@ -16,14 +16,15 @@ "@dcloudio/uni-h5-vue": "../../uni-h5-vue", "@dcloudio/uni-i18n": "../../uni-i18n", "@dcloudio/uni-shared": "../../uni-shared", - "vue": "link:../../uni-h5-vue" + "@vue/shared": "^3.1.0-beta.2", + "vue": "../../uni-h5-vue" }, "devDependencies": { "@dcloudio/uni-cli-shared": "../../uni-cli-shared", "@dcloudio/vite-plugin-uni": "../../vite-plugin-uni", "@vitejs/plugin-vue": "^1.2.2", - "@vue/compiler-sfc": "^3.0.11", - "@vue/server-renderer": "^3.0.11", + "@vue/compiler-sfc": "^3.1.0-beta.2", + "@vue/server-renderer": "^3.1.0-beta.2", "compression": "^1.7.4", "cypress": "^7.3.0", "serve-static": "^1.14.1", diff --git a/packages/playground/ssr/vite.config.js b/packages/playground/ssr/vite.config.js index dbe576123e3d6e60f8a5bb91047d7c61a0c0dd7a..6726e24c5c4cfdb17a4ef4ebe18f31dcfa8b42d1 100644 --- a/packages/playground/ssr/vite.config.js +++ b/packages/playground/ssr/vite.config.js @@ -1,12 +1,6 @@ import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import uni, { uniVueTemplateOptions } from '@dcloudio/vite-plugin-uni' +import uni from '@dcloudio/vite-plugin-uni' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [ - vue({ - template: uniVueTemplateOptions, - }), - uni(), - ], + plugins: [uni()], }) diff --git a/packages/playground/ssr/yarn.lock b/packages/playground/ssr/yarn.lock index d551649c1f4d7b32b2cf1ceccf4598f4dcc3fc4e..10199bdc1aa84361353ebf5e36a8ea3abab41378 100644 --- a/packages/playground/ssr/yarn.lock +++ b/packages/playground/ssr/yarn.lock @@ -104,7 +104,6 @@ version "3.0.0" dependencies: "@rollup/pluginutils" "^4.1.0" - "@vue/compiler-sfc" "^3.0.11" autoprefixer "^10.2.5" cac "^6.7.3" chalk "^4.1.1" @@ -200,36 +199,36 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.2.2.tgz#b0038fc11b9099f4cd01fcbf0ee419adda417b52" integrity sha512-5BI2WFfs/Z0pAV4S/IQf1oH3bmFYlL5ATMBHgTt1Lf7hAnfpNd5oUAAs6hZPfk3QhvyUQgtk0rJBlabwNFcBJQ== -"@vue/compiler-core@3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.11.tgz#5ef579e46d7b336b8735228758d1c2c505aae69a" - integrity sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw== +"@vue/compiler-core@3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.0-beta.2.tgz#fa66626d621801676d11fd28e05ca43f88c67b2f" + integrity sha512-HLd5kCiZojcbcu4+PqD22XKkmqvo3XuM7xRAst3y0KXMlmCnkHIK7Z5mmogPjf/xBBZllWl2CIy9+bR7wrdDSA== dependencies: "@babel/parser" "^7.12.0" "@babel/types" "^7.12.0" - "@vue/shared" "3.0.11" + "@vue/shared" "3.1.0-beta.2" estree-walker "^2.0.1" source-map "^0.6.1" -"@vue/compiler-dom@3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz#b15fc1c909371fd671746020ba55b5dab4a730ee" - integrity sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw== +"@vue/compiler-dom@3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.0-beta.2.tgz#4c415102e20b3f54f733dd47d299f396bd0026ca" + integrity sha512-FgGCZyaJZ81eCydc6IY0u79DVt09vURYKj95bgQJo07doHW0tHptz9N3zRudfhA0VjoXuRMeDoKHMHuxI1rVHA== dependencies: - "@vue/compiler-core" "3.0.11" - "@vue/shared" "3.0.11" + "@vue/compiler-core" "3.1.0-beta.2" + "@vue/shared" "3.1.0-beta.2" -"@vue/compiler-sfc@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.11.tgz#cd8ca2154b88967b521f5ad3b10f5f8b6b665679" - integrity sha512-7fNiZuCecRleiyVGUWNa6pn8fB2fnuJU+3AGjbjl7r1P5wBivfl02H4pG+2aJP5gh2u+0wXov1W38tfWOphsXw== +"@vue/compiler-sfc@^3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.0-beta.2.tgz#445b13a577545ca7c347ff59e66ee3e48fe307e5" + integrity sha512-LmCCGJoqX8N5hkBzFQkwrXCgZQdMzsQNuB16CmlsehBomQNfv1MDNaBexU9yUMC6OIn3Be/6ZN7Tg/MlhpSQTw== dependencies: "@babel/parser" "^7.13.9" "@babel/types" "^7.13.0" - "@vue/compiler-core" "3.0.11" - "@vue/compiler-dom" "3.0.11" - "@vue/compiler-ssr" "3.0.11" - "@vue/shared" "3.0.11" + "@vue/compiler-core" "3.1.0-beta.2" + "@vue/compiler-dom" "3.1.0-beta.2" + "@vue/compiler-ssr" "3.1.0-beta.2" + "@vue/shared" "3.1.0-beta.2" consolidate "^0.16.0" estree-walker "^2.0.1" hash-sum "^2.0.0" @@ -241,26 +240,26 @@ postcss-selector-parser "^6.0.4" source-map "^0.6.1" -"@vue/compiler-ssr@3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.11.tgz#ac5a05fd1257412fa66079c823d8203b6a889a13" - integrity sha512-66yUGI8SGOpNvOcrQybRIhl2M03PJ+OrDPm78i7tvVln86MHTKhM3ERbALK26F7tXl0RkjX4sZpucCpiKs3MnA== +"@vue/compiler-ssr@3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.0-beta.2.tgz#cb37aeebc891565563344d9de6d14909b85c9306" + integrity sha512-so6oRJnRAQUzTT/e+RmsjbVx1nixkp1VQjFtRVaeeWM+foW7aYcXWQYIodMrK8u7gobyvE0vMpXL2+frEG8QOw== dependencies: - "@vue/compiler-dom" "3.0.11" - "@vue/shared" "3.0.11" + "@vue/compiler-dom" "3.1.0-beta.2" + "@vue/shared" "3.1.0-beta.2" -"@vue/server-renderer@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.0.11.tgz#d340f0db630ed56d4af7615faf495dc77558b44c" - integrity sha512-NtXRxCq+jJWohce7s2kgUdO7gD6LRrWhvpGUMrpp65ODxuwolVHVyacyvAnU9bxTj11xw+ErC7Q2+su9mJusEg== +"@vue/server-renderer@^3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.1.0-beta.2.tgz#fcaa8c7a67dba62d74f3ce5534cada6dc70fdb7e" + integrity sha512-q7akXQl+y5JKBlRs6ehR2WlPStObr/7IiIpR+s7S3jnxpEYhXEorH/z+CVkvWIU3nCk1Kvkyl97Igj+WNmtSqA== dependencies: - "@vue/compiler-ssr" "3.0.11" - "@vue/shared" "3.0.11" + "@vue/compiler-ssr" "3.1.0-beta.2" + "@vue/shared" "3.1.0-beta.2" -"@vue/shared@3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77" - integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA== +"@vue/shared@3.1.0-beta.2", "@vue/shared@^3.1.0-beta.2": + version "3.1.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.0-beta.2.tgz#1189078bbf081c3f19e98709c27cbbafbfcdc6f7" + integrity sha512-PZNk03DalUOn3f5Egf/pcaINPLwpcwshjo4PuMXV/76PBfHvKxvkVhCL+aYDfY/9ZeKH+H0hQ00otuAFRLjlKw== accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" @@ -1929,7 +1928,7 @@ postcss-value-parser@^4.1.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@^8.1.10, postcss@^8.2.1: +postcss@^8.1.10, postcss@^8.2.10: version "8.2.15" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== @@ -2450,12 +2449,12 @@ verror@1.10.0: extsprintf "^1.2.0" vite@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.0.tgz#02b007c7aa4ac88cc18f854b9c68e4fbe76e3ef4" - integrity sha512-gsCy0t3X9nGGYDoNiE2NJgYq6BPxrtKeo6FkpMXdMvtUluYxnRhl7xfpHaYDmQLCnMbYTWhvWS1L/Hpw/V9L5w== + version "2.3.1" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.1.tgz#0786c2e097a744f122ae8c0319d0a6910b32d41c" + integrity sha512-yvcLclv/G0syHL+bBtahdaymH0x6La8kbTlnAssRH+XFvDNb8VPRruHhILCCmZgtx6Zu/UKNFTQnQ4Gk/omyUA== dependencies: esbuild "^0.11.19" - postcss "^8.2.1" + postcss "^8.2.10" resolve "^1.19.0" rollup "^2.38.5" optionalDependencies: @@ -2466,9 +2465,8 @@ vue-router@^4.0.6: resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.6.tgz#91750db507d26642f225b0ec6064568e5fe448d6" integrity sha512-Y04llmK2PyaESj+N33VxLjGCUDuv9t4q2OpItEGU7POZiuQZaugV6cJpE6Qm1sVFtxufodLKN2y2dQl9nk0Reg== -"vue@link:../../uni-h5-vue": - version "0.0.0" - uid "" +vue@../../uni-h5-vue: + version "3.0.0" which@^2.0.1: version "2.0.2" diff --git a/packages/uni-cli-shared/src/json/manifest.ts b/packages/uni-cli-shared/src/json/manifest.ts index 9259c422d0676ae84404f435518ba856ce30dc64..48e44ef4887ec5d327aa7276a13f8ecbece5e863 100644 --- a/packages/uni-cli-shared/src/json/manifest.ts +++ b/packages/uni-cli-shared/src/json/manifest.ts @@ -18,3 +18,12 @@ export const parseRpx2UnitOnce = once((inputDir: string) => { const { h5 } = parseManifestJsonOnce(inputDir) return extend({}, defaultRpx2Unit, (h5 && h5.rpx) || {}) }) + +interface CompilerCompatConfig { + MODE?: 2 | 3 +} +function parseCompatConfig(inputDir: string): CompilerCompatConfig { + return parseManifestJsonOnce(inputDir).compatConfig || {} +} + +export const parseCompatConfigOnce = once(parseCompatConfig) diff --git a/packages/uni-h5-vue/dist/vue.runtime.compat.cjs.js b/packages/uni-h5-vue/dist/vue.runtime.compat.cjs.js new file mode 100644 index 0000000000000000000000000000000000000000..609a5a501e41d994e4c092847b005610b9fcd8ff --- /dev/null +++ b/packages/uni-h5-vue/dist/vue.runtime.compat.cjs.js @@ -0,0 +1,20099 @@ +'use strict'; + +var parser = require('@babel/parser'); +var estreeWalker = require('estree-walker'); +var sourceMap = require('source-map'); + +/** + * Make a map and return a function for checking if a key + * is in that map. + * IMPORTANT: all calls of this function must be prefixed with + * \/\*#\_\_PURE\_\_\*\/ + * So that rollup can tree-shake them if necessary. + */ +function makeMap(str, expectsLowerCase) { + const map = Object.create(null); + const list = str.split(','); + for (let i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]; +} + +/** + * dev only flag -> name mapping + */ +const PatchFlagNames = { + [1 /* TEXT */]: `TEXT`, + [2 /* CLASS */]: `CLASS`, + [4 /* STYLE */]: `STYLE`, + [8 /* PROPS */]: `PROPS`, + [16 /* FULL_PROPS */]: `FULL_PROPS`, + [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`, + [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`, + [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`, + [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`, + [512 /* NEED_PATCH */]: `NEED_PATCH`, + [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`, + [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`, + [-1 /* HOISTED */]: `HOISTED`, + [-2 /* BAIL */]: `BAIL` +}; + +/** + * Dev only + */ +const slotFlagsText = { + [1 /* STABLE */]: 'STABLE', + [2 /* DYNAMIC */]: 'DYNAMIC', + [3 /* FORWARDED */]: 'FORWARDED' +}; + +const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' + + 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' + + 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt'; +const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED); + +const range = 2; +function generateCodeFrame(source, start = 0, end = source.length) { + const lines = source.split(/\r?\n/); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + 1; + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) + continue; + const line = j + 1; + res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + if (j === i) { + // push underline + const pad = start - (count - lineLength) + 1; + const length = Math.max(1, end > count ? lineLength - pad : end - start); + res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); + } + else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + '^'.repeat(length)); + } + count += lineLength + 1; + } + } + break; + } + } + return res.join('\n'); +} + +/** + * On the client we only need to offer special cases for boolean attributes that + * have different names from their corresponding dom properties: + * - itemscope -> N/A + * - allowfullscreen -> allowFullscreen + * - formnovalidate -> formNoValidate + * - ismap -> isMap + * - nomodule -> noModule + * - novalidate -> noValidate + * - readonly -> readOnly + */ +const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; +const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs); +/** + * CSS properties that accept plain numbers + */ +const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` + + `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` + + `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` + + `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` + + `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` + + `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` + + // SVG + `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` + + `stroke-miterlimit,stroke-opacity,stroke-width`); +/** + * Known attributes, this is used for stringification of runtime static nodes + * so that we don't stringify bindings that cannot be set from HTML. + * Don't also forget to allow `data-*` and `aria-*`! + * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes + */ +const isKnownAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` + + `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` + + `border,buffered,capture,challenge,charset,checked,cite,class,code,` + + `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` + + `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` + + `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` + + `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` + + `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` + + `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` + + `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` + + `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` + + `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` + + `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` + + `start,step,style,summary,tabindex,target,title,translate,type,usemap,` + + `value,width,wrap`); + +function normalizeStyle(value) { + if (isArray(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } + else if (isObject(value)) { + return value; + } +} +const listDelimiterRE = /;(?![^(]*\))/g; +const propertyDelimiterRE = /:(.+)/; +function parseStringStyle(cssText) { + const ret = {}; + cssText.split(listDelimiterRE).forEach(item => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; +} +function stringifyStyle(styles) { + let ret = ''; + if (!styles) { + return ret; + } + for (const key in styles) { + const value = styles[key]; + const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); + if (isString(value) || + (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) { + // only render valid values + ret += `${normalizedKey}:${value};`; + } + } + return ret; +} +function normalizeClass(value) { + let res = ''; + if (isString(value)) { + res = value; + } + else if (isArray(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + ' '; + } + } + } + else if (isObject(value)) { + for (const name in value) { + if (value[name]) { + res += name + ' '; + } + } + } + return res.trim(); +} + +// These tag configs are shared between compiler-dom and runtime-dom, so they +// https://developer.mozilla.org/en-US/docs/Web/HTML/Element +const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' + + 'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' + + 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' + + 'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' + + 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' + + 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' + + 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' + + 'option,output,progress,select,textarea,details,dialog,menu,' + + 'summary,template,blockquote,iframe,tfoot'; +// https://developer.mozilla.org/en-US/docs/Web/SVG/Element +const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' + + 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' + + 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' + + 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' + + 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' + + 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' + + 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' + + 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' + + 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' + + 'text,textPath,title,tspan,unknown,use,view'; +const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'; +const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS); +const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS); +const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS); + +const escapeRE = /["'&<>]/; +function escapeHtml(string) { + const str = '' + string; + const match = escapeRE.exec(str); + if (!match) { + return str; + } + let html = ''; + let escaped; + let index; + let lastIndex = 0; + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: // " + escaped = '"'; + break; + case 38: // & + escaped = '&'; + break; + case 39: // ' + escaped = '''; + break; + case 60: // < + escaped = '<'; + break; + case 62: // > + escaped = '>'; + break; + default: + continue; + } + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + lastIndex = index + 1; + html += escaped; + } + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; +} + +function looseCompareArrays(a, b) { + if (a.length !== b.length) + return false; + let equal = true; + for (let i = 0; equal && i < a.length; i++) { + equal = looseEqual(a[i], b[i]); + } + return equal; +} +function looseEqual(a, b) { + if (a === b) + return true; + let aValidType = isDate(a); + let bValidType = isDate(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? a.getTime() === b.getTime() : false; + } + aValidType = isArray(a); + bValidType = isArray(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? looseCompareArrays(a, b) : false; + } + aValidType = isObject(a); + bValidType = isObject(b); + if (aValidType || bValidType) { + /* istanbul ignore if: this if will probably never be called */ + if (!aValidType || !bValidType) { + return false; + } + const aKeysCount = Object.keys(a).length; + const bKeysCount = Object.keys(b).length; + if (aKeysCount !== bKeysCount) { + return false; + } + for (const key in a) { + const aHasKey = a.hasOwnProperty(key); + const bHasKey = b.hasOwnProperty(key); + if ((aHasKey && !bHasKey) || + (!aHasKey && bHasKey) || + !looseEqual(a[key], b[key])) { + return false; + } + } + } + return String(a) === String(b); +} +function looseIndexOf(arr, val) { + return arr.findIndex(item => looseEqual(item, val)); +} + +/** + * For converting {{ interpolation }} values to displayed strings. + * @private + */ +const toDisplayString = (val) => { + return val == null + ? '' + : isObject(val) + ? JSON.stringify(val, replacer, 2) + : String(val); +}; +const replacer = (_key, val) => { + if (isMap(val)) { + return { + [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => { + entries[`${key} =>`] = val; + return entries; + }, {}) + }; + } + else if (isSet(val)) { + return { + [`Set(${val.size})`]: [...val.values()] + }; + } + else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { + return String(val); + } + return val; +}; + +/** + * List of @babel/parser plugins that are used for template expression + * transforms and SFC script transforms. By default we enable proposals slated + * for ES2020. This will need to be updated as the spec moves forward. + * Full list at https://babeljs.io/docs/en/next/babel-parser#plugins + */ +const babelParserDefaultPlugins = [ + 'bigInt', + 'optionalChaining', + 'nullishCoalescingOperator' +]; +const EMPTY_OBJ = Object.freeze({}) + ; +const EMPTY_ARR = Object.freeze([]) ; +const NOOP = () => { }; +/** + * Always return false. + */ +const NO = () => false; +const onRE = /^on[^a-z]/; +const isOn = (key) => onRE.test(key); +const isModelListener = (key) => key.startsWith('onUpdate:'); +const extend = Object.assign; +const remove = (arr, el) => { + const i = arr.indexOf(el); + if (i > -1) { + arr.splice(i, 1); + } +}; +const hasOwnProperty = Object.prototype.hasOwnProperty; +const hasOwn = (val, key) => hasOwnProperty.call(val, key); +const isArray = Array.isArray; +const isMap = (val) => toTypeString(val) === '[object Map]'; +const isSet = (val) => toTypeString(val) === '[object Set]'; +const isDate = (val) => val instanceof Date; +const isFunction = (val) => typeof val === 'function'; +const isString = (val) => typeof val === 'string'; +const isSymbol = (val) => typeof val === 'symbol'; +const isObject = (val) => val !== null && typeof val === 'object'; +const isPromise = (val) => { + return isObject(val) && isFunction(val.then) && isFunction(val.catch); +}; +const objectToString = Object.prototype.toString; +const toTypeString = (value) => objectToString.call(value); +const toRawType = (value) => { + // extract "RawType" from strings like "[object RawType]" + return toTypeString(value).slice(8, -1); +}; +const isPlainObject = (val) => toTypeString(val) === '[object Object]'; +const isIntegerKey = (key) => isString(key) && + key !== 'NaN' && + key[0] !== '-' && + '' + parseInt(key, 10) === key; +const isReservedProp = /*#__PURE__*/ makeMap( +// the leading comma is intentional so empty string "" is also included +',key,ref,' + + 'onVnodeBeforeMount,onVnodeMounted,' + + 'onVnodeBeforeUpdate,onVnodeUpdated,' + + 'onVnodeBeforeUnmount,onVnodeUnmounted'); +const cacheStringFunction = (fn) => { + const cache = Object.create(null); + return ((str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }); +}; +const camelizeRE = /-(\w)/g; +/** + * @private + */ +const camelize = cacheStringFunction((str) => { + return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); +}); +const hyphenateRE = /\B([A-Z])/g; +/** + * @private + */ +const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase()); +/** + * @private + */ +const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1)); +/** + * @private + */ +const toHandlerKey = cacheStringFunction((str) => (str ? `on${capitalize(str)}` : ``)); +// compare whether a value has changed, accounting for NaN. +const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue); +const invokeArrayFns = (fns, arg) => { + for (let i = 0; i < fns.length; i++) { + fns[i](arg); + } +}; +const def = (obj, key, value) => { + Object.defineProperty(obj, key, { + configurable: true, + enumerable: false, + value + }); +}; +const toNumber = (val) => { + const n = parseFloat(val); + return isNaN(n) ? val : n; +}; +let _globalThis; +const getGlobalThis = () => { + return (_globalThis || + (_globalThis = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {})); +}; + +const targetMap = new WeakMap(); +const effectStack = []; +let activeEffect; +const ITERATE_KEY = Symbol('iterate' ); +const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' ); +function isEffect(fn) { + return fn && fn._isEffect === true; +} +function effect(fn, options = EMPTY_OBJ) { + if (isEffect(fn)) { + fn = fn.raw; + } + const effect = createReactiveEffect(fn, options); + if (!options.lazy) { + effect(); + } + return effect; +} +function stop(effect) { + if (effect.active) { + cleanup(effect); + if (effect.options.onStop) { + effect.options.onStop(); + } + effect.active = false; + } +} +let uid = 0; +function createReactiveEffect(fn, options) { + const effect = function reactiveEffect() { + if (!effect.active) { + return options.scheduler ? undefined : fn(); + } + if (!effectStack.includes(effect)) { + cleanup(effect); + try { + enableTracking(); + effectStack.push(effect); + activeEffect = effect; + return fn(); + } + finally { + effectStack.pop(); + resetTracking(); + activeEffect = effectStack[effectStack.length - 1]; + } + } + }; + effect.id = uid++; + effect.allowRecurse = !!options.allowRecurse; + effect._isEffect = true; + effect.active = true; + effect.raw = fn; + effect.deps = []; + effect.options = options; + return effect; +} +function cleanup(effect) { + const { deps } = effect; + if (deps.length) { + for (let i = 0; i < deps.length; i++) { + deps[i].delete(effect); + } + deps.length = 0; + } +} +let shouldTrack = true; +const trackStack = []; +function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; +} +function enableTracking() { + trackStack.push(shouldTrack); + shouldTrack = true; +} +function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === undefined ? true : last; +} +function track(target, type, key) { + if (!shouldTrack || activeEffect === undefined) { + return; + } + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, (depsMap = new Map())); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, (dep = new Set())); + } + if (!dep.has(activeEffect)) { + dep.add(activeEffect); + activeEffect.deps.push(dep); + if (activeEffect.options.onTrack) { + activeEffect.options.onTrack({ + effect: activeEffect, + target, + type, + key + }); + } + } +} +function trigger(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + // never been tracked + return; + } + const effects = new Set(); + const add = (effectsToAdd) => { + if (effectsToAdd) { + effectsToAdd.forEach(effect => { + if (effect !== activeEffect || effect.allowRecurse) { + effects.add(effect); + } + }); + } + }; + if (type === "clear" /* CLEAR */) { + // collection being cleared + // trigger all effects for target + depsMap.forEach(add); + } + else if (key === 'length' && isArray(target)) { + depsMap.forEach((dep, key) => { + if (key === 'length' || key >= newValue) { + add(dep); + } + }); + } + else { + // schedule runs for SET | ADD | DELETE + if (key !== void 0) { + add(depsMap.get(key)); + } + // also run for iteration key on ADD | DELETE | Map.SET + switch (type) { + case "add" /* ADD */: + if (!isArray(target)) { + add(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + add(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + else if (isIntegerKey(key)) { + // new index added to array -> length changes + add(depsMap.get('length')); + } + break; + case "delete" /* DELETE */: + if (!isArray(target)) { + add(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + add(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set" /* SET */: + if (isMap(target)) { + add(depsMap.get(ITERATE_KEY)); + } + break; + } + } + const run = (effect) => { + if (effect.options.onTrigger) { + effect.options.onTrigger({ + effect, + target, + key, + type, + newValue, + oldValue, + oldTarget + }); + } + if (effect.options.scheduler) { + effect.options.scheduler(effect); + } + else { + effect(); + } + }; + effects.forEach(run); +} + +const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`); +const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol) + .map(key => Symbol[key]) + .filter(isSymbol)); +const get = /*#__PURE__*/ createGetter(); +const shallowGet = /*#__PURE__*/ createGetter(false, true); +const readonlyGet = /*#__PURE__*/ createGetter(true); +const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); +const arrayInstrumentations = {}; +['includes', 'indexOf', 'lastIndexOf'].forEach(key => { + const method = Array.prototype[key]; + arrayInstrumentations[key] = function (...args) { + const arr = toRaw(this); + for (let i = 0, l = this.length; i < l; i++) { + track(arr, "get" /* GET */, i + ''); + } + // we run the method using the original args first (which may be reactive) + const res = method.apply(arr, args); + if (res === -1 || res === false) { + // if that didn't work, run it again using raw values. + return method.apply(arr, args.map(toRaw)); + } + else { + return res; + } + }; +}); +['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => { + const method = Array.prototype[key]; + arrayInstrumentations[key] = function (...args) { + pauseTracking(); + const res = method.apply(this, args); + resetTracking(); + return res; + }; +}); +function createGetter(isReadonly = false, shallow = false) { + return function get(target, key, receiver) { + if (key === "__v_isReactive" /* IS_REACTIVE */) { + return !isReadonly; + } + else if (key === "__v_isReadonly" /* IS_READONLY */) { + return isReadonly; + } + else if (key === "__v_raw" /* RAW */ && + receiver === + (isReadonly + ? shallow + ? shallowReadonlyMap + : readonlyMap + : shallow + ? shallowReactiveMap + : reactiveMap).get(target)) { + return target; + } + const targetIsArray = isArray(target); + if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) { + return Reflect.get(arrayInstrumentations, key, receiver); + } + const res = Reflect.get(target, key, receiver); + if (isSymbol(key) + ? builtInSymbols.has(key) + : isNonTrackableKeys(key)) { + return res; + } + if (!isReadonly) { + track(target, "get" /* GET */, key); + } + if (shallow) { + return res; + } + if (isRef(res)) { + // ref unwrapping - does not apply for Array + integer key. + const shouldUnwrap = !targetIsArray || !isIntegerKey(key); + return shouldUnwrap ? res.value : res; + } + if (isObject(res)) { + // Convert returned value into a proxy as well. we do the isObject check + // here to avoid invalid value warning. Also need to lazy access readonly + // and reactive here to avoid circular dependency. + return isReadonly ? readonly(res) : reactive(res); + } + return res; + }; +} +const set = /*#__PURE__*/ createSetter(); +const shallowSet = /*#__PURE__*/ createSetter(true); +function createSetter(shallow = false) { + return function set(target, key, value, receiver) { + let oldValue = target[key]; + if (!shallow) { + value = toRaw(value); + oldValue = toRaw(oldValue); + if (!isArray(target) && isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + } + const hadKey = isArray(target) && isIntegerKey(key) + ? Number(key) < target.length + : hasOwn(target, key); + const result = Reflect.set(target, key, value, receiver); + // don't trigger if target is something up in the prototype chain of original + if (target === toRaw(receiver)) { + if (!hadKey) { + trigger(target, "add" /* ADD */, key, value); + } + else if (hasChanged(value, oldValue)) { + trigger(target, "set" /* SET */, key, value, oldValue); + } + } + return result; + }; +} +function deleteProperty(target, key) { + const hadKey = hasOwn(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger(target, "delete" /* DELETE */, key, undefined, oldValue); + } + return result; +} +function has(target, key) { + const result = Reflect.has(target, key); + if (!isSymbol(key) || !builtInSymbols.has(key)) { + track(target, "has" /* HAS */, key); + } + return result; +} +function ownKeys(target) { + track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY); + return Reflect.ownKeys(target); +} +const mutableHandlers = { + get, + set, + deleteProperty, + has, + ownKeys +}; +const readonlyHandlers = { + get: readonlyGet, + set(target, key) { + { + console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + }, + deleteProperty(target, key) { + { + console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + } +}; +const shallowReactiveHandlers = extend({}, mutableHandlers, { + get: shallowGet, + set: shallowSet +}); +// Props handlers are special in the sense that it should not unwrap top-level +// refs (in order to allow refs to be explicitly passed down), but should +// retain the reactivity of the normal readonly object. +const shallowReadonlyHandlers = extend({}, readonlyHandlers, { + get: shallowReadonlyGet +}); + +const toReactive = (value) => isObject(value) ? reactive(value) : value; +const toReadonly = (value) => isObject(value) ? readonly(value) : value; +const toShallow = (value) => value; +const getProto = (v) => Reflect.getPrototypeOf(v); +function get$1(target, key, isReadonly = false, isShallow = false) { + // #1772: readonly(reactive(Map)) should return readonly + reactive version + // of the value + target = target["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (key !== rawKey) { + !isReadonly && track(rawTarget, "get" /* GET */, key); + } + !isReadonly && track(rawTarget, "get" /* GET */, rawKey); + const { has } = getProto(rawTarget); + const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; + if (has.call(rawTarget, key)) { + return wrap(target.get(key)); + } + else if (has.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } + else if (target !== rawTarget) { + // #3602 readonly(reactive(Map)) + // ensure that the nested reactive `Map` can do tracking for itself + target.get(key); + } +} +function has$1(key, isReadonly = false) { + const target = this["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (key !== rawKey) { + !isReadonly && track(rawTarget, "has" /* HAS */, key); + } + !isReadonly && track(rawTarget, "has" /* HAS */, rawKey); + return key === rawKey + ? target.has(key) + : target.has(key) || target.has(rawKey); +} +function size(target, isReadonly = false) { + target = target["__v_raw" /* RAW */]; + !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY); + return Reflect.get(target, 'size', target); +} +function add(value) { + value = toRaw(value); + const target = toRaw(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + if (!hadKey) { + target.add(value); + trigger(target, "add" /* ADD */, value, value); + } + return this; +} +function set$1(key, value) { + value = toRaw(value); + const target = toRaw(this); + const { has, get } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } + else { + checkIdentityKeys(target, has, key); + } + const oldValue = get.call(target, key); + target.set(key, value); + if (!hadKey) { + trigger(target, "add" /* ADD */, key, value); + } + else if (hasChanged(value, oldValue)) { + trigger(target, "set" /* SET */, key, value, oldValue); + } + return this; +} +function deleteEntry(key) { + const target = toRaw(this); + const { has, get } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } + else { + checkIdentityKeys(target, has, key); + } + const oldValue = get ? get.call(target, key) : undefined; + // forward the operation before queueing reactions + const result = target.delete(key); + if (hadKey) { + trigger(target, "delete" /* DELETE */, key, undefined, oldValue); + } + return result; +} +function clear() { + const target = toRaw(this); + const hadItems = target.size !== 0; + const oldTarget = isMap(target) + ? new Map(target) + : new Set(target) + ; + // forward the operation before queueing reactions + const result = target.clear(); + if (hadItems) { + trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget); + } + return result; +} +function createForEach(isReadonly, isShallow) { + return function forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; + !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY); + return target.forEach((value, key) => { + // important: make sure the callback is + // 1. invoked with the reactive map as `this` and 3rd arg + // 2. the value received should be a corresponding reactive/readonly. + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + }; +} +function createIterableMethod(method, isReadonly, isShallow) { + return function (...args) { + const target = this["__v_raw" /* RAW */]; + const rawTarget = toRaw(target); + const targetIsMap = isMap(rawTarget); + const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap); + const isKeyOnly = method === 'keys' && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; + !isReadonly && + track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); + // return a wrapped iterator which returns observed versions of the + // values emitted from the real iterator + return { + // iterator protocol + next() { + const { value, done } = innerIterator.next(); + return done + ? { value, done } + : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + // iterable protocol + [Symbol.iterator]() { + return this; + } + }; + }; +} +function createReadonlyMethod(type) { + return function (...args) { + { + const key = args[0] ? `on key "${args[0]}" ` : ``; + console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this)); + } + return type === "delete" /* DELETE */ ? false : this; + }; +} +const mutableInstrumentations = { + get(key) { + return get$1(this, key); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) +}; +const shallowInstrumentations = { + get(key) { + return get$1(this, key, false, true); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) +}; +const readonlyInstrumentations = { + get(key) { + return get$1(this, key, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod("add" /* ADD */), + set: createReadonlyMethod("set" /* SET */), + delete: createReadonlyMethod("delete" /* DELETE */), + clear: createReadonlyMethod("clear" /* CLEAR */), + forEach: createForEach(true, false) +}; +const shallowReadonlyInstrumentations = { + get(key) { + return get$1(this, key, true, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod("add" /* ADD */), + set: createReadonlyMethod("set" /* SET */), + delete: createReadonlyMethod("delete" /* DELETE */), + clear: createReadonlyMethod("clear" /* CLEAR */), + forEach: createForEach(true, true) +}; +const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; +iteratorMethods.forEach(method => { + mutableInstrumentations[method] = createIterableMethod(method, false, false); + readonlyInstrumentations[method] = createIterableMethod(method, true, false); + shallowInstrumentations[method] = createIterableMethod(method, false, true); + shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); +}); +function createInstrumentationGetter(isReadonly, shallow) { + const instrumentations = shallow + ? isReadonly + ? shallowReadonlyInstrumentations + : shallowInstrumentations + : isReadonly + ? readonlyInstrumentations + : mutableInstrumentations; + return (target, key, receiver) => { + if (key === "__v_isReactive" /* IS_REACTIVE */) { + return !isReadonly; + } + else if (key === "__v_isReadonly" /* IS_READONLY */) { + return isReadonly; + } + else if (key === "__v_raw" /* RAW */) { + return target; + } + return Reflect.get(hasOwn(instrumentations, key) && key in target + ? instrumentations + : target, key, receiver); + }; +} +const mutableCollectionHandlers = { + get: createInstrumentationGetter(false, false) +}; +const shallowCollectionHandlers = { + get: createInstrumentationGetter(false, true) +}; +const readonlyCollectionHandlers = { + get: createInstrumentationGetter(true, false) +}; +const shallowReadonlyCollectionHandlers = { + get: createInstrumentationGetter(true, true) +}; +function checkIdentityKeys(target, has, key) { + const rawKey = toRaw(key); + if (rawKey !== key && has.call(target, rawKey)) { + const type = toRawType(target); + console.warn(`Reactive ${type} contains both the raw and reactive ` + + `versions of the same object${type === `Map` ? ` as keys` : ``}, ` + + `which can lead to inconsistencies. ` + + `Avoid differentiating between the raw and reactive versions ` + + `of an object and only use the reactive version if possible.`); + } +} + +const reactiveMap = new WeakMap(); +const shallowReactiveMap = new WeakMap(); +const readonlyMap = new WeakMap(); +const shallowReadonlyMap = new WeakMap(); +function targetTypeMap(rawType) { + switch (rawType) { + case 'Object': + case 'Array': + return 1 /* COMMON */; + case 'Map': + case 'Set': + case 'WeakMap': + case 'WeakSet': + return 2 /* COLLECTION */; + default: + return 0 /* INVALID */; + } +} +function getTargetType(value) { + return value["__v_skip" /* SKIP */] || !Object.isExtensible(value) + ? 0 /* INVALID */ + : targetTypeMap(toRawType(value)); +} +function reactive(target) { + // if trying to observe a readonly proxy, return the readonly version. + if (target && target["__v_isReadonly" /* IS_READONLY */]) { + return target; + } + return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); +} +/** + * Return a shallowly-reactive copy of the original object, where only the root + * level properties are reactive. It also does not auto-unwrap refs (even at the + * root level). + */ +function shallowReactive(target) { + return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); +} +/** + * Creates a readonly copy of the original object. Note the returned copy is not + * made reactive, but `readonly` can be called on an already reactive object. + */ +function readonly(target) { + return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); +} +/** + * Returns a reactive-copy of the original object, where only the root level + * properties are readonly, and does NOT unwrap refs nor recursively convert + * returned properties. + * This is used for creating the props proxy object for stateful components. + */ +function shallowReadonly(target) { + return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); +} +function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { + if (!isObject(target)) { + { + console.warn(`value cannot be made reactive: ${String(target)}`); + } + return target; + } + // target is already a Proxy, return it. + // exception: calling readonly() on a reactive object + if (target["__v_raw" /* RAW */] && + !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) { + return target; + } + // target already has corresponding Proxy + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + // only a whitelist of value types can be observed. + const targetType = getTargetType(target); + if (targetType === 0 /* INVALID */) { + return target; + } + const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); + proxyMap.set(target, proxy); + return proxy; +} +function isReactive(value) { + if (isReadonly(value)) { + return isReactive(value["__v_raw" /* RAW */]); + } + return !!(value && value["__v_isReactive" /* IS_REACTIVE */]); +} +function isReadonly(value) { + return !!(value && value["__v_isReadonly" /* IS_READONLY */]); +} +function isProxy(value) { + return isReactive(value) || isReadonly(value); +} +function toRaw(observed) { + return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed); +} +function markRaw(value) { + def(value, "__v_skip" /* SKIP */, true); + return value; +} + +const convert = (val) => isObject(val) ? reactive(val) : val; +function isRef(r) { + return Boolean(r && r.__v_isRef === true); +} +function ref(value) { + return createRef(value); +} +function shallowRef(value) { + return createRef(value, true); +} +class RefImpl { + constructor(_rawValue, _shallow = false) { + this._rawValue = _rawValue; + this._shallow = _shallow; + this.__v_isRef = true; + this._value = _shallow ? _rawValue : convert(_rawValue); + } + get value() { + track(toRaw(this), "get" /* GET */, 'value'); + return this._value; + } + set value(newVal) { + if (hasChanged(toRaw(newVal), this._rawValue)) { + this._rawValue = newVal; + this._value = this._shallow ? newVal : convert(newVal); + trigger(toRaw(this), "set" /* SET */, 'value', newVal); + } + } +} +function createRef(rawValue, shallow = false) { + if (isRef(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); +} +function triggerRef(ref) { + trigger(toRaw(ref), "set" /* SET */, 'value', ref.value ); +} +function unref(ref) { + return isRef(ref) ? ref.value : ref; +} +const shallowUnwrapHandlers = { + get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + else { + return Reflect.set(target, key, value, receiver); + } + } +}; +function proxyRefs(objectWithRefs) { + return isReactive(objectWithRefs) + ? objectWithRefs + : new Proxy(objectWithRefs, shallowUnwrapHandlers); +} +class CustomRefImpl { + constructor(factory) { + this.__v_isRef = true; + const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value')); + this._get = get; + this._set = set; + } + get value() { + return this._get(); + } + set value(newVal) { + this._set(newVal); + } +} +function customRef(factory) { + return new CustomRefImpl(factory); +} +function toRefs(object) { + if (!isProxy(object)) { + console.warn(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = toRef(object, key); + } + return ret; +} +class ObjectRefImpl { + constructor(_object, _key) { + this._object = _object; + this._key = _key; + this.__v_isRef = true; + } + get value() { + return this._object[this._key]; + } + set value(newVal) { + this._object[this._key] = newVal; + } +} +function toRef(object, key) { + return isRef(object[key]) + ? object[key] + : new ObjectRefImpl(object, key); +} + +class ComputedRefImpl { + constructor(getter, _setter, isReadonly) { + this._setter = _setter; + this._dirty = true; + this.__v_isRef = true; + this.effect = effect(getter, { + lazy: true, + scheduler: () => { + if (!this._dirty) { + this._dirty = true; + trigger(toRaw(this), "set" /* SET */, 'value'); + } + } + }); + this["__v_isReadonly" /* IS_READONLY */] = isReadonly; + } + get value() { + // the computed ref may get wrapped by other proxies e.g. readonly() #3376 + const self = toRaw(this); + if (self._dirty) { + self._value = this.effect(); + self._dirty = false; + } + track(self, "get" /* GET */, 'value'); + return self._value; + } + set value(newValue) { + this._setter(newValue); + } +} +function computed(getterOrOptions) { + let getter; + let setter; + if (isFunction(getterOrOptions)) { + getter = getterOrOptions; + setter = () => { + console.warn('Write operation failed: computed value is readonly'); + } + ; + } + else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set); +} + +const stack = []; +function pushWarningContext(vnode) { + stack.push(vnode); +} +function popWarningContext() { + stack.pop(); +} +function warn(msg, ...args) { + // avoid props formatting or warn handler tracking deps that might be mutated + // during patch, leading to infinite recursion. + pauseTracking(); + const instance = stack.length ? stack[stack.length - 1].component : null; + const appWarnHandler = instance && instance.appContext.config.warnHandler; + const trace = getComponentTrace(); + if (appWarnHandler) { + callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [ + msg + args.join(''), + instance && instance.proxy, + trace + .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) + .join('\n'), + trace + ]); + } + else { + const warnArgs = [`[Vue warn]: ${msg}`, ...args]; + /* istanbul ignore if */ + if (trace.length && + // avoid spamming console during tests + !false) { + warnArgs.push(`\n`, ...formatTrace(trace)); + } + console.warn(...warnArgs); + } + resetTracking(); +} +function getComponentTrace() { + let currentVNode = stack[stack.length - 1]; + if (!currentVNode) { + return []; + } + // we can't just use the stack because it will be incomplete during updates + // that did not start from the root. Re-construct the parent chain using + // instance parent pointers. + const normalizedStack = []; + while (currentVNode) { + const last = normalizedStack[0]; + if (last && last.vnode === currentVNode) { + last.recurseCount++; + } + else { + normalizedStack.push({ + vnode: currentVNode, + recurseCount: 0 + }); + } + const parentInstance = currentVNode.component && currentVNode.component.parent; + currentVNode = parentInstance && parentInstance.vnode; + } + return normalizedStack; +} +/* istanbul ignore next */ +function formatTrace(trace) { + const logs = []; + trace.forEach((entry, i) => { + logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); + }); + return logs; +} +function formatTraceEntry({ vnode, recurseCount }) { + const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; + const isRoot = vnode.component ? vnode.component.parent == null : false; + const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; + const close = `>` + postfix; + return vnode.props + ? [open, ...formatProps(vnode.props), close] + : [open + close]; +} +/* istanbul ignore next */ +function formatProps(props) { + const res = []; + const keys = Object.keys(props); + keys.slice(0, 3).forEach(key => { + res.push(...formatProp(key, props[key])); + }); + if (keys.length > 3) { + res.push(` ...`); + } + return res; +} +/* istanbul ignore next */ +function formatProp(key, value, raw) { + if (isString(value)) { + value = JSON.stringify(value); + return raw ? value : [`${key}=${value}`]; + } + else if (typeof value === 'number' || + typeof value === 'boolean' || + value == null) { + return raw ? value : [`${key}=${value}`]; + } + else if (isRef(value)) { + value = formatProp(key, toRaw(value.value), true); + return raw ? value : [`${key}=Ref<`, value, `>`]; + } + else if (isFunction(value)) { + return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; + } + else { + value = toRaw(value); + return raw ? value : [`${key}=`, value]; + } +} + +const ErrorTypeStrings = { + ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook', + ["c" /* CREATED */]: 'created hook', + ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook', + ["m" /* MOUNTED */]: 'mounted hook', + ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook', + ["u" /* UPDATED */]: 'updated', + ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook', + ["um" /* UNMOUNTED */]: 'unmounted hook', + ["a" /* ACTIVATED */]: 'activated hook', + ["da" /* DEACTIVATED */]: 'deactivated hook', + ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook', + ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook', + ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook', + [0 /* SETUP_FUNCTION */]: 'setup function', + [1 /* RENDER_FUNCTION */]: 'render function', + [2 /* WATCH_GETTER */]: 'watcher getter', + [3 /* WATCH_CALLBACK */]: 'watcher callback', + [4 /* WATCH_CLEANUP */]: 'watcher cleanup function', + [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler', + [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler', + [7 /* VNODE_HOOK */]: 'vnode hook', + [8 /* DIRECTIVE_HOOK */]: 'directive hook', + [9 /* TRANSITION_HOOK */]: 'transition hook', + [10 /* APP_ERROR_HANDLER */]: 'app errorHandler', + [11 /* APP_WARN_HANDLER */]: 'app warnHandler', + [12 /* FUNCTION_REF */]: 'ref function', + [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader', + [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' + + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next' +}; +function callWithErrorHandling(fn, instance, type, args) { + let res; + try { + res = args ? fn(...args) : fn(); + } + catch (err) { + handleError(err, instance, type); + } + return res; +} +function callWithAsyncErrorHandling(fn, instance, type, args) { + if (isFunction(fn)) { + const res = callWithErrorHandling(fn, instance, type, args); + if (res && isPromise(res)) { + res.catch(err => { + handleError(err, instance, type); + }); + } + return res; + } + const values = []; + for (let i = 0; i < fn.length; i++) { + values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); + } + return values; +} +function handleError(err, instance, type, throwInDev = true) { + const contextVNode = instance ? instance.vnode : null; + if (instance) { + let cur = instance.parent; + // the exposed instance is the render proxy to keep it consistent with 2.x + const exposedInstance = instance.proxy; + // in production the hook receives only the error code + const errorInfo = ErrorTypeStrings[type] ; + while (cur) { + const errorCapturedHooks = cur.ec; + if (errorCapturedHooks) { + for (let i = 0; i < errorCapturedHooks.length; i++) { + if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { + return; + } + } + } + cur = cur.parent; + } + // app-level handling + const appErrorHandler = instance.appContext.config.errorHandler; + if (appErrorHandler) { + callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]); + return; + } + } + logError(err, type, contextVNode, throwInDev); +} +function logError(err, type, contextVNode, throwInDev = true) { + { + const info = ErrorTypeStrings[type]; + if (contextVNode) { + pushWarningContext(contextVNode); + } + warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`); + if (contextVNode) { + popWarningContext(); + } + // crash in dev by default so it's more noticeable + if (throwInDev) { + throw err; + } + else { + console.error(err); + } + } +} + +let isFlushing = false; +let isFlushPending = false; +const queue = []; +let flushIndex = 0; +const pendingPreFlushCbs = []; +let activePreFlushCbs = null; +let preFlushIndex = 0; +const pendingPostFlushCbs = []; +let activePostFlushCbs = null; +let postFlushIndex = 0; +const resolvedPromise = Promise.resolve(); +let currentFlushPromise = null; +let currentPreFlushParentJob = null; +const RECURSION_LIMIT = 100; +function nextTick(fn) { + const p = currentFlushPromise || resolvedPromise; + return fn ? p.then(this ? fn.bind(this) : fn) : p; +} +// #2768 +// Use binary-search to find a suitable position in the queue, +// so that the queue maintains the increasing order of job's id, +// which can prevent the job from being skipped and also can avoid repeated patching. +function findInsertionIndex(job) { + // the start index should be `flushIndex + 1` + let start = flushIndex + 1; + let end = queue.length; + const jobId = getId(job); + while (start < end) { + const middle = (start + end) >>> 1; + const middleJobId = getId(queue[middle]); + middleJobId < jobId ? (start = middle + 1) : (end = middle); + } + return start; +} +function queueJob(job) { + // the dedupe search uses the startIndex argument of Array.includes() + // by default the search index includes the current job that is being run + // so it cannot recursively trigger itself again. + // if the job is a watch() callback, the search will start with a +1 index to + // allow it recursively trigger itself - it is the user's responsibility to + // ensure it doesn't end up in an infinite loop. + if ((!queue.length || + !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) && + job !== currentPreFlushParentJob) { + const pos = findInsertionIndex(job); + if (pos > -1) { + queue.splice(pos, 0, job); + } + else { + queue.push(job); + } + queueFlush(); + } +} +function queueFlush() { + if (!isFlushing && !isFlushPending) { + isFlushPending = true; + currentFlushPromise = resolvedPromise.then(flushJobs); + } +} +function invalidateJob(job) { + const i = queue.indexOf(job); + if (i > flushIndex) { + queue.splice(i, 1); + } +} +function queueCb(cb, activeQueue, pendingQueue, index) { + if (!isArray(cb)) { + if (!activeQueue || + !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) { + pendingQueue.push(cb); + } + } + else { + // if cb is an array, it is a component lifecycle hook which can only be + // triggered by a job, which is already deduped in the main queue, so + // we can skip duplicate check here to improve perf + pendingQueue.push(...cb); + } + queueFlush(); +} +function queuePreFlushCb(cb) { + queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); +} +function queuePostFlushCb(cb) { + queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); +} +function flushPreFlushCbs(seen, parentJob = null) { + if (pendingPreFlushCbs.length) { + currentPreFlushParentJob = parentJob; + activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; + pendingPreFlushCbs.length = 0; + { + seen = seen || new Map(); + } + for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { + if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) { + continue; + } + activePreFlushCbs[preFlushIndex](); + } + activePreFlushCbs = null; + preFlushIndex = 0; + currentPreFlushParentJob = null; + // recursively flush until it drains + flushPreFlushCbs(seen, parentJob); + } +} +function flushPostFlushCbs(seen) { + if (pendingPostFlushCbs.length) { + const deduped = [...new Set(pendingPostFlushCbs)]; + pendingPostFlushCbs.length = 0; + // #1947 already has active queue, nested flushPostFlushCbs call + if (activePostFlushCbs) { + activePostFlushCbs.push(...deduped); + return; + } + activePostFlushCbs = deduped; + { + seen = seen || new Map(); + } + activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); + for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { + if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) { + continue; + } + activePostFlushCbs[postFlushIndex](); + } + activePostFlushCbs = null; + postFlushIndex = 0; + } +} +const getId = (job) => job.id == null ? Infinity : job.id; +function flushJobs(seen) { + isFlushPending = false; + isFlushing = true; + { + seen = seen || new Map(); + } + flushPreFlushCbs(seen); + // Sort queue before flush. + // This ensures that: + // 1. Components are updated from parent to child. (because parent is always + // created before the child so its render effect will have smaller + // priority number) + // 2. If a component is unmounted during a parent component's update, + // its update can be skipped. + queue.sort((a, b) => getId(a) - getId(b)); + try { + for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex]; + if (job) { + if (true && checkRecursiveUpdates(seen, job)) { + continue; + } + callWithErrorHandling(job, null, 14 /* SCHEDULER */); + } + } + } + finally { + flushIndex = 0; + queue.length = 0; + flushPostFlushCbs(seen); + isFlushing = false; + currentFlushPromise = null; + // some postFlushCb queued jobs! + // keep flushing until it drains. + if (queue.length || pendingPostFlushCbs.length) { + flushJobs(seen); + } + } +} +function checkRecursiveUpdates(seen, fn) { + if (!seen.has(fn)) { + seen.set(fn, 1); + } + else { + const count = seen.get(fn); + if (count > RECURSION_LIMIT) { + const instance = fn.ownerInstance; + const componentName = instance && getComponentName(instance.type); + warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` + + `This means you have a reactive effect that is mutating its own ` + + `dependencies and thus recursively triggering itself. Possible sources ` + + `include component template, render function, updated hook or ` + + `watcher source function.`); + return true; + } + else { + seen.set(fn, count + 1); + } + } +} + +/* eslint-disable no-restricted-globals */ +let isHmrUpdating = false; +const hmrDirtyComponents = new Set(); +// Expose the HMR runtime on the global object +// This makes it entirely tree-shakable without polluting the exports and makes +// it easier to be used in toolings like vue-loader +// Note: for a component to be eligible for HMR it also needs the __hmrId option +// to be set so that its instances can be registered / removed. +{ + const globalObject = typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : {}; + globalObject.__VUE_HMR_RUNTIME__ = { + createRecord: tryWrap(createRecord), + rerender: tryWrap(rerender), + reload: tryWrap(reload) + }; +} +const map = new Map(); +function registerHMR(instance) { + const id = instance.type.__hmrId; + let record = map.get(id); + if (!record) { + createRecord(id, instance.type); + record = map.get(id); + } + record.instances.add(instance); +} +function unregisterHMR(instance) { + map.get(instance.type.__hmrId).instances.delete(instance); +} +function createRecord(id, component) { + if (!component) { + warn(`HMR API usage is out of date.\n` + + `Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` + + `dependency that handles Vue SFC compilation.`); + component = {}; + } + if (map.has(id)) { + return false; + } + map.set(id, { + component: isClassComponent(component) ? component.__vccOpts : component, + instances: new Set() + }); + return true; +} +function rerender(id, newRender) { + const record = map.get(id); + if (!record) + return; + if (newRender) + record.component.render = newRender; + // Array.from creates a snapshot which avoids the set being mutated during + // updates + Array.from(record.instances).forEach(instance => { + if (newRender) { + instance.render = newRender; + } + instance.renderCache = []; + // this flag forces child components with slot content to update + isHmrUpdating = true; + instance.update(); + isHmrUpdating = false; + }); +} +function reload(id, newComp) { + const record = map.get(id); + if (!record) + return; + // Array.from creates a snapshot which avoids the set being mutated during + // updates + const { component, instances } = record; + if (!hmrDirtyComponents.has(component)) { + // 1. Update existing comp definition to match new one + newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp; + extend(component, newComp); + for (const key in component) { + if (key !== '__file' && !(key in newComp)) { + delete component[key]; + } + } + // 2. Mark component dirty. This forces the renderer to replace the component + // on patch. + hmrDirtyComponents.add(component); + // 3. Make sure to unmark the component after the reload. + queuePostFlushCb(() => { + hmrDirtyComponents.delete(component); + }); + } + Array.from(instances).forEach(instance => { + if (instance.parent) { + // 4. Force the parent instance to re-render. This will cause all updated + // components to be unmounted and re-mounted. Queue the update so that we + // don't end up forcing the same parent to re-render multiple times. + queueJob(instance.parent.update); + } + else if (instance.appContext.reload) { + // root instance mounted via createApp() has a reload method + instance.appContext.reload(); + } + else if (typeof window !== 'undefined') { + // root instance inside tree created via raw render(). Force reload. + window.location.reload(); + } + else { + console.warn('[HMR] Root or manually mounted instance modified. Full reload required.'); + } + }); +} +function tryWrap(fn) { + return (id, arg) => { + try { + return fn(id, arg); + } + catch (e) { + console.error(e); + console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` + + `Full reload required.`); + } + }; +} + +let devtools; +function setDevtoolsHook(hook) { + devtools = hook; +} +function devtoolsInitApp(app, version) { + // TODO queue if devtools is undefined + if (!devtools) + return; + devtools.emit("app:init" /* APP_INIT */, app, version, { + Fragment, + Text, + Comment, + Static + }); +} +function devtoolsUnmountApp(app) { + if (!devtools) + return; + devtools.emit("app:unmount" /* APP_UNMOUNT */, app); +} +const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */); +const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */); +const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */); +function createDevtoolsComponentHook(hook) { + return (component) => { + if (!devtools) + return; + devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); + }; +} +function devtoolsComponentEmit(component, event, params) { + if (!devtools) + return; + devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); +} + +const deprecationData = { + ["GLOBAL_MOUNT" /* GLOBAL_MOUNT */]: { + message: `The global app bootstrapping API has changed: vm.$mount() and the "el" ` + + `option have been removed. Use createApp(RootComponent).mount() instead.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance` + }, + ["GLOBAL_MOUNT_CONTAINER" /* GLOBAL_MOUNT_CONTAINER */]: { + message: `Vue detected directives on the mount container. ` + + `In Vue 3, the container is no longer considered part of the template ` + + `and will not be processed/replaced.`, + link: `https://v3.vuejs.org/guide/migration/mount-changes.html` + }, + ["GLOBAL_EXTEND" /* GLOBAL_EXTEND */]: { + message: `Vue.extend() has been removed in Vue 3. ` + + `Use defineComponent() instead.`, + link: `https://v3.vuejs.org/api/global-api.html#definecomponent` + }, + ["GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */]: { + message: `Vue.prototype is no longer available in Vue 3. ` + + `Use app.config.globalProperties instead.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties` + }, + ["GLOBAL_SET" /* GLOBAL_SET */]: { + message: `Vue.set() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + ["GLOBAL_DELETE" /* GLOBAL_DELETE */]: { + message: `Vue.delete() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + ["GLOBAL_OBSERVABLE" /* GLOBAL_OBSERVABLE */]: { + message: `Vue.observable() has been removed. ` + + `Use \`import { reactive } from "vue"\` from Composition API instead.`, + link: `https://v3.vuejs.org/api/basic-reactivity.html` + }, + ["GLOBAL_PRIVATE_UTIL" /* GLOBAL_PRIVATE_UTIL */]: { + message: `Vue.util has been removed. Please refactor to avoid its usage ` + + `since it was an internal API even in Vue 2.` + }, + ["CONFIG_SILENT" /* CONFIG_SILENT */]: { + message: `config.silent has been removed because it is not good practice to ` + + `intentionally suppress warnings. You can use your browser console's ` + + `filter features to focus on relevant messages.` + }, + ["CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */]: { + message: `config.devtools has been removed. To enable devtools for ` + + `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`, + link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags` + }, + ["CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */]: { + message: `config.keyCodes has been removed. ` + + `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`, + link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` + }, + ["CONFIG_PRODUCTION_TIP" /* CONFIG_PRODUCTION_TIP */]: { + message: `config.productionTip has been removed.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed` + }, + ["CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */]: { + message: () => { + let msg = `config.ignoredElements has been removed.`; + if (isRuntimeOnly()) { + msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`; + } + else { + msg += ` Use config.isCustomElement instead.`; + } + return msg; + }, + link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement` + }, + ["CONFIG_WHITESPACE" /* CONFIG_WHITESPACE */]: { + // this warning is only relevant in the full build when using runtime + // compilation, so it's put in the runtime compatConfig list. + message: `Vue 3 compiler's whitespace option will default to "condense" instead of ` + + `"preserve". To suppress this warning, provide an explicit value for ` + + `\`config.compilerOptions.whitespace\`.` + }, + ["CONFIG_OPTION_MERGE_STRATS" /* CONFIG_OPTION_MERGE_STRATS */]: { + message: `config.optionMergeStrategies no longer exposes internal strategies. ` + + `Use custom merge functions instead.` + }, + ["INSTANCE_SET" /* INSTANCE_SET */]: { + message: `vm.$set() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + ["INSTANCE_DELETE" /* INSTANCE_DELETE */]: { + message: `vm.$delete() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + ["INSTANCE_DESTROY" /* INSTANCE_DESTROY */]: { + message: `vm.$destroy() has been removed. Use app.unmount() instead.`, + link: `https://v3.vuejs.org/api/application-api.html#unmount` + }, + ["INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */]: { + message: `vm.$on/$once/$off() have been removed. ` + + `Use an external event emitter library instead.`, + link: `https://v3.vuejs.org/guide/migration/events-api.html` + }, + ["INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */]: { + message: event => `"${event}" lifecycle events are no longer supported. From templates, ` + + `use the "vnode" prefix instead of "hook:". For example, @${event} ` + + `should be changed to @vnode-${event.slice(5)}. ` + + `From JavaScript, use Composition API to dynamically register lifecycle ` + + `hooks.`, + link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html` + }, + ["INSTANCE_CHILDREN" /* INSTANCE_CHILDREN */]: { + message: `vm.$children has been removed. Consider refactoring your logic ` + + `to avoid relying on direct access to child components.`, + link: `https://v3.vuejs.org/guide/migration/children.html` + }, + ["INSTANCE_LISTENERS" /* INSTANCE_LISTENERS */]: { + message: `vm.$listeners has been removed. In Vue 3, parent v-on listeners are ` + + `included in vm.$attrs and it is no longer necessary to separately use ` + + `v-on="$listeners" if you are already using v-bind="$attrs". ` + + `(Note: the Vue 3 behavior only applies if this compat config is disabled)`, + link: `https://v3.vuejs.org/guide/migration/listeners-removed.html` + }, + ["INSTANCE_SCOPED_SLOTS" /* INSTANCE_SCOPED_SLOTS */]: { + message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`, + link: `https://v3.vuejs.org/guide/migration/slots-unification.html` + }, + ["INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */]: { + message: componentName => `Component <${componentName || + 'Anonymous'}> has \`inheritAttrs: false\` but is ` + + `relying on class/style fallthrough from parent. In Vue 3, class/style ` + + `are now included in $attrs and will no longer fallthrough when ` + + `inheritAttrs is false. If you are already using v-bind="$attrs" on ` + + `component root it should render the same end result. ` + + `If you are binding $attrs to a non-root element and expecting ` + + `class/style to fallthrough on root, you will need to now manually bind ` + + `them on root via :class="$attrs.class".`, + link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html` + }, + ["OPTIONS_DATA_FN" /* OPTIONS_DATA_FN */]: { + message: `The "data" option can no longer be a plain object. ` + + `Always use a function.`, + link: `https://v3.vuejs.org/guide/migration/data-option.html` + }, + ["OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */]: { + message: (key) => `Detected conflicting key "${key}" when merging data option values. ` + + `In Vue 3, data keys are merged shallowly and will override one another.`, + link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change` + }, + ["OPTIONS_BEFORE_DESTROY" /* OPTIONS_BEFORE_DESTROY */]: { + message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.` + }, + ["OPTIONS_DESTROYED" /* OPTIONS_DESTROYED */]: { + message: `\`destroyed\` has been renamed to \`unmounted\`.` + }, + ["WATCH_ARRAY" /* WATCH_ARRAY */]: { + message: `"watch" option or vm.$watch on an array value will no longer ` + + `trigger on array mutation unless the "deep" option is specified. ` + + `If current usage is intended, you can disable the compat behavior and ` + + `suppress this warning with:` + + `\n\n configureCompat({ ${"WATCH_ARRAY" /* WATCH_ARRAY */}: false })\n`, + link: `https://v3.vuejs.org/guide/migration/watch.html` + }, + ["PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */]: { + message: (key) => `props default value function no longer has access to "this". The compat ` + + `build only offers access to this.$options.` + + `(found in prop "${key}")`, + link: `https://v3.vuejs.org/guide/migration/props-default-this.html` + }, + ["CUSTOM_DIR" /* CUSTOM_DIR */]: { + message: (legacyHook, newHook) => `Custom directive hook "${legacyHook}" has been removed. ` + + `Use "${newHook}" instead.`, + link: `https://v3.vuejs.org/guide/migration/custom-directives.html` + }, + ["V_FOR_REF" /* V_FOR_REF */]: { + message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` + + `Consider using function refs or refactor to avoid ref usage altogether.`, + link: `https://v3.vuejs.org/guide/migration/array-refs.html` + }, + ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: { + message: `Using keyCode as v-on modifier is no longer supported. ` + + `Use kebab-case key name modifiers instead.`, + link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` + }, + ["ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */]: { + message: (name) => `Attribute "${name}" with v-bind value \`false\` will render ` + + `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` + + `use \`null\` or \`undefined\` instead. If the usage is intended, ` + + `you can disable the compat behavior and suppress this warning with:` + + `\n\n configureCompat({ ${"ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */}: false })\n`, + link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` + }, + ["ATTR_ENUMERATED_COERSION" /* ATTR_ENUMERATED_COERSION */]: { + message: (name, value, coerced) => `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` + + `${value === null ? `be removed` : `render the value as-is`} instead of coercing the value to "${coerced}" in Vue 3. ` + + `Always use explicit "true" or "false" values for enumerated attributes. ` + + `If the usage is intended, ` + + `you can disable the compat behavior and suppress this warning with:` + + `\n\n configureCompat({ ${"ATTR_ENUMERATED_COERSION" /* ATTR_ENUMERATED_COERSION */}: false })\n`, + link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` + }, + ["TRANSITION_CLASSES" /* TRANSITION_CLASSES */]: { + message: `` // this feature cannot be runtime-detected + }, + ["TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */]: { + message: ` no longer renders a root element by ` + + `default if no "tag" prop is specified. If you do not rely on the span ` + + `for styling, you can disable the compat behavior and suppress this ` + + `warning with:` + + `\n\n configureCompat({ ${"TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */}: false })\n`, + link: `https://v3.vuejs.org/guide/migration/transition-group.html` + }, + ["COMPONENT_ASYNC" /* COMPONENT_ASYNC */]: { + message: (comp) => { + const name = getComponentName(comp); + return (`Async component${name ? ` <${name}>` : `s`} should be explicitly created via \`defineAsyncComponent()\` ` + + `in Vue 3. Plain functions will be treated as functional components in ` + + `non-compat build. If you have already migrated all async component ` + + `usage and intend to use plain functions for functional components, ` + + `you can disable the compat behavior and suppress this ` + + `warning with:` + + `\n\n configureCompat({ ${"COMPONENT_ASYNC" /* COMPONENT_ASYNC */}: false })\n`); + }, + link: `https://v3.vuejs.org/guide/migration/async-components.html` + }, + ["COMPONENT_FUNCTIONAL" /* COMPONENT_FUNCTIONAL */]: { + message: (comp) => { + const name = getComponentName(comp); + return (`Functional component${name ? ` <${name}>` : `s`} should be defined as a plain function in Vue 3. The "functional" ` + + `option has been removed. NOTE: Before migrating to use plain ` + + `functions for functional components, first make sure that all async ` + + `components usage have been migrated and its compat behavior has ` + + `been disabled.`); + }, + link: `https://v3.vuejs.org/guide/migration/functional-components.html` + }, + ["COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */]: { + message: (comp) => { + const configMsg = `opt-in to ` + + `Vue 3 behavior on a per-component basis with \`compatConfig: { ${"COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */}: false }\`.`; + if (comp.props && isArray(comp.props) + ? comp.props.includes('modelValue') + : hasOwn(comp.props, 'modelValue')) { + return (`Component delcares "modelValue" prop, which is Vue 3 usage, but ` + + `is running under Vue 2 compat v-model behavior. You can ${configMsg}`); + } + return (`v-model usage on component has changed in Vue 3. Component that expects ` + + `to work with v-model should now use the "modelValue" prop and emit the ` + + `"update:modelValue" event. You can update the usage and then ${configMsg}`); + }, + link: `https://v3.vuejs.org/guide/migration/v-model.html` + }, + ["RENDER_FUNCTION" /* RENDER_FUNCTION */]: { + message: `Vue 3's render function API has changed. ` + + `You can opt-in to the new API with:` + + `\n\n configureCompat({ ${"RENDER_FUNCTION" /* RENDER_FUNCTION */}: false })\n` + + `\n (This can also be done per-component via the "compatConfig" option.)`, + link: `https://v3.vuejs.org/guide/migration/render-function-api.html` + }, + ["FILTERS" /* FILTERS */]: { + message: `filters have been removed in Vue 3. ` + + `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` + + `Use method calls or computed properties instead.`, + link: `https://v3.vuejs.org/guide/migration/filters.html` + }, + ["PRIVATE_APIS" /* PRIVATE_APIS */]: { + message: name => `"${name}" is a Vue 2 private API that no longer exists in Vue 3. ` + + `If you are seeing this warning only due to a dependency, you can ` + + `suppress this warning via { PRIVATE_APIS: 'supress-warning' }.` + } +}; +const instanceWarned = Object.create(null); +const warnCount = Object.create(null); +function warnDeprecation(key, instance, ...args) { + instance = instance || getCurrentInstance(); + // check user config + const config = getCompatConfigForKey(key, instance); + if (config === 'suppress-warning') { + return; + } + const dupKey = key + args.join(''); + let compId = instance && formatComponentName(instance, instance.type); + if (compId === 'Anonymous' && instance) { + compId = instance.uid; + } + // skip if the same warning is emitted for the same component type + const componentDupKey = dupKey + compId; + if (componentDupKey in instanceWarned) { + return; + } + instanceWarned[componentDupKey] = true; + // same warning, but different component. skip the long message and just + // log the key and count. + if (dupKey in warnCount) { + warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`); + return; + } + warnCount[dupKey] = 0; + const { message, link } = deprecationData[key]; + warn(`(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`); + if (!isCompatEnabled(key, instance)) { + console.error(`^ The above deprecation's compat behavior is disabled and will likely ` + + `lead to runtime errors.`); + } +} +const globalCompatConfig = { + MODE: 2 +}; +function configureCompat(config) { + { + validateCompatConfig(config); + } + extend(globalCompatConfig, config); +} +const seenConfigObjects = /*#__PURE__*/ new WeakSet(); +const warnedInvalidKeys = {}; +// dev only +function validateCompatConfig(config) { + if (seenConfigObjects.has(config)) { + return; + } + seenConfigObjects.add(config); + for (const key of Object.keys(config)) { + if (key !== 'MODE' && + !(key in deprecationData) && + !(key in warnedInvalidKeys)) { + if (key.startsWith('COMPILER_')) { + if (isRuntimeOnly()) { + warn(`Deprecation config "${key}" is compiler-specific and you are ` + + `running a runtime-only build of Vue. This deprecation should be ` + + `configured via compiler options in your build setup instead.` + // TODO link to migration build docs on build setup + ); + } + } + else { + warn(`Invalid deprecation config "${key}".`); + } + warnedInvalidKeys[key] = true; + } + } +} +function getCompatConfigForKey(key, instance) { + const instanceConfig = instance && instance.type.compatConfig; + if (instanceConfig && key in instanceConfig) { + return instanceConfig[key]; + } + return globalCompatConfig[key]; +} +function isCompatEnabled(key, instance, enableForBuiltIn = false) { + // skip compat for built-in components + if (!enableForBuiltIn && instance && instance.type.__isBuiltIn) { + return false; + } + const rawMode = getCompatConfigForKey('MODE', instance) || 2; + const val = getCompatConfigForKey(key, instance); + const mode = isFunction(rawMode) + ? rawMode(instance && instance.type) + : rawMode; + if (mode === 2) { + return val !== false; + } + else { + return val === true || val === 'suppress-warning'; + } +} +/** + * Use this for features that are completely removed in non-compat build. + */ +function assertCompatEnabled(key, instance, ...args) { + if (!isCompatEnabled(key, instance)) { + throw new Error(`${key} compat has been disabled.`); + } + else { + warnDeprecation(key, instance, ...args); + } +} +/** + * Use this for features where legacy usage is still possible, but will likely + * lead to runtime error if compat is disabled. (warn in all cases) + */ +function softAssertCompatEnabled(key, instance, ...args) { + { + warnDeprecation(key, instance, ...args); + } + return isCompatEnabled(key, instance); +} +/** + * Use this for features with the same syntax but with mutually exclusive + * behavior in 2 vs 3. Only warn if compat is enabled. + * e.g. render function + */ +function checkCompatEnabled(key, instance, ...args) { + const enabled = isCompatEnabled(key, instance); + if (enabled) { + warnDeprecation(key, instance, ...args); + } + return enabled; +} + +const eventRegistryMap = /*#__PURE__*/ new WeakMap(); +function getRegistry(instance) { + let events = eventRegistryMap.get(instance); + if (!events) { + eventRegistryMap.set(instance, (events = Object.create(null))); + } + return events; +} +function on(instance, event, fn) { + if (isArray(event)) { + event.forEach(e => on(instance, e, fn)); + } + else { + if (event.startsWith('hook:')) { + assertCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance, event); + } + else { + assertCompatEnabled("INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */, instance); + } + const events = getRegistry(instance); + (events[event] || (events[event] = [])).push(fn); + } + return instance.proxy; +} +function once(instance, event, fn) { + const wrapped = (...args) => { + off(instance, event, wrapped); + fn.call(instance.proxy, ...args); + }; + wrapped.fn = fn; + on(instance, event, wrapped); + return instance.proxy; +} +function off(instance, event, fn) { + assertCompatEnabled("INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */, instance); + const vm = instance.proxy; + // all + if (!event) { + eventRegistryMap.set(instance, Object.create(null)); + return vm; + } + // array of events + if (isArray(event)) { + event.forEach(e => off(instance, e, fn)); + return vm; + } + // specific event + const events = getRegistry(instance); + const cbs = events[event]; + if (!cbs) { + return vm; + } + if (!fn) { + events[event] = undefined; + return vm; + } + events[event] = cbs.filter(cb => !(cb === fn || cb.fn === fn)); + return vm; +} +function emit(instance, event, args) { + const cbs = getRegistry(instance)[event]; + if (cbs) { + callWithAsyncErrorHandling(cbs.map(cb => cb.bind(instance.proxy)), instance, 6 /* COMPONENT_EVENT_HANDLER */, args); + } + return instance.proxy; +} + +const compatModelEventPrefix = `onModelCompat:`; +const warnedTypes = new WeakSet(); +function convertLegacyVModelProps(vnode) { + const { type, shapeFlag, props, dynamicProps } = vnode; + if (shapeFlag & 6 /* COMPONENT */ && props && 'modelValue' in props) { + if (!isCompatEnabled("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, + // this is a special case where we want to use the vnode component's + // compat config instead of the current rendering instance (which is the + // parent of the component that exposes v-model) + { type })) { + return; + } + if (!warnedTypes.has(type)) { + pushWarningContext(vnode); + warnDeprecation("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, { type }, type); + popWarningContext(); + warnedTypes.add(type); + } + // v3 compiled model code -> v2 compat props + // modelValue -> value + // onUpdate:modelValue -> onModelCompat:input + const { prop = 'value', event = 'input' } = type.model || {}; + props[prop] = props.modelValue; + delete props.modelValue; + // important: update dynamic props + if (dynamicProps) { + dynamicProps[dynamicProps.indexOf('modelValue')] = prop; + } + props[compatModelEventPrefix + event] = props['onUpdate:modelValue']; + delete props['onUpdate:modelValue']; + } +} +function compatModelEmit(instance, event, args) { + if (!isCompatEnabled("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, instance)) { + return; + } + const props = instance.vnode.props; + const modelHandler = props && props[compatModelEventPrefix + event]; + if (modelHandler) { + callWithErrorHandling(modelHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); + } +} + +function emit$1(instance, event, ...rawArgs) { + const props = instance.vnode.props || EMPTY_OBJ; + { + const { emitsOptions, propsOptions: [propsOptions] } = instance; + if (emitsOptions) { + if (!(event in emitsOptions) && + !((event.startsWith('hook:') || + event.startsWith(compatModelEventPrefix)))) { + if (!propsOptions || !(toHandlerKey(event) in propsOptions)) { + warn(`Component emitted event "${event}" but it is neither declared in ` + + `the emits option nor as an "${toHandlerKey(event)}" prop.`); + } + } + else { + const validator = emitsOptions[event]; + if (isFunction(validator)) { + const isValid = validator(...rawArgs); + if (!isValid) { + warn(`Invalid event arguments: event validation failed for event "${event}".`); + } + } + } + } + } + let args = rawArgs; + const isModelListener = event.startsWith('update:'); + // for v-model update:xxx events, apply modifiers on args + const modelArg = isModelListener && event.slice(7); + if (modelArg && modelArg in props) { + const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`; + const { number, trim } = props[modifiersKey] || EMPTY_OBJ; + if (trim) { + args = rawArgs.map(a => a.trim()); + } + else if (number) { + args = rawArgs.map(toNumber); + } + } + { + devtoolsComponentEmit(instance, event, args); + } + { + const lowerCaseEvent = event.toLowerCase(); + if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) { + warn(`Event "${lowerCaseEvent}" is emitted in component ` + + `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` + + `Note that HTML attributes are case-insensitive and you cannot use ` + + `v-on to listen to camelCase events when using in-DOM templates. ` + + `You should probably use "${hyphenate(event)}" instead of "${event}".`); + } + } + let handlerName; + let handler = props[(handlerName = toHandlerKey(event))] || + // also try camelCase event handler (#2249) + props[(handlerName = toHandlerKey(camelize(event)))]; + // for v-model update:xxx events, also trigger kebab-case equivalent + // for props passed via kebab-case + if (!handler && isModelListener) { + handler = props[(handlerName = toHandlerKey(hyphenate(event)))]; + } + if (handler) { + callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); + } + const onceHandler = props[handlerName + `Once`]; + if (onceHandler) { + if (!instance.emitted) { + (instance.emitted = {})[handlerName] = true; + } + else if (instance.emitted[handlerName]) { + return; + } + callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); + } + { + compatModelEmit(instance, event, args); + return emit(instance, event, args); + } +} +function normalizeEmitsOptions(comp, appContext, asMixin = false) { + if (!appContext.deopt && comp.__emits !== undefined) { + return comp.__emits; + } + const raw = comp.emits; + let normalized = {}; + // apply mixin/extends props + let hasExtends = false; + if (!isFunction(comp)) { + const extendEmits = (raw) => { + const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); + if (normalizedFromExtend) { + hasExtends = true; + extend(normalized, normalizedFromExtend); + } + }; + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendEmits); + } + if (comp.extends) { + extendEmits(comp.extends); + } + if (comp.mixins) { + comp.mixins.forEach(extendEmits); + } + } + if (!raw && !hasExtends) { + return (comp.__emits = null); + } + if (isArray(raw)) { + raw.forEach(key => (normalized[key] = null)); + } + else { + extend(normalized, raw); + } + return (comp.__emits = normalized); +} +// Check if an incoming prop key is a declared emit event listener. +// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are +// both considered matched listeners. +function isEmitListener(options, key) { + if (!options || !isOn(key)) { + return false; + } + if (key.startsWith(compatModelEventPrefix)) { + return true; + } + key = key.slice(2).replace(/Once$/, ''); + return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) || + hasOwn(options, hyphenate(key)) || + hasOwn(options, key)); +} + +let isRenderingCompiledSlot = 0; +const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n); +/** + * Compiler runtime helper for rendering `` + * @private + */ +function renderSlot(slots, name, props = {}, +// this is not a user-facing function, so the fallback is always generated by +// the compiler and guaranteed to be a function returning an array +fallback, noSlotted) { + let slot = slots[name]; + if (slot && slot.length > 1) { + warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` + + `function. You need to mark this component with $dynamic-slots in the ` + + `parent template.`); + slot = () => []; + } + // a compiled slot disables block tracking by default to avoid manual + // invocation interfering with template-based block tracking, but in + // `renderSlot` we can be sure that it's template-based so we can force + // enable it. + isRenderingCompiledSlot++; + openBlock(); + const validSlotContent = slot && ensureValidVNode(slot(props)); + const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */ + ? 64 /* STABLE_FRAGMENT */ + : -2 /* BAIL */); + if (!noSlotted && rendered.scopeId) { + rendered.slotScopeIds = [rendered.scopeId + '-s']; + } + isRenderingCompiledSlot--; + return rendered; +} +function ensureValidVNode(vnodes) { + return vnodes.some(child => { + if (!isVNode(child)) + return true; + if (child.type === Comment) + return false; + if (child.type === Fragment && + !ensureValidVNode(child.children)) + return false; + return true; + }) + ? vnodes + : null; +} + +/** + * mark the current rendering instance for asset resolution (e.g. + * resolveComponent, resolveDirective) during render + */ +let currentRenderingInstance = null; +let currentScopeId = null; +/** + * Note: rendering calls maybe nested. The function returns the parent rendering + * instance if present, which should be restored after the render is done: + * + * ```js + * const prev = setCurrentRenderingInstance(i) + * // ...render + * setCurrentRenderingInstance(prev) + * ``` + */ +function setCurrentRenderingInstance(instance) { + const prev = currentRenderingInstance; + currentRenderingInstance = instance; + currentScopeId = (instance && instance.type.__scopeId) || null; + // v2 pre-compiled components uses _scopeId instead of __scopeId + if (!currentScopeId) { + currentScopeId = (instance && instance.type._scopeId) || null; + } + return prev; +} +/** + * Set scope id when creating hoisted vnodes. + * @private compiler helper + */ +function pushScopeId(id) { + currentScopeId = id; +} +/** + * Technically we no longer need this after 3.0.8 but we need to keep the same + * API for backwards compat w/ code generated by compilers. + * @private + */ +function popScopeId() { + currentScopeId = null; +} +/** + * Only for backwards compat + * @private + */ +const withScopeId = (_id) => withCtx; +/** + * Wrap a slot function to memoize current rendering instance + * @private compiler helper + */ +function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // true only +) { + if (!ctx) + return fn; + const renderFnWithContext = (...args) => { + // If a user calls a compiled slot inside a template expression (#1745), it + // can mess up block tracking, so by default we need to push a null block to + // avoid that. This isn't necessary if rendering a compiled ``. + if (!isRenderingCompiledSlot) { + openBlock(true /* null block that disables tracking */); + } + const prevInstance = setCurrentRenderingInstance(ctx); + const res = fn(...args); + setCurrentRenderingInstance(prevInstance); + if (!isRenderingCompiledSlot) { + closeBlock(); + } + return res; + }; + // mark this as a compiled slot function. + // this is used in vnode.ts -> normalizeChildren() to set the slot + // rendering flag. + renderFnWithContext._c = true; + if (isNonScopedSlot) { + renderFnWithContext._nonScoped = true; + } + return renderFnWithContext; +} + +/** + * dev only flag to track whether $attrs was used during render. + * If $attrs was used during render then the warning for failed attrs + * fallthrough can be suppressed. + */ +let accessedAttrs = false; +function markAttrsAccessed() { + accessedAttrs = true; +} +function renderComponentRoot(instance) { + const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance; + let result; + const prev = setCurrentRenderingInstance(instance); + { + accessedAttrs = false; + } + try { + let fallthroughAttrs; + if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { + // withProxy is a proxy with a different `has` trap only for + // runtime-compiled render functions using `with` block. + const proxyToUse = withProxy || proxy; + result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); + fallthroughAttrs = attrs; + } + else { + // functional + const render = Component; + // in dev, mark attrs accessed if optional props (attrs === props) + if (true && attrs === props) { + markAttrsAccessed(); + } + result = normalizeVNode(render.length > 1 + ? render(props, true + ? { + get attrs() { + markAttrsAccessed(); + return attrs; + }, + slots, + emit + } + : { attrs, slots, emit }) + : render(props, null /* we know it doesn't need it */)); + fallthroughAttrs = Component.props + ? attrs + : getFunctionalFallthrough(attrs); + } + // attr merging + // in dev mode, comments are preserved, and it's possible for a template + // to have comments along side the root element which makes it a fragment + let root = result; + let setRoot = undefined; + if (true && + result.patchFlag > 0 && + result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) { + ; + [root, setRoot] = getChildRoot(result); + } + if (fallthroughAttrs && Component.inheritAttrs !== false) { + const keys = Object.keys(fallthroughAttrs); + const { shapeFlag } = root; + if (keys.length) { + if (shapeFlag & 1 /* ELEMENT */ || + shapeFlag & 6 /* COMPONENT */) { + if (propsOptions && keys.some(isModelListener)) { + // If a v-model listener (onUpdate:xxx) has a corresponding declared + // prop, it indicates this component expects to handle v-model and + // it should not fallthrough. + // related: #1543, #1643, #1989 + fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions); + } + root = cloneVNode(root, fallthroughAttrs); + } + else if (true && !accessedAttrs && root.type !== Comment) { + const allAttrs = Object.keys(attrs); + const eventAttrs = []; + const extraAttrs = []; + for (let i = 0, l = allAttrs.length; i < l; i++) { + const key = allAttrs[i]; + if (isOn(key)) { + // ignore v-model handlers when they fail to fallthrough + if (!isModelListener(key)) { + // remove `on`, lowercase first letter to reflect event casing + // accurately + eventAttrs.push(key[2].toLowerCase() + key.slice(3)); + } + } + else { + extraAttrs.push(key); + } + } + if (extraAttrs.length) { + warn(`Extraneous non-props attributes (` + + `${extraAttrs.join(', ')}) ` + + `were passed to component but could not be automatically inherited ` + + `because component renders fragment or text root nodes.`); + } + if (eventAttrs.length) { + warn(`Extraneous non-emits event listeners (` + + `${eventAttrs.join(', ')}) ` + + `were passed to component but could not be automatically inherited ` + + `because component renders fragment or text root nodes. ` + + `If the listener is intended to be a component custom event listener only, ` + + `declare it using the "emits" option.`); + } + } + } + } + if (true && + isCompatEnabled("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance) && + vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ && + (root.shapeFlag & 1 /* ELEMENT */ || + root.shapeFlag & 6 /* COMPONENT */)) { + const { class: cls, style } = vnode.props || {}; + if (cls || style) { + if (true && Component.inheritAttrs === false) { + warnDeprecation("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance, getComponentName(instance.type)); + } + root = cloneVNode(root, { + class: cls, + style: style + }); + } + } + // inherit directives + if (vnode.dirs) { + if (true && !isElementRoot(root)) { + warn(`Runtime directive used on component with non-element root node. ` + + `The directives will not function as intended.`); + } + root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs; + } + // inherit transition data + if (vnode.transition) { + if (true && !isElementRoot(root)) { + warn(`Component inside renders non-element root node ` + + `that cannot be animated.`); + } + root.transition = vnode.transition; + } + if (true && setRoot) { + setRoot(root); + } + else { + result = root; + } + } + catch (err) { + blockStack.length = 0; + handleError(err, instance, 1 /* RENDER_FUNCTION */); + result = createVNode(Comment); + } + setCurrentRenderingInstance(prev); + return result; +} +/** + * dev only + * In dev mode, template root level comments are rendered, which turns the + * template into a fragment root, but we need to locate the single element + * root for attrs and scope id processing. + */ +const getChildRoot = (vnode) => { + const rawChildren = vnode.children; + const dynamicChildren = vnode.dynamicChildren; + const childRoot = filterSingleRoot(rawChildren); + if (!childRoot) { + return [vnode, undefined]; + } + const index = rawChildren.indexOf(childRoot); + const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; + const setRoot = (updatedRoot) => { + rawChildren[index] = updatedRoot; + if (dynamicChildren) { + if (dynamicIndex > -1) { + dynamicChildren[dynamicIndex] = updatedRoot; + } + else if (updatedRoot.patchFlag > 0) { + vnode.dynamicChildren = [...dynamicChildren, updatedRoot]; + } + } + }; + return [normalizeVNode(childRoot), setRoot]; +}; +function filterSingleRoot(children) { + let singleRoot; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (isVNode(child)) { + // ignore user comment + if (child.type !== Comment || child.children === 'v-if') { + if (singleRoot) { + // has more than 1 non-comment child, return now + return; + } + else { + singleRoot = child; + } + } + } + else { + return; + } + } + return singleRoot; +} +const getFunctionalFallthrough = (attrs) => { + let res; + for (const key in attrs) { + if (key === 'class' || key === 'style' || isOn(key)) { + (res || (res = {}))[key] = attrs[key]; + } + } + return res; +}; +const filterModelListeners = (attrs, props) => { + const res = {}; + for (const key in attrs) { + if (!isModelListener(key) || !(key.slice(9) in props)) { + res[key] = attrs[key]; + } + } + return res; +}; +const isElementRoot = (vnode) => { + return (vnode.shapeFlag & 6 /* COMPONENT */ || + vnode.shapeFlag & 1 /* ELEMENT */ || + vnode.type === Comment // potential v-if branch switch + ); +}; +function shouldUpdateComponent(prevVNode, nextVNode, optimized) { + const { props: prevProps, children: prevChildren, component } = prevVNode; + const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; + const emits = component.emitsOptions; + // Parent component's render function was hot-updated. Since this may have + // caused the child component's slots content to have changed, we need to + // force the child to update as well. + if ((prevChildren || nextChildren) && isHmrUpdating) { + return true; + } + // force child update for runtime directive or transition on component vnode. + if (nextVNode.dirs || nextVNode.transition) { + return true; + } + if (optimized && patchFlag >= 0) { + if (patchFlag & 1024 /* DYNAMIC_SLOTS */) { + // slot content that references values that might have changed, + // e.g. in a v-for + return true; + } + if (patchFlag & 16 /* FULL_PROPS */) { + if (!prevProps) { + return !!nextProps; + } + // presence of this flag indicates props are always non-null + return hasPropsChanged(prevProps, nextProps, emits); + } + else if (patchFlag & 8 /* PROPS */) { + const dynamicProps = nextVNode.dynamicProps; + for (let i = 0; i < dynamicProps.length; i++) { + const key = dynamicProps[i]; + if (nextProps[key] !== prevProps[key] && + !isEmitListener(emits, key)) { + return true; + } + } + } + } + else { + // this path is only taken by manually written render functions + // so presence of any children leads to a forced update + if (prevChildren || nextChildren) { + if (!nextChildren || !nextChildren.$stable) { + return true; + } + } + if (prevProps === nextProps) { + return false; + } + if (!prevProps) { + return !!nextProps; + } + if (!nextProps) { + return true; + } + return hasPropsChanged(prevProps, nextProps, emits); + } + return false; +} +function hasPropsChanged(prevProps, nextProps, emitsOptions) { + const nextKeys = Object.keys(nextProps); + if (nextKeys.length !== Object.keys(prevProps).length) { + return true; + } + for (let i = 0; i < nextKeys.length; i++) { + const key = nextKeys[i]; + if (nextProps[key] !== prevProps[key] && + !isEmitListener(emitsOptions, key)) { + return true; + } + } + return false; +} +function updateHOCHostEl({ vnode, parent }, el // HostNode +) { + while (parent && parent.subTree === vnode) { + (vnode = parent.vnode).el = el; + parent = parent.parent; + } +} + +const isSuspense = (type) => type.__isSuspense; +// Suspense exposes a component-like API, and is treated like a component +// in the compiler, but internally it's a special built-in type that hooks +// directly into the renderer. +const SuspenseImpl = { + name: 'Suspense', + // In order to make Suspense tree-shakable, we need to avoid importing it + // directly in the renderer. The renderer checks for the __isSuspense flag + // on a vnode's type and calls the `process` method, passing in renderer + // internals. + __isSuspense: true, + process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, + // platform-specific impl passed from renderer + rendererInternals) { + if (n1 == null) { + mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals); + } + else { + patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals); + } + }, + hydrate: hydrateSuspense, + create: createSuspenseBoundary +}; +// Force-casted public typing for h and TSX props inference +const Suspense = (SuspenseImpl + ); +function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) { + const { p: patch, o: { createElement } } = rendererInternals; + const hiddenContainer = createElement('div'); + const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals)); + // start mounting the content subtree in an off-dom container + patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds); + // now check if we have encountered any async deps + if (suspense.deps > 0) { + // has async + // mount the fallback tree + patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, slotScopeIds); + setActiveBranch(suspense, vnode.ssFallback); + } + else { + // Suspense has no async deps. Just resolve. + suspense.resolve(); + } +} +function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) { + const suspense = (n2.suspense = n1.suspense); + suspense.vnode = n2; + n2.el = n1.el; + const newBranch = n2.ssContent; + const newFallback = n2.ssFallback; + const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense; + if (pendingBranch) { + suspense.pendingBranch = newBranch; + if (isSameVNodeType(newBranch, pendingBranch)) { + // same root type but content may have changed. + patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + else if (isInFallback) { + patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, slotScopeIds, optimized); + setActiveBranch(suspense, newFallback); + } + } + else { + // toggled before pending tree is resolved + suspense.pendingId++; + if (isHydrating) { + // if toggled before hydration is finished, the current DOM tree is + // no longer valid. set it as the active branch so it will be unmounted + // when resolved + suspense.isHydrating = false; + suspense.activeBranch = pendingBranch; + } + else { + unmount(pendingBranch, parentComponent, suspense); + } + // increment pending ID. this is used to invalidate async callbacks + // reset suspense state + suspense.deps = 0; + // discard effects from pending branch + suspense.effects.length = 0; + // discard previous container + suspense.hiddenContainer = createElement('div'); + if (isInFallback) { + // already in fallback state + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + else { + patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, slotScopeIds, optimized); + setActiveBranch(suspense, newFallback); + } + } + else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { + // toggled "back" to current active branch + patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized); + // force resolve + suspense.resolve(true); + } + else { + // switched to a 3rd branch + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + if (suspense.deps <= 0) { + suspense.resolve(); + } + } + } + } + else { + if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { + // root did not change, just normal patch + patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized); + setActiveBranch(suspense, newBranch); + } + else { + // root node toggled + // invoke @pending event + const onPending = n2.props && n2.props.onPending; + if (isFunction(onPending)) { + onPending(); + } + // mount pending branch in off-dom container + suspense.pendingBranch = newBranch; + suspense.pendingId++; + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + if (suspense.deps <= 0) { + // incoming branch has no async deps, resolve now. + suspense.resolve(); + } + else { + const { timeout, pendingId } = suspense; + if (timeout > 0) { + setTimeout(() => { + if (suspense.pendingId === pendingId) { + suspense.fallback(newFallback); + } + }, timeout); + } + else if (timeout === 0) { + suspense.fallback(newFallback); + } + } + } + } +} +let hasWarned = false; +function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) { + /* istanbul ignore if */ + if (!hasWarned) { + hasWarned = true; + // @ts-ignore `console.info` cannot be null error + console[console.info ? 'info' : 'log'](` is an experimental feature and its API will likely change.`); + } + const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals; + const timeout = toNumber(vnode.props && vnode.props.timeout); + const suspense = { + vnode, + parent, + parentComponent, + isSVG, + container, + hiddenContainer, + anchor, + deps: 0, + pendingId: 0, + timeout: typeof timeout === 'number' ? timeout : -1, + activeBranch: null, + pendingBranch: null, + isInFallback: true, + isHydrating, + isUnmounted: false, + effects: [], + resolve(resume = false) { + { + if (!resume && !suspense.pendingBranch) { + throw new Error(`suspense.resolve() is called without a pending branch.`); + } + if (suspense.isUnmounted) { + throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`); + } + } + const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense; + if (suspense.isHydrating) { + suspense.isHydrating = false; + } + else if (!resume) { + const delayEnter = activeBranch && + pendingBranch.transition && + pendingBranch.transition.mode === 'out-in'; + if (delayEnter) { + activeBranch.transition.afterLeave = () => { + if (pendingId === suspense.pendingId) { + move(pendingBranch, container, anchor, 0 /* ENTER */); + } + }; + } + // this is initial anchor on mount + let { anchor } = suspense; + // unmount current active tree + if (activeBranch) { + // if the fallback tree was mounted, it may have been moved + // as part of a parent suspense. get the latest anchor for insertion + anchor = next(activeBranch); + unmount(activeBranch, parentComponent, suspense, true); + } + if (!delayEnter) { + // move content from off-dom container to actual container + move(pendingBranch, container, anchor, 0 /* ENTER */); + } + } + setActiveBranch(suspense, pendingBranch); + suspense.pendingBranch = null; + suspense.isInFallback = false; + // flush buffered effects + // check if there is a pending parent suspense + let parent = suspense.parent; + let hasUnresolvedAncestor = false; + while (parent) { + if (parent.pendingBranch) { + // found a pending parent suspense, merge buffered post jobs + // into that parent + parent.effects.push(...effects); + hasUnresolvedAncestor = true; + break; + } + parent = parent.parent; + } + // no pending parent suspense, flush all jobs + if (!hasUnresolvedAncestor) { + queuePostFlushCb(effects); + } + suspense.effects = []; + // invoke @resolve event + const onResolve = vnode.props && vnode.props.onResolve; + if (isFunction(onResolve)) { + onResolve(); + } + }, + fallback(fallbackVNode) { + if (!suspense.pendingBranch) { + return; + } + const { vnode, activeBranch, parentComponent, container, isSVG } = suspense; + // invoke @fallback event + const onFallback = vnode.props && vnode.props.onFallback; + if (isFunction(onFallback)) { + onFallback(); + } + const anchor = next(activeBranch); + const mountFallback = () => { + if (!suspense.isInFallback) { + return; + } + // mount the fallback tree + patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, slotScopeIds, optimized); + setActiveBranch(suspense, fallbackVNode); + }; + const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; + if (delayEnter) { + activeBranch.transition.afterLeave = mountFallback; + } + // unmount current active branch + unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now + true // shouldRemove + ); + suspense.isInFallback = true; + if (!delayEnter) { + mountFallback(); + } + }, + move(container, anchor, type) { + suspense.activeBranch && + move(suspense.activeBranch, container, anchor, type); + suspense.container = container; + }, + next() { + return suspense.activeBranch && next(suspense.activeBranch); + }, + registerDep(instance, setupRenderEffect) { + const isInPendingSuspense = !!suspense.pendingBranch; + if (isInPendingSuspense) { + suspense.deps++; + } + const hydratedEl = instance.vnode.el; + instance + .asyncDep.catch(err => { + handleError(err, instance, 0 /* SETUP_FUNCTION */); + }) + .then(asyncSetupResult => { + // retry when the setup() promise resolves. + // component may have been unmounted before resolve. + if (instance.isUnmounted || + suspense.isUnmounted || + suspense.pendingId !== instance.suspenseId) { + return; + } + // retry from this component + instance.asyncResolved = true; + const { vnode } = instance; + { + pushWarningContext(vnode); + } + handleSetupResult(instance, asyncSetupResult, false); + if (hydratedEl) { + // vnode may have been replaced if an update happened before the + // async dep is resolved. + vnode.el = hydratedEl; + } + const placeholder = !hydratedEl && instance.subTree.el; + setupRenderEffect(instance, vnode, + // component may have been moved before resolve. + // if this is not a hydration, instance.subTree will be the comment + // placeholder. + parentNode(hydratedEl || instance.subTree.el), + // anchor will not be used if this is hydration, so only need to + // consider the comment placeholder case. + hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized); + if (placeholder) { + remove(placeholder); + } + updateHOCHostEl(instance, vnode.el); + { + popWarningContext(); + } + // only decrease deps count if suspense is not already resolved + if (isInPendingSuspense && --suspense.deps === 0) { + suspense.resolve(); + } + }); + }, + unmount(parentSuspense, doRemove) { + suspense.isUnmounted = true; + if (suspense.activeBranch) { + unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove); + } + if (suspense.pendingBranch) { + unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove); + } + } + }; + return suspense; +} +function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) { + /* eslint-disable no-restricted-globals */ + const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */)); + // there are two possible scenarios for server-rendered suspense: + // - success: ssr content should be fully resolved + // - failure: ssr content should be the fallback branch. + // however, on the client we don't really know if it has failed or not + // attempt to hydrate the DOM assuming it has succeeded, but we still + // need to construct a suspense boundary first + const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized); + if (suspense.deps === 0) { + suspense.resolve(); + } + return result; + /* eslint-enable no-restricted-globals */ +} +function normalizeSuspenseChildren(vnode) { + const { shapeFlag, children } = vnode; + let content; + let fallback; + if (shapeFlag & 32 /* SLOTS_CHILDREN */) { + content = normalizeSuspenseSlot(children.default); + fallback = normalizeSuspenseSlot(children.fallback); + } + else { + content = normalizeSuspenseSlot(children); + fallback = normalizeVNode(null); + } + return { + content, + fallback + }; +} +function normalizeSuspenseSlot(s) { + if (isFunction(s)) { + s = s(); + } + if (isArray(s)) { + const singleChild = filterSingleRoot(s); + if (!singleChild) { + warn(` slots expect a single root node.`); + } + s = singleChild; + } + return normalizeVNode(s); +} +function queueEffectWithSuspense(fn, suspense) { + if (suspense && suspense.pendingBranch) { + if (isArray(fn)) { + suspense.effects.push(...fn); + } + else { + suspense.effects.push(fn); + } + } + else { + queuePostFlushCb(fn); + } +} +function setActiveBranch(suspense, branch) { + suspense.activeBranch = branch; + const { vnode, parentComponent } = suspense; + const el = (vnode.el = branch.el); + // in case suspense is the root node of a component, + // recursively update the HOC el + if (parentComponent && parentComponent.subTree === vnode) { + parentComponent.vnode.el = el; + updateHOCHostEl(parentComponent, el); + } +} + +function provide(key, value) { + if (!currentInstance) { + { + warn(`provide() can only be used inside setup().`); + } + } + else { + let provides = currentInstance.provides; + // by default an instance inherits its parent's provides object + // but when it needs to provide values of its own, it creates its + // own provides object using parent provides object as prototype. + // this way in `inject` we can simply look up injections from direct + // parent and let the prototype chain do the work. + const parentProvides = currentInstance.parent && currentInstance.parent.provides; + if (parentProvides === provides) { + provides = currentInstance.provides = Object.create(parentProvides); + } + // TS doesn't allow symbol as index type + provides[key] = value; + } +} +function inject(key, defaultValue, treatDefaultAsFactory = false) { + // fallback to `currentRenderingInstance` so that this can be called in + // a functional component + const instance = currentInstance || currentRenderingInstance; + if (instance) { + // #2400 + // to support `app.use` plugins, + // fallback to appContext's `provides` if the intance is at root + const provides = instance.parent == null + ? instance.vnode.appContext && instance.vnode.appContext.provides + : instance.parent.provides; + if (provides && key in provides) { + // TS doesn't allow symbol as index type + return provides[key]; + } + else if (arguments.length > 1) { + return treatDefaultAsFactory && isFunction(defaultValue) + ? defaultValue() + : defaultValue; + } + else { + warn(`injection "${String(key)}" not found.`); + } + } + else { + warn(`inject() can only be used inside setup() or functional components.`); + } +} + +// Simple effect. +function watchEffect(effect, options) { + return doWatch(effect, null, options); +} +// initial value for watchers to trigger on undefined initial values +const INITIAL_WATCHER_VALUE = {}; +// implementation +function watch(source, cb, options) { + if (!isFunction(cb)) { + warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` + + `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` + + `supports \`watch(source, cb, options?) signature.`); + } + return doWatch(source, cb, options); +} +function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) { + if (!cb) { + if (immediate !== undefined) { + warn(`watch() "immediate" option is only respected when using the ` + + `watch(source, callback, options?) signature.`); + } + if (deep !== undefined) { + warn(`watch() "deep" option is only respected when using the ` + + `watch(source, callback, options?) signature.`); + } + } + const warnInvalidSource = (s) => { + warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` + + `a reactive object, or an array of these types.`); + }; + let getter; + let forceTrigger = false; + let isMultiSource = false; + if (isRef(source)) { + getter = () => source.value; + forceTrigger = !!source._shallow; + } + else if (isReactive(source)) { + getter = () => source; + deep = true; + } + else if (isArray(source)) { + isMultiSource = true; + forceTrigger = source.some(isReactive); + getter = () => source.map(s => { + if (isRef(s)) { + return s.value; + } + else if (isReactive(s)) { + return traverse(s); + } + else if (isFunction(s)) { + return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */, [ + instance && instance.proxy + ]); + } + else { + warnInvalidSource(s); + } + }); + } + else if (isFunction(source)) { + if (cb) { + // getter with cb + getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */, [ + instance && instance.proxy + ]); + } + else { + // no cb -> simple effect + getter = () => { + if (instance && instance.isUnmounted) { + return; + } + if (cleanup) { + cleanup(); + } + return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]); + }; + } + } + else { + getter = NOOP; + warnInvalidSource(source); + } + // 2.x array mutation watch compat + if (cb && !deep) { + const baseGetter = getter; + getter = () => { + const val = baseGetter(); + if (isArray(val) && + checkCompatEnabled("WATCH_ARRAY" /* WATCH_ARRAY */, instance)) { + traverse(val); + } + return val; + }; + } + if (cb && deep) { + const baseGetter = getter; + getter = () => traverse(baseGetter()); + } + let cleanup; + let onInvalidate = (fn) => { + cleanup = runner.options.onStop = () => { + callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */); + }; + }; + let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE; + const job = () => { + if (!runner.active) { + return; + } + if (cb) { + // watch(source, cb) + const newValue = runner(); + if (deep || + forceTrigger || + (isMultiSource + ? newValue.some((v, i) => hasChanged(v, oldValue[i])) + : hasChanged(newValue, oldValue)) || + (isArray(newValue) && + isCompatEnabled("WATCH_ARRAY" /* WATCH_ARRAY */, instance))) { + // cleanup before running cb again + if (cleanup) { + cleanup(); + } + callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [ + newValue, + // pass undefined as the old value when it's changed for the first time + oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, + onInvalidate + ]); + oldValue = newValue; + } + } + else { + // watchEffect + runner(); + } + }; + // important: mark the job as a watcher callback so that scheduler knows + // it is allowed to self-trigger (#1727) + job.allowRecurse = !!cb; + let scheduler; + if (flush === 'sync') { + scheduler = job; + } + else if (flush === 'post') { + scheduler = () => queuePostRenderEffect(job, instance && instance.suspense); + } + else { + // default: 'pre' + scheduler = () => { + if (!instance || instance.isMounted) { + queuePreFlushCb(job); + } + else { + // with 'pre' option, the first call must happen before + // the component is mounted so it is called synchronously. + job(); + } + }; + } + const runner = effect(getter, { + lazy: true, + onTrack, + onTrigger, + scheduler + }); + recordInstanceBoundEffect(runner, instance); + // initial run + if (cb) { + if (immediate) { + job(); + } + else { + oldValue = runner(); + } + } + else if (flush === 'post') { + queuePostRenderEffect(runner, instance && instance.suspense); + } + else { + runner(); + } + return () => { + stop(runner); + if (instance) { + remove(instance.effects, runner); + } + }; +} +// this.$watch +function instanceWatch(source, value, options) { + const publicThis = this.proxy; + const getter = isString(source) + ? source.includes('.') + ? createPathGetter(publicThis, source) + : () => publicThis[source] + : source.bind(publicThis); + let cb; + if (isFunction(value)) { + cb = value; + } + else { + cb = value.handler; + options = value; + } + return doWatch(getter, cb.bind(publicThis), options, this); +} +function createPathGetter(ctx, path) { + const segments = path.split('.'); + return () => { + let cur = ctx; + for (let i = 0; i < segments.length && cur; i++) { + cur = cur[segments[i]]; + } + return cur; + }; +} +function traverse(value, seen = new Set()) { + if (!isObject(value) || seen.has(value)) { + return value; + } + seen.add(value); + if (isRef(value)) { + traverse(value.value, seen); + } + else if (isArray(value)) { + for (let i = 0; i < value.length; i++) { + traverse(value[i], seen); + } + } + else if (isSet(value) || isMap(value)) { + value.forEach((v) => { + traverse(v, seen); + }); + } + else if (isPlainObject(value)) { + for (const key in value) { + traverse(value[key], seen); + } + } + return value; +} + +function useTransitionState() { + const state = { + isMounted: false, + isLeaving: false, + isUnmounting: false, + leavingVNodes: new Map() + }; + onMounted(() => { + state.isMounted = true; + }); + onBeforeUnmount(() => { + state.isUnmounting = true; + }); + return state; +} +const TransitionHookValidator = [Function, Array]; +const BaseTransitionImpl = { + name: `BaseTransition`, + props: { + mode: String, + appear: Boolean, + persisted: Boolean, + // enter + onBeforeEnter: TransitionHookValidator, + onEnter: TransitionHookValidator, + onAfterEnter: TransitionHookValidator, + onEnterCancelled: TransitionHookValidator, + // leave + onBeforeLeave: TransitionHookValidator, + onLeave: TransitionHookValidator, + onAfterLeave: TransitionHookValidator, + onLeaveCancelled: TransitionHookValidator, + // appear + onBeforeAppear: TransitionHookValidator, + onAppear: TransitionHookValidator, + onAfterAppear: TransitionHookValidator, + onAppearCancelled: TransitionHookValidator + }, + setup(props, { slots }) { + const instance = getCurrentInstance(); + const state = useTransitionState(); + let prevTransitionKey; + return () => { + const children = slots.default && getTransitionRawChildren(slots.default(), true); + if (!children || !children.length) { + return; + } + // warn multiple elements + if (children.length > 1) { + warn(' can only be used on a single element or component. Use ' + + ' for lists.'); + } + // there's no need to track reactivity for these props so use the raw + // props for a bit better perf + const rawProps = toRaw(props); + const { mode } = rawProps; + // check mode + if (mode && !['in-out', 'out-in', 'default'].includes(mode)) { + warn(`invalid mode: ${mode}`); + } + // at this point children has a guaranteed length of 1. + const child = children[0]; + if (state.isLeaving) { + return emptyPlaceholder(child); + } + // in the case of , we need to + // compare the type of the kept-alive children. + const innerChild = getKeepAliveChild(child); + if (!innerChild) { + return emptyPlaceholder(child); + } + const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); + setTransitionHooks(innerChild, enterHooks); + const oldChild = instance.subTree; + const oldInnerChild = oldChild && getKeepAliveChild(oldChild); + let transitionKeyChanged = false; + const { getTransitionKey } = innerChild.type; + if (getTransitionKey) { + const key = getTransitionKey(); + if (prevTransitionKey === undefined) { + prevTransitionKey = key; + } + else if (key !== prevTransitionKey) { + prevTransitionKey = key; + transitionKeyChanged = true; + } + } + // handle mode + if (oldInnerChild && + oldInnerChild.type !== Comment && + (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { + const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); + // update old tree's hooks in case of dynamic transition + setTransitionHooks(oldInnerChild, leavingHooks); + // switching between different views + if (mode === 'out-in') { + state.isLeaving = true; + // return placeholder node and queue update when leave finishes + leavingHooks.afterLeave = () => { + state.isLeaving = false; + instance.update(); + }; + return emptyPlaceholder(child); + } + else if (mode === 'in-out' && innerChild.type !== Comment) { + leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { + const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); + leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; + // early removal callback + el._leaveCb = () => { + earlyRemove(); + el._leaveCb = undefined; + delete enterHooks.delayedLeave; + }; + enterHooks.delayedLeave = delayedLeave; + }; + } + } + return child; + }; + } +}; +{ + BaseTransitionImpl.__isBuiltIn = true; +} +// export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files +const BaseTransition = BaseTransitionImpl; +function getLeavingNodesForType(state, vnode) { + const { leavingVNodes } = state; + let leavingVNodesCache = leavingVNodes.get(vnode.type); + if (!leavingVNodesCache) { + leavingVNodesCache = Object.create(null); + leavingVNodes.set(vnode.type, leavingVNodesCache); + } + return leavingVNodesCache; +} +// The transition hooks are attached to the vnode as vnode.transition +// and will be called at appropriate timing in the renderer. +function resolveTransitionHooks(vnode, props, state, instance) { + const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props; + const key = String(vnode.key); + const leavingVNodesCache = getLeavingNodesForType(state, vnode); + const callHook = (hook, args) => { + hook && + callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args); + }; + const hooks = { + mode, + persisted, + beforeEnter(el) { + let hook = onBeforeEnter; + if (!state.isMounted) { + if (appear) { + hook = onBeforeAppear || onBeforeEnter; + } + else { + return; + } + } + // for same element (v-show) + if (el._leaveCb) { + el._leaveCb(true /* cancelled */); + } + // for toggled element with same key (v-if) + const leavingVNode = leavingVNodesCache[key]; + if (leavingVNode && + isSameVNodeType(vnode, leavingVNode) && + leavingVNode.el._leaveCb) { + // force early removal (not cancelled) + leavingVNode.el._leaveCb(); + } + callHook(hook, [el]); + }, + enter(el) { + let hook = onEnter; + let afterHook = onAfterEnter; + let cancelHook = onEnterCancelled; + if (!state.isMounted) { + if (appear) { + hook = onAppear || onEnter; + afterHook = onAfterAppear || onAfterEnter; + cancelHook = onAppearCancelled || onEnterCancelled; + } + else { + return; + } + } + let called = false; + const done = (el._enterCb = (cancelled) => { + if (called) + return; + called = true; + if (cancelled) { + callHook(cancelHook, [el]); + } + else { + callHook(afterHook, [el]); + } + if (hooks.delayedLeave) { + hooks.delayedLeave(); + } + el._enterCb = undefined; + }); + if (hook) { + hook(el, done); + if (hook.length <= 1) { + done(); + } + } + else { + done(); + } + }, + leave(el, remove) { + const key = String(vnode.key); + if (el._enterCb) { + el._enterCb(true /* cancelled */); + } + if (state.isUnmounting) { + return remove(); + } + callHook(onBeforeLeave, [el]); + let called = false; + const done = (el._leaveCb = (cancelled) => { + if (called) + return; + called = true; + remove(); + if (cancelled) { + callHook(onLeaveCancelled, [el]); + } + else { + callHook(onAfterLeave, [el]); + } + el._leaveCb = undefined; + if (leavingVNodesCache[key] === vnode) { + delete leavingVNodesCache[key]; + } + }); + leavingVNodesCache[key] = vnode; + if (onLeave) { + onLeave(el, done); + if (onLeave.length <= 1) { + done(); + } + } + else { + done(); + } + }, + clone(vnode) { + return resolveTransitionHooks(vnode, props, state, instance); + } + }; + return hooks; +} +// the placeholder really only handles one special case: KeepAlive +// in the case of a KeepAlive in a leave phase we need to return a KeepAlive +// placeholder with empty content to avoid the KeepAlive instance from being +// unmounted. +function emptyPlaceholder(vnode) { + if (isKeepAlive(vnode)) { + vnode = cloneVNode(vnode); + vnode.children = null; + return vnode; + } +} +function getKeepAliveChild(vnode) { + return isKeepAlive(vnode) + ? vnode.children + ? vnode.children[0] + : undefined + : vnode; +} +function setTransitionHooks(vnode, hooks) { + if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) { + setTransitionHooks(vnode.component.subTree, hooks); + } + else if (vnode.shapeFlag & 128 /* SUSPENSE */) { + vnode.ssContent.transition = hooks.clone(vnode.ssContent); + vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); + } + else { + vnode.transition = hooks; + } +} +function getTransitionRawChildren(children, keepComment = false) { + let ret = []; + let keyedFragmentCount = 0; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + // handle fragment children case, e.g. v-for + if (child.type === Fragment) { + if (child.patchFlag & 128 /* KEYED_FRAGMENT */) + keyedFragmentCount++; + ret = ret.concat(getTransitionRawChildren(child.children, keepComment)); + } + // comment placeholders should be skipped, e.g. v-if + else if (keepComment || child.type !== Comment) { + ret.push(child); + } + } + // #1126 if a transition children list contains multiple sub fragments, these + // fragments will be merged into a flat children array. Since each v-for + // fragment may contain different static bindings inside, we need to de-op + // these children to force full diffs to ensure correct behavior. + if (keyedFragmentCount > 1) { + for (let i = 0; i < ret.length; i++) { + ret[i].patchFlag = -2 /* BAIL */; + } + } + return ret; +} + +const isKeepAlive = (vnode) => vnode.type.__isKeepAlive; +class Cache { + constructor(max) { + this.max = max; + this._cache = new Map(); + this._keys = new Set(); + this._max = parseInt(max, 10); + } + get(key) { + const { _cache, _keys, _max } = this; + const cached = _cache.get(key); + if (cached) { + // make this key the freshest + _keys.delete(key); + _keys.add(key); + } + else { + _keys.add(key); + // prune oldest entry + if (_max && _keys.size > _max) { + const staleKey = _keys.values().next().value; + this.pruneCacheEntry(_cache.get(staleKey)); + this.delete(staleKey); + } + } + return cached; + } + set(key, value) { + this._cache.set(key, value); + } + delete(key) { + this._cache.delete(key); + this._keys.delete(key); + } + forEach(fn, thisArg) { + this._cache.forEach(fn.bind(thisArg)); + } +} +const KeepAliveImpl = { + name: `KeepAlive`, + // Marker for special handling inside the renderer. We are not using a === + // check directly on KeepAlive in the renderer, because importing it directly + // would prevent it from being tree-shaken. + __isKeepAlive: true, + props: { + include: [String, RegExp, Array], + exclude: [String, RegExp, Array], + max: [String, Number], + matchBy: { + type: String, + default: 'name' + }, + cache: Object + }, + setup(props, { slots }) { + const instance = getCurrentInstance(); + // KeepAlive communicates with the instantiated renderer via the + // ctx where the renderer passes in its internals, + // and the KeepAlive instance exposes activate/deactivate implementations. + // The whole point of this is to avoid importing KeepAlive directly in the + // renderer to facilitate tree-shaking. + const sharedContext = instance.ctx; + // if the internal renderer is not registered, it indicates that this is server-side rendering, + // for KeepAlive, we just need to render its children + if (!sharedContext.renderer) { + return () => slots.default && slots.default()[0]; // fixed by xxxxxx + } + if (props.cache && props.max) { + // fixed by xxxxxx + warn('The `max` prop will be ignored if you provide a custom caching strategy'); + } + const cache = props.cache || new Cache(props.max); + cache.pruneCacheEntry = pruneCacheEntry; + let current = null; + function pruneCacheEntry(cached) { + if (!current || + cached.type !== current.type || + (props.matchBy === 'key' && cached.key !== current.key)) { + unmount(cached); + } + else if (current) { + // current active instance should no longer be kept-alive. + // we can't unmount it now but it might be later, so reset its flag now. + resetShapeFlag(current); + } + } + const parentSuspense = instance.suspense; + const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext; + const storageContainer = createElement('div'); + sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { + const instance = vnode.component; + if (instance.ba) { + const currentState = instance.isDeactivated; + instance.isDeactivated = false; + invokeArrayFns(instance.ba); + instance.isDeactivated = currentState; + } + move(vnode, container, anchor, 0 /* ENTER */, parentSuspense); + // in case props have changed + patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized); + queuePostRenderEffect(() => { + instance.isDeactivated = false; + if (instance.a) { + invokeArrayFns(instance.a); + } + const vnodeHook = vnode.props && vnode.props.onVnodeMounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); + } + }, parentSuspense); + { + // Update components tree + devtoolsComponentAdded(instance); + } + }; + sharedContext.deactivate = (vnode) => { + const instance = vnode.component; + if (instance.bda) { + invokeKeepAliveHooks(instance.bda); + } + move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense); + queuePostRenderEffect(() => { + if (instance.bda) { + resetHookState(instance.bda); + } + if (instance.da) { + invokeArrayFns(instance.da); + } + const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); + } + instance.isDeactivated = true; + }, parentSuspense); + { + // Update components tree + devtoolsComponentAdded(instance); + } + }; + function unmount(vnode) { + // reset the shapeFlag so it can be properly unmounted + resetShapeFlag(vnode); + _unmount(vnode, instance, parentSuspense); + } + function pruneCache(filter) { + cache.forEach((vnode, key) => { + const name = getMatchingName(vnode, props.matchBy); + if (name && (!filter || !filter(name))) { + cache.delete(key); + pruneCacheEntry(vnode); + } + }); + } + // prune cache on include/exclude prop change + watch(() => [props.include, props.exclude, props.matchBy], ([include, exclude]) => { + include && pruneCache(name => matches(include, name)); + exclude && pruneCache(name => !matches(exclude, name)); + }, + // prune post-render after `current` has been updated + { flush: 'post', deep: true }); + // cache sub tree after render + let pendingCacheKey = null; + const cacheSubtree = () => { + // fix #1621, the pendingCacheKey could be 0 + if (pendingCacheKey != null) { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + } + }; + onMounted(cacheSubtree); + onUpdated(cacheSubtree); + onBeforeUnmount(() => { + cache.forEach((cached, key) => { + cache.delete(key); + pruneCacheEntry(cached); + const { subTree, suspense } = instance; + const vnode = getInnerChild(subTree); + if (cached.type === vnode.type && + (props.matchBy !== 'key' || cached.key === vnode.key)) { + // invoke its beforeDeactivate hook here + if (vnode.component.bda) { + invokeArrayFns(vnode.component.bda); + } + // current instance will be unmounted as part of keep-alive's unmount + resetShapeFlag(vnode); + // but invoke its deactivated hook here + const da = vnode.component.da; + da && queuePostRenderEffect(da, suspense); + return; + } + }); + }); + return () => { + pendingCacheKey = null; + if (!slots.default) { + return null; + } + const children = slots.default(); + const rawVNode = children[0]; + if (children.length > 1) { + { + warn(`KeepAlive should contain exactly one component child.`); + } + current = null; + return children; + } + else if (!isVNode(rawVNode) || + (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) && + !isSuspense(rawVNode.type))) { + current = null; + return rawVNode; + } + let vnode = getInnerChild(rawVNode); + const comp = vnode.type; + const name = getMatchingName(vnode, props.matchBy); + const { include, exclude } = props; + if ((include && (!name || !matches(include, name))) || + (exclude && name && matches(exclude, name))) { + current = vnode; + return rawVNode; + } + const key = vnode.key == null ? comp : vnode.key; + const cachedVNode = cache.get(key); + // clone vnode if it's reused because we are going to mutate it + if (vnode.el) { + vnode = cloneVNode(vnode); + if (isSuspense(rawVNode.type)) { + rawVNode.ssContent = vnode; + } + } + // #1513 it's possible for the returned vnode to be cloned due to attr + // fallthrough or scopeId, so the vnode here may not be the final vnode + // that is mounted. Instead of caching it directly, we store the pending + // key and cache `instance.subTree` (the normalized vnode) in + // beforeMount/beforeUpdate hooks. + pendingCacheKey = key; + if (cachedVNode) { + // copy over mounted state + vnode.el = cachedVNode.el; + vnode.component = cachedVNode.component; + if (vnode.transition) { + // recursively update transition hooks on subTree + setTransitionHooks(vnode, vnode.transition); + } + // avoid vnode being mounted as fresh + vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */; + } + // avoid vnode being unmounted + vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; + current = vnode; + return isSuspense(rawVNode.type) ? rawVNode : vnode; + }; + } +}; +{ + KeepAliveImpl.__isBuildIn = true; +} +// export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files +const KeepAlive = KeepAliveImpl; +function matches(pattern, name) { + if (isArray(pattern)) { + return pattern.some((p) => matches(p, name)); + } + else if (isString(pattern)) { + return pattern.split(',').indexOf(name) > -1; + } + else if (pattern.test) { + return pattern.test(name); + } + /* istanbul ignore next */ + return false; +} +function onBeforeActivate(hook, target) { + registerKeepAliveHook(hook, "ba" /* BEFORE_ACTIVATE */, target); +} +function onActivated(hook, target) { + registerKeepAliveHook(hook, "a" /* ACTIVATED */, target); +} +function onBeforeDeactivate(hook, target) { + registerKeepAliveHook(hook, "bda" /* BEFORE_DEACTIVATE */, target); +} +function onDeactivated(hook, target) { + registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target); +} +function registerKeepAliveHook(hook, type, target = currentInstance) { + // cache the deactivate branch check wrapper for injected hooks so the same + // hook can be properly deduped by the scheduler. "__wdc" stands for "with + // deactivation check". + const wrappedHook = hook.__wdc || + (hook.__wdc = () => { + // only fire the hook if the target instance is NOT in a deactivated branch. + let current = target; + while (current) { + if (current.isDeactivated) { + return; + } + current = current.parent; + } + hook(); + }); + wrappedHook.__called = false; + injectHook(type, wrappedHook, target); + // In addition to registering it on the target instance, we walk up the parent + // chain and register it on all ancestor instances that are keep-alive roots. + // This avoids the need to walk the entire component tree when invoking these + // hooks, and more importantly, avoids the need to track child components in + // arrays. + if (target) { + let current = target.parent; + while (current && current.parent) { + if (isKeepAlive(current.parent.vnode)) { + injectToKeepAliveRoot(wrappedHook, type, target, current); + } + current = current.parent; + } + } +} +function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { + // injectHook wraps the original for error handling, so make sure to remove + // the wrapped version. + const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); + onUnmounted(() => { + remove(keepAliveRoot[type], injected); + }, target); +} +function resetShapeFlag(vnode) { + let shapeFlag = vnode.shapeFlag; + if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { + shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; + } + if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { + shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */; + } + vnode.shapeFlag = shapeFlag; +} +function getInnerChild(vnode) { + return isSuspense(vnode.type) ? vnode.ssContent : vnode; +} +function getMatchingName(vnode, matchBy) { + if (matchBy === 'name') { + return getComponentName(vnode.type); + } + return String(vnode.key); +} +function invokeKeepAliveHooks(hooks) { + for (let i = 0; i < hooks.length; i++) { + const hook = hooks[i]; + if (!hook.__called) { + hook(); + hook.__called = true; + } + } +} +function resetHookState(hooks) { + hooks.forEach((hook) => (hook.__called = false)); +} + +function injectHook(type, hook, target = currentInstance, prepend = false) { + if (target) { + const hooks = target[type] || (target[type] = []); + // cache the error handling wrapper for injected hooks so the same hook + // can be properly deduped by the scheduler. "__weh" stands for "with error + // handling". + const wrappedHook = hook.__weh || + (hook.__weh = (...args) => { + if (target.isUnmounted) { + return; + } + // disable tracking inside all lifecycle hooks + // since they can potentially be called inside effects. + pauseTracking(); + // Set currentInstance during hook invocation. + // This assumes the hook does not synchronously trigger other hooks, which + // can only be false when the user does something really funky. + setCurrentInstance(target); + const res = callWithAsyncErrorHandling(hook, target, type, args); + setCurrentInstance(null); + resetTracking(); + return res; + }); + if (prepend) { + hooks.unshift(wrappedHook); + } + else { + hooks.push(wrappedHook); + } + return wrappedHook; + } + else { + const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, '')); + warn(`${apiName} is called when there is no active component instance to be ` + + `associated with. ` + + `Lifecycle injection APIs can only be used during execution of setup().` + + (` If you are using async setup(), make sure to register lifecycle ` + + `hooks before the first await statement.` + )); + } +} +const createHook = (lifecycle) => (hook, target = currentInstance) => +// post-create lifecycle registrations are noops during SSR (except for serverPrefetch) +(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) && + injectHook(lifecycle, hook, target); +const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */); +const onMounted = createHook("m" /* MOUNTED */); +const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */); +const onUpdated = createHook("u" /* UPDATED */); +const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */); +const onUnmounted = createHook("um" /* UNMOUNTED */); +const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */); +const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */); +const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */); +function onErrorCaptured(hook, target = currentInstance) { + injectHook("ec" /* ERROR_CAPTURED */, hook, target); +} + +function deepMergeData(to, from, instance) { + for (const key in from) { + const toVal = to[key]; + const fromVal = from[key]; + if (key in to && isPlainObject(toVal) && isPlainObject(fromVal)) { + warnDeprecation("OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */, instance, key); + deepMergeData(toVal, fromVal, instance); + } + else { + to[key] = fromVal; + } + } +} +function mergeDataOption(to, from) { + if (!from) { + return to; + } + if (!to) { + return from; + } + return function mergedDataFn() { + return deepMergeData(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from, this.$); + }; +} + +const COMPONENTS = 'components'; +const DIRECTIVES = 'directives'; +const FILTERS = 'filters'; +/** + * @private + */ +function resolveComponent(name, maybeSelfReference) { + return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; +} +const NULL_DYNAMIC_COMPONENT = Symbol(); +/** + * @private + */ +function resolveDynamicComponent(component) { + if (isString(component)) { + return resolveAsset(COMPONENTS, component, false) || component; + } + else { + // invalid types will fallthrough to createVNode and raise warning + return (component || NULL_DYNAMIC_COMPONENT); + } +} +/** + * @private + */ +function resolveDirective(name) { + return resolveAsset(DIRECTIVES, name); +} +/** + * v2 compat only + * @internal + */ +function resolveFilter(name) { + return resolveAsset(FILTERS, name); +} +// implementation +function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { + const instance = currentRenderingInstance || currentInstance; + if (instance) { + const Component = instance.type; + // explicit self name has highest priority + if (type === COMPONENTS) { + const selfName = getComponentName(Component); + if (selfName && + (selfName === name || + selfName === camelize(name) || + selfName === capitalize(camelize(name)))) { + return Component; + } + } + const res = + // local registration + // check instance[type] first for components with mixin or extends. + resolve(instance[type] || Component[type], name) || + // global registration + resolve(instance.appContext[type], name); + if (!res && maybeSelfReference) { + // fallback to implicit self-reference + return Component; + } + if (warnMissing && !res) { + warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`); + } + return res; + } + else { + warn(`resolve${capitalize(type.slice(0, -1))} ` + + `can only be used in render() or setup().`); + } +} +function resolve(registry, name) { + return (registry && + (registry[name] || + registry[camelize(name)] || + registry[capitalize(camelize(name))])); +} + +function createDuplicateChecker() { + const cache = Object.create(null); + return (type, key) => { + if (cache[key]) { + warn(`${type} property "${key}" is already defined in ${cache[key]}.`); + } + else { + cache[key] = type; + } + }; +} +let shouldCacheAccess = true; +function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) { + if (isFunction(options)) { + options = options.options; + } + const { + // composition + mixins, extends: extendsOptions, + // state + data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, + // lifecycle + beforeMount, mounted, beforeUpdate, updated, beforeActivate, activated, beforeDeactivate, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch, + // public API + expose } = options; + const publicThis = instance.proxy; + const ctx = instance.ctx; + const globalMixins = instance.appContext.mixins; + if (asMixin && render && instance.render === NOOP) { + instance.render = render; + } + // fixed by xxxxxx + const customApplyOptions = ctx.$applyOptions; + if (customApplyOptions) { + customApplyOptions(options, instance, publicThis); + } + // applyOptions is called non-as-mixin once per instance + if (!asMixin) { + shouldCacheAccess = false; + callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins); + shouldCacheAccess = true; + // global mixins are applied first + applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide); + } + // extending a base component... + if (extendsOptions) { + applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true); + } + // local mixins + if (mixins) { + applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide); + } + const checkDuplicateProperties = createDuplicateChecker() ; + { + const [propsOptions] = instance.propsOptions; + if (propsOptions) { + for (const key in propsOptions) { + checkDuplicateProperties("Props" /* PROPS */, key); + } + } + } + // options initialization order (to be consistent with Vue 2): + // - props (already done outside of this function) + // - inject + // - methods + // - data (deferred since it relies on `this` access) + // - computed + // - watch (deferred since it relies on `this` access) + if (injectOptions) { + resolveInjections(injectOptions, ctx, checkDuplicateProperties); + } + if (methods) { + for (const key in methods) { + const methodHandler = methods[key]; + if (isFunction(methodHandler)) { + // In dev mode, we use the `createRenderContext` function to define methods to the proxy target, + // and those are read-only but reconfigurable, so it needs to be redefined here + { + Object.defineProperty(ctx, key, { + value: methodHandler.bind(publicThis), + configurable: true, + enumerable: true, + writable: true + }); + } + { + checkDuplicateProperties("Methods" /* METHODS */, key); + } + } + else { + warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` + + `Did you reference the function correctly?`); + } + } + } + if (!asMixin) { + if (deferredData.length) { + deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis)); + } + if (dataOptions) { + // @ts-ignore dataOptions is not fully type safe + resolveData(instance, dataOptions, publicThis); + } + { + const rawData = toRaw(instance.data); + for (const key in rawData) { + checkDuplicateProperties("Data" /* DATA */, key); + // expose data on ctx during dev + if (key[0] !== '$' && key[0] !== '_') { + Object.defineProperty(ctx, key, { + configurable: true, + enumerable: true, + get: () => rawData[key], + set: NOOP + }); + } + } + } + } + else if (dataOptions) { + deferredData.push(dataOptions); + } + if (computedOptions) { + for (const key in computedOptions) { + const opt = computedOptions[key]; + const get = isFunction(opt) + ? opt.bind(publicThis, publicThis) + : isFunction(opt.get) + ? opt.get.bind(publicThis, publicThis) + : NOOP; + if (get === NOOP) { + warn(`Computed property "${key}" has no getter.`); + } + const set = !isFunction(opt) && isFunction(opt.set) + ? opt.set.bind(publicThis) + : () => { + warn(`Write operation failed: computed property "${key}" is readonly.`); + } + ; + const c = computed$1({ + get, + set + }); + Object.defineProperty(ctx, key, { + enumerable: true, + configurable: true, + get: () => c.value, + set: v => (c.value = v) + }); + { + checkDuplicateProperties("Computed" /* COMPUTED */, key); + } + } + } + if (watchOptions) { + deferredWatch.push(watchOptions); + } + if (!asMixin && deferredWatch.length) { + deferredWatch.forEach(watchOptions => { + for (const key in watchOptions) { + createWatcher(watchOptions[key], ctx, publicThis, key); + } + }); + } + if (provideOptions) { + deferredProvide.push(provideOptions); + } + if (!asMixin && deferredProvide.length) { + deferredProvide.forEach(provideOptions => { + const provides = isFunction(provideOptions) + ? provideOptions.call(publicThis) + : provideOptions; + Reflect.ownKeys(provides).forEach(key => { + provide(key, provides[key]); + }); + }); + } + // asset options. + // To reduce memory usage, only components with mixins or extends will have + // resolved asset registry attached to instance. + if (asMixin) { + resolveInstanceAssets(instance, options, COMPONENTS); + resolveInstanceAssets(instance, options, DIRECTIVES); + if (isCompatEnabled("FILTERS" /* FILTERS */, instance)) { + resolveInstanceAssets(instance, options, FILTERS); + } + } + // lifecycle options + if (!asMixin) { + callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins); + } + if (beforeMount) { + onBeforeMount(beforeMount.bind(publicThis)); + } + if (mounted) { + onMounted(mounted.bind(publicThis)); + } + if (beforeUpdate) { + onBeforeUpdate(beforeUpdate.bind(publicThis)); + } + if (updated) { + onUpdated(updated.bind(publicThis)); + } + if (beforeActivate) { + onBeforeActivate(beforeActivate.bind(publicThis)); + } + if (activated) { + onActivated(activated.bind(publicThis)); + } + if (beforeDeactivate) { + onBeforeDeactivate(beforeDeactivate.bind(publicThis)); + } + if (deactivated) { + onDeactivated(deactivated.bind(publicThis)); + } + if (errorCaptured) { + onErrorCaptured(errorCaptured.bind(publicThis)); + } + if (renderTracked) { + onRenderTracked(renderTracked.bind(publicThis)); + } + if (renderTriggered) { + onRenderTriggered(renderTriggered.bind(publicThis)); + } + if (beforeUnmount) { + onBeforeUnmount(beforeUnmount.bind(publicThis)); + } + if (unmounted) { + onUnmounted(unmounted.bind(publicThis)); + } + if (serverPrefetch) { + onServerPrefetch(serverPrefetch.bind(publicThis)); + } + { + if (beforeDestroy && + softAssertCompatEnabled("OPTIONS_BEFORE_DESTROY" /* OPTIONS_BEFORE_DESTROY */, instance)) { + onBeforeUnmount(beforeDestroy.bind(publicThis)); + } + if (destroyed && + softAssertCompatEnabled("OPTIONS_DESTROYED" /* OPTIONS_DESTROYED */, instance)) { + onUnmounted(destroyed.bind(publicThis)); + } + } + if (isArray(expose)) { + if (!asMixin) { + if (expose.length) { + const exposed = instance.exposed || (instance.exposed = proxyRefs({})); + expose.forEach(key => { + exposed[key] = toRef(publicThis, key); + }); + } + else if (!instance.exposed) { + instance.exposed = EMPTY_OBJ; + } + } + else { + warn(`The \`expose\` option is ignored when used in mixins.`); + } + } +} +function resolveInstanceAssets(instance, mixin, type) { + if (mixin[type]) { + extend(instance[type] || + (instance[type] = extend({}, instance.type[type])), mixin[type]); + } +} +function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP) { + if (isArray(injectOptions)) { + for (let i = 0; i < injectOptions.length; i++) { + const key = injectOptions[i]; + ctx[key] = inject(key); + { + checkDuplicateProperties("Inject" /* INJECT */, key); + } + } + } + else { + for (const key in injectOptions) { + const opt = injectOptions[key]; + if (isObject(opt)) { + ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */); + } + else { + ctx[key] = inject(opt); + } + { + checkDuplicateProperties("Inject" /* INJECT */, key); + } + } + } +} +function callSyncHook(name, type, options, instance, globalMixins) { + for (let i = 0; i < globalMixins.length; i++) { + callHookWithMixinAndExtends(name, type, globalMixins[i], instance); + } + callHookWithMixinAndExtends(name, type, options, instance); +} +function callHookWithMixinAndExtends(name, type, options, instance) { + const { extends: base, mixins } = options; + const selfHook = options[name]; + if (base) { + callHookWithMixinAndExtends(name, type, base, instance); + } + if (mixins) { + for (let i = 0; i < mixins.length; i++) { + callHookWithMixinAndExtends(name, type, mixins[i], instance); + } + } + if (selfHook) { + callWithAsyncErrorHandling(isArray(selfHook) + ? selfHook.map(h => h.bind(instance.proxy)) + : selfHook.bind(instance.proxy), instance, type); + } +} +function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) { + for (let i = 0; i < mixins.length; i++) { + applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true); + } +} +function resolveData(instance, dataFn, publicThis) { + if (!isFunction(dataFn)) { + warn(`The data option must be a function. ` + + `Plain object usage is no longer supported.`); + } + shouldCacheAccess = false; + const data = dataFn.call(publicThis, publicThis); + shouldCacheAccess = true; + if (isPromise(data)) { + warn(`data() returned a Promise - note data() cannot be async; If you ` + + `intend to perform data fetching before component renders, use ` + + `async setup() + .`); + } + if (!isObject(data)) { + warn(`data() should return an object.`); + } + else if (instance.data === EMPTY_OBJ) { + instance.data = reactive(data); + } + else { + // existing data: this is a mixin or extends. + if (isCompatEnabled("OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */, instance)) { + deepMergeData(instance.data, data, instance); + } + else { + extend(instance.data, data); + } + } +} +function createWatcher(raw, ctx, publicThis, key) { + const getter = key.includes('.') + ? createPathGetter(publicThis, key) + : () => publicThis[key]; + if (isString(raw)) { + const handler = ctx[raw]; + if (isFunction(handler)) { + watch(getter, handler); + } + else { + warn(`Invalid watch handler specified by key "${raw}"`, handler); + } + } + else if (isFunction(raw)) { + watch(getter, raw.bind(publicThis)); + } + else if (isObject(raw)) { + if (isArray(raw)) { + raw.forEach(r => createWatcher(r, ctx, publicThis, key)); + } + else { + const handler = isFunction(raw.handler) + ? raw.handler.bind(publicThis) + : ctx[raw.handler]; + if (isFunction(handler)) { + watch(getter, handler, raw); + } + else { + warn(`Invalid watch handler specified by key "${raw.handler}"`, handler); + } + } + } + else { + warn(`Invalid watch option: "${key}"`, raw); + } +} +function resolveMergedOptions(instance) { + const raw = instance.type; + const { __merged, mixins, extends: extendsOptions } = raw; + if (__merged) + return __merged; + const globalMixins = instance.appContext.mixins; + if (!globalMixins.length && !mixins && !extendsOptions) + return raw; + const options = {}; + globalMixins.forEach(m => mergeOptions(options, m, instance)); + mergeOptions(options, raw, instance); + return (raw.__merged = options); +} +function mergeOptions(to, from, instance, strats = instance && instance.appContext.config.optionMergeStrategies) { + if (isFunction(from)) { + from = from.options; + } + const { mixins, extends: extendsOptions } = from; + extendsOptions && mergeOptions(to, extendsOptions, instance, strats); + mixins && + mixins.forEach((m) => mergeOptions(to, m, instance, strats)); + for (const key in from) { + if (strats && hasOwn(strats, key)) { + to[key] = strats[key](to[key], from[key], instance && instance.proxy, key); + } + else { + to[key] = from[key]; + } + } + return to; +} + +function createPropsDefaultThis(instance, rawProps, propKey) { + return new Proxy({}, { + get(_, key) { + warnDeprecation("PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */, null, propKey); + // $options + if (key === '$options') { + return resolveMergedOptions(instance); + } + // props + if (key in rawProps) { + return rawProps[key]; + } + // injections + const injections = instance.type.inject; + if (injections) { + if (isArray(injections)) { + if (injections.includes(key)) { + return inject(key); + } + } + else if (key in injections) { + return inject(key); + } + } + } + }); +} + +function shouldSkipAttr(key, instance) { + if (key === 'is') { + return true; + } + if ((key === 'class' || key === 'style') && + isCompatEnabled("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance)) { + return true; + } + if (isOn(key) && + isCompatEnabled("INSTANCE_LISTENERS" /* INSTANCE_LISTENERS */, instance)) { + return true; + } + // vue-router + if (key.startsWith('routerView') || key === 'registerRouteInstance') { + return true; + } + return false; +} + +function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison +isSSR = false) { + const props = {}; + const attrs = {}; + def(attrs, InternalObjectKey, 1); + instance.propsDefaults = Object.create(null); + setFullProps(instance, rawProps, props, attrs); + // ensure all declared prop keys are present + for (const key in instance.propsOptions[0]) { + if (!(key in props)) { + props[key] = undefined; + } + } + // validation + { + validateProps(rawProps || {}, props, instance); + } + if (isStateful) { + // stateful + instance.props = isSSR ? props : shallowReactive(props); + } + else { + if (!instance.type.props) { + // functional w/ optional props, props === attrs + instance.props = attrs; + } + else { + // functional w/ declared props + instance.props = props; + } + } + instance.attrs = attrs; +} +function updateProps(instance, rawProps, rawPrevProps, optimized) { + const { props, attrs, vnode: { patchFlag } } = instance; + const rawCurrentProps = toRaw(props); + const [options] = instance.propsOptions; + let hasAttrsChanged = false; + if ( + // always force full diff in dev + // - #1942 if hmr is enabled with sfc component + // - vite#872 non-sfc component used by sfc component + !((instance.type.__hmrId || + (instance.parent && instance.parent.type.__hmrId))) && + (optimized || patchFlag > 0) && + !(patchFlag & 16 /* FULL_PROPS */)) { + if (patchFlag & 8 /* PROPS */) { + // Compiler-generated props & no keys change, just set the updated + // the props. + const propsToUpdate = instance.vnode.dynamicProps; + for (let i = 0; i < propsToUpdate.length; i++) { + let key = propsToUpdate[i]; + // PROPS flag guarantees rawProps to be non-null + const value = rawProps[key]; + if (options) { + // attr / props separation was done on init and will be consistent + // in this code path, so just check if attrs have it. + if (hasOwn(attrs, key)) { + if (value !== attrs[key]) { + attrs[key] = value; + hasAttrsChanged = true; + } + } + else { + const camelizedKey = camelize(key); + props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance); + } + } + else { + { + if (isOn(key) && key.endsWith('Native')) { + key = key.slice(0, -6); // remove Native postfix + } + else if (shouldSkipAttr(key, instance)) { + continue; + } + } + if (value !== attrs[key]) { + attrs[key] = value; + hasAttrsChanged = true; + } + } + } + } + } + else { + // full props update. + if (setFullProps(instance, rawProps, props, attrs)) { + hasAttrsChanged = true; + } + // in case of dynamic props, check if we need to delete keys from + // the props object + let kebabKey; + for (const key in rawCurrentProps) { + if (!rawProps || + // for camelCase + (!hasOwn(rawProps, key) && + // it's possible the original props was passed in as kebab-case + // and converted to camelCase (#955) + ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) { + if (options) { + if (rawPrevProps && + // for camelCase + (rawPrevProps[key] !== undefined || + // for kebab-case + rawPrevProps[kebabKey] !== undefined)) { + props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance); + } + } + else { + delete props[key]; + } + } + } + // in the case of functional component w/o props declaration, props and + // attrs point to the same object so it should already have been updated. + if (attrs !== rawCurrentProps) { + for (const key in attrs) { + if (!rawProps || !hasOwn(rawProps, key)) { + delete attrs[key]; + hasAttrsChanged = true; + } + } + } + } + // trigger updates for $attrs in case it's used in component slots + if (hasAttrsChanged) { + trigger(instance, "set" /* SET */, '$attrs'); + } + { + validateProps(rawProps || {}, props, instance); + } +} +function setFullProps(instance, rawProps, props, attrs) { + const [options, needCastKeys] = instance.propsOptions; + let hasAttrsChanged = false; + if (rawProps) { + for (let key in rawProps) { + // key, ref are reserved and never passed down + if (isReservedProp(key)) { + continue; + } + { + if (key.startsWith('onHook:')) { + softAssertCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance, key.slice(2).toLowerCase()); + } + if (key === 'inline-template') { + continue; + } + } + const value = rawProps[key]; + // prop option names are camelized during normalization, so to support + // kebab -> camel conversion here we need to camelize the key. + let camelKey; + if (options && hasOwn(options, (camelKey = camelize(key)))) { + props[camelKey] = value; + } + else if (!isEmitListener(instance.emitsOptions, key)) { + // Any non-declared (either as a prop or an emitted event) props are put + // into a separate `attrs` object for spreading. Make sure to preserve + // original key casing + { + if (isOn(key) && key.endsWith('Native')) { + key = key.slice(0, -6); // remove Native postfix + } + else if (shouldSkipAttr(key, instance)) { + continue; + } + } + if (value !== attrs[key]) { + attrs[key] = value; + hasAttrsChanged = true; + } + } + } + } + if (needCastKeys) { + const rawCurrentProps = toRaw(props); + for (let i = 0; i < needCastKeys.length; i++) { + const key = needCastKeys[i]; + props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance); + } + } + return hasAttrsChanged; +} +function resolvePropValue(options, props, key, value, instance) { + const opt = options[key]; + if (opt != null) { + const hasDefault = hasOwn(opt, 'default'); + // default values + if (hasDefault && value === undefined) { + const defaultValue = opt.default; + if (opt.type !== Function && isFunction(defaultValue)) { + const { propsDefaults } = instance; + if (key in propsDefaults) { + value = propsDefaults[key]; + } + else { + setCurrentInstance(instance); + value = propsDefaults[key] = defaultValue.call(isCompatEnabled("PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */, instance) + ? createPropsDefaultThis(instance, props, key) + : null, props); + setCurrentInstance(null); + } + } + else { + value = defaultValue; + } + } + // boolean casting + if (opt[0 /* shouldCast */]) { + if (!hasOwn(props, key) && !hasDefault) { + value = false; + } + else if (opt[1 /* shouldCastTrue */] && + (value === '' || value === hyphenate(key))) { + value = true; + } + } + } + return value; +} +function normalizePropsOptions(comp, appContext, asMixin = false) { + if (!appContext.deopt && comp.__props) { + return comp.__props; + } + const raw = comp.props; + const normalized = {}; + const needCastKeys = []; + // apply mixin/extends props + let hasExtends = false; + if (!isFunction(comp)) { + const extendProps = (raw) => { + if (isFunction(raw)) { + raw = raw.options; + } + hasExtends = true; + const [props, keys] = normalizePropsOptions(raw, appContext, true); + extend(normalized, props); + if (keys) + needCastKeys.push(...keys); + }; + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendProps); + } + if (comp.extends) { + extendProps(comp.extends); + } + if (comp.mixins) { + comp.mixins.forEach(extendProps); + } + } + if (!raw && !hasExtends) { + return (comp.__props = EMPTY_ARR); + } + if (isArray(raw)) { + for (let i = 0; i < raw.length; i++) { + if (!isString(raw[i])) { + warn(`props must be strings when using array syntax.`, raw[i]); + } + const normalizedKey = camelize(raw[i]); + if (validatePropName(normalizedKey)) { + normalized[normalizedKey] = EMPTY_OBJ; + } + } + } + else if (raw) { + if (!isObject(raw)) { + warn(`invalid props options`, raw); + } + for (const key in raw) { + const normalizedKey = camelize(key); + if (validatePropName(normalizedKey)) { + const opt = raw[key]; + const prop = (normalized[normalizedKey] = + isArray(opt) || isFunction(opt) ? { type: opt } : opt); + if (prop) { + const booleanIndex = getTypeIndex(Boolean, prop.type); + const stringIndex = getTypeIndex(String, prop.type); + prop[0 /* shouldCast */] = booleanIndex > -1; + prop[1 /* shouldCastTrue */] = + stringIndex < 0 || booleanIndex < stringIndex; + // if the prop needs boolean casting or default value + if (booleanIndex > -1 || hasOwn(prop, 'default')) { + needCastKeys.push(normalizedKey); + } + } + } + } + } + return (comp.__props = [normalized, needCastKeys]); +} +function validatePropName(key) { + if (key[0] !== '$') { + return true; + } + else { + warn(`Invalid prop name: "${key}" is a reserved property.`); + } + return false; +} +// use function string name to check type constructors +// so that it works across vms / iframes. +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ''; +} +function isSameType(a, b) { + return getType(a) === getType(b); +} +function getTypeIndex(type, expectedTypes) { + if (isArray(expectedTypes)) { + return expectedTypes.findIndex(t => isSameType(t, type)); + } + else if (isFunction(expectedTypes)) { + return isSameType(expectedTypes, type) ? 0 : -1; + } + return -1; +} +/** + * dev only + */ +function validateProps(rawProps, props, instance) { + const resolvedValues = toRaw(props); + const options = instance.propsOptions[0]; + for (const key in options) { + let opt = options[key]; + if (opt == null) + continue; + validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key))); + } +} +/** + * dev only + */ +function validateProp(name, value, prop, isAbsent) { + const { type, required, validator } = prop; + // required! + if (required && isAbsent) { + warn('Missing required prop: "' + name + '"'); + return; + } + // missing but optional + if (value == null && !prop.required) { + return; + } + // type check + if (type != null && type !== true) { + let isValid = false; + const types = isArray(type) ? type : [type]; + const expectedTypes = []; + // value is valid as long as one of the specified types match + for (let i = 0; i < types.length && !isValid; i++) { + const { valid, expectedType } = assertType(value, types[i]); + expectedTypes.push(expectedType || ''); + isValid = valid; + } + if (!isValid) { + warn(getInvalidTypeMessage(name, value, expectedTypes)); + return; + } + } + // custom validator + if (validator && !validator(value)) { + warn('Invalid prop: custom validator check failed for prop "' + name + '".'); + } +} +const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt'); +/** + * dev only + */ +function assertType(value, type) { + let valid; + const expectedType = getType(type); + if (isSimpleType(expectedType)) { + const t = typeof value; + valid = t === expectedType.toLowerCase(); + // for primitive wrapper objects + if (!valid && t === 'object') { + valid = value instanceof type; + } + } + else if (expectedType === 'Object') { + valid = isObject(value); + } + else if (expectedType === 'Array') { + valid = isArray(value); + } + else { + valid = value instanceof type; + } + return { + valid, + expectedType + }; +} +/** + * dev only + */ +function getInvalidTypeMessage(name, value, expectedTypes) { + let message = `Invalid prop: type check failed for prop "${name}".` + + ` Expected ${expectedTypes.map(capitalize).join(', ')}`; + const expectedType = expectedTypes[0]; + const receivedType = toRawType(value); + const expectedValue = styleValue(value, expectedType); + const receivedValue = styleValue(value, receivedType); + // check if we need to specify expected value + if (expectedTypes.length === 1 && + isExplicable(expectedType) && + !isBoolean(expectedType, receivedType)) { + message += ` with value ${expectedValue}`; + } + message += `, got ${receivedType} `; + // check if we need to specify received value + if (isExplicable(receivedType)) { + message += `with value ${receivedValue}.`; + } + return message; +} +/** + * dev only + */ +function styleValue(value, type) { + if (type === 'String') { + return `"${value}"`; + } + else if (type === 'Number') { + return `${Number(value)}`; + } + else { + return `${value}`; + } +} +/** + * dev only + */ +function isExplicable(type) { + const explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some(elem => type.toLowerCase() === elem); +} +/** + * dev only + */ +function isBoolean(...args) { + return args.some(elem => elem.toLowerCase() === 'boolean'); +} + +const isInternalKey = (key) => key[0] === '_' || key === '$stable'; +const normalizeSlotValue = (value) => isArray(value) + ? value.map(normalizeVNode) + : [normalizeVNode(value)]; +const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => { + if (currentInstance) { + warn(`Slot "${key}" invoked outside of the render function: ` + + `this will not track dependencies used in the slot. ` + + `Invoke the slot function inside the render function instead.`); + } + return normalizeSlotValue(rawSlot(props)); +}, ctx); +const normalizeObjectSlots = (rawSlots, slots, instance) => { + const ctx = rawSlots._ctx; + for (const key in rawSlots) { + if (isInternalKey(key)) + continue; + const value = rawSlots[key]; + if (isFunction(value)) { + slots[key] = normalizeSlot(key, value, ctx); + } + else if (value != null) { + if (!(isCompatEnabled("RENDER_FUNCTION" /* RENDER_FUNCTION */, instance))) { + warn(`Non-function value encountered for slot "${key}". ` + + `Prefer function slots for better performance.`); + } + const normalized = normalizeSlotValue(value); + slots[key] = () => normalized; + } + } +}; +const normalizeVNodeSlots = (instance, children) => { + if (!isKeepAlive(instance.vnode) && + !(isCompatEnabled("RENDER_FUNCTION" /* RENDER_FUNCTION */, instance))) { + warn(`Non-function value encountered for default slot. ` + + `Prefer function slots for better performance.`); + } + const normalized = normalizeSlotValue(children); + instance.slots.default = () => normalized; +}; +const initSlots = (instance, children) => { + if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { + const type = children._; + if (type) { + instance.slots = children; + // make compiler marker non-enumerable + def(children, '_', type); + } + else { + normalizeObjectSlots(children, (instance.slots = {}), instance); + } + } + else { + instance.slots = {}; + if (children) { + normalizeVNodeSlots(instance, children); + } + } + def(instance.slots, InternalObjectKey, 1); +}; +const updateSlots = (instance, children, optimized) => { + const { vnode, slots } = instance; + let needDeletionCheck = true; + let deletionComparisonTarget = EMPTY_OBJ; + if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { + const type = children._; + if (type) { + // compiled slots. + if (isHmrUpdating) { + // Parent was HMR updated so slot content may have changed. + // force update slots and mark instance for hmr as well + extend(slots, children); + } + else if (optimized && type === 1 /* STABLE */) { + // compiled AND stable. + // no need to update, and skip stale slots removal. + needDeletionCheck = false; + } + else { + // compiled but dynamic (v-if/v-for on slots) - update slots, but skip + // normalization. + extend(slots, children); + // #2893 + // when rendering the optimized slots by manually written render function, + // we need to delete the `slots._` flag if necessary to make subsequent updates reliable, + // i.e. let the `renderSlot` create the bailed Fragment + if (!optimized && type === 1 /* STABLE */) { + delete slots._; + } + } + } + else { + needDeletionCheck = !children.$stable; + normalizeObjectSlots(children, slots, instance); + } + deletionComparisonTarget = children; + } + else if (children) { + // non slot object children (direct value) passed to a component + normalizeVNodeSlots(instance, children); + deletionComparisonTarget = { default: 1 }; + } + // delete stale slots + if (needDeletionCheck) { + for (const key in slots) { + if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { + delete slots[key]; + } + } + } +}; + +const legacyDirectiveHookMap = { + beforeMount: 'bind', + mounted: 'inserted', + updated: ['update', 'componentUpdated'], + unmounted: 'unbind' +}; +function mapCompatDirectiveHook(name, dir, instance) { + const mappedName = legacyDirectiveHookMap[name]; + if (mappedName) { + if (isArray(mappedName)) { + const hook = []; + mappedName.forEach(mapped => { + const mappedHook = dir[mapped]; + if (mappedHook) { + softAssertCompatEnabled("CUSTOM_DIR" /* CUSTOM_DIR */, instance, mapped, name); + hook.push(mappedHook); + } + }); + return hook.length ? hook : undefined; + } + else { + if (dir[mappedName]) { + softAssertCompatEnabled("CUSTOM_DIR" /* CUSTOM_DIR */, instance, mappedName, name); + } + return dir[mappedName]; + } + } +} + +/** +Runtime helper for applying directives to a vnode. Example usage: + +const comp = resolveComponent('comp') +const foo = resolveDirective('foo') +const bar = resolveDirective('bar') + +return withDirectives(h(comp), [ + [foo, this.x], + [bar, this.y] +]) +*/ +const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text'); +function validateDirectiveName(name) { + if (isBuiltInDirective(name)) { + warn('Do not use built-in directive ids as custom directive id: ' + name); + } +} +/** + * Adds directives to a VNode. + */ +function withDirectives(vnode, directives) { + const internalInstance = currentRenderingInstance; + if (internalInstance === null) { + warn(`withDirectives can only be used inside render functions.`); + return vnode; + } + const instance = internalInstance.proxy; + const bindings = vnode.dirs || (vnode.dirs = []); + for (let i = 0; i < directives.length; i++) { + let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; + if (isFunction(dir)) { + dir = { + mounted: dir, + updated: dir + }; + } + bindings.push({ + dir, + instance, + value, + oldValue: void 0, + arg, + modifiers + }); + } + return vnode; +} +function invokeDirectiveHook(vnode, prevVNode, instance, name) { + const bindings = vnode.dirs; + const oldBindings = prevVNode && prevVNode.dirs; + for (let i = 0; i < bindings.length; i++) { + const binding = bindings[i]; + if (oldBindings) { + binding.oldValue = oldBindings[i].value; + } + let hook = binding.dir[name]; + if (!hook) { + hook = mapCompatDirectiveHook(name, binding.dir, instance); + } + if (hook) { + callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [ + vnode.el, + binding, + vnode, + prevVNode + ]); + } + } +} + +// dev only +function installLegacyConfigWarnings(config) { + const legacyConfigOptions = { + silent: "CONFIG_SILENT" /* CONFIG_SILENT */, + devtools: "CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */, + ignoredElements: "CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */, + keyCodes: "CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */, + productionTip: "CONFIG_PRODUCTION_TIP" /* CONFIG_PRODUCTION_TIP */ + }; + Object.keys(legacyConfigOptions).forEach(key => { + let val = config[key]; + Object.defineProperty(config, key, { + enumerable: true, + get() { + return val; + }, + set(newVal) { + if (!isCopyingConfig) { + warnDeprecation(legacyConfigOptions[key], null); + } + val = newVal; + } + }); + }); +} +function installLegacyOptionMergeStrats(config) { + config.optionMergeStrategies = new Proxy({}, { + get(target, key) { + if (key in target) { + return target[key]; + } + if (key in legacyOptionMergeStrats && + softAssertCompatEnabled("CONFIG_OPTION_MERGE_STRATS" /* CONFIG_OPTION_MERGE_STRATS */, null)) { + return legacyOptionMergeStrats[key]; + } + } + }); +} +const legacyOptionMergeStrats = { + data: mergeDataOption, + beforeCreate: mergeHook, + created: mergeHook, + beforeMount: mergeHook, + mounted: mergeHook, + beforeUpdate: mergeHook, + updated: mergeHook, + beforeDestroy: mergeHook, + destroyed: mergeHook, + activated: mergeHook, + deactivated: mergeHook, + errorCaptured: mergeHook, + serverPrefetch: mergeHook, + // assets + components: mergeObjectOptions, + directives: mergeObjectOptions, + filters: mergeObjectOptions, + // objects + props: mergeObjectOptions, + methods: mergeObjectOptions, + inject: mergeObjectOptions, + computed: mergeObjectOptions, + // watch has special merge behavior in v2, but isn't actually needed in v3. + // since we are only exposing these for compat and nobody should be relying + // on the watch-specific behavior, just expose the object merge strat. + watch: mergeObjectOptions +}; +function mergeHook(to, from) { + return Array.from(new Set([...(isArray(to) ? to : to ? [to] : []), from])); +} +function mergeObjectOptions(to, from) { + return to ? extend(extend(Object.create(null), to), from) : from; +} + +let isCopyingConfig = false; +// exported only for test +let singletonApp; +let singletonCtor; +// Legacy global Vue constructor +function createCompatVue(createApp, createSingletonApp) { + singletonApp = createSingletonApp({}); + const Vue = (singletonCtor = function Vue(options = {}) { + return createCompatApp(options, Vue); + }); + function createCompatApp(options = {}, Ctor) { + assertCompatEnabled("GLOBAL_MOUNT" /* GLOBAL_MOUNT */, null); + const { data } = options; + if (data && + !isFunction(data) && + softAssertCompatEnabled("OPTIONS_DATA_FN" /* OPTIONS_DATA_FN */, null)) { + options.data = () => data; + } + const app = createApp(options); + if (Ctor !== Vue) { + applySingletonPrototype(app, Ctor); + } + const vm = app._createRoot(options); + if (options.el) { + return vm.$mount(options.el); + } + else { + return vm; + } + } + Vue.version = "3.1.0-beta.2"; + Vue.config = singletonApp.config; + Vue.use = (p, ...options) => { + if (p && isFunction(p.install)) { + p.install(Vue, ...options); + } + else if (isFunction(p)) { + p(Vue, ...options); + } + return Vue; + }; + Vue.mixin = m => { + singletonApp.mixin(m); + return Vue; + }; + Vue.component = ((name, comp) => { + if (comp) { + singletonApp.component(name, comp); + return Vue; + } + else { + return singletonApp.component(name); + } + }); + Vue.directive = ((name, dir) => { + if (dir) { + singletonApp.directive(name, dir); + return Vue; + } + else { + return singletonApp.directive(name); + } + }); + Vue.options = { _base: Vue }; + let cid = 1; + Vue.cid = cid; + Vue.nextTick = nextTick; + const extendCache = new WeakMap(); + function extendCtor(extendOptions = {}) { + assertCompatEnabled("GLOBAL_EXTEND" /* GLOBAL_EXTEND */, null); + if (isFunction(extendOptions)) { + extendOptions = extendOptions.options; + } + if (extendCache.has(extendOptions)) { + return extendCache.get(extendOptions); + } + const Super = this; + function SubVue(inlineOptions) { + if (!inlineOptions) { + return createCompatApp(SubVue.options, SubVue); + } + else { + return createCompatApp(mergeOptions(extend({}, SubVue.options), inlineOptions, null, legacyOptionMergeStrats), SubVue); + } + } + SubVue.super = Super; + SubVue.prototype = Object.create(Vue.prototype); + SubVue.prototype.constructor = SubVue; + // clone non-primitive base option values for edge case of mutating + // extended options + const mergeBase = {}; + for (const key in Super.options) { + const superValue = Super.options[key]; + mergeBase[key] = isArray(superValue) + ? superValue.slice() + : isObject(superValue) + ? extend(Object.create(null), superValue) + : superValue; + } + SubVue.options = mergeOptions(mergeBase, extendOptions, null, legacyOptionMergeStrats); + SubVue.options._base = SubVue; + SubVue.extend = extendCtor.bind(SubVue); + SubVue.mixin = Super.mixin; + SubVue.use = Super.use; + SubVue.cid = ++cid; + extendCache.set(extendOptions, SubVue); + return SubVue; + } + Vue.extend = extendCtor.bind(Vue); + Vue.set = (target, key, value) => { + assertCompatEnabled("GLOBAL_SET" /* GLOBAL_SET */, null); + target[key] = value; + }; + Vue.delete = (target, key) => { + assertCompatEnabled("GLOBAL_DELETE" /* GLOBAL_DELETE */, null); + delete target[key]; + }; + Vue.observable = (target) => { + assertCompatEnabled("GLOBAL_OBSERVABLE" /* GLOBAL_OBSERVABLE */, null); + return reactive(target); + }; + Vue.filter = ((name, filter) => { + if (filter) { + singletonApp.filter(name, filter); + return Vue; + } + else { + return singletonApp.filter(name); + } + }); + // internal utils - these are technically internal but some plugins use it. + const util = { + warn: warn , + extend, + mergeOptions: (parent, child, vm) => mergeOptions(parent, child, vm && vm.$, vm ? undefined : legacyOptionMergeStrats), + defineReactive + }; + Object.defineProperty(Vue, 'util', { + get() { + assertCompatEnabled("GLOBAL_PRIVATE_UTIL" /* GLOBAL_PRIVATE_UTIL */, null); + return util; + } + }); + Vue.configureCompat = configureCompat; + return Vue; +} +function installAppCompatProperties(app, context, render) { + installFilterMethod(app, context); + installLegacyOptionMergeStrats(app.config); + if (!singletonApp) { + // this is the call of creating the singleton itself so the rest is + // unnecessary + return; + } + installCompatMount(app, context, render); + installLegacyAPIs(app); + applySingletonAppMutations(app); + installLegacyConfigWarnings(app.config); +} +function installFilterMethod(app, context) { + context.filters = {}; + app.filter = (name, filter) => { + assertCompatEnabled("FILTERS" /* FILTERS */, null); + if (!filter) { + return context.filters[name]; + } + if (context.filters[name]) { + warn(`Filter "${name}" has already been registered.`); + } + context.filters[name] = filter; + return app; + }; +} +function installLegacyAPIs(app) { + // expose global API on app instance for legacy plugins + Object.defineProperties(app, { + // so that app.use() can work with legacy plugins that extend prototypes + prototype: { + get() { + warnDeprecation("GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */, null); + return app.config.globalProperties; + } + }, + nextTick: { value: nextTick }, + extend: { value: singletonCtor.extend }, + set: { value: singletonCtor.set }, + delete: { value: singletonCtor.delete }, + observable: { value: singletonCtor.observable }, + util: { + get() { + return singletonCtor.util; + } + } + }); +} +function applySingletonAppMutations(app) { + ['mixins', 'components', 'directives', 'filters', 'deopt'].forEach(key => { + // @ts-ignore + app._context[key] = singletonApp._context[key]; + }); + // copy over global config mutations + isCopyingConfig = true; + for (const key in singletonApp.config) { + if (key === 'isNativeTag') + continue; + if (isRuntimeOnly() && + (key === 'isCustomElement' || key === 'compilerOptions')) { + continue; + } + const val = singletonApp.config[key]; + // @ts-ignore + app.config[key] = val; + // compat for runtime ignoredElements -> isCustomElement + if (key === 'ignoredElements' && + isCompatEnabled("CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */, null) && + !isRuntimeOnly() && + isArray(val)) { + app.config.compilerOptions.isCustomElement = tag => { + return val.some(v => (isString(v) ? v === tag : v.test(tag))); + }; + } + } + isCopyingConfig = false; + applySingletonPrototype(app, singletonCtor); +} +function applySingletonPrototype(app, Ctor) { + // copy prototype augmentations as config.globalProperties + const enabled = isCompatEnabled("GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */, null); + if (enabled) { + app.config.globalProperties = Object.create(Ctor.prototype); + } + let hasPrototypeAugmentations = false; + const descriptors = Object.getOwnPropertyDescriptors(Ctor.prototype); + for (const key in descriptors) { + if (key !== 'constructor') { + hasPrototypeAugmentations = true; + if (enabled) { + Object.defineProperty(app.config.globalProperties, key, descriptors[key]); + } + } + } + if (hasPrototypeAugmentations) { + warnDeprecation("GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */, null); + } +} +function installCompatMount(app, context, render) { + let isMounted = false; + /** + * Vue 2 supports the behavior of creating a component instance but not + * mounting it, which is no longer possible in Vue 3 - this internal + * function simulates that behavior. + */ + app._createRoot = options => { + const component = app._component; + const vnode = createVNode(component, options.propsData || null); + vnode.appContext = context; + const hasNoRender = !isFunction(component) && !component.render && !component.template; + const emptyRender = () => { }; + // create root instance + const instance = createComponentInstance(vnode, null, null); + // suppress "missing render fn" warning since it can't be determined + // until $mount is called + if (hasNoRender) { + instance.render = emptyRender; + } + setupComponent(instance); + vnode.component = instance; + // $mount & $destroy + // these are defined on ctx and picked up by the $mount/$destroy + // public property getters on the instance proxy. + // Note: the following assumes DOM environment since the compat build + // only targets web. It essentially includes logic for app.mount from + // both runtime-core AND runtime-dom. + instance.ctx._compat_mount = (selectorOrEl) => { + if (isMounted) { + warn(`Root instance is already mounted.`); + return; + } + let container; + if (typeof selectorOrEl === 'string') { + // eslint-disable-next-line + const result = document.querySelector(selectorOrEl); + if (!result) { + warn(`Failed to mount root instance: selector "${selectorOrEl}" returned null.`); + return; + } + container = result; + } + else { + // eslint-disable-next-line + container = selectorOrEl || document.createElement('div'); + } + const isSVG = container instanceof SVGElement; + // HMR root reload + { + context.reload = () => { + const cloned = cloneVNode(vnode); + // compat mode will use instance if not reset to null + cloned.component = null; + render(cloned, container, isSVG); + }; + } + // resolve in-DOM template if component did not provide render + // and no setup/mixin render functions are provided (by checking + // that the instance is still using the placeholder render fn) + if (hasNoRender && instance.render === emptyRender) { + // root directives check + { + for (let i = 0; i < container.attributes.length; i++) { + const attr = container.attributes[i]; + if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) { + warnDeprecation("GLOBAL_MOUNT_CONTAINER" /* GLOBAL_MOUNT_CONTAINER */, null); + break; + } + } + } + instance.render = null; + component.template = container.innerHTML; + finishComponentSetup(instance, false, true /* skip options */); + } + // clear content before mounting + container.innerHTML = ''; + // TODO hydration + render(vnode, container, isSVG); + if (container instanceof Element) { + container.removeAttribute('v-cloak'); + container.setAttribute('data-v-app', ''); + } + isMounted = true; + app._container = container; + container.__vue_app__ = app; + { + devtoolsInitApp(app, version); + } + return instance.proxy; + }; + instance.ctx._compat_destroy = () => { + if (isMounted) { + render(null, app._container); + { + devtoolsUnmountApp(app); + } + delete app._container.__vue_app__; + } + else { + const { bum, effects, um } = instance; + // beforeDestroy hooks + if (bum) { + invokeArrayFns(bum); + } + if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) { + instance.emit('hook:beforeDestroy'); + } + // stop effects + if (effects) { + for (let i = 0; i < effects.length; i++) { + stop(effects[i]); + } + } + // unmounted hook + if (um) { + invokeArrayFns(um); + } + if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) { + instance.emit('hook:destroyed'); + } + } + }; + return instance.proxy; + }; +} +const methodsToPatch = [ + 'push', + 'pop', + 'shift', + 'unshift', + 'splice', + 'sort', + 'reverse' +]; +const patched = new WeakSet(); +function defineReactive(obj, key, val) { + // it's possible for the orignial object to be mutated after being defined + // and expecting reactivity... we are covering it here because this seems to + // be a bit more common. + if (isObject(val) && !isReactive(val) && !patched.has(val)) { + const reactiveVal = reactive(val); + if (isArray(val)) { + methodsToPatch.forEach(m => { + // @ts-ignore + val[m] = (...args) => { + // @ts-ignore + Array.prototype[m].call(reactiveVal, ...args); + }; + }); + } + else { + Object.keys(val).forEach(key => { + try { + defineReactiveSimple(val, key, val[key]); + } + catch (e) { } + }); + } + } + const i = obj.$; + if (i && obj === i.proxy) { + // target is a Vue instance - define on instance.ctx + defineReactiveSimple(i.ctx, key, val); + i.accessCache = Object.create(null); + } + else if (isReactive(obj)) { + obj[key] = val; + } + else { + defineReactiveSimple(obj, key, val); + } +} +function defineReactiveSimple(obj, key, val) { + val = isObject(val) ? reactive(val) : val; + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + get() { + track(obj, "get" /* GET */, key); + return val; + }, + set(newVal) { + val = isObject(newVal) ? reactive(newVal) : newVal; + trigger(obj, "set" /* SET */, key, newVal); + } + }); +} + +function createAppContext() { + return { + app: null, + config: { + isNativeTag: NO, + performance: false, + globalProperties: {}, + optionMergeStrategies: {}, + errorHandler: undefined, + warnHandler: undefined, + compilerOptions: {} + }, + mixins: [], + components: {}, + directives: {}, + provides: Object.create(null) + }; +} +let uid$1 = 0; +function createAppAPI(render, hydrate) { + return function createApp(rootComponent, rootProps = null) { + if (rootProps != null && !isObject(rootProps)) { + warn(`root props passed to app.mount() must be an object.`); + rootProps = null; + } + const context = createAppContext(); + const installedPlugins = new Set(); + let isMounted = false; + const app = (context.app = { + _uid: uid$1++, + _component: rootComponent, + _props: rootProps, + _container: null, + _context: context, + version, + get config() { + return context.config; + }, + set config(v) { + { + warn(`app.config cannot be replaced. Modify individual options instead.`); + } + }, + use(plugin, ...options) { + if (installedPlugins.has(plugin)) { + warn(`Plugin has already been applied to target app.`); + } + else if (plugin && isFunction(plugin.install)) { + installedPlugins.add(plugin); + plugin.install(app, ...options); + } + else if (isFunction(plugin)) { + installedPlugins.add(plugin); + plugin(app, ...options); + } + else { + warn(`A plugin must either be a function or an object with an "install" ` + + `function.`); + } + return app; + }, + mixin(mixin) { + { + if (!context.mixins.includes(mixin)) { + context.mixins.push(mixin); + // global mixin with props/emits de-optimizes props/emits + // normalization caching. + if (mixin.props || mixin.emits) { + context.deopt = true; + } + } + else { + warn('Mixin has already been applied to target app' + + (mixin.name ? `: ${mixin.name}` : '')); + } + } + return app; + }, + component(name, component) { + { + validateComponentName(name, context.config); + } + if (!component) { + return context.components[name]; + } + if (context.components[name]) { + warn(`Component "${name}" has already been registered in target app.`); + } + context.components[name] = component; + return app; + }, + directive(name, directive) { + { + validateDirectiveName(name); + } + if (!directive) { + return context.directives[name]; + } + if (context.directives[name]) { + warn(`Directive "${name}" has already been registered in target app.`); + } + context.directives[name] = directive; + return app; + }, + mount(rootContainer, isHydrate, isSVG) { + if (!isMounted) { + const vnode = createVNode(rootComponent, rootProps); + // store app context on the root VNode. + // this will be set on the root instance on initial mount. + vnode.appContext = context; + // HMR root reload + { + context.reload = () => { + render(cloneVNode(vnode), rootContainer, isSVG); + }; + } + if (isHydrate && hydrate) { + hydrate(vnode, rootContainer); + } + else { + render(vnode, rootContainer, isSVG); + } + isMounted = true; + app._container = rootContainer; + rootContainer.__vue_app__ = app; + { + devtoolsInitApp(app, version); + } + return vnode.component.proxy; + } + else { + warn(`App has already been mounted.\n` + + `If you want to remount the same app, move your app creation logic ` + + `into a factory function and create fresh app instances for each ` + + `mount - e.g. \`const createMyApp = () => createApp(App)\``); + } + }, + unmount() { + if (isMounted) { + render(null, app._container); + { + devtoolsUnmountApp(app); + } + delete app._container.__vue_app__; + } + else { + warn(`Cannot unmount an app that is not mounted.`); + } + }, + provide(key, value) { + if (key in context.provides) { + warn(`App already provides property with key "${String(key)}". ` + + `It will be overwritten with the new value.`); + } + // TypeScript doesn't allow symbols as index type + // https://github.com/Microsoft/TypeScript/issues/24587 + context.provides[key] = value; + return app; + } + }); + { + installAppCompatProperties(app, context, render); + } + return app; + }; +} + +let hasMismatch = false; +const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; +const isComment = (node) => node.nodeType === 8 /* COMMENT */; +// Note: hydration is DOM-specific +// But we have to place it in core due to tight coupling with core - splitting +// it out creates a ton of unnecessary complexity. +// Hydration also depends on some renderer internal logic which needs to be +// passed in via arguments. +function createHydrationFunctions(rendererInternals) { + const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals; + const hydrate = (vnode, container) => { + if (!container.hasChildNodes()) { + warn(`Attempting to hydrate existing markup but container is empty. ` + + `Performing full mount instead.`); + patch(null, vnode, container); + return; + } + hasMismatch = false; + hydrateNode(container.firstChild, vnode, null, null, null); + flushPostFlushCbs(); + if (hasMismatch && !false) { + // this error should show up in production + console.error(`Hydration completed but contains mismatches.`); + } + }; + const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => { + const isFragmentStart = isComment(node) && node.data === '['; + const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart); + const { type, ref, shapeFlag } = vnode; + const domType = node.nodeType; + vnode.el = node; + let nextNode = null; + switch (type) { + case Text: + if (domType !== 3 /* TEXT */) { + nextNode = onMismatch(); + } + else { + if (node.data !== vnode.children) { + hasMismatch = true; + warn(`Hydration text mismatch:` + + `\n- Client: ${JSON.stringify(node.data)}` + + `\n- Server: ${JSON.stringify(vnode.children)}`); + node.data = vnode.children; + } + nextNode = nextSibling(node); + } + break; + case Comment: + if (domType !== 8 /* COMMENT */ || isFragmentStart) { + nextNode = onMismatch(); + } + else { + nextNode = nextSibling(node); + } + break; + case Static: + if (domType !== 1 /* ELEMENT */) { + nextNode = onMismatch(); + } + else { + // determine anchor, adopt content + nextNode = node; + // if the static vnode has its content stripped during build, + // adopt it from the server-rendered HTML. + const needToAdoptContent = !vnode.children.length; + for (let i = 0; i < vnode.staticCount; i++) { + if (needToAdoptContent) + vnode.children += nextNode.outerHTML; + if (i === vnode.staticCount - 1) { + vnode.anchor = nextNode; + } + nextNode = nextSibling(nextNode); + } + return nextNode; + } + break; + case Fragment: + if (!isFragmentStart) { + nextNode = onMismatch(); + } + else { + nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } + break; + default: + if (shapeFlag & 1 /* ELEMENT */) { + if (domType !== 1 /* ELEMENT */ || + vnode.type.toLowerCase() !== + node.tagName.toLowerCase()) { + nextNode = onMismatch(); + } + else { + nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } + } + else if (shapeFlag & 6 /* COMPONENT */) { + // when setting up the render effect, if the initial vnode already + // has .el set, the component will perform hydration instead of mount + // on its sub-tree. + vnode.slotScopeIds = slotScopeIds; + const container = parentNode(node); + mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized); + // component may be async, so in the case of fragments we cannot rely + // on component's rendered output to determine the end of the fragment + // instead, we do a lookahead to find the end anchor node. + nextNode = isFragmentStart + ? locateClosingAsyncAnchor(node) + : nextSibling(node); + } + else if (shapeFlag & 64 /* TELEPORT */) { + if (domType !== 8 /* COMMENT */) { + nextNode = onMismatch(); + } + else { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren); + } + } + else if (shapeFlag & 128 /* SUSPENSE */) { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode); + } + else { + warn('Invalid HostVNode type:', type, `(${typeof type})`); + } + } + if (ref != null) { + setRef(ref, null, parentSuspense, vnode); + } + return nextNode; + }; + const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { + optimized = optimized || !!vnode.dynamicChildren; + const { props, patchFlag, shapeFlag, dirs } = vnode; + // skip props & children if this is hoisted static nodes + if (patchFlag !== -1 /* HOISTED */) { + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, 'created'); + } + // props + if (props) { + if (!optimized || + (patchFlag & 16 /* FULL_PROPS */ || + patchFlag & 32 /* HYDRATE_EVENTS */)) { + for (const key in props) { + if (!isReservedProp(key) && isOn(key)) { + patchProp(el, key, null, props[key]); + } + } + } + else if (props.onClick) { + // Fast path for click listeners (which is most often) to avoid + // iterating through props. + patchProp(el, 'onClick', null, props.onClick); + } + } + // vnode / directive hooks + let vnodeHooks; + if ((vnodeHooks = props && props.onVnodeBeforeMount)) { + invokeVNodeHook(vnodeHooks, parentComponent, vnode); + } + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); + } + if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { + queueEffectWithSuspense(() => { + vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); + dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); + }, parentSuspense); + } + // children + if (shapeFlag & 16 /* ARRAY_CHILDREN */ && + // skip if element has innerHTML / textContent + !(props && (props.innerHTML || props.textContent))) { + let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized); + let hasWarned = false; + while (next) { + hasMismatch = true; + if (!hasWarned) { + warn(`Hydration children mismatch in <${vnode.type}>: ` + + `server rendered element contains more child nodes than client vdom.`); + hasWarned = true; + } + // The SSRed DOM contains more nodes than it should. Remove them. + const cur = next; + next = next.nextSibling; + remove(cur); + } + } + else if (shapeFlag & 8 /* TEXT_CHILDREN */) { + if (el.textContent !== vnode.children) { + hasMismatch = true; + warn(`Hydration text content mismatch in <${vnode.type}>:\n` + + `- Client: ${el.textContent}\n` + + `- Server: ${vnode.children}`); + el.textContent = vnode.children; + } + } + } + return el.nextSibling; + }; + const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => { + optimized = optimized || !!parentVNode.dynamicChildren; + const children = parentVNode.children; + const l = children.length; + let hasWarned = false; + for (let i = 0; i < l; i++) { + const vnode = optimized + ? children[i] + : (children[i] = normalizeVNode(children[i])); + if (node) { + node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } + else if (vnode.type === Text && !vnode.children) { + continue; + } + else { + hasMismatch = true; + if (!hasWarned) { + warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` + + `server rendered element contains fewer child nodes than client vdom.`); + hasWarned = true; + } + // the SSRed DOM didn't contain enough nodes. Mount the missing ones. + patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); + } + } + return node; + }; + const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { + const { slotScopeIds: fragmentSlotScopeIds } = vnode; + if (fragmentSlotScopeIds) { + slotScopeIds = slotScopeIds + ? slotScopeIds.concat(fragmentSlotScopeIds) + : fragmentSlotScopeIds; + } + const container = parentNode(node); + const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized); + if (next && isComment(next) && next.data === ']') { + return nextSibling((vnode.anchor = next)); + } + else { + // fragment didn't hydrate successfully, since we didn't get a end anchor + // back. This should have led to node/children mismatch warnings. + hasMismatch = true; + // since the anchor is missing, we need to create one and insert it + insert((vnode.anchor = createComment(`]`)), container, next); + return next; + } + }; + const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => { + hasMismatch = true; + warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */ + ? `(text)` + : isComment(node) && node.data === '[' + ? `(start of fragment)` + : ``); + vnode.el = null; + if (isFragment) { + // remove excessive fragment nodes + const end = locateClosingAsyncAnchor(node); + while (true) { + const next = nextSibling(node); + if (next && next !== end) { + remove(next); + } + else { + break; + } + } + } + const next = nextSibling(node); + const container = parentNode(node); + remove(node); + patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); + return next; + }; + const locateClosingAsyncAnchor = (node) => { + let match = 0; + while (node) { + node = nextSibling(node); + if (node && isComment(node)) { + if (node.data === '[') + match++; + if (node.data === ']') { + if (match === 0) { + return nextSibling(node); + } + else { + match--; + } + } + } + } + return node; + }; + return [hydrate, hydrateNode]; +} + +let supported; +let perf; +function startMeasure(instance, type) { + if (instance.appContext.config.performance && isSupported()) { + perf.mark(`vue-${type}-${instance.uid}`); + } +} +function endMeasure(instance, type) { + if (instance.appContext.config.performance && isSupported()) { + const startTag = `vue-${type}-${instance.uid}`; + const endTag = startTag + `:end`; + perf.mark(endTag); + perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag); + perf.clearMarks(startTag); + perf.clearMarks(endTag); + } +} +function isSupported() { + if (supported !== undefined) { + return supported; + } + /* eslint-disable no-restricted-globals */ + if (typeof window !== 'undefined' && window.performance) { + supported = true; + perf = window.performance; + } + else { + supported = false; + } + /* eslint-enable no-restricted-globals */ + return supported; +} + +// implementation, close to no-op +function defineComponent(options) { + return isFunction(options) ? { setup: options, name: options.name } : options; +} + +const isAsyncWrapper = (i) => !!i.type.__asyncLoader; +function defineAsyncComponent(source) { + if (isFunction(source)) { + source = { loader: source }; + } + const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out + suspensible = true, onError: userOnError } = source; + let pendingRequest = null; + let resolvedComp; + let retries = 0; + const retry = () => { + retries++; + pendingRequest = null; + return load(); + }; + const load = () => { + let thisRequest; + return (pendingRequest || + (thisRequest = pendingRequest = loader() + .catch(err => { + err = err instanceof Error ? err : new Error(String(err)); + if (userOnError) { + return new Promise((resolve, reject) => { + const userRetry = () => resolve(retry()); + const userFail = () => reject(err); + userOnError(err, userRetry, userFail, retries + 1); + }); + } + else { + throw err; + } + }) + .then((comp) => { + if (thisRequest !== pendingRequest && pendingRequest) { + return pendingRequest; + } + if (!comp) { + warn(`Async component loader resolved to undefined. ` + + `If you are using retry(), make sure to return its return value.`); + } + // interop module default + if (comp && + (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { + comp = comp.default; + } + if (comp && !isObject(comp) && !isFunction(comp)) { + throw new Error(`Invalid async component load result: ${comp}`); + } + resolvedComp = comp; + return comp; + }))); + }; + return defineComponent({ + __asyncLoader: load, + name: 'AsyncComponentWrapper', + setup() { + const instance = currentInstance; + // already resolved + if (resolvedComp) { + return () => createInnerComp(resolvedComp, instance); + } + const onError = (err) => { + pendingRequest = null; + handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */); + }; + // suspense-controlled or SSR. + if ((suspensible && instance.suspense) || + (false )) { + return load() + .then(comp => { + return () => createInnerComp(comp, instance); + }) + .catch(err => { + onError(err); + return () => errorComponent + ? createVNode(errorComponent, { + error: err + }) + : null; + }); + } + const loaded = ref(false); + const error = ref(); + const delayed = ref(!!delay); + if (delay) { + setTimeout(() => { + delayed.value = false; + }, delay); + } + if (timeout != null) { + setTimeout(() => { + if (!loaded.value && !error.value) { + const err = new Error(`Async component timed out after ${timeout}ms.`); + onError(err); + error.value = err; + } + }, timeout); + } + load() + .then(() => { + loaded.value = true; + }) + .catch(err => { + onError(err); + error.value = err; + }); + return () => { + if (loaded.value && resolvedComp) { + return createInnerComp(resolvedComp, instance); + } + else if (error.value && errorComponent) { + return createVNode(errorComponent, { + error: error.value + }); + } + else if (loadingComponent && !delayed.value) { + return createVNode(loadingComponent); + } + }; + } + }); +} +function createInnerComp(comp, { vnode: { ref, props, children } }) { + const vnode = createVNode(comp, props, children); + // ensure inner component inherits the async wrapper's ref owner + vnode.ref = ref; + return vnode; +} + +function convertLegacyRefInFor(vnode) { + // refInFor + if (vnode.props && vnode.props.refInFor) { + delete vnode.props.refInFor; + if (vnode.ref) { + if (isArray(vnode.ref)) { + vnode.ref.forEach(r => (r.f = true)); + } + else { + vnode.ref.f = true; + } + } + } +} +function registerLegacyRef(refs, key, value, owner, isInFor, isUnmount) { + const existing = refs[key]; + if (isUnmount) { + if (isArray(existing)) { + remove(existing, value); + } + else { + refs[key] = null; + } + } + else if (isInFor) { + warnDeprecation("V_FOR_REF" /* V_FOR_REF */, owner); + if (!isArray(existing)) { + refs[key] = [value]; + } + else if (!existing.includes(value)) { + existing.push(value); + } + } + else { + refs[key] = value; + } +} + +function createDevEffectOptions(instance) { + return { + scheduler: queueJob, + allowRecurse: true, + onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0, + onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0 + }; +} +const queuePostRenderEffect = queueEffectWithSuspense + ; +const setRef = (rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) => { + if (isArray(rawRef)) { + rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount)); + return; + } + if (isAsyncWrapper(vnode) && !isUnmount) { + // when mounting async components, nothing needs to be done, + // because the template ref is forwarded to inner component + return; + } + const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ + ? vnode.component.exposed || vnode.component.proxy + : vnode.el; + const value = isUnmount ? null : refValue; + const { i: owner, r: ref } = rawRef; + if (!owner) { + warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` + + `A vnode with ref must be created inside the render function.`); + return; + } + const oldRef = oldRawRef && oldRawRef.r; + const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs; + const setupState = owner.setupState; + // dynamic ref changed. unset old ref + if (oldRef != null && oldRef !== ref) { + if (isString(oldRef)) { + refs[oldRef] = null; + if (hasOwn(setupState, oldRef)) { + setupState[oldRef] = null; + } + } + else if (isRef(oldRef)) { + oldRef.value = null; + } + } + if (isString(ref)) { + const doSet = () => { + if (isCompatEnabled("V_FOR_REF" /* V_FOR_REF */, owner)) { + registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount); + } + else { + refs[ref] = value; + } + if (hasOwn(setupState, ref)) { + setupState[ref] = value; + } + }; + // #1789: for non-null values, set them after render + // null values means this is unmount and it should not overwrite another + // ref with the same key + if (value) { + doSet.id = -1; + queuePostRenderEffect(doSet, parentSuspense); + } + else { + doSet(); + } + } + else if (isRef(ref)) { + const doSet = () => { + ref.value = value; + }; + if (value) { + doSet.id = -1; + queuePostRenderEffect(doSet, parentSuspense); + } + else { + doSet(); + } + } + else if (isFunction(ref)) { + callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]); + } + else { + warn('Invalid template ref type:', value, `(${typeof value})`); + } +}; +/** + * The createRenderer function accepts two generic arguments: + * HostNode and HostElement, corresponding to Node and Element types in the + * host environment. For example, for runtime-dom, HostNode would be the DOM + * `Node` interface and HostElement would be the DOM `Element` interface. + * + * Custom renderers can pass in the platform specific types like this: + * + * ``` js + * const { render, createApp } = createRenderer({ + * patchProp, + * ...nodeOps + * }) + * ``` + */ +function createRenderer(options) { + return baseCreateRenderer(options); +} +// Separate API for creating hydration-enabled renderer. +// Hydration logic is only used when calling this function, making it +// tree-shakable. +function createHydrationRenderer(options) { + return baseCreateRenderer(options, createHydrationFunctions); +} +// implementation +function baseCreateRenderer(options, createHydrationFns) { + { + const target = getGlobalThis(); + target.__VUE__ = true; + setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__); + } + const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options; + // Note: functions inside this closure should use `const xxx = () => {}` + // style in order to prevent being inlined by minifiers. + const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = false) => { + // patching & not same type, unmount old tree + if (n1 && !isSameVNodeType(n1, n2)) { + anchor = getNextHostNode(n1); + unmount(n1, parentComponent, parentSuspense, true); + n1 = null; + } + if (n2.patchFlag === -2 /* BAIL */) { + optimized = false; + n2.dynamicChildren = null; + } + const { type, ref, shapeFlag } = n2; + switch (type) { + case Text: + processText(n1, n2, container, anchor); + break; + case Comment: + processCommentNode(n1, n2, container, anchor); + break; + case Static: + if (n1 == null) { + mountStaticNode(n2, container, anchor, isSVG); + } + else { + patchStaticNode(n1, n2, container, isSVG); + } + break; + case Fragment: + processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); + break; + default: + if (shapeFlag & 1 /* ELEMENT */) { + processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); + } + else if (shapeFlag & 6 /* COMPONENT */) { + processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); + } + else if (shapeFlag & 64 /* TELEPORT */) { + type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); + } + else if (shapeFlag & 128 /* SUSPENSE */) { + type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); + } + else { + warn('Invalid VNode type:', type, `(${typeof type})`); + } + } + // set ref + if (ref != null && parentComponent) { + setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2); + } + }; + const processText = (n1, n2, container, anchor) => { + if (n1 == null) { + hostInsert((n2.el = hostCreateText(n2.children)), container, anchor); + } + else { + const el = (n2.el = n1.el); + if (n2.children !== n1.children) { + hostSetText(el, n2.children); + } + } + }; + const processCommentNode = (n1, n2, container, anchor) => { + if (n1 == null) { + hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor); + } + else { + // there's no support for dynamic comments + n2.el = n1.el; + } + }; + const mountStaticNode = (n2, container, anchor, isSVG) => { + [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); + }; + /** + * Dev / HMR only + */ + const patchStaticNode = (n1, n2, container, isSVG) => { + // static nodes are only patched during dev for HMR + if (n2.children !== n1.children) { + const anchor = hostNextSibling(n1.anchor); + // remove existing + removeStaticNode(n1); + [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); + } + else { + n2.el = n1.el; + n2.anchor = n1.anchor; + } + }; + const moveStaticNode = ({ el, anchor }, container, nextSibling) => { + let next; + while (el && el !== anchor) { + next = hostNextSibling(el); + hostInsert(el, container, nextSibling); + el = next; + } + hostInsert(anchor, container, nextSibling); + }; + const removeStaticNode = ({ el, anchor }) => { + let next; + while (el && el !== anchor) { + next = hostNextSibling(el); + hostRemove(el); + el = next; + } + hostRemove(anchor); + }; + const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { + isSVG = isSVG || n2.type === 'svg'; + if (n1 == null) { + mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); + } + else { + patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); + } + }; + const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { + let el; + let vnodeHook; + const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode; + { + el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props); + // mount children first, since some props may rely on child content + // being already rendered, e.g. `